# Reference versus copy

**URL:** <https://discourse.julialang.org/t/reference-versus-copy/98447>\
**Category:** General Usage\
**Created:** [May 7, 2023, 8:34pm UTC](https://discourse.julialang.org/t/reference-versus-copy/98447 "2023-05-07T20:34:49Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)\
**Post date:** [May 7, 2023, 8:34pm UTC](https://discourse.julialang.org/t/reference-versus-copy/98447/1 "2023-05-07T20:34:49Z")

</div>

I create a simple MWE to demonstrate some kind of reference problem which is leading to unwanted behavior when creating matrices with function elements. Here is the code:

```julia
function test()
    zfcts = Any[t -> 0., t -> 0.]
    fcts = Any[t -> sin(t), t -> cos(t)]
    g = Any[]
    push!(g, zfcts)
    push!(g, zfcts)
    g[1][1] = fcts[1] # sin
    g[2][1] = fcts[2] # cos
    x = 2.1
    @show g[1][1](x)
    @show (g[2][1](x))
    @show (g[1] === g[2]) # Should not be true!!! <<<<<<
    @show (g[1][1] === g[2][1]) # true
    @show (g[1][2] === g[2][2]) # true
    @show (g[1][1] === g[1][2]) # true
    @show (fcts[1] === fcts[2]) # false (as it should be)
end

test()

```

I expect

```julia
g[1][1] = sin(2.1)
g[2][[1] = cos(2.1)

```

However, the results are always the same, and equal to `fcts[2]`, the second function define in the `fcts` list. I thought that `push!` did a copy.

Here is the code output:

```julia
> test()
((g[1])[1])(x) = -0.5048461045998576
((g[2])[1])(x) = -0.5048461045998576
g[1] === g[2] = true
(g[1])[1] === (g[2])[1] = true
(g[1])[2] === (g[2])[2] = true
(g[1])[1] === (g[1])[2] = false
fcts[1] === fcts[2] = false
false

```

As usual, any insight is appreciated. I feel as if I should understand this coming from a C++ background, but I clearly am missing something important about functions and `push!`. Thanks.

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [May 7, 2023, 8:54pm UTC](https://discourse.julialang.org/t/reference-versus-copy/98447/2 "2023-05-07T20:54:28Z")

</div>

Your title implies you know exactly what’s going on here?

`g` is a vector containing two references to the same vector. When you change the first element of that vector, it changes, no matter which reference you use to access it.

---

<div class="post-metadata">

**Author:** ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)\
**Post date:** [May 7, 2023, 9:09pm UTC](https://discourse.julialang.org/t/reference-versus-copy/98447/3 "2023-05-07T21:09:51Z")

</div>

My title indicates that I “should” know what is going on.  
I just solve the problem (thanks for the push):

```julia
push!(g, copy(zfcts))
push!(g, copy(zfcts))

```

The rest of the code is the same.

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [May 7, 2023, 9:13pm UTC](https://discourse.julialang.org/t/reference-versus-copy/98447/4 "2023-05-07T21:13:21Z")

</div>

Where did you read that `push!` copies? I can’t find that in the documentation. I would try it, but it appears you already have.

Does `push!(g, copy(zfcts))` work?

---

<div class="post-metadata">

**Author:** ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)\
**Post date:** [May 7, 2023, 9:25pm UTC](https://discourse.julialang.org/t/reference-versus-copy/98447/5 "2023-05-07T21:25:41Z")

</div>

Yes, simply copying the list of functions inside the `push!` did the trick. Regarding operation of the push, I just assumed. I do not check every little detail in the documentation. I guess it does do a copy: what was copied was the pointer to the beginning of the list of functions (using C++ lingo).

---

<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 7, 2023, 11:47pm UTC](https://discourse.julialang.org/t/reference-versus-copy/98447/6 "2023-05-07T23:47:41Z")

</div>

> [@erlebach](#):
>
> Regarding operation of the push, I just assumed. I do not check every little detail in the documentation.

Passing arguments in Julia (as for most languages) works just like assignment (`=`): it binds a  
new name to the same object, it does not copy the object. This not a little detail — it is fundamental to how the language works.

(Of course, a function like `push!` _could_ internally call `copy` on its argument before storing it in a data structure, but this is the exception rather than the rule.)

(Nor is Julia’s behavior particularly unusual among languages here.)
