Add deepcopy operator := to avoid bugs

When doing everyday data analysis, avoiding bugs is often more time saving than having great code performance. One of my reoccurring bugs is that I forget that z=x doesn’t create a copy of x if x is an array.

Therefore I suggest to add a new operator := which assigns by creating a deepcopy.

In the same spirit, a colon at the end of a function name could create deepcopies of the function arguments when passed to the function (such that in my_fun:(x) the input variable x can be manipulated without affecting the value outside the variable outside the function).

By using the above operator and function-syntax I agree to the resulting performance penalty. If the code needs to be optimised for speed at a later stage, it is not very hard to inspect the code, check that no variables are unintentionally changed, and remove the colon.

1 Like

An assignment never copies, not for any type. It always rebinds the name z to point to the same thing that x binds (i.e. refers) to. If you’re thinking of something like z = x[1:3] and how that copies - it’s the x[1:3] part (the slice) that copies, not the assignment.

Also, your suggestion about : would change julia quite a lot - note that we’re not necessarily at that stage of development anymore.

3 Likes

Did you consider creating a macro that modifies your code the way you need (e.g. rewriting z = x to z = deepcopy(x))? Then you would be able to write something like this:

@copyall begin
    z = x                  # translated to z = deepcopy(x)
    u = my_fun(x)   # translated to u = my_fun(deepcopy(x))
    ...

end

A macro like that doesn’t work well with functions that modify their arguments intentionally - and you may not know if that happens, if the function doesn’t follow the ! convention. I suspect this will lead to more bugs than are prevented by deeply changing how julia feels & thinks about memory.

Isn’t it what the OP asked for?

1 Like

That is actually easy to implement:

(::Colon)(f::Function, args::Tuple) = f(map(deepcopy, args)...)
a = [1] 
b = [2]
copyto!:(a,b) # does not modify a
3 Likes

Hi Per,
That bit of code impressed me a lot! :slight_smile: :+1:
Thanks!!

Hi @dfdx
Thanks for your input, I will look into the solution with the macro!
PS. Per solved the function-call part of the original question.