# Functions as fields of mutable struct in if-elseif environment

**URL:** <https://discourse.julialang.org/t/functions-as-fields-of-mutable-struct-in-if-elseif-environment/17342>\
**Category:** General Usage\
**Created:** [November 9, 2018, 1:50pm UTC](https://discourse.julialang.org/t/functions-as-fields-of-mutable-struct-in-if-elseif-environment/17342 "2018-11-09T13:50:36Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Faber](https://avatars.discourse-cdn.com/v4/letter/f/97f17d/32.png) [@Faber](https://discourse.julialang.org/u/Faber)\
**Post date:** [November 9, 2018, 1:50pm UTC](https://discourse.julialang.org/t/functions-as-fields-of-mutable-struct-in-if-elseif-environment/17342/1 "2018-11-09T13:50:36Z")

</div>

Hi,  
so I’m trying to do define functions as fields of a mutable struct based on input parameters. The general structure of which has the following form

```julia
module TestModule
  mutable struct TestStruct
    F
    function TestStruct(args...)
        f(x) = x;
        if length(args)==0
            println("0 args")
            f(x) = x
            println("The value of f(x)=x at x=1.0 is $(f(1.0))")
            return new(f)
        elseif length(args)>0
            println("at least 1 arg")
            f(x) = -x;
            println("The value of f(x)=-x at x=1.0 is $(f(1.0))")
            return new(f)
        end
        end
    end
end

```

which seems to produce the wrong value for f(x), in the sense that

```julia
c=MyModule.MyStruct();

```

produces

```julia
0 args
The value of f(x)=x at x=1.0 is -1.0

```

which is wrong, and, e.g.

```julia
c=MyModule.MyStruct(1);

```

gives

```julia
at least 1 arg
The value of f(x)=-x at x=1.0 is -1.0

```

However, if I remove all occurrences of elseif , I get a correct assignment of c.F function to f(x) = x, i.e.

```julia
module TestModule
  mutable struct TestStruct
    F
    function TestStruct(args...)
        f(x) = x;
        if length(args)==0
            println("0 args")
            f(x) = x
            println("The value of f(x)=x at x=1.0 is $(f(1.0))")
            return new(f)    
        end
        end
    end
end

```

Is this behavior intentional? am I’m doing weird design flops?  
how do I get the field F of a mutable struct to be assigned the correct function in the ifelse environment?  
Thanks!

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [November 9, 2018, 2:06pm UTC](https://discourse.julialang.org/t/functions-as-fields-of-mutable-struct-in-if-elseif-environment/17342/2 "2018-11-09T14:06:24Z")

</div>

Use anonymous functions for `f` (`f = x -> x` and `f = x -> -x`), see e.g. [Defining a function inside if...else..end NOT as expected?](https://discourse.julialang.org/t/defining-a-function-inside-if-else-end-not-as-expected/13815). There is also an issue about this that I can’t find now.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [November 9, 2018, 2:10pm UTC](https://discourse.julialang.org/t/functions-as-fields-of-mutable-struct-in-if-elseif-environment/17342/3 "2018-11-09T14:10:41Z")

</div>

Yeah, this is an (in my opinion, unfortunate) consequence of Julia’s design. It’s not necessary to have a `struct` definition involved to see the issue, you can simply do:

```julia
julia> function foo()
         f() = 0
         if true
           f() = 1
         else
           f() = 2
         end
         return f
       end
foo (generic function with 1 method)

julia> f = foo()
f (generic function with 1 method)

julia> f()
2 # nooooooooo

```

Basically, inside a function, _all_ of those `f() = whatever` definitions get compiled before a particular branch of the `if-else` statement is chosen, and they all modify the definition of the same function `f()`. `f()` can only do one thing, so it ends up doing whatever the last definition was, even if that branch of the `if-else` will not be chosen at run-time.

Fortunately, the fix is very simple: if you use anonymous functions, you can make sure that each branch of the `if-else` returns a different, correct, anonymous function:

```julia
julia> function foo()
         if true
           f = () -> 1
         else 
           f = () -> 2
         end
       end
foo (generic function with 1 method)

julia> f = foo()
#7 (generic function with 1 method)

julia> f()
1 # what you expected

```

---

<div class="post-metadata">

**Author:** ![Faber](https://avatars.discourse-cdn.com/v4/letter/f/97f17d/32.png) [@Faber](https://discourse.julialang.org/u/Faber)\
**Post date:** [November 9, 2018, 5:37pm UTC](https://discourse.julialang.org/t/functions-as-fields-of-mutable-struct-in-if-elseif-environment/17342/4 "2018-11-09T17:37:31Z")

</div>

I really appreciate your reply, fixed my issue, saved me time. Always super helpful.  
Many thanks!
