# Misunderstanding of the copy() function

**URL:** <https://discourse.julialang.org/t/misunderstanding-of-the-copy-function/90078>\
**Category:** General Usage\
**Tags:** deepcopy\
**Created:** [November 10, 2022, 10:22pm UTC](https://discourse.julialang.org/t/misunderstanding-of-the-copy-function/90078 "2022-11-10T22:22:42Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Zackyzz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zackyzz/32/44173_2.png) [@Zackyzz](https://discourse.julialang.org/u/Zackyzz)\
**Post date:** [November 10, 2022, 10:22pm UTC](https://discourse.julialang.org/t/misunderstanding-of-the-copy-function/90078/1 "2022-11-10T22:22:42Z")

</div>

Hello! I come from a Lisp background and mostly when I change a parameter inside a function I prefer to have it modified only in that function.  
Now from what I’ve seen from the bellow code, `lst` actually gets modified too:

```julia
lst = [1 2 3 4 5]

function f(x)
    x[1] = 0
    return x
end

display(lst)
display(f(lst))
display(lst)

 1 2 3 4 5
 0 2 3 4 5
 0 2 3 4 5

```

The workaround I found is to always make a copy like this:

```julia
function g(x)
    clone = copy(x)
    clone[2] = 0
    return clone
end

```

And it works as I intended, however that’s not the issue I have right now.  
When I try to work with expressions, although the code is quite similar, for some reason even though I use copy, it still modifies like there was no copy at all.

```julia
expr_lst = [:(a(1)) :(b(2)) :(c(3))]

function ef(x)
    x[1].args[1] = :(d)
    return x
end

function eg(x)
    clone = copy(x)
    clone[2].args[1] = :(e)
    return clone
end

display(expr_lst)
display(ef(expr_lst))
display(eg(expr_lst))
display(expr_lst)

```

The output being:

```julia

 :(a(1)) :(b(2)) :(c(3))
 :(d(1)) :(b(2)) :(c(3))
 :(d(1)) :(e(2)) :(c(3))
 :(d(1)) :(e(2)) :(c(3))

```

What am I missing? Also how can I solve this issue (perhaps in a more elegant way without using copy every time)? I would imagine there can be a keyword that automatically makes a copy for each parameter inside the function.

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [November 10, 2022, 10:37pm UTC](https://discourse.julialang.org/t/misunderstanding-of-the-copy-function/90078/2 "2022-11-10T22:37:26Z")

</div>

`copy` only copies the outer collection. If the elements are mutable, then effectively what you get is a new collection with fresh pointers to the same mutable objects. Here’s an example of that phenomenon:

```julia
julia> x = [[1], [2]];

julia> y = copy(x);

julia> x === y
false

julia> y[1][1] = 100;

julia> x
2-element Vector{Vector{Int64}}:
 [100]
 [2]

```

There is `deepcopy`, but it’s not recommended. It’s better to explicitly construct a new object than to use `deepcopy`.

Maybe a more functional approach would help, like this:

```julia
julia> function change_f(ex)
           if ex.args[1] == :a
               :(d($(ex.args[2])))
           elseif ex.args[1] == :b
               :(e($(ex.args[2])))
           else
               ex
           end
       end
change_f (generic function with 1 method)

julia> exs = [:(a(1)) :(b(2)) :(c(3))]
1×3 Matrix{Expr}:
 :(a(1)) :(b(2)) :(c(3))

julia> map(change_f, exs)
1×3 Matrix{Expr}:
 :(d(1)) :(e(2)) :(c(3))

julia> exs
1×3 Matrix{Expr}:
 :(a(1)) :(b(2)) :(c(3))

```
