# Copy of immutable with multiple fields changed

**URL:** <https://discourse.julialang.org/t/copy-of-immutable-with-multiple-fields-changed/29719>\
**Category:** General Usage\
**Tags:** question\
**Created:** [October 10, 2019, 8:23am UTC](https://discourse.julialang.org/t/copy-of-immutable-with-multiple-fields-changed/29719 "2019-10-10T08:23:53Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [October 10, 2019, 8:23am UTC](https://discourse.julialang.org/t/copy-of-immutable-with-multiple-fields-changed/29719/1 "2019-10-10T08:23:53Z")

</div>

Is there a package which makes it convenient to get a copy of an (immutable) `struct` with new values for some fields? I am aware of Setfield, but my understanding (see below) is that it requires nesting to do this.

```julia
using Setfield

struct Foo
    a
    b
    c
end

x = Foo(1, 2, 3)
y = @set (@set x.a = 'a').b = 'b' # making this simpler?

```

---

<div class="post-metadata">

**Author:** ![MatFi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/matfi/32/10002_2.png) [@MatFi](https://discourse.julialang.org/u/MatFi)\
**Post date:** [October 10, 2019, 9:10am UTC](https://discourse.julialang.org/t/copy-of-immutable-with-multiple-fields-changed/29719/2 "2019-10-10T09:10:02Z")

</div>

I am also looking for such a package. Right now i am using `Parameters.jl` wich allows for this

```julia
using Parameters

@with_kw struct Foo
   a
   b
   c
end

x = Foo(1, 2, 3)
y = Foo(x, a='a', b='b')

```

---

<div class="post-metadata">

**Author:** ![pmarg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pmarg/32/936_2.png) [@pmarg](https://discourse.julialang.org/u/pmarg)\
**Post date:** [October 10, 2019, 11:49am UTC](https://discourse.julialang.org/t/copy-of-immutable-with-multiple-fields-changed/29719/3 "2019-10-10T11:49:40Z")

</div>

This is a simplified version of my `set` function which takes a single argument. It can be extended for a tuple:

```julia
function set(str,var,val)
    !any(i->i==var, fieldnames(typeof(str))) && @warn "\n No field in struct $(typeof(str)) is named $(var)!\n Fields are $(fieldnames(typeof(str)))"
    dict = Dict{Symbol,Any}()
    for name in fieldnames(typeof(str))
        if name == var
            dict[name] = val
        else
            dict[name] = getfield(str,name)
        end
    end
    x = NamedTuple{Tuple(keys(dict))}(values(dict))
    str = typeof(str)(x...)
end

```

E.g.:

```julia
struct Foo
    a
    b
    c
end

x = Foo(1, 2, 3)

y = set(x, :a, 5)

julia> y
Foo(5, 2, 3)

```

There must be more efficient ways to deal with this with macros as in `Setfield.jl` but I don’t use it in performance-critical parts of the code so it works for me.

---

<div class="post-metadata">

**Author:** ![DrChainsaw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/drchainsaw/32/8497_2.png) [@DrChainsaw](https://discourse.julialang.org/u/DrChainsaw)\
**Post date:** [October 10, 2019, 11:58am UTC](https://discourse.julialang.org/t/copy-of-immutable-with-multiple-fields-changed/29719/4 "2019-10-10T11:58:57Z")

</div>

Setfield exports the function setproperites which allows you to set multiple fields in one call with a namedtuple:

```julia
julia> using Setfield

julia> struct A;a;b;c;end

julia> a = A(1,2,3)
A(1, 2, 3)

julia> setproperties(a, (b=5, c=7))
A(1, 5, 7)

```
