# Package Parameters, mutable struct as function argument

**URL:** <https://discourse.julialang.org/t/package-parameters-mutable-struct-as-function-argument/47175>\
**Category:** General Usage\
**Tags:** question, package, behavior, struct\
**Created:** [September 24, 2020, 3:50am UTC](https://discourse.julialang.org/t/package-parameters-mutable-struct-as-function-argument/47175 "2020-09-24T03:50:05Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![cricci](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cricci/32/25160_2.png) [@cricci](https://discourse.julialang.org/u/cricci)\
**Post date:** [September 24, 2020, 3:50am UTC](https://discourse.julialang.org/t/package-parameters-mutable-struct-as-function-argument/47175/1 "2020-09-24T03:50:05Z")

</div>

I am using the Parameters package to do some work. One of the parameters is an array and surprisingly the struct gets changed when I give it as an argument to a function that modify the array after unpacking

```julia
using Parameters

@with_kw struct MyStruct
    x::Array{Float64,1} = zeros(N)
end

function noModify(structIn::MyStruct)
    @unpack x = structIn
    x = ones(N)
end

function yesModify(structIn::MyStruct)
    @unpack x = structIn
    for i=1:N
        x[i] = 2.0
    end
end

N = 10
exampleStruct = MyStruct()

println(exampleStruct.x)
noModify(exampleStruct)
println(exampleStruct.x)
yesModify(exampleStruct)
println(exampleStruct.x)

@unpack x = exampleStruct
x = 3 * ones(N)
println(exampleStruct.x)
for i=1:N
    x[i] = 4.0
end
println(exampleStruct.x)

```

It runs as

```julia
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
[2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0]
[2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0]
[2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0]

```

As expected the function `noModify` doesn’t modify the global variable `exampleStruct`.  
What I found weird is that the function `yesModify` does!  
Of course doing it directly in the global scope doesn’t change anything. The only case that is unexpected for me is the one in the function `yesModify` that has a for loop inside.  
Am I missing something? is that something that is supposed to happen? I thought that even if I unpack something and modify it, the orignal structure (called `exampleStruct` in this case) should not change.

---

<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:** [September 24, 2020, 5:28am UTC](https://discourse.julialang.org/t/package-parameters-mutable-struct-as-function-argument/47175/2 "2020-09-24T05:28:50Z")

</div>

This is just how Julia works. Unpacking scope, and structs are all just distractions here–the core of the matter is:

```julia
julia> a = [1, 2, 3]
3-element Array{Int64,1}:
 1
 2
 3

julia> b = a
3-element Array{Int64,1}:
 1
 2
 3

```

At this point, `b` and `a` are labels for the _same_ array. Modifying an entry of `b` modifies `a` as well because they are labels of the same value:

```julia
julia> b === a
true

julia> b[1] = 5
5

julia> a
3-element Array{Int64,1}:
 5
 2
 3

```

However, if you do:

```julia
b = ones(3)

```

Then you have created a _new_ array of ones and then attached the `b` label to that new array. `b` and `a` are now completely unrelated, and your change to `b` has no effect on `a`:

```julia
julia> b === a
false

julia> a
3-element Array{Int64,1}:
 5
 2
 3

```

`@unpack` is just a helpful macro to produce syntax like `x = structIn.x`. That means that `x` is just a label attached to the same data as `structIn.x`. Modifying an entry of `x` must then modify the data in `structIn` because they are still the same array. Doing `x = ones(N)` creates a new array and attaches the `x` label to that array. This now has nothing to do with `structIn`’s data, so it is not modified.

---

<div class="post-metadata">

**Author:** ![mchitre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mchitre/32/13756_2.png) [@mchitre](https://discourse.julialang.org/u/mchitre)\
**Post date:** [September 24, 2020, 5:52am UTC](https://discourse.julialang.org/t/package-parameters-mutable-struct-as-function-argument/47175/3 "2020-09-24T05:52:47Z")

</div>

Just one point to add in addition to @rdeits response…

The only reason you’re not seeing the modification in your global scope code:

```julia
for i=1:N
    x[i] = 4.0
end

```

is because the `x = 3 * ones(N)` call just before reassigned `x` to not be an alias for the `exampleStruct.x`. Whether in global of function scope, @rdeits explanation above is valid.

---

<div class="post-metadata">

**Author:** ![cricci](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cricci/32/25160_2.png) [@cricci](https://discourse.julialang.org/u/cricci)\
**Post date:** [September 24, 2020, 6:21am UTC](https://discourse.julialang.org/t/package-parameters-mutable-struct-as-function-argument/47175/4 "2020-09-24T06:21:44Z")

</div>

Thanks @rdeits, @mchitre! Now it’s more clear
