# Functions with a bang!

I’m currently going through this excellent book on getting started with Julia, and I’ve run into a behavior I don’t quite understand. The book provides this example of a function that overwrites its inputs:

``````function addone!(a)
for i in 1:length(a)
a[i] += 1
end
end
``````

Now any input gets overwritten by adding one to it:

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

julia> x
1×3 Matrix{Int64}:
2  3  4
``````

Above, we see that every element of `x` now has 1 added to it.

To me, the loop in the function above looks like just an unnecessary bit of clutter, so I attempted to rewrite the function as follows:

``````function my_addone!(a)
a = a .+ 1
end
``````

Now when I try to use `my_addone!` in the same way that I used `addone!` above, I find that the behavior is different:

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

julia> x
1×3 Matrix{Int64}:
1  2  3
``````

Why is it that the function only overwrites the input if there’s a loop inside the function? I feel like I’m missing some fundamental principle.

No worries, you did well. You just missed a little dot:

``````function my_addone!(a)
a .= a .+ 1
end
``````

will do.

I thought I find a section about why your version copies the result, but I didn’t found it. So I just tell you that

``````a .+ 1
``````

creates a new array, which is than assigned to `a`. … aah I give up, @lmiq does a better job

2 Likes

With the `dot` above, the `a .= a .+ 1` is a syntax sugar for the same loop of the original function. Without the dot, `a = a .+ 1` creates a new array from the result of `a .+ 1` (with the elements with 1 added), but assigns that label `a` to this new array. The fact that the label `a` was “taken” does not matter here, that is equivalent to `b = a .+ 1` where `b` is the label of the newly created array.

6 Likes

The best source of info about that is probably this post: More Dots: Syntactic Loop Fusion in Julia

3 Likes

Many thanks, @oheil and @lmiq! Your explanations are very clear.

I see that my attempt with `=` was just making a copy that happened to have the same name as the input `a`, whereas `.=` is shorthand that overwrites each element of `a`. Very cool!

2 Likes

To contribute nothing more than a name, this behaviour is called variable shadowing.

3 Likes