Assignment of array elements

I have an array a and I create an array b that has the same form and values as a. Then I want to change values in b alone, but they also change in a:

julia> a = ones(3)'
1×3 RowVector{Float64,Array{Float64,1}}:
 1.0  1.0  1.0

julia> b = a
1×3 RowVector{Float64,Array{Float64,1}}:
 1.0  1.0  1.0

julia> b[1] = 41
41

julia> a
1×3 RowVector{Float64,Array{Float64,1}}:
 41.0  1.0  1.0

I would expect this for functions, and not for the assignment operator =. Why does this specifically happen when changing individual values in an array?

When I assign a new value to the array as a whole, I guess b is reinitialised and hence the assignment doesn’t carry over to the original array a or something:

julia> b = zeros(3)'
1×3 RowVector{Float64,Array{Float64,1}}:
 0.0  0.0  0.0

julia> a
1×3 RowVector{Float64,Array{Float64,1}}:
 41.0  1.0  1.0

Check this out Values vs. Bindings: The Map is Not the Territory · John Myles White. In short, in the first case, a and b are both bound to the same data object (array in this case). When you rebind b to another data object, a is still bound to the first one. If you want them to be independent you will have to use copy for the above case, or deepcopy if your data object has a deeper structure and you want to copy the whole structure over.

Keywords: copying by value, copying by reference, variable binding, variable assignment, variable mutation, data mutation

1 Like

Thank you, this works:

julia> a
1×3 RowVector{Float64,Array{Float64,1}}:
 41.0  1.0  1.0

julia> a = ones(3)'
1×3 RowVector{Float64,Array{Float64,1}}:
 1.0  1.0  1.0

julia> b = copy(a)
1×3 RowVector{Float64,Array{Float64,1}}:
 1.0  1.0  1.0

julia> b[1] = 41
41

julia> a
1×3 RowVector{Float64,Array{Float64,1}}:
 1.0  1.0  1.0

I need to build up my “Julia intuition”, such that I will be able to more easily see the link between the syntax and whether we talk about variable binding, assignment etc.