# Conditional evaluation of lines

**URL:** <https://discourse.julialang.org/t/conditional-evaluation-of-lines/57426>\
**Category:** General Usage\
**Created:** [March 18, 2021, 12:58am UTC](https://discourse.julialang.org/t/conditional-evaluation-of-lines/57426 "2021-03-18T00:58:41Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)\
**Post date:** [March 18, 2021, 12:58am UTC](https://discourse.julialang.org/t/conditional-evaluation-of-lines/57426/1 "2021-03-18T00:58:41Z")

</div>

I have a function `f` that creates and filsl a vector of `n` components with the result of expensive functions `gi`. I am interested in having `f` depend on `n`. I have tried the following, but I’m wondering if there is a better, perhaps more elegant way:

```julia
function f(n)
    a = Vector{Float64}(undef, n)

    (n >= 1) && (a[1] = g1(x, y, z))
    (n >= 2) && (a[2] = g2(x, y, z))
    (n >= 3) && (a[3] = g3(x, y, z))
    (n >= 4) && (a[4] = g4(x, y, z))
    (n >= 5) && (a[5] = g5(x, y, z))

    return sum(a)
end

```

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [March 18, 2021, 1:09am UTC](https://discourse.julialang.org/t/conditional-evaluation-of-lines/57426/2 "2021-03-18T01:09:23Z")

</div>

> [@amrods](#):
>
> I have tried the following, but I’m wondering if there is a better, perhaps more elegant way:

Have an array of functions, or pass `i` as a parameter to `g`? That way you can write a loop.

> [@amrods](#):
>
> `return sum(a)`

There’s not much point in allocating an array `a` just to sum it. Why not just add up the results directly?

Also, where are `x,y,z` coming from? Hopefully not globals?

Combining the above suggestions, you could have e.g. `f(n, x,y,z) = sum(i -> g(i,x,y,z), 1:n)`.

---

<div class="post-metadata">

**Author:** ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)\
**Post date:** [March 18, 2021, 1:22am UTC](https://discourse.julialang.org/t/conditional-evaluation-of-lines/57426/3 "2021-03-18T01:22:15Z")

</div>

> [@stevengj](#):
>
> Have an array of functions, or pass `i` as a parameter to `g` ? That way you can write a loop.

The problem is that `gi` are hard to parameterize with respect to `i`. I guess I can create another function, but then I would just write that hard coding of `gi` to that auxiliary function, instead of inside `f`.

> [@stevengj](#):
>
> Also, where are `x,y,z` coming from? Hopefully not globals?

I’m not worried about performance here. This is just a mwe. Those `x,y,z` are just my implicit attempt at saying “don’t worry about that”.

I take your point about allocating a vector. Perhaps this is better:

```julia
function f(n)
    a = 0.0

    (n >= 1) && (a += g1(x, y, z))
    (n >= 2) && (a += g2(x, y, z))
    (n >= 3) && (a += g3(x, y, z))
    (n >= 4) && (a += g4(x, y, z))
    (n >= 5) && (a += g5(x, y, z))

    return a
end

```

---

<div class="post-metadata">

**Author:** ![tchr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tchr/32/15138_2.png) [@tchr](https://discourse.julialang.org/u/tchr)\
**Post date:** [March 18, 2021, 2:08am UTC](https://discourse.julialang.org/t/conditional-evaluation-of-lines/57426/4 "2021-03-18T02:08:38Z")

</div>

The suggestion of using an array of functions  
is nice and general:

```nohighlight
gs = (g1, g2, g3, g4, g5)
sum(i -> gs[i](x,y,z), 1:n)

```

---

<div class="post-metadata">

**Author:** ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)\
**Post date:** [March 18, 2021, 5:07am UTC](https://discourse.julialang.org/t/conditional-evaluation-of-lines/57426/5 "2021-03-18T05:07:50Z")

</div>

suppose each argument that goes inside the `gi` is different, can I form an array like your `gs` that doesn’t evaluate when it is assigned?

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [March 18, 2021, 5:52am UTC](https://discourse.julialang.org/t/conditional-evaluation-of-lines/57426/7 "2021-03-18T05:52:20Z")

</div>

> [@amrods](#):
>
> suppose each argument that goes inside the `gi` is different,

What does this mean? Are you sure that your MWE captures the essential parts of the problem?

> [@amrods](#):
>
> can I form an array like your `gs` that doesn’t evaluate when it is assigned?

Not sure I understand, but do you mean something like this:

```julia
gs = (()->g1(x, y, z), ()->g2(a, b),...) 

```

?

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [March 18, 2021, 5:59am UTC](https://discourse.julialang.org/t/conditional-evaluation-of-lines/57426/8 "2021-03-18T05:59:25Z")

</div>

> [@amrods](#):
>
> > [@stevengj](#):
> >
> > Also, where are `x,y,z` coming from? Hopefully not globals?
> 
> I’m not worried about performance here. This is just a mwe.

I think it’s good to get into this way of thinking as a matter of habit. This is a typical performance trap, and it’s good to just always keep these things at the back of your mind. The same goes for the unnecessary vector.

BTW, it’s not an actual MWE unless it runs.

---

<div class="post-metadata">

**Author:** ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)\
**Post date:** [March 18, 2021, 6:33am UTC](https://discourse.julialang.org/t/conditional-evaluation-of-lines/57426/9 "2021-03-18T06:33:09Z")

</div>

Let me try again.

```julia
using ComponentArrays
using Parameters

args = ComponentArray(x1 = 1, x2 = 2, y2 = 2, x3 = 3, y3 = 3, z3 = 3)

function g1(a1, args)
    @unpack x1 = args
    @assert x1 == a1
    sleep(1)
    return x1
end

function g2(a2, b2, args)
    @unpack x2, y2 = args
    @assert x2 == a2 && y2 == b2
    sleep(2)
    return x2
end

function g3(a3, b3, c3, args)
    @unpack x3, y3, z3 = args
    @assert x3 == a3 && y3 == b3 && z3 == c3
    sleep(3)
    return x3
end

function f(n, args)
    @unpack x1, x2, y2, x3, y3, z3 = args
    a = zero(eltype(args))

    (n >= 1) && (a += g1(1, args))
    (n >= 2) && (a += g2(2, 2, args))
    (n >= 3) && (a += g3(3, 3, 3, args))

    return a
end

```

That should run without problem. What I am looking for is whether there exists a better way of doing what `f` is doing. That is, only evaluating the functions `gi` when they are necessary.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [March 18, 2021, 7:57am UTC](https://discourse.julialang.org/t/conditional-evaluation-of-lines/57426/10 "2021-03-18T07:57:50Z")

</div>

A bit in a hurry here, but I would wrap both the functions and the arguments in two different containers, either tuples or vectors, and then do something like this:

```julia
function f(fun, args, n=length(fun))
    a = zero(something)
    for i in 1:n
        a += fun[i](args[i]...)
    end
    return a
end

```
