# Ambiguity in change of variable behaviour in a struct?

**URL:** https://discourse.julialang.org/t/ambiguity-in-change-of-variable-behaviour-in-a-struct/113012
**Category:** General Usage
**Tags:** question
**Created:** [April 16, 2024, 1:18pm UTC](https://discourse.julialang.org/t/ambiguity-in-change-of-variable-behaviour-in-a-struct/113012 "2024-04-16T13:18:46Z")
**Posts on this page:** 14
**Page:** 1

<div class="post-metadata">

### Author: ![Maddy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maddy/32/210658_2.png) [@Maddy](https://discourse.julialang.org/u/Maddy)
#### Post date: [April 16, 2024, 1:18pm UTC](https://discourse.julialang.org/t/ambiguity-in-change-of-variable-behaviour-in-a-struct/113012/1 "2024-04-16T13:18:46Z")

</div>

I was recently writing some code and noticed a peculiar behaviour of structs

 ![image](https://global.discourse-cdn.com/julialang/original/3X/0/6/06613009ac54cdea0c759d3418a549ec1e3e1f98.png)

Notice how earlier, I define a variable a with value 1. I push this into a list. Change the value of the list variable but that doesn’t change ‘a’.

However, if I define a struct. And NOW push it into a list, and alter the list element. It changes the struct!  
What’s happening? Is it normal and preferred behaviour or an artifact of the mutable type or @kwdef argument?

---

<div class="post-metadata">

### Author: ![Daniel\_Berge](https://avatars.discourse-cdn.com/v4/letter/d/eb9ed0/32.png) [@Daniel\_Berge](https://discourse.julialang.org/u/Daniel_Berge)
#### Post date: [April 16, 2024, 1:27pm UTC](https://discourse.julialang.org/t/ambiguity-in-change-of-variable-behaviour-in-a-struct/113012/2 "2024-04-16T13:27:08Z")

</div>

That behavior is expected, the manual goes over this behavior in the section [Variables · The Julia Language](https://docs.julialang.org/en/v1/manual/variables/#man-assignment-expressions).

In the case of the mutable struct and `a = Hello(5)`. You are assigning the first index of the list to be bound to the variable `a`. At which point you are mutating the variable bound to `a`, and not assigning a new value to the first index of the list.

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [April 16, 2024, 1:49pm UTC](https://discourse.julialang.org/t/ambiguity-in-change-of-variable-behaviour-in-a-struct/113012/3 "2024-04-16T13:49:07Z")

</div>

The proper comparison of what you do with the mutable struct is what happens to your list in the first case. Note that the list element is modified, as the element of the struct, without changing the value bound to the label `a`:

```julia-repl
julia> a = 1
1

julia> list = []
Any[]

julia> push!(list, 1)
1-element Vector{Any}:
 1

julia> list[1] = 5
5

julia> list
1-element Vector{Any}:
 5

julia> a
1

```

The above is equivalent, in this sense, to:

```julia-repl
julia> mutable struct A
           x
       end

julia> s = A(a)
A(1)

julia> s.x = 5
5

julia> s
A(5)

julia> a
1

```

where the struct is playing the same role as the list, as being a mutable container of a data value.

---

<div class="post-metadata">

### Author: ![Maddy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maddy/32/210658_2.png) [@Maddy](https://discourse.julialang.org/u/Maddy)
#### Post date: [April 16, 2024, 2:19pm UTC](https://discourse.julialang.org/t/ambiguity-in-change-of-variable-behaviour-in-a-struct/113012/4 "2024-04-16T14:19:24Z")

</div>

Ahhh! Any specific reasons for that? Ig that’s the opposite of how normal variables work when pushed into a list.

Also, if I don’t want this behaviour, how would I define the list? Perhaps push a .copy of the struct?

---

<div class="post-metadata">

### Author: ![Maddy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maddy/32/210658_2.png) [@Maddy](https://discourse.julialang.org/u/Maddy)
#### Post date: [April 16, 2024, 2:19pm UTC](https://discourse.julialang.org/t/ambiguity-in-change-of-variable-behaviour-in-a-struct/113012/5 "2024-04-16T14:19:53Z")

</div>

I’m sorry I did not catch that…

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [April 16, 2024, 2:27pm UTC](https://discourse.julialang.org/t/ambiguity-in-change-of-variable-behaviour-in-a-struct/113012/6 "2024-04-16T14:27:40Z")

</div>

> [@Maddy](#):
>
> how normal variables

There aren’t “normal” or “not normal” variables. There are mutable values and immutable values.  
The `mutable struct` is mutable. Thus you can _mutate_ it, for example by changing `list[1].val = 5` as in your example. There, `list[1]` is a mutable struct of type `Hello`, and you are _mutating_ the value of `val` inside it. The list itself is also a mutable type, thus why you can replace the values of its elements.

In your original example, you are mutating the value `val` of the mutable struct that is stored in the first element of `list`.

And, indeed, if you want to mutate the instance that is stored in `list[1]` without affecting it outside, you need to copy it. That is the same as:

```julia-repl
julia> x = [1]
1-element Vector{Int64}:
 1

julia> list = [x]
1-element Vector{Vector{Int64}}:
 [1]

julia> list[1][1] = 0
0

julia> x
1-element Vector{Int64}:
 0

julia> list = [copy(x)]
1-element Vector{Vector{Int64}}:
 [0]

julia> list[1][1] = 2
2

julia> x
1-element Vector{Int64}:
 0

```

Where `x` is taking the role of your mutable struct.

---

<div class="post-metadata">

### Author: ![Maddy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maddy/32/210658_2.png) [@Maddy](https://discourse.julialang.org/u/Maddy)
#### Post date: [April 16, 2024, 2:53pm UTC](https://discourse.julialang.org/t/ambiguity-in-change-of-variable-behaviour-in-a-struct/113012/7 "2024-04-16T14:53:57Z")

</div>

Yeah, I understand mutable structs are mutable. So is the variable ‘a’ though. My question was, when pushed into a list, why is a new element indexed in a list that would now be unrelated to the root variable ‘a’. Whereas in case of a mutable struct, the pushed value is bound to the struct, not assigning a new value.

@Daniel_Berge did point out this is how struct behaviour is defined

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [April 16, 2024, 3:04pm UTC](https://discourse.julialang.org/t/ambiguity-in-change-of-variable-behaviour-in-a-struct/113012/8 "2024-04-16T15:04:44Z")

</div>

No, no, the `a` is just a label to a value. The value when `a = 1` is `1` an that is an immutable value. If you push `1` to a list, the label `a` is still bound to the value `1`. If you change the value of the list to something else (like `5`), that does not affect the value to which the label `a` is bound.

This is the same with a mutable value:

```julia
julia> x = [1];

julia> list = [x]
1-element Vector{Vector{Int64}}:
 [1]

julia> list[1] = [2] # bind list[1] to *another* value
1-element Vector{Int64}:
 2

```

So, in this sense, they are exactly the same. The difference is that if you do, above:

```julia
julia> list[1][1] = 5
5

julia> list
1-element Vector{Vector{Int64}}:
 [5]

```

you are _mutating_ `list[1]`, not assigning it to another value (mutable or not), as in the first case.

---

<div class="post-metadata">

### Author: ![Maddy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maddy/32/210658_2.png) [@Maddy](https://discourse.julialang.org/u/Maddy)
#### Post date: [April 16, 2024, 3:25pm UTC](https://discourse.julialang.org/t/ambiguity-in-change-of-variable-behaviour-in-a-struct/113012/9 "2024-04-16T15:25:41Z")

</div>

![image](https://global.discourse-cdn.com/julialang/original/3X/8/1/811feafdeb0b93a97c1453b4d814febb546926da.png)  
Ahhhhh now I get your point. Woah! I didn’t know that.

So any structure that inherently has its own elements… like a list, or a struct would be mutable? When pushed into a list, all variables are bound in their original form. When you redefine an element of the list, you just disconnect the variable. But if you mutate an element of the list’s element, does that mutate the actual struct that was bound in the first place?

That’s what I understood. Is that correct?

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [April 16, 2024, 4:22pm UTC](https://discourse.julialang.org/t/ambiguity-in-change-of-variable-behaviour-in-a-struct/113012/10 "2024-04-16T16:22:39Z")

</div>

> [@Maddy](#):
>
> or a struct would be mutable?

No, not really. A struct can be immutable as well, then you simply cannot do that:

```julia-repl
julia> struct A
           x
       end

julia> a = A(1)
A(1)

julia> list = [a]
1-element Vector{A}:
 A(1)

julia> list[1].x = 1
ERROR: setfield!: immutable struct of type A cannot be changed

```

To change `list[1]` you need to replace the structure completely (identically to if it was a number):

```julia-repl
julia> list[1] = A(2)
A(2)

julia> list
1-element Vector{A}:
 A(2)

```

---

<div class="post-metadata">

### Author: ![Maddy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maddy/32/210658_2.png) [@Maddy](https://discourse.julialang.org/u/Maddy)
#### Post date: [April 16, 2024, 4:26pm UTC](https://discourse.julialang.org/t/ambiguity-in-change-of-variable-behaviour-in-a-struct/113012/11 "2024-04-16T16:26:43Z")

</div>

All right, I have to admit… I did not know that! Woah! a = 2 followed by a = 3 does not change the value of a. But rather makes a point to a different element!

Gotta admit, never saw it this way in my years of programming. Thank you! (love the Julia documentation lol)

---

<div class="post-metadata">

### Author: ![Maddy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maddy/32/210658_2.png) [@Maddy](https://discourse.julialang.org/u/Maddy)
#### Post date: [April 16, 2024, 4:27pm UTC](https://discourse.julialang.org/t/ambiguity-in-change-of-variable-behaviour-in-a-struct/113012/12 "2024-04-16T16:27:12Z")

</div>

Also, you were right lol… thank you! Just read the Julia documentation!

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [April 16, 2024, 4:29pm UTC](https://discourse.julialang.org/t/ambiguity-in-change-of-variable-behaviour-in-a-struct/113012/13 "2024-04-16T16:29:52Z")

</div>

Note that this is the behavior in Python and most (all?) other interactive languages. The language where that can be really thought differently (as `a` being the container of the value, rather than simply a label given to a value, is Fortran - on the surface everything in Fortran looks like mutable objects).

---

<div class="post-metadata">

### Author: ![Maddy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maddy/32/210658_2.png) [@Maddy](https://discourse.julialang.org/u/Maddy)
#### Post date: [April 16, 2024, 5:13pm UTC](https://discourse.julialang.org/t/ambiguity-in-change-of-variable-behaviour-in-a-struct/113012/14 "2024-04-16T17:13:52Z")

</div>

ahaha I did check out the same on Python actually. Which is why I said I did not know this for all these years. Lol, Thank you for your help!
