Dear Julia community,
I am trying to use the “!” prefix in order to modify a variable inside a function and have made this little test:
function test_copy!(a,b)
a = b
println("a in function: $a")
end
a = 0.0; b = 1.0;
test_copy!(a,b)
println("a outside function: $a")
The results are: “a in function: 1.0” and “a outside function: 0.0” .
So the variable a has not been modified by the call to test_copy!.
But if I do the same test with size(1) arrays
function test_equal_arrays!(vec,x)
vec[1] = x
end
vec = [0.0]; x = 1.0
test_equal_arrays!(vec,x)
@show(vec)
I get “vec = [1.0]” .
So I am getting a little confused. Does someone knows how the “!” prefix work in that case ?
Thanks to all
The exclamation mark doesn’t do any work at all, it’s just a naming convention.
The difference between the two cases is that in the first case you just create a new local binding for the variable name a. In the second case you update the content of the mutable object that vec points to.
Nitpicking here, but the ! in foo!() is actually a postfix. This had me confused when I first read your title.
Ho thanks, I didn’t realise it was only a convention!
You’re right I’ll modify it !
Nitpicking here, XD, but the ! in foo!() is actually a suffix, because the character makes part of the token and it is not a separate operator.
Dammit, Jesus was right about that whole casting the first stone thing
About the difference between bindings and modifying mutable objects, there were many questions about it here in this forum, I selected some of my previous answers:
I did not find the specific section of the manual that explains this, so I will try to explain it myself (but I am almost sure such section exists).
The problem I see is that your mental model on how variables and objects work is not how they work in Julia (but I am sure in other languages you would see the behavior you did expect).
In Julia, a variable is just a name for some value in some scope. When you attribute a value to some variable you are never copying it, you are binding it, this is…
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:
“changes I make to them do not refle…
The confusing thing is that the equal sign in x[1] = 2 has absolutely nothing to do with the equal sign in x = 2. For instance you can see with x = randn(2); @which x[1] = 2 that this actually gets lowered to a function call.
The title was revised again