# Why I can't set what parameters are mutable explicitly?

**URL:** <https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091>\
**Category:** Offtopic\
**Tags:** functions\
**Created:** [August 21, 2022, 3:50pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091 "2022-08-21T15:50:10Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Dan\_Micsa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan_micsa/32/30233_2.png) [@Dan\_Micsa](https://discourse.julialang.org/u/Dan_Micsa)\
**Post date:** [August 21, 2022, 3:50pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/1 "2022-08-21T15:50:10Z")

</div>

I still don’t understand why parameters can be silently changed in function calls and why there is not a const or mutable like keyword to warn us if this is happening?

Running this example will silently change the content of the vector w/o knowing that.

```julia
a = [1, 2]
f(v) = v[2] = 3
f(a)

```

I found that ‘!’ after the name of a mutable function useless for general usage with multiple parameters.

a function like:

```julia
g!(a, b, c) 

```

is changing what?!?

Of course I don’t even touch the fact that ‘!’ is at this momment just some convention and not enforced by the compiler.

[Later edit:] Instead g!(a, b, c) should be something like: g(a!, b, c!) that tells that a and c are mutable. ‘!’ can be anything post or prefix.

---

<div class="post-metadata">

**Author:** ![jebej](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jebej/32/1784_2.png) [@jebej](https://discourse.julialang.org/u/jebej)\
**Post date:** [August 21, 2022, 3:58pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/2 "2022-08-21T15:58:39Z")

</div>

In your example, you are not changing “the array”, but the content of the array, commonly called “mutating”. Nothing is silently changing anything in your example. You explicitly wrote “set the second index of this array to 3”, and that’s what the code is doing. This is the case in most programming languages.

Putting `!` is simply a convention, and has no effects on the code.

There is no way to prevent a function from mutating an array if that’s how it was written. What you can do in this case, is to pass a copy of your array: `f(copy(a))`.

---

<div class="post-metadata">

**Author:** ![Dan\_Micsa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan_micsa/32/30233_2.png) [@Dan\_Micsa](https://discourse.julialang.org/u/Dan_Micsa)\
**Post date:** [August 21, 2022, 4:06pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/3 "2022-08-21T16:06:54Z")

</div>

I would dare to say that I’m changing it! Just compare it with a copy of that array done before the function call.

A similar C++ example:

```julia
void f(const vector<double> &r) { r[0] = 2.0; }

```

This example doesn’t even compile and errors out with: “error C3892: ‘r’: you cannot assign to a variable that is const”

I personaly, don’t care or see any important use of what you said, I care a lot the content of the array to be imuable when I make a function call that suposidly should be constant.

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [August 21, 2022, 4:16pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/4 "2022-08-21T16:16:04Z")

</div>

The trend in Julia is to make data structures entitely immutable after construction. In Julia 1.8, `const` fields were introduced to mutable structures.

```julia
julia> using StaticArrays

julia> a = SA[1,2]
2-element SVector{2, Int64} with indices SOneTo(2):
 1
 2

julia> f(v) = v[2] = 3
f (generic function with 1 method)

julia> f(a)
ERROR: setindex!(::SVector{2, Int64}, value, ::Int) is not defined.
Hint: Use `MArray` or `SizedArray` to create a mutable static array
Stacktrace:
...

```

`const` arguments would require some level of static analysis not easily available to Julia via its JIT compilation model.

---

<div class="post-metadata">

**Author:** ![Dan\_Micsa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan_micsa/32/30233_2.png) [@Dan\_Micsa](https://discourse.julialang.org/u/Dan_Micsa)\
**Post date:** [August 21, 2022, 4:23pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/5 "2022-08-21T16:23:48Z")

</div>

Thank you but I don’t want a StaticArray I want a normal array that I’m changing in my code and is very expenssive to make a copy or conversion of it.

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [August 21, 2022, 4:38pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/6 "2022-08-21T16:38:29Z")

</div>

Try a `ReadOnlyArray` then:

```julia
julia> using ReadOnlyArrays

julia> A = rand(1024, 1024);

julia> ROA = ReadOnlyArray(A);

julia> f(v) = v[2] = 3
f (generic function with 1 method)

julia> f(A)
3

julia> f(ROA)
ERROR: setindex! not defined for ReadOnlyArray{Float64, 2, Matrix{Float64}}
Stacktrace:
 [1] error(::String, ::Type)
   @ Base ./error.jl:42
 [2] error_if_canonical_setindex(#unused#::IndexLinear, A::ReadOnlyArray{Float64, 2, Matrix{Float64}}, #unused#::Int64)
   @ Base ./abstractarray.jl:1323
 [3] setindex!
   @ ./abstractarray.jl:1314 [inlined]
 [4] f(v::ReadOnlyArray{Float64, 2, Matrix{Float64}})
   @ Main ./REPL[12]:1
 [5] top-level scope
   @ REPL[14]:1

julia> sizeof(ROA)
8

julia> ROA[2] # ROA is a no-copy view of A
3.0

```

---

<div class="post-metadata">

**Author:** ![PeterSimon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petersimon/32/25193_2.png) [@PeterSimon](https://discourse.julialang.org/u/PeterSimon)\
**Post date:** [August 21, 2022, 4:38pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/7 "2022-08-21T16:38:39Z")

</div>

Julia currently doesn’t support a way to prevent mutable objects from being mutated by functions. It simply isn’t as safe as some compiled languages such as C++, Fortran, or Rust. However, it has a lot of other great features like composability, dynamicism, speed, and reproducible environments. I personally agree that adding a feature like that to the language would be a good idea, but I have no idea how difficult it would be to implement. It most likely would have to wait for Julia 2.0 to be incorporated. If you feel strongly about it, then you could open an [issue](https://github.com/JuliaLang/julia/issues).

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [August 21, 2022, 4:47pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/8 "2022-08-21T16:47:38Z")

</div>

Some other references:

> **[GitHub - tkf/Mutabilities.jl](https://github.com/tkf/Mutabilities.jl)**
>
> Contribute to tkf/Mutabilities.jl development by creating an account on GitHub.

> <https://github.com/JuliaLang/julia/pull/31630>
>
> This is part of a larger set of overhauls I'd like to do in the 2.0 timeframe (a…long with #21912 and other things along these lines). As such this is more of a straw-man implementation to play with various ideas. I doubt any of this code will get merged as is, but should provide a place for experimentation and we may start picking off good ideas from here.
> 
> The basic concept here is that I think we're missing a heap-allocated \*immutable\* array. We have Array (mutable and dynamically sized), StaticArray (immutable and statically sized) and MArray (mutable and statically sized), but we don't really have an immutable dynamically sized array. This PR adds that.
> 
> In my ideal world, most functions would return immutable arrays. In a lot of code, it is fairly rare to require semantically mutable arrays at the highest level of the API (of course operations are internally often implemented as mutating operations) and even in a good chunk of the cases that make use of them, they are used as a performance optimization rather than a semantic necessity. 
> 
> On the other hand, having an immutability guarantee can be quite useful. For example, it would solve a lot of the performance problems around aliasing (the reason LLVM can't vectorize in a lot of cases is that it doesn't know that the output array doesn't overlap the input array - if the input array is immutable that obviously can't happen).
> 
> Immutability is also nice for higher level applications. Since views and slices are the same thing in immutable arrays, operations that would semantically be required to make copies on mutable arrays (say an AD system taking captures during the forward pass), can use views instead.
> 
> Now, the problem here of course is that sometimes you do want mutation, particularly during construction of various objects (i.e. you construct the object once by setting something to every memory location, but then it's immutable afterwards). This PR introduces the \`freeze\` function, which takes a mutable array and returns an immutable array with the same memory contents. Semantically this function is a copy, but the idea is that the compiler will be able to elide this copy in most circumstances, thus allowing immutable arrays to be constructed using mutating operations without overhead. Similarly, there is the \`melt\` function which does the opposite. Once this infrastructure is mature, it should be trivial to get either the immutable or the mutable version in a zero-overhead (after compiler optimizations) manner of any array function just by adding the appropriate freeze/melt function. The 2.0 goal would then be to actually make most array operations return the immutable versions of the array.
> 
> Another motivation here is to make it easier to write code that it generic over mutability in order to support things like XLA and other optimizing linear algebra compilers that operate on immutable tensors as their primitives. By having a well defined way to talk about mutability in the standard library, it should be easier to plug in those external implementations seamlessly.

> [@Making an immutable array type?](https://discourse.julialang.org/t/making-an-immutable-array-type/31129):
>
> I’ve been writing an immutable collections and STM library for Julia based on similar awesome libraries in [scala](https://nbronson.github.io/scala-stm/) and [clojure](https://clojure.org/about/concurrent_programming) (work in progress, but repo is [here](https://github.com/noahbenson/Air.jl)). As I’ve been writing it, I’ve noticed that some of the operations have a performance comparible with both Julia’s native types and clojure’s persistent types (e.g., for the persistent dictionary type PDict: get, in, haskey are very fast). However, other operations, despite being implemented very similarly to clojure’s, have many orders…

> [@Constant function arguments](https://discourse.julialang.org/t/constant-function-arguments/8649):
>
> Is there a way to declare function arguments as constants to prevent their accidental modification in the function body? For example, function foo(x::const Int, y::Int) return x + y end or function foo(x::immutable Int, y::Int) return x + y end Or even, some method like in FORTRAN, via intent keyword; e.g.: function func(i) result(j) integer, intent(in) :: i ! input integer :: j ! output j = i\*\*2 + i\*\*3 end function func

---

<div class="post-metadata">

**Author:** ![PeterSimon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petersimon/32/25193_2.png) [@PeterSimon](https://discourse.julialang.org/u/PeterSimon)\
**Post date:** [August 21, 2022, 4:54pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/9 "2022-08-21T16:54:00Z")

</div>

> [@mkitti](#):
>
> Try a `ReadOnlyArray` then:

Great suggestion. Shouldn’t it be possible then to write a small macro `@immutable` that would be used as in the following?

```julia
function fun(a::AbstractVector, b::Real, c::AbstractVector)
    @immutable a c
    # From here on in the function, a and c are immutable
end

```

where the code generated by the macro would do something like the following:

```julia
a_orig = a # Or preferably gensym a random name
a = ReadOnlyArray(a_orig)
# and the same for c

```

Your thoughts?

Note: I didn’t supply actual code for the macro since my macro-foo is pretty weak. I could work out the correct code eventually, but hoping for you or some other wizard to whip it up in a few seconds.

---

<div class="post-metadata">

**Author:** ![Dan\_Micsa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan_micsa/32/30233_2.png) [@Dan\_Micsa](https://discourse.julialang.org/u/Dan_Micsa)\
**Post date:** [August 21, 2022, 4:54pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/10 "2022-08-21T16:54:39Z")

</div>

I don’t need a read only array. I’m in the middle of changing the array and is expenssive to make copies.

---

<div class="post-metadata">

**Author:** ![PeterSimon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petersimon/32/25193_2.png) [@PeterSimon](https://discourse.julialang.org/u/PeterSimon)\
**Post date:** [August 21, 2022, 4:59pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/11 "2022-08-21T16:59:02Z")

</div>

> [@Dan\_Micsa](#):
>
> and is expenssive to make copies

Note that as @mkitti showed above, `ReadOnlyArrays` does not make a copy of the original array. It provides a so-called “wrapper” that is cheap and fast.

---

<div class="post-metadata">

**Author:** ![Dan\_Micsa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan_micsa/32/30233_2.png) [@Dan\_Micsa](https://discourse.julialang.org/u/Dan_Micsa)\
**Post date:** [August 21, 2022, 5:06pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/12 "2022-08-21T17:06:36Z")

</div>

I wrote over 4000 lines of Julia (mostly Cut and Paste) and easy over 1.000.000 of C++. I can say that Julia is like templates în C++. Is relatively strong typed even if we don’t like to say so. My problem is that I can’t understand when and what parameters are changed or not in a function call because parameters are not decorated to make this explicit.

---

<div class="post-metadata">

**Author:** ![jebej](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jebej/32/1784_2.png) [@jebej](https://discourse.julialang.org/u/jebej)\
**Post date:** [August 21, 2022, 5:39pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/13 "2022-08-21T17:39:22Z")

</div>

You can’t decorate arguments to prevent mutation of standard arrays like in C++. If you absolutely require this feature, julia won’t work for you.

> [@Dan\_Micsa](#):
>
> I can’t understand when and what parameters are changed or not in a function call

This is why there is the convention to add a bang `!` to function names when mutation occurs. It’s also convention that the first argument is the one mutated.

> [@Dan\_Micsa](#):
>
> parameters are not decorated to make this explicit.

You could always have documentation, and/or write a comment at the top of the function to make it explicit. See, for example, the `push!` docstring:

```julia
help?> push!
search: push! pushfirst! pushdisplay

  push!(collection, items...) -> collection

  Insert one or more items in collection. If collection is an ordered
  container, the items are inserted at the end (in the given order).

```

---

<div class="post-metadata">

**Author:** ![Dan\_Micsa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan_micsa/32/30233_2.png) [@Dan\_Micsa](https://discourse.julialang.org/u/Dan_Micsa)\
**Post date:** [August 21, 2022, 5:43pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/14 "2022-08-21T17:43:01Z")

</div>

Ok so, again, the question is: A function like:

```julia
g!(a, b, c) 

```

is changing what parameters out of the three?!?

I understand this in other languages easy, for example looking at:  
void g(int a, int& b, int& c)  
I understand that the 2nd and 3rd parameter are changed inside the function, How do I understand this in Julia?

---

<div class="post-metadata">

**Author:** ![jebej](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jebej/32/1784_2.png) [@jebej](https://discourse.julialang.org/u/jebej)\
**Post date:** [August 21, 2022, 5:55pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/15 "2022-08-21T17:55:57Z")

</div>

If you wrote the `g!` function yourself, then you know which arguments you are mutating, if you didn’t write `g!`, you will need to look at the documentation or the code.

---

<div class="post-metadata">

**Author:** ![jebej](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jebej/32/1784_2.png) [@jebej](https://discourse.julialang.org/u/jebej)\
**Post date:** [August 21, 2022, 6:00pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/16 "2022-08-21T18:00:20Z")

</div>

Note that in Julia, you cannot mutate `Int`. All arguments are passed by value. If you wanted to mutate a single number, you would need to wrap it in a container, like a `Ref`. The equilvalent signature in Julia is thus:

```julia
g(a::Int, b::Ref{Int}, c::Ref{Int})

```

that would give you exactly the same hint as to whether the arguments are changed as in C.

---

<div class="post-metadata">

**Author:** ![Dan\_Micsa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan_micsa/32/30233_2.png) [@Dan\_Micsa](https://discourse.julialang.org/u/Dan_Micsa)\
**Post date:** [August 21, 2022, 6:00pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/17 "2022-08-21T18:00:27Z")

</div>

I didn’t wrote it I just want to use it or I want to use it 2 years after I wrote it and I forgot.

---

<div class="post-metadata">

**Author:** ![Dan\_Micsa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan_micsa/32/30233_2.png) [@Dan\_Micsa](https://discourse.julialang.org/u/Dan_Micsa)\
**Post date:** [August 21, 2022, 6:02pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/18 "2022-08-21T18:02:44Z")

</div>

My C++ answer was with Ints is the same with containers and of course still doesn’t answer the main question:

What params are mutable looking at this function definition in Julia: g!(a, b, c)?

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [August 21, 2022, 6:32pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/19 "2022-08-21T18:32:55Z")

</div>

> [@Dan\_Micsa](#):
>
> What params are mutable looking at this function definition in Julia: g!(a, b, c)?

This has been answered a few times now: You cannot tell, it is not possible. It could be all, none, or any other subset.

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [August 21, 2022, 6:57pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/20 "2022-08-21T18:57:10Z")

</div>

It is possible to decorate arguments.

```julia
function f!(a!, b)
    a! .= 0
end

```

The compiler cannot take advantage of it, but the user can.

[Next page](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091.md?page=2)
