# 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:** 2

<div class="post-metadata">

### Author: ![jacobusmmsmit](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jacobusmmsmit/32/217669_2.png) [@jacobusmmsmit](https://discourse.julialang.org/u/jacobusmmsmit)
#### Post date: [August 21, 2022, 7:06pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/21 "2022-08-21T19:06:04Z")

</div>

It’s not done by the compiler, but you could always do:

```julia
a = [1, 2]
b = [3, 4]
c = [5, 6]
"""
    g!(a, b, c)

Warning: mutates the second argument
"""
g!(a, b, c) = b[2] = 1
g!(a, b, c)

```

and then you would know that whenever you saw a function with a `!` in the name you could check which are mutated by writing `?g!` in the REPL to check the docstring.

---

<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, 7:10pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/22 "2022-08-21T19:10:16Z")

</div>

This should be solved by language constructs like most of the modern languages and not comments that some people adds them some not.

---

<div class="post-metadata">

### Author: ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)
#### Post date: [August 21, 2022, 7:12pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/23 "2022-08-21T19:12:14Z")

</div>

Unless you go the Fortran route and disallow aliasing, you can’t really make guarantees here.

---

<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, 7:18pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/24 "2022-08-21T19:18:52Z")

</div>

> [@Dan\_Micsa](#):
>
> ```julia
> void g(int a, int& b, int& c)
> 
> ```

But in C++ you cannot actually tell either. You know that `b` and `c` _can_ be changed, but not that they _are_.

In julia

```julia
g(a::Int, b::Vector, c::Vector) 

```

you can similarly tell that `b` and `c` _can_ be changed, but not whether they _are_.

> [@Dan\_Micsa](#):
>
> like most of the modern languages

I am not certain what counts as a modern language. Are there many modern dynamic languages with this feature?

---

<div class="post-metadata">

### Author: ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)
#### Post date: [August 21, 2022, 7:42pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/26 "2022-08-21T19:42:32Z")

</div>

> [@Dan\_Micsa](#):
>
> A function like:
> 
> ```julia
> g!(a, b, c) 
> 
> ```
> 
> is changing what parameters out of the three?!?

Assuming the function author follows the Julia style guide, `a` should be mutated: [Style Guide · The Julia Language](https://docs.julialang.org/en/v1/manual/style-guide/#Write-functions-with-argument-ordering-similar-to-Julia-Base).

---

<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, 7:57pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/27 "2022-08-21T19:57:09Z")

</div>

But it could be that more than one argument that is mutated.

And then there are cases like `rand!` and `map!` where multiple conventions collide.

---

<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, 8:28pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/28 "2022-08-21T20:28:52Z")

</div>

> > you can similarly tell that `b` and `c` _can_ be changed, but not whether they _are_ .

In C++, for example, if they are not const they WILL be changed. I assume in many other languages too. In Julia is not clear if they are intended to be mutable or const nor enfocerced by the language or compiler. The person who makes the call cant guess what happens looking at the function call with its data specially if the name has an exclamation sign.

---

<div class="post-metadata">

### Author: ![sylvaticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sylvaticus/32/203883_2.png) [@sylvaticus](https://discourse.julialang.org/u/sylvaticus)
#### Post date: [August 21, 2022, 8:51pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/29 "2022-08-21T20:51:35Z")

</div>

I see this discussion going nowhere.  
I think your point is clear, but also the answer: it isn’t currently possible.

I also believe that if this isn’t possible, there is a reason “blocking” it.

What would be interesting instead would be to have a comment on what is blocking to have this language feature and if there are plans (in Julia 2??) to remove this bloccage. …

---

<div class="post-metadata">

### Author: ![ForceBru](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/forcebru/32/21389_2.png) [@ForceBru](https://discourse.julialang.org/u/ForceBru)
#### Post date: [August 21, 2022, 8:53pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/30 "2022-08-21T20:53:27Z")

</div>

> [@Dan\_Micsa](#):
>
> In Julia is not clear if they are intended to be mutable or const nor enfocerced by the language or compiler. The person who makes the call cant guess what happens looking at the function call with its data specially if the name has an exclamation sign.

Well, this is it, though: the language doesn’t let us express (im)mutability of function arguments. In Rust there’s special syntax to say “this argument is mutable”, but Julia doesn’t have this.

The compiler can’t help you with this, so, unfortunately, you have to rely on comments and meaningful variable names.

---

<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, 9:00pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/31 "2022-08-21T21:00:44Z")

</div>

> [@Dan\_Micsa](#):
>
> In C++, for example, if they are not const they WILL be changed.

Excuse me, but how do you know that? Doesn’t the code actually have to perform some sort of mutating operation on the variable? The act of not putting `const` in the signature surely does not change the argument all by itself.

---

<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, 9:13pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/32 "2022-08-21T21:13:25Z")

</div>

> [@ForceBru](#):
>
> Well, this is it, though: the language doesn’t let us express (im)mutability of function arguments. In Rust there’s special syntax to say “this argument is mutable”, but Julia doesn’t have this.

I don’t fully agree: You can tell if an argument is mutable or immutable by inspecting its type. So saying “this argument is mutable (or immutable)” is possible. But you cannot take any arbitrary mutable object and force it to be immutable. That might be useful, perhaps, having an annotation that guarantees that mutable object are not mutated.

---

<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, 9:43pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/33 "2022-08-21T21:43:55Z")

</div>

I got out the manual and after a few tries, managed to write the macro I referred to [earlier](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/9):

```julia
"""
    @immutable x 
    @immutable x y z 

Declare function argument(s) immutable, and generate an error if an attempt is made to mutate it/them.

Invisibly wraps the named argument(s) in a `ReadOnlyArray` wrapper, preventing accidental modifications 
to the arguments' contents. If the argument is other than a mutable `AbstractArray` the macro is a no-op.

## Example

    function f!(x,y,z)
        @immutable y z
        # Code which mutates x and uses values in y and z
    end
"""
macro immutable(xs...)
    local q = Expr[]
    local t
    for x in xs
        push!(q, 
        quote
            if isa($(esc(x)), AbstractArray) && ismutable($(esc(x)))
                t = $(esc(x))
                $(esc(x)) = ReadOnlyArray(t)
            end
        end)
    end
    return Expr(:block, q...)
end

```

A small demo:

```julia
julia> using ReadOnlyArrays

julia> function f!(x, y, z)
           @immutable x z
           @show typeof.((x,y,z))
           y[2] = 2
       end
f! (generic function with 1 method)

julia> x = (1,2,3,4);

julia> y = rand(4);

julia> z = rand(3);

julia> f!(x, y, z)
typeof.((x, y, z)) = (NTuple{4, Int64}, Vector{Float64}, ReadOnlyArray{Float64, 1, Vector{Float64}})
2

julia> y
4-element Vector{Float64}:
 0.5389943545876524
 2.0
 0.4961355278094852
 0.10676683774485696

```

Note that within the function the type of the tuple `x` wasn’t altered by the macro. Only `z` being a mutable `AbstractArray` was wrapped in a `ReadOnlyArray`.

I know this isn’t the complete answer to the OP’s post, but it would allow one to annotate and enforce immutability of function arguments. It may be worth a small package or perhaps a PR to `ReadOnlyArrays`.

---

<div class="post-metadata">

### Author: ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)
#### Post date: [August 21, 2022, 10:24pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/34 "2022-08-21T22:24:33Z")

</div>

> [@Dan\_Micsa](#):
>
> 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

No… it is not exactly like that, a `const` object in C++ can be changed, as a Julia one can (but is a little harder to do it) because it can have a pointer to some memory that can be changed even if the object itself is `const`. So, in the end, this is only better than Julia in the sense that most sensible programmers will annotate a parameter with `const` if it does not change state in any way, but not-so-sensible programmers can forget to add `const` to unchanging parameters, and hazardous programmers can mutate the state of `const` objects. In the end you are just relying on the prudence of previous programmers.

> [@Dan\_Micsa](#):
>
> 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.

> [@Dan\_Micsa](#):
>
> My C++ answer was with Ints is the same with containers and of course still doesn’t answer the main question

This is a problem to be solved by documentation.

> [@Dan\_Micsa](#):
>
> This should be solved by language constructs like most of the modern languages and not comments that some people adds them some not.

Why?

1. No language does that automatically, they always rely on the user annotating the parameter (or using a different object type) to guarantee `const`ness.
2. To suggest Julia do that, you need to understand Julia’s model, and have a good proposal how do you add that to the language. Julia’s model has no good way to implement that without breaking other parts of the language (or possibly being a performance hindrance). “Most modern languages” as you mention have a model in which the variable is a memory position, in Julia it is a binding, one very mainstream language that have a model that gets close to Julia is Java, and, surprise, surprise, Java also do not have a way to do what you want. The recommendation would be basically the same as here, create a immutable wrapper or use an immutable object.

---

<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 22, 2022, 12:53am UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/35 "2022-08-22T00:53:57Z")

</div>

> [@PeterSimon](#):
>
> `ReadOnlyArrays`

Thank you for the example.

Is again, a ReadOnlyArray my arrays are not so. Are big and mutable.

---

<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 22, 2022, 1:34am UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/36 "2022-08-22T01:34:54Z")

</div>

Dan, from your comment it sounds like you aren’t appreciating exactly how `ReadOnlyArrays` can be used for your purposes. Please consider the following example function, where I intend to mutate the first argument to be the reversed cumulative sum of the second argument. The second argument is annotated with `@immutable` to ensure it is not accidentally mutated in this function:

```julia
function revcumsum!(a::Vector, b::AbstractVector)
    @immutable b # Disallow mutations to second argument
    length(a) == length(b) || throw(ArgumentError("arguments must have same length"))
    a .= b
    cumsum!(a, b)
    reverse!(a)
    return a
end

```

Now we exercise the function on an array of one million elements. Note that both arrays are mutable outside of the function:

```julia
julia> b = collect(1:1_000_000);

julia> a = similar(b);

julia> revcumsum!(a, b);

julia> b[1:5]
5-element Vector{Int64}:
 1
 2
 3
 4
 5

julia> a[1:5] # contains the reversal of the cumulative sum of b
5-element Vector{Int64}:
 500000500000
 499999500000
 499998500001
 499997500003
 499996500006

julia> b[1] # Still retains original value
1

julia> b[1] = 0 # I am mutating b 
0

julia> b[1:5] # We see that the mutation occurred as requested
5-element Vector{Int64}:
 0
 2
 3
 4
 5

```

The point is that within the function, and only within the function, `b` becomes immutable. Also, we see that the function does not perform any memory allocation:

```julia
julia> using BenchMarkTools

julia> @btime revcumsum!($a, $b);
  1.390 ms (0 allocations: 0 bytes)

```

And if we make a similar function that omits the `@immutable` statement:

```julia
julia> function revcumsum2!(a::Vector, b::AbstractVector)
           length(a) == length(b) || throw(ArgumentError("arguments must have same length"))
           a .= b
           cumsum!(a, b)
           reverse!(a)
           return a
       end
revcumsum2! (generic function with 1 method)

julia> @btime revcumsum2!($a, $b);
  1.408 ms (0 allocations: 0 bytes)

```

the execution time is essentially identical to the original function that includes the `@immutable` statement. The execution time cost is negligible.

So to summarize, the point of `@immutable` is to allow you to annotate and disallow mutation of mutable arrays (of any size) within functions that you define. That way the function caller does not have to do anything special. The presence of the `@immutable` statement (typically and preferentially) on the second line of the function permits a quick inspection of the function to reveal which arguments could or could not be mutated.

That is the primary use case that I was thinking of. If I understand your wishes correctly, I believe that this goes at least partway (i.e. for functions that you yourself write) towards the goal you seek.

---

<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 22, 2022, 2:56am UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/37 "2022-08-22T02:56:42Z")

</div>

tyvm for your time to write this example! @imutable should be on Julia’s library.

It solves some of the problems pointed by me but is not a professional solution for large scale development:

- Objects with mutable fields are not protected.
- The ‘!’ decorator is still optional for mutable functions and this should be enforced even if I deeply dislike this solution.

---

<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 22, 2022, 3:58am UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/38 "2022-08-22T03:58:16Z")

</div>

> [@Henrique\_Becker](#):
>
> at to the language. Julia’s model has no good way to implement that without breaking other parts of the language

Sad … quite very sad and crippling for large scale software development. This togheter with inability to create standalone executable and inability to run scripts fast makes it useful just to replace eventually R, Matlab or Mathematica and never become a big language. No wonder the rate of adoption is so slow and Go and Rust, comparable old languages, are flying when compared with Julia.

---

<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 22, 2022, 5:04am UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/39 "2022-08-22T05:04:48Z")

</div>

> [@Dan\_Micsa](#):
>
> Sad … quite very sad and crippling for large scale software development.

Well, based on this discussion, it seems that other languages cannot do it either, or only partially 🤷

> [@Dan\_Micsa](#):
>
> This togheter with inability to create standalone executable and inability to run scripts fast

Standalone executables are under development and will be available in the not too distant future, and latency is actively worked on and has improved drastically over the last few years.

---

<div class="post-metadata">

### Author: ![favba](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/favba/32/2735_2.png) [@favba](https://discourse.julialang.org/u/favba)
#### Post date: [August 22, 2022, 5:12am UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/40 "2022-08-22T05:12:39Z")

</div>

> [@Dan\_Micsa](#):
>
> makes it useful just to replace eventually R, Matlab or Mathematica

Boy, that alone would not be a small feat!

---

<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 22, 2022, 9:23am UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/41 "2022-08-22T09:23:28Z")

</div>

> [@DNF](#):
>
> Well, based on this discussion, it seems that other languages cannot do it either, or only partially 🤷

C, C++, Rust, C# are some languages that are doing it even Python tries hard to solve it somehow because is so important.

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

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