Assignment vs mutation with bang! functions

Hi, a question on mutating functions. If I have a function sum!(A::Matrix, B::Matrix) that adds A to B in place, due to Julia’s way of handling arrays it won’t actually overwrite B unless I call it in the following way: B = sum!(A,B) . Should I append ! to such functions anyway as they’re still mutating the function arguments in a sense? Also, does this have implications for memory allocation? Is it still an efficient function? Does B = sum!(A,B) still operate in place?

Note that the original poster on Slack cannot see your response here on Discourse. Consider transcribing the appropriate answer back to Slack, or pinging the poster here on Discourse so they can follow this thread.
(Original message :slack:) (More Info)

1 Like

That’s not correct. If you actually modify the contents of B in your function, there is no need for an assignment afterwards.

4 Likes

In other words, the bang in the function name does not affect how Julia treats the function in any way. It is just a convention for the benefit of the reader.

The convention is: if a function mutates one or more of its arguments, signal that to the user and to other developers by adding a bang to the function name. Also, the convention is that the modified arguments should (if possible) come first, followed by non-mutated arguments. There is an exception to this when a function is the first argument, as in map!(func, destination_array, ...). In that case it is undertood that it is the second argument that is being mutated.

Example from Julia’s build-in sum!

help?> sum!
search: sum! cumsum! sum summary cumsum isnumeric VersionNumber ...

  sum!(r, A)

  Sum elements of A over the singleton dimensions of r, and write results to r.
....
2 Likes