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.
6 Likes
Nitpicking here, but the !
in foo!()
is actually a postfix. This had me confused when I first read your title.
3 Likes
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.
5 Likes
Dammit, Jesus was right about that whole casting the first stone thing
4 Likes
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…
1 Like
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.
3 Likes
The title was revised again