Mutating function and array assignment in Julia
Shuvomoy Das Gupta
January 18, 2021
A mutating function in Julia changes one of its inputs. A common convention is to use !
after the name of the function if it is a mutating function.
If we are mutating an array type object, for proper mutation we must change what the array contains, not what the array points to.
function frst_inpt_dbl_of_2nd_inpt!(A::AbstractMatrix{<: Real}, B::AbstractMatrix{<: Real})
A .= 2*B # this .= notation ensures that we are changing the content of A
# 💀 if we do A = B, then it will only change the reference to the array A
end
Let us test the function above.
B = ones(5,5)
A = similar(A)
frst_inpt_dbl_of_2nd_inpt!(A, B)
A
which indeed gives us the output:
A =
2.0 2.0 2.0 2.0 2.0
2.0 2.0 2.0 2.0 2.0
2.0 2.0 2.0 2.0 2.0
2.0 2.0 2.0 2.0 2.0
2.0 2.0 2.0 2.0 2.0
So the contents of A
has indeed changed.
Just to experiment, let us experiment with a wrong implementation below.
function wrong_frst_inpt_dbl_of_2nd_inpt_💀!(A::AbstractMatrix{<: Real}, B::AbstractMatrix{<: Real})
A = 2*B # this will change the references to A, not the values
end
B = ones(5,5)
A = similar(A)
wrong_frst_inpt_dbl_of_2nd_inpt_💀!(A, B)
println(A)
which gives us the disastrous output:
A =
3.5e-323 8.4e-323 1.43e-322 2.17e-322 2.8e-322
4.0e-323 9.4e-323 1.73e-322 2.4e-322 2.87e-322
4.4e-323 1.1e-322 1.9e-322 2.5e-322 3.1e-322
7.0e-323 1.14e-322 2.03e-322 2.57e-322 3.16e-322
8.0e-323 1.33e-322 2.08e-322 2.67e-322 3.2e-322
For a more detailed explanation of why this happens, see the blog by John White here.
© Shuvomoy Das Gupta. Last modified: October 11, 2024. Website built with Franklin.jl and the Julia programming language.