Is there any way to explicitly prohibit a function from modifying the `mutable struct` or `Vector/Array` parameters?

As we know, Julia's functions can modify the contents of the passed mutable struct or Array. Sometimes this can cause confusion as to whether the function modifies the members of the mutable struct or not. It might be helpful to write a detailed document.

I would like to ask if there are other solutions?

Thanks!

https://docs.julialang.org/en/v1/manual/style-guide/#bang-convention

Thanks for your reply!

Append ! to names of functions that modify their arguments, this is indeed sufficient in everyday situations. But in complex situations, it may not help much, e.g.

mutable struct TypeA
    #
end

mutable struct TypeB
    #
end

function fun!(a::TypeA, b::TypeB, c::Vector{Float64})
    #
end

I may only modify a, or I may modify both a and b at the same time (even modify c).

I think just adding a symbol ! doesn’t help much.

Julia users who know the meaning of ! are savvy enough to browse the code to see which arg is mutated and which is not.

2 Likes

Before that, I would probably read the documentation of the function.

6 Likes

You can help yourself much by adding a doc string.

Minimal working example:

mutable struct TypeA
    n::Int
end

mutable struct TypeB
    x::Float64
end

"""
`fun!(a::TypeA, b::TypeB, c::AbstractVector{Float64})` only mutates `b`.
"""
function fun!(a::TypeA, b::TypeB, c::AbstractVector{Float64})
    b.x = sum(c) / a.n
end

a, b, c = TypeA(10), TypeB(0.0), collect(1.0:10.0)
fun!(a, b, c)
@show a b c;
a = TypeA(10)
b = TypeB(5.5)
c = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
@doc fun!
  fun!(a::TypeA, b::TypeB, c::AbstractVector{Float64}) only mutates b.
julia> ?
help?> fun!
search: fun! function Function functionloc @functionloc @cfunction fullname

  fun!(a::TypeA, b::TypeB, c::AbstractVector{Float64}) only mutates b.
3 Likes