Does splatting create a shallow copy?

A wise decision.

In practice things happens as you describe, but there is also a fundamental misunderstanding here: copy is blind to the inner elements, it does not take different decisions based on the type of the inner elements, it always do the same thing: copying a reference to the element.

“But what about Ints”, you may say, “they are copied by value” or yet, “changes I make to them do not reflect in the original array”. To that I have two answers:

  1. “changes I make to them do not reflect in the original array” – You never make changes to an Ints object, they are immutable. You cannot take 5 and modify it. You can have an Int field/position and modify which Int object is inside it, but the field/position itself is a property of the container not of the object; the object itself is never modified. This confusion arises of the old: binding/label/reference versus variable/box/memory-block.
  2. “they are copied by value” – They may, or they may not. This is just a compiler optimization. And this is not just for Ints but for any immutable object, if the compiler deems the object “too large to be copied” or is able to perceive it will be copied to a lot of places, it can instead copy a reference instead. As the object is immutable, it is impossible to the user to see a semantic difference: the user cannot change the object to see a change in many places. You can sometimes see a performance difference however: see this very interesting case in which the compiler is able to do an unexpectedly smart deduction.

I think we are at the binding/label/reference versus variable/box/memory-block again. If you can forget memory layout for a moment, the best way to see it is that copy over a container always duplicate the container itself but the container is always a container of bindings/labels/references. Consequently, if you copy