# Assignment and mutation

Subtle differences between assignment and mutation in Julia as shown in the script below are easy to be missed or misunderstood by a beginner like me. I’m starting to understand and realize the importance, but still not really confident. If there’s a good (clear, plain, accurate and concise) document on the issue for beginners, I really appreciate a pointer to it.

In the script below, temp(a) has an assignment, and temp1(a) a mutation. The difference is just a dot, and the results look the same [4,5,6]. It’s hard for a beginner to realize they are actually different arrays. Interestingly, temp1(a) allocates more than six times of memory than temp(a) and slower (true when @benchmark is used).

temp2(a) is same as temp1(a) except it returns nothing. It has smaller allocation and faster execution than the other two functions.

I was naively using functions like temp(a), but realize that I should use functions like temp2(a) as temp!(a) when I mean mutation of the array a. Is this thinking correct?

``````a = [1,2,3];
``````
``````function temp(a)
a = [4,5,6]
end
function temp1(a)
a .= [4,5,6]
end
function temp2(a)
a .= [4,5,6]
return nothing
end
``````
``````temp2 (generic function with 1 method)
``````
``````@time a1 = temp(a)
``````
``````  0.007462 seconds (3.14 k allocations: 163.691 KiB)

3-element Array{Int64,1}:
4
5
6
``````
``````@time a2 = temp1(a)
``````
``````  0.056520 seconds (20.21 k allocations: 1.006 MiB)

3-element Array{Int64,1}:
4
5
6
``````
``````a == a1 == a2
``````
``````true
``````
``````a === a1
``````
``````false
``````
``````a === a2
``````
``````true
``````
``````a = [1,2,3]
``````
``````3-element Array{Int64,1}:
1
2
3
``````
``````@time temp2(a)
``````
``````  0.005079 seconds (217 allocations: 12.904 KiB)
``````
``````a
``````
``````3-element Array{Int64,1}:
4
5
6``````
2 Likes

Maybe this is a good read: http://www.johnmyleswhite.com/notebook/2014/09/06/values-vs-bindings-the-map-is-not-the-territory/

3 Likes

Perhaps this will help as well: Primitive and Composite? Types

2 Likes

The simplest version of this I can come up with is this:

• Assignment changes which object a name refers to: `x = ex` causes the name `x` to refer to the value resulting from the evaluation of the expression `ex`. Assignment never changes the values of any objects.

• Mutation changes the value of an object: `x[i] = ex` and `x.f = ex` both mutate the object referred to by `x` changing a value at index or a property with a name, respectively. Mutation never changes what objects any names in any scope refer to.

Perhaps the confusion comes from the fact that these all use the `=` in their syntax? They’re really totally unrelated. It’s also possible that people think of assignment as setting a named property on some implicit “scope object”. That’s probably a view that can be worked out coherently, in which case having a clear notion of what all the different “scope objects” are would be crucial but I’m not entirely sure if that’s a helpful way to think about the matter or not.

6 Likes

Thanks for the pointer.

I needed to know how to make sure an array in a function was mutating, not copying when I used it thousands of times repeatedly. Because copying increases allocation and tons of garbage collection tend to make it slow.

Thank you for a nice and helpful explanation.

The meaning of “=” is indeed ambiguous sometimes, not only in programming languages, but also in mathematics. Even “abused” in a sense…

In R, “<-” is used for assignment. So, an operation like temp(a <- a + 1) is possible. In Julia, temp(a = a + 1) has a different meaning. In Mathematica, “=:” is used for definition, for example. It uses “->”, too. In Matlab,…

I like Julia’s syntax enabling users to write code following math (… there’s a nice word for it…I forgot). It’s quite obvious how important syntax or notation in math. But, I can view the language like Julia not only as following the math, but also extending the math in a sense. The concept of multiple dispatch, for example, is very common in math, but Julia’s extensive, systematic and contextual use of it made it much more general. In a sense, it’s extending math… In that sense, Julia can even clarify and correct ambiguous syntax/notation existing in math for some historical reasons.

There is a trade-off between keeping the syntax convenient and clearly demarcating various semantics. In a sense, `.=` extends the broadcasting syntax naturally to assignment.

I think you may find it neat when you get used to it, but if you carry over intuition from other languages it is true that you can run into surprises. I would recommend working through the manual (not reference or the developer docs, just the first part).

1 Like