# Does splatting create a shallow copy?

**URL:** <https://discourse.julialang.org/t/does-splatting-create-a-shallow-copy/55566>\
**Category:** General Usage\
**Created:** [February 18, 2021, 6:25pm UTC](https://discourse.julialang.org/t/does-splatting-create-a-shallow-copy/55566 "2021-02-18T18:25:50Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![anon60034542](https://avatars.discourse-cdn.com/v4/letter/a/90ced4/32.png) [@anon60034542](https://discourse.julialang.org/u/anon60034542)\
**Post date:** [February 18, 2021, 6:25pm UTC](https://discourse.julialang.org/t/does-splatting-create-a-shallow-copy/55566/1 "2021-02-18T18:25:50Z")

</div>

A while ago I asked [a question](https://discourse.julialang.org/t/why-doesnt-modifying-a-shallow-copy-of-an-array-reflect-on-the-original/48445/2) about shallow and deep copies and why a change in the copied array doesn’t reflect on the original.

When you splat an array, does it create a shallow or deep copy?

As explained in [this answer](https://discourse.julialang.org/t/why-doesnt-modifying-a-shallow-copy-of-an-array-reflect-on-the-original/48445/3), because it’s a 1 dimensional array, does it copy the first level?

```julia
letters = String["a","b","c","d","e"]
copy_of_letters = String[letters...]
copy_of_letters[3] = "x"

```

**Output** :

```julia
copy_of_letters
5-element Array{String,1}:
 "a"
 "b"
 "x"
 "d"
 "e"

letters
5-element Array{String,1}:
 "a"
 "b"
 "c"
 "d"
 "e"

```

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [February 18, 2021, 6:38pm UTC](https://discourse.julialang.org/t/does-splatting-create-a-shallow-copy/55566/2 "2021-02-18T18:38:12Z")

</div>

“shallow” I guess, because splatting only splat the depth-1:

```julia
julia> a = [[1], [2]]
2-element Vector{Vector{Int64}}:
 [1]
 [2]

julia> b = [a...]
2-element Vector{Vector{Int64}}:
 [1]
 [2]

julia> b[1][1] = 10; b
2-element Vector{Vector{Int64}}:
 [10]
 [2]

julia> a
2-element Vector{Vector{Int64}}:
 [10]
 [2]

```

---

<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:** [February 18, 2021, 6:44pm UTC](https://discourse.julialang.org/t/does-splatting-create-a-shallow-copy/55566/3 "2021-02-18T18:44:47Z")

</div>

Well, what would be the difference between shallow and deep in your case? `String`s are immutable, so you do not have how to “change inside a `String`” that may (or may not) be in both arrays to test if it is modified in both.

If you test with a mutable object you can see a shallow copy:

```julia
julia> refs = [Ref(1), Ref(2), Ref(3)]
3-element Array{Base.RefValue{Int64},1}:
 Base.RefValue{Int64}(1)
 Base.RefValue{Int64}(2)
 Base.RefValue{Int64}(3)

julia> copy_of_refs = Base.RefValue{Int64}[refs...]
3-element Array{Base.RefValue{Int64},1}:
 Base.RefValue{Int64}(1)
 Base.RefValue{Int64}(2)
 Base.RefValue{Int64}(3)

julia> refs[2][] = 20
20

julia> refs
3-element Array{Base.RefValue{Int64},1}:
 Base.RefValue{Int64}(1)
 Base.RefValue{Int64}(20)
 Base.RefValue{Int64}(3)

julia> copy_of_refs
3-element Array{Base.RefValue{Int64},1}:
 Base.RefValue{Int64}(1)
 Base.RefValue{Int64}(20)
 Base.RefValue{Int64}(3)

```

---

<div class="post-metadata">

**Author:** ![anon60034542](https://avatars.discourse-cdn.com/v4/letter/a/90ced4/32.png) [@anon60034542](https://discourse.julialang.org/u/anon60034542)\
**Post date:** [February 18, 2021, 8:33pm UTC](https://discourse.julialang.org/t/does-splatting-create-a-shallow-copy/55566/4 "2021-02-18T20:33:10Z")

</div>

Does the documentation exist for Base.RefValue? I would like to read about it. Typing ? into the REPL and `Base.RefValue` returns `No documentation found.`

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [February 18, 2021, 9:36pm UTC](https://discourse.julialang.org/t/does-splatting-create-a-shallow-copy/55566/5 "2021-02-18T21:36:00Z")

</div>

You’re looking for

```julia
help?> Ref
search: Ref WeakRef prevfloat UndefRefError GlobalRef uppercasefirst lowercasefirst ProcessFailedException searchsortedfirst

  Ref{T}

  An object that safely references data of type T. This type is guaranteed to point to valid, Julia-allocated memory of
  the correct type. The underlying data is protected from freeing by the garbage collector as long as the Ref itself is
  referenced.

  In Julia, Ref objects are dereferenced (loaded or stored) with [].

  Creation of a Ref to a value x of type T is usually written Ref(x). Additionally, for creating interior pointers to
  containers (such as Array or Ptr), it can be written Ref(a, i) for creating a reference to the i-th element of a.

  When passed as a ccall argument (either as a Ptr or Ref type), a Ref object will be converted to a native pointer to the
  data it references.

  There is no invalid (NULL) Ref in Julia, but a C_NULL instance of Ptr can be passed to a ccall Ref argument.

  Use in broadcasting
  ≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡

  Ref is sometimes used in broadcasting in order to treat the referenced values as a scalar:

  julia> isa.(Ref([1,2,3]), [Array, Dict, Int])
  3-element BitArray{1}:
   1
   0
   0

```

---

<div class="post-metadata">

**Author:** ![anon60034542](https://avatars.discourse-cdn.com/v4/letter/a/90ced4/32.png) [@anon60034542](https://discourse.julialang.org/u/anon60034542)\
**Post date:** [February 19, 2021, 3:26pm UTC](https://discourse.julialang.org/t/does-splatting-create-a-shallow-copy/55566/6 "2021-02-19T15:26:14Z")

</div>

Bare with me here cause I’m still learning 😀. I want to make sure I have a good understanding of `copy()` before I start using it.

When you have a simple structure, for example, an array or multidimensional array, `copy()` will copy the structure and elements inside making them independent, meaning any changes done to the copy won’t reflect in the original, correct?

Example:

```julia
even_numbers = Int32[2,4,6,8,10] # Creating a 5 element array.
b = copy(even_numbers)
deleteat!(b, 2) # the element of 4 should be removed.
println(even_numbers)

```

Output:

```julia
5-element Array{Int32,1}:
  2
  4
  6
  8
 10

```

However, if the structure is more complicated for example, nested arrays or dictionaries, it will copy the structure, and copy references to the original elements, meaning any change done to the copy, will reflect in the original structure, correct?

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [February 19, 2021, 3:45pm UTC](https://discourse.julialang.org/t/does-splatting-create-a-shallow-copy/55566/7 "2021-02-19T15:45:32Z")

</div>

copy copies 1-level, deepcopy is recursive

---

<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:** [February 19, 2021, 3:53pm UTC](https://discourse.julialang.org/t/does-splatting-create-a-shallow-copy/55566/8 "2021-02-19T15:53:31Z")

</div>

> [@anon60034542](#):
>
> Bare with me here cause I’m still learning 😀. I want to make sure I have a good understanding of `copy()` before I start using it.

A wise decision.

> [@anon60034542](#):
>
> When you have a simple structure  
> …  
> However, if the structure is more complicated for example

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 `Int`s”, 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 `Int`s 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 `Int`s 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](https://discourse.julialang.org/t/how-come-this-is-non-allocating/55216/4).

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 `binding`s/`label`s/`reference`s. Consequently, if you `copy`
