# Changing field with a function in a mutable struct

**URL:** <https://discourse.julialang.org/t/changing-field-with-a-function-in-a-mutable-struct/84006>\
**Category:** General Usage\
**Tags:** struct\
**Created:** [July 9, 2022, 11:29pm UTC](https://discourse.julialang.org/t/changing-field-with-a-function-in-a-mutable-struct/84006 "2022-07-09T23:29:54Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![RicardoFR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ricardofr/32/37512_2.png) [@RicardoFR](https://discourse.julialang.org/u/RicardoFR)\
**Post date:** [July 9, 2022, 11:29pm UTC](https://discourse.julialang.org/t/changing-field-with-a-function-in-a-mutable-struct/84006/1 "2022-07-09T23:29:55Z")

</div>

Hello all!

I have a mutable struct that must carry a function in one of its fields. Once I assign it to a variable, however, I cannot change the function. Here’s an example:

```julia
mutable struct Foo{T<:Real,F<:Function}
    a::T
    f::F
end
bar = () -> 1
baz = () -> 2
foo = Foo(1,bar)
foo.f = baz

```

Which results in the following error:

```julia
ERROR: MethodError: Cannot `convert` an object of type var"#121#122" to an object of type var"#119#120"

```

I solved this by creating a new variable with the desired function and then assigning all fields except the function from the old variable to the new:

```julia
foobar = Foo(2,baz)
for name in fieldnames(Foo)
    if !(name === :f)
        setfield!(foobar,name,getfield(foo,name))
    end
end

```

However, this seems overly convoluted and naive. I was wondering if there is a simpler way?

---

<div class="post-metadata">

**Author:** ![affans](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/affans/32/11911_2.png) [@affans](https://discourse.julialang.org/u/affans)\
**Post date:** [July 10, 2022, 12:10am UTC](https://discourse.julialang.org/t/changing-field-with-a-function-in-a-mutable-struct/84006/2 "2022-07-10T00:10:56Z")

</div>

In Julia, each function is its own type, and so when you instantiate the struct, `f` becomes a fixed type and when you try to assign a different function to it, you are actually changing the type of that field. It’s no different than doing

```julia
mutable struct Foo 
   a::Int64 
end 
foo = Foo(1)
foo.a = "hello world" # fails 

```

However, I do not know how to answer your particular problem, though I am pretty sure it has a solution.

---

<div class="post-metadata">

**Author:** ![RicardoFR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ricardofr/32/37512_2.png) [@RicardoFR](https://discourse.julialang.org/u/RicardoFR)\
**Post date:** [July 10, 2022, 12:12am UTC](https://discourse.julialang.org/t/changing-field-with-a-function-in-a-mutable-struct/84006/3 "2022-07-10T00:12:07Z")

</div>

I appreciate the input!

---

<div class="post-metadata">

**Author:** ![brianguenter](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brianguenter/32/29519_2.png) [@brianguenter](https://discourse.julialang.org/u/brianguenter)\
**Post date:** [July 10, 2022, 12:56am UTC](https://discourse.julialang.org/t/changing-field-with-a-function-in-a-mutable-struct/84006/4 "2022-07-10T00:56:33Z")

</div>

Not sure why you need the function type in the type signature of your struct. But if that isn’t essential then this alternative will work:

```julia
mutable struct Foo{T<:Real}
    a::T
    f::Function
end

```

Foo is a concrete type so I would expect it to be efficient:

```julia
julia> foo = Foo(1,bar)
Foo{Int64}(1, var"#9#10"())

julia> foo.f = baz
#11 (generic function with 1 method)

julia> isconcretetype(typeof(foo))
true

```

@code\_warntype suggests there might be a type instability but @code\_llvm and @code\_native both look very efficient.

This function benchmarks well

```julia
f(a,f1,f2) = (a.f === f1) ? a.f = f2 : a.f = f1

julia> @benchmark f($foo,$bar,$baz)
BenchmarkTools.Trial: 10000 samples with 1000 evaluations.
 Range (min … max): 1.800 ns … 23.100 ns ┊ GC (min … max): 0.00% … 0.00%
 Time (median): 2.100 ns ┊ GC (median): 0.00%
 Time (mean ± σ): 2.161 ns ± 0.499 ns ┊ GC (mean ± σ): 0.00% ± 0.00%

  ▅ ▄ █ ▄ ▄ ▅ ▁ ▁ ▁
  █▁▁█▁▁▁█▁▁█▁▁▁█▁▁▁█▁▁█▁▁▁▇▁▁█▁▁▁█▁▁▁▅▁▁▆▁▁▁█▁▁▁▁▁▁▃▁▁▁▅▁▁▆ █
  1.8 ns Histogram: log(frequency) by time 3.4 ns <

 Memory estimate: 0 bytes, allocs estimate: 0.

```

so it looks like the compiler is generating efficient code for accessing the function field.

---

<div class="post-metadata">

**Author:** ![RicardoFR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ricardofr/32/37512_2.png) [@RicardoFR](https://discourse.julialang.org/u/RicardoFR)\
**Post date:** [July 10, 2022, 3:10am UTC](https://discourse.julialang.org/t/changing-field-with-a-function-in-a-mutable-struct/84006/5 "2022-07-10T03:10:23Z")

</div>

Thank you for the solution! Indeed I don’t recquire the function type in the type signature, I just read elsewhere that declaring a struct as such could improve efficiency.

Much appreciated!

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [July 10, 2022, 3:13am UTC](https://discourse.julialang.org/t/changing-field-with-a-function-in-a-mutable-struct/84006/6 "2022-07-10T03:13:20Z")

</div>

The moment you decided to store a `Function` inside the `struct` you kinda already thrown efficiency out of the window, so I would not worry.

---

<div class="post-metadata">

**Author:** ![RicardoFR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ricardofr/32/37512_2.png) [@RicardoFR](https://discourse.julialang.org/u/RicardoFR)\
**Post date:** [July 10, 2022, 3:16am UTC](https://discourse.julialang.org/t/changing-field-with-a-function-in-a-mutable-struct/84006/7 "2022-07-10T03:16:28Z")

</div>

Hmm, perhaps I could store the function symbol and have it evaluated with @eval and such later on?

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [July 10, 2022, 6:25am UTC](https://discourse.julialang.org/t/changing-field-with-a-function-in-a-mutable-struct/84006/8 "2022-07-10T06:25:27Z")

</div>

Do you really need the struct to be mutable? It’s easy to make a new `Foo` instance with the `f` field replaced:

```julia
julia> using Accessors

julia> struct Foo{T<:Real,F<:Function}
           a::T
           f::F
       end

julia> bar = () -> 1
#1 (generic function with 1 method)

julia> baz = () -> 2
#3 (generic function with 1 method)

julia> foo = Foo(1,bar)
Foo{Int64, var"#1#2"}(1, var"#1#2"())

julia> newfoo = @set foo.f = baz
Foo{Int64, var"#3#4"}(1, var"#3#4"())

```

Here, everything stays type-stable and performant.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [July 10, 2022, 3:24pm UTC](https://discourse.julialang.org/t/changing-field-with-a-function-in-a-mutable-struct/84006/9 "2022-07-10T15:24:10Z")

</div>

This probably would be worse, `eval` is even slower.

---

<div class="post-metadata">

**Author:** ![RicardoFR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ricardofr/32/37512_2.png) [@RicardoFR](https://discourse.julialang.org/u/RicardoFR)\
**Post date:** [July 11, 2022, 7:25pm UTC](https://discourse.julialang.org/t/changing-field-with-a-function-in-a-mutable-struct/84006/10 "2022-07-11T19:25:16Z")

</div>

Oooh that’s a nice take! I wasn’t aware of the Accessors package. Much appreciated!
