# What is the philosophy behind arrays not being copied when assigned to another variable?

**URL:** <https://discourse.julialang.org/t/what-is-the-philosophy-behind-arrays-not-being-copied-when-assigned-to-another-variable/98702>\
**Category:** New to Julia\
**Created:** [May 11, 2023, 10:24pm UTC](https://discourse.julialang.org/t/what-is-the-philosophy-behind-arrays-not-being-copied-when-assigned-to-another-variable/98702 "2023-05-11T22:24:13Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Bizzi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bizzi/32/51484_2.png) [@Bizzi](https://discourse.julialang.org/u/Bizzi)\
**Post date:** [May 11, 2023, 10:24pm UTC](https://discourse.julialang.org/t/what-is-the-philosophy-behind-arrays-not-being-copied-when-assigned-to-another-variable/98702/1 "2023-05-11T22:24:13Z")

</div>

Very basic question, but I am hoping there might be an underlying principle which could help me understand other (at first) puzzling aspects of Julia.

As a heavy Matlab and C user, it is hard to imagine why someone would want to have changes to `a` alter `b` after `b=a`. If I later need to use the new value of `a` for some other computation, well, why not just use `a`?. Why would I have created `b` in the first place?

Confusion over Assignment vs. Shallow copy vs. Deep copy is also one of the most common sources of error for (novice) Python users, so I assume this choice wasn’t made to make Julia more accessible to the Python crowd.

So how should I think about this? Is it about performance? Wouldn’t lazy copies a la Matlab/R be a better fix?

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [May 11, 2023, 10:28pm UTC](https://discourse.julialang.org/t/what-is-the-philosophy-behind-arrays-not-being-copied-when-assigned-to-another-variable/98702/2 "2023-05-11T22:28:41Z")

</div>

It is a matter of the most useful semantics, IMO. No copy (explicit copy) is generally better, I believe.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [May 11, 2023, 10:33pm UTC](https://discourse.julialang.org/t/what-is-the-philosophy-behind-arrays-not-being-copied-when-assigned-to-another-variable/98702/3 "2023-05-11T22:33:49Z")

</div>

It’s (at least in part) about consistency. Assignment `a = b` is _always_ just binding a new name `a` to an existing object `b`, and is _never_ (conceptually) making a copy (although the compiler is allowed to copy data as an optimization _if_ the object is immutable). See also [the manual section on assignment vs. mutation](https://docs.julialang.org/en/v1/manual/variables/#man-assignment-expressions).

Nor is Julia unusual — this behavior is pretty typical for a lot of mainstream languages. Matlab’s copy-on-write semantics are the odd one out here. (And C++ is completely inconsistent because assignment is overloadable, so you never know what it is going to do.)

Realize also that passing function arguments is equivalent to assignment. Matlab’s copy-on-write argument-passing semantics make it impossible to implement functions that act in-place on array arguments.

If assignment made a copy, you’d want _another_ syntax to “opt out” of copying. What would it be? Whereas opting into copying with `a = copy(b)` is pretty explicit, clear, and familiar in a lot of languages.

---

<div class="post-metadata">

**Author:** ![mrufsvold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrufsvold/32/31600_2.png) [@mrufsvold](https://discourse.julialang.org/u/mrufsvold)\
**Post date:** [May 12, 2023, 2:09am UTC](https://discourse.julialang.org/t/what-is-the-philosophy-behind-arrays-not-being-copied-when-assigned-to-another-variable/98702/4 "2023-05-12T02:09:12Z")

</div>

> why someone would want to have changes to a alter b

```julia
struct Cars
     models
     ages
end

cars = Cars(["Camery", "RAV4"], [1, 5])

# At the end of the year, we need to do some summary stats, 
# save them, and increment
ages = cars.ages
ave = average(ages)
# other stuff
ages .= ages .+ 1

```

Just a bit contrived case where it’s nice to pull out an attribute of another object, modify it, and have it be meaningful that the original object should stay in sync.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [May 12, 2023, 2:34am UTC](https://discourse.julialang.org/t/what-is-the-philosophy-behind-arrays-not-being-copied-when-assigned-to-another-variable/98702/5 "2023-05-12T02:34:11Z")

</div>

Two things.

1. There is a previous answer of mine that helps to internalize the memory model. On boxes vs labels: [Is it appropriate to say a variable is a label or box? - #19 by Henrique\_Becker](https://discourse.julialang.org/t/is-it-appropriate-to-say-a-variable-is-a-label-or-box/46068/19)
2. In C, you can have static-sized arrays and (mutable) structs that when assigned to a variable will copy the value to the variable because the variable is kinda guaranteed to be a memory space. However, any array with dimensions only known at runtime (and a lot of structs that have pointers stored) will have no-copy/shallow-copy problems a lot of times.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [May 12, 2023, 3:19am UTC](https://discourse.julialang.org/t/what-is-the-philosophy-behind-arrays-not-being-copied-when-assigned-to-another-variable/98702/6 "2023-05-12T03:19:17Z")

</div>

Strictly speaking the change is to 1 mutable instance assigned to both `a` and `b`. It’s pretty common to have multiple references to 1 instance like this:

```julia
a = Ref(0) # assigned to `a` in global scope

increment!(b) = b[] += 1 # simplest mutating method
increment!(a) # assigned to `b` in the method body, just like `b = a`

A = []
push!(A, a) # assigned to an element in array A
A[1] === a # same instance

```

For the record, the behavior in the copy-on-write example currently on the Mathworks website _also_ happens in Julia, it just happens a different way because of the separation between variables and instances in Julia (though we commonly optimize by making sure a variable is always assigned to instances of 1 type during a call, this is “type stability”).

```julia
% MATLAB copy-on-write example, verbatim
A = rand(1e7,1);
B = f2(A);

function Y = f2(X)
X = X.*1.1; % X is an independent copy of A
Y = X; % Y is a shared copy of X
end

# Julia version
function f2(X) # local X assigned to input array via input A
  X = X .* 1.1 # X.*1.1 makes new array, reassign X to it
  Y = X # Y assigned to new array via X
  return Y
end

# Julia no-copy version that mutates the input array
function f2!(X) # local X assigned to input array via input A
  X .= X .* 1.1 # no new array. reassigns the elements, not X
end

```

What MATLAB does that Julia doesn’t do is copy-on-write on lines like `mat[i] = num` (in MATLAB, `mat(i) = num;`). There are countless questions in MATLAB Answers asking why mutation within a custom function doesn’t affect the input array, and the answer is generally to return the copy and reassign the input variable in the call scope. Turns out you _can_ mimic the mutating function style in MATLAB, but it really just [moves the call scope reassignment code into the function](https://www.mathworks.com/matlabcentral/answers/368678-how-to-change-a-matrix-within-a-function). No point in hiding the copy-on-write semantics like that.

---

<div class="post-metadata">

**Author:** ![JanKap](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jankap/32/22763_2.png) [@JanKap](https://discourse.julialang.org/u/JanKap)\
**Post date:** [May 12, 2023, 8:50am UTC](https://discourse.julialang.org/t/what-is-the-philosophy-behind-arrays-not-being-copied-when-assigned-to-another-variable/98702/7 "2023-05-12T08:50:43Z")

</div>

Fyi, even in Matlab this behavior can be achieved via handle classes and I have the feeling there’s a trend towards it.

---

<div class="post-metadata">

**Author:** ![kevbonham](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kevbonham/32/216165_2.png) [@kevbonham](https://discourse.julialang.org/u/kevbonham)\
**Post date:** [May 12, 2023, 11:19am UTC](https://discourse.julialang.org/t/what-is-the-philosophy-behind-arrays-not-being-copied-when-assigned-to-another-variable/98702/8 "2023-05-12T11:19:35Z")

</div>

> [@Henrique\_Becker](#):
>
> 1. There is a previous answer of mine that helps to internalize the memory model. On boxes vs labels: [Is it appropriate to say a variable is a label or box? - #19 by Henrique\_Becker](https://discourse.julialang.org/t/is-it-appropriate-to-say-a-variable-is-a-label-or-box/46068/19)

Just so it’s ~~only~~ not only @Henrique_Becker 's self-promotion, I just wanted to highly endorse this recommendation - I remember clearly reading it the first time and having all the pieces fall into place in my brain.

---

<div class="post-metadata">

**Author:** ![sylvaticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sylvaticus/32/203883_2.png) [@sylvaticus](https://discourse.julialang.org/u/sylvaticus)\
**Post date:** [May 12, 2023, 11:36am UTC](https://discourse.julialang.org/t/what-is-the-philosophy-behind-arrays-not-being-copied-when-assigned-to-another-variable/98702/9 "2023-05-12T11:36:02Z")

</div>

See also [this example](https://sylvaticus.github.io/SPMLJ/dev/01_-_JULIA1_-_Basic_Julia_programming/0102_-_Types_and_objects.html#Three-different-ways-to-%22copy%22-objects...) and [this quiz](https://sylvaticus.github.io/SPMLJ/dev/01_-_JULIA1_-_Basic_Julia_programming/0102q_-_QUIZ_1.3.html) on the subject.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [May 12, 2023, 12:00pm UTC](https://discourse.julialang.org/t/what-is-the-philosophy-behind-arrays-not-being-copied-when-assigned-to-another-variable/98702/10 "2023-05-12T12:00:36Z")

</div>

@kevbonham Thanks! I shamelessly self-promote that link, XD. Someday it will be the post with most backlinks (except by Tama’s PSA probably). There is another example that is very good, that I say in a post here but was not able to locate this time: a cat alternates between living two houses, in one of them it is called Tiger, in the other it is called Fluffy, the cat is the same, and it does not know any of its names.

@sylvaticus I need to start referencing these links too. They are good code examples.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [May 12, 2023, 1:40pm UTC](https://discourse.julialang.org/t/what-is-the-philosophy-behind-arrays-not-being-copied-when-assigned-to-another-variable/98702/11 "2023-05-12T13:40:46Z")

</div>

> [@kevbonham](#):
>
> Just so it’s only only @Henrique_Becker 's self-promotion

That’s not so nice 😉

---

<div class="post-metadata">

**Author:** ![Bizzi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bizzi/32/51484_2.png) [@Bizzi](https://discourse.julialang.org/u/Bizzi)\
**Post date:** [May 12, 2023, 7:37pm UTC](https://discourse.julialang.org/t/what-is-the-philosophy-behind-arrays-not-being-copied-when-assigned-to-another-variable/98702/12 "2023-05-12T19:37:56Z")

</div>

Thank you all for the very insightful comments. I will soon tag @stevengj 's reply as the solution as it gives the “philosophical” background I asked for. His third argument in particular seems to seal the deal.

EDIT: Said something silly. Thank you all again for the patience.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [May 12, 2023, 7:47pm UTC](https://discourse.julialang.org/t/what-is-the-philosophy-behind-arrays-not-being-copied-when-assigned-to-another-variable/98702/13 "2023-05-12T19:47:28Z")

</div>

> [@Bizzi](#):
>
> it does strike me as odd that it should work differently for (for example) arrays and scalars

It does **not** work differently for arrays and scalars.

```julia
a = 3
b = a

```

makes `b` refer to the “same object” `3` as `a`. (Because `3` is immutable, the compiler is free to make a copy if it wants to, but this is purely an implementation detail and is not visible to the user: `a === b` will be `true` regardless.)

---

<div class="post-metadata">

**Author:** ![sylvaticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sylvaticus/32/203883_2.png) [@sylvaticus](https://discourse.julialang.org/u/sylvaticus)\
**Post date:** [May 12, 2023, 7:55pm UTC](https://discourse.julialang.org/t/what-is-the-philosophy-behind-arrays-not-being-copied-when-assigned-to-another-variable/98702/14 "2023-05-12T19:55:33Z")

</div>

… hmm… but here we are dealing with operations as copy an object (or assigning a parameter to a function).  
These are not mathematical concepts, but computer ones, so I am not surprised that computer implementations, as the fact if the object is mutable, matters… scalars and vectors are implemented very differently… the memory they use, the operations that a CPU can do at the bare metal level… they are fundamentally different and so on a computational level they behave very different, even if they are very close conceptually in math.

---

<div class="post-metadata">

**Author:** ![Bizzi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bizzi/32/51484_2.png) [@Bizzi](https://discourse.julialang.org/u/Bizzi)\
**Post date:** [May 12, 2023, 8:01pm UTC](https://discourse.julialang.org/t/what-is-the-philosophy-behind-arrays-not-being-copied-when-assigned-to-another-variable/98702/16 "2023-05-12T20:01:02Z")

</div>

That a and b themselves do not count as true “objects” in this sense was perhaps the insight I was missing. This is clear now.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [May 12, 2023, 8:03pm UTC](https://discourse.julialang.org/t/what-is-the-philosophy-behind-arrays-not-being-copied-when-assigned-to-another-variable/98702/17 "2023-05-12T20:03:15Z")

</div>

> [@sylvaticus](#):
>
> … hmm… but here we are dealing with operations as copy an object (or assigning a parameter to a function).  
> These are not mathematical concepts, but computer ones, so I am not surprised that computer implementations, as the fact if the object is mutable, matters… scalars and vectors are implemented very differently… the memory they use, the operations that a CPU can do at the bare metal level… they are fundamentally different and so on a computational level they behave very different, even if they are very close conceptually in mat

There’s a difference between the semantics of a language — which _are_ a mathematical concept — and the implementation. The former are what are necessary to understand syntax and the _meaning_ of a program. The latter is more relevant when you are optimizing.

For example, a variable may not actually be stored _anywhere_ — the compiler could optimize it out completely. e.g. in

```julia
function f(x)
    a = 3
    b = 2a
    return b + x
end

```

the variable `a` will actually _not exist_ in the implementation, because the compiler will [constant-fold](https://en.wikipedia.org/wiki/Constant_folding) this into `b = 6` (or equivalent — e.g. for `x::Int` it may turn into an [immediate value](https://en.wikichip.org/wiki/immediate_value)).

Confusing semantics for implementation will just lead you into perplexity.

---

<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:** [May 12, 2023, 8:16pm UTC](https://discourse.julialang.org/t/what-is-the-philosophy-behind-arrays-not-being-copied-when-assigned-to-another-variable/98702/18 "2023-05-12T20:16:35Z")

</div>

There is another typical confusion (I made it), regarding assigning and mutation syntax, as both can use the `=` operator. I have a note summarizing previous answers about that here: [Assignment and mutation · JuliaNotes.jl](https://m3g.github.io/JuliaNotes.jl/stable/assignment/)

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [May 12, 2023, 8:20pm UTC](https://discourse.julialang.org/t/what-is-the-philosophy-behind-arrays-not-being-copied-when-assigned-to-another-variable/98702/19 "2023-05-12T20:20:10Z")

</div>

Yes, that’s exactly the insight — the names themselves aren’t Julia objects or boxes or pointers or memory locations. I’m fully on board with @Henrique_Becker’s [post](https://discourse.julialang.org/t/is-it-appropriate-to-say-a-variable-is-a-label-or-box/46068/19) linked above — I don’t even like the word “variable” because it has a lot of the “box” baggage in my experience. Assignments are just choosing a name for a Julia object to make _your_ life easier.

You can name numbers, you can name arrays, you can name functions, you can name pretty much anything in Julia, and it’s all assignment. You can decide that you have a better use for that name and use the name for something new (as long as it wasn’t `const`). Or you might decide that it’s useful to have two different names that refer to exactly the same thing.

Somewhat confusingly, the poorly named “updating” operators don’t actually “update” (or mutate) a Julia object. Doing something like `x += 1` is simply saying that you have a better use for the name `x` — and it’s going to be one more than whatever the value of `x` previously was.

Syntactically similar — but _hugely_ different — is that you can use “indexed assignment” (`y[1] = ...`) or field mutation (`y.foo = ...`) to change some property about the thing you named `y`. Or you can broadcast into the object named `y` with `y .= 1`. Or you can pass it to a mutating function (like `normalize!(y)`). All of those things don’t really change anything about the name “y” itself, but rather they change **the object** that you chose to refer to by the name “y”. And there could be other places in your code where you refer to that same object by other names, it doesn’t matter, it’s all one object.

---

<div class="post-metadata">

**Author:** ![ggggggggg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ggggggggg/32/265_2.png) [@ggggggggg](https://discourse.julialang.org/u/ggggggggg)\
**Post date:** [May 12, 2023, 9:24pm UTC](https://discourse.julialang.org/t/what-is-the-philosophy-behind-arrays-not-being-copied-when-assigned-to-another-variable/98702/21 "2023-05-12T21:24:51Z")

</div>

This blog post helped me understand the same issues many years ago, it’s still accurate.  
[https://www.juliabloggers.com/values-vs-bindings-the-map-is-not-the-territory-3/](https://www.juliabloggers.com/values-vs-bindings-the-map-is-not-the-territory-3/)

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [May 13, 2023, 12:34am UTC](https://discourse.julialang.org/t/what-is-the-philosophy-behind-arrays-not-being-copied-when-assigned-to-another-variable/98702/22 "2023-05-13T00:34:52Z")

</div>

Thanks, but I believe @kevbonham just chose a word with a negative baggage, what I did is by definition ‘self-promotion’, and the rest of his comment makes clear he agree with both the content of my post and me linking it here.

[Next page](https://discourse.julialang.org/t/what-is-the-philosophy-behind-arrays-not-being-copied-when-assigned-to-another-variable/98702.md?page=2)
