docs mentioned that:
Julia function arguments follow a convention sometimes called “pass-by-sharing”… Modifications to mutable values (such as
Array
s) made within a function will be visible to the caller.
I think it causes a bit of confusion, especially if we’re defining “wrong” side-effect functions on immutables, e.g.
julia> x = 1
1
julia> f!(a) = a+=2
f! (generic function with 1 method)
julia> f!(x)
3
julia> x
1
julia> isimmutable(x)
true
here we call f()
with the immutable x
does not throw any error.
moreover, sometimes isimmutable()
is not a reliable check:
julia> y = [11, 12, 13];
julia> vy = @view y[1:3];
julia> isimmutable(y)
false
julia> isimmutable(vy)
true
julia> f2!(b) = b .+= 3
f2! (generic function with 1 method)
julia> f2!(y)
3-element Array{Int64,1}:
14
15
16
julia> f2!(vy)
3-element view(::Array{Int64,1}, 1:3) with eltype Int64:
17
18
19
noted that a view
is immutable! (according to isimmutable()
), yet apparently it’s often been used in !
functions.
another example:
julia> t = (1, 2)
(1, 2)
julia> g!(a) = a[1]+=2
g! (generic function with 1 method)
julia> g!(t)
ERROR: MethodError: no method matching setindex!(::Tuple{Int64,Int64}, ::Int64, ::Int64)
now an MethodError
is thrown, but it’s not about side-effect on immutables.
so, if I’m crazy enough to do:
julia> Base.setindex!(tup::Tuple{Int, Int}, v::Int, i::Int) = setfield!(tup, 1, v)
julia> g!(t)
ERROR: setfield! immutable struct of type Tuple cannot be changed
finally a relevant error is thrown, yet it is of the generic type ErrorException
.
should we define an error type of it? and throw the error as long as it happens?
thanks.