# Function which returns an immutable type using Metaprogramming

**URL:** <https://discourse.julialang.org/t/function-which-returns-an-immutable-type-using-metaprogramming/10824>\
**Category:** General Usage\
**Created:** [May 10, 2018, 9:20pm UTC](https://discourse.julialang.org/t/function-which-returns-an-immutable-type-using-metaprogramming/10824 "2018-05-10T21:20:02Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![bkang119](https://avatars.discourse-cdn.com/v4/letter/b/a3d4f5/32.png) [@bkang119](https://discourse.julialang.org/u/bkang119)\
**Post date:** [May 10, 2018, 9:20pm UTC](https://discourse.julialang.org/t/function-which-returns-an-immutable-type-using-metaprogramming/10824/1 "2018-05-10T21:20:02Z")

</div>

Hi I have a question on defining a function that returns an immutable type.  
To be specific, let me define two immutable types:

```julia
immutable test1
    a::Int64
    b::Int64
end

```

```julia
immutable test2
    a::Int64
    b::Bool
end

```

For `t1 = test1(1,1)` and `t2 = test2(1, true)`, I want to change `t1.a` and `t2.a` from `1` to, say, `2`. But since both `test1` and `test2` are immutable type, I cannot change the value in the usual way.

So I wrote a function as follows:

```julia
using Base.Cartesian
@generated function change_immutable(t::Any, name::Symbol, val::Any)
    names = fieldnames(t)
    len = length(names)
    quote
        @ncall $len typeof(t) i-> 
             getindex($names, i) == name ? val : getfield(t, i)
    end
end

```

The first argument takes any (immutable) type, the second argument takes the symbol in the type where the corresponding value needs to be changed to `val`, the third argument.  
For example, `change_immutable(t1, :a, 2)` gives `test1(2, 1)` and `change_immutable(t2, :a, 2)` gives `test2(2, true)`. I know that `t1` and `t2` haven’t changed, but that is okay and this function does what I want to implement.

But the problem is that `change_immutable` function sometimes allocates additional memory. Using the following function:

```julia
function memory_test(t)
    for i=1:1000
        change_immutable(t, :a, i)
    end
end

```

`@time memory_test(t1)` returns ` 0.000013 seconds (4 allocations: 160 bytes)` but  
`@time memory_test(t2)` returns `0.000067 seconds (1.49 k allocations: 39.047 KiB)`, which allocates additional memory compared to the first case.

Do you know how to construct a function that does the same thing as `change_immutable` yet allocates less memory even in `test2` immutable type?

---

<div class="post-metadata">

**Author:** ![jonathanBieler](https://avatars.discourse-cdn.com/v4/letter/j/82dd89/32.png) [@jonathanBieler](https://discourse.julialang.org/u/jonathanBieler)\
**Post date:** [May 11, 2018, 9:28am UTC](https://discourse.julialang.org/t/function-which-returns-an-immutable-type-using-metaprogramming/10824/2 "2018-05-11T09:28:38Z")

</div>

The extra allocation don’t happen on v0.7 so it seems to be some sort of optimization problem in v0.6.

Ideally you would want to directly generate the correct expression `T(t.f1,t.f2,t.f3,val,t.f4)` but I’m not sure that’s possible.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [May 11, 2018, 11:29am UTC](https://discourse.julialang.org/t/function-which-returns-an-immutable-type-using-metaprogramming/10824/3 "2018-05-11T11:29:02Z")

</div>

> **[GitHub - jw3126/Setfield.jl: Update deeply nested immutable structs.](https://github.com/jw3126/Setfield.jl)**
>
> Update deeply nested immutable structs. Contribute to jw3126/Setfield.jl development by creating an account on GitHub.

---

<div class="post-metadata">

**Author:** ![bkang119](https://avatars.discourse-cdn.com/v4/letter/b/a3d4f5/32.png) [@bkang119](https://discourse.julialang.org/u/bkang119)\
**Post date:** [May 12, 2018, 3:49pm UTC](https://discourse.julialang.org/t/function-which-returns-an-immutable-type-using-metaprogramming/10824/4 "2018-05-12T15:49:17Z")

</div>

Yes, I was using v0.6. Great to hear that v0.7 does not have this problem!

---

<div class="post-metadata">

**Author:** ![bkang119](https://avatars.discourse-cdn.com/v4/letter/b/a3d4f5/32.png) [@bkang119](https://discourse.julialang.org/u/bkang119)\
**Post date:** [May 12, 2018, 3:49pm UTC](https://discourse.julialang.org/t/function-which-returns-an-immutable-type-using-metaprogramming/10824/5 "2018-05-12T15:49:51Z")

</div>

This is what I’ve been looking for! Thanks a lot!!!
