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

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [August 22, 2022, 6:06pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/83 "2022-08-22T18:06:55Z")

</div>

> [@Dan\_Micsa](#):
>
> What macro we have that works?

I believe they are referring to the `@immutable` macro described earlier, but you’re right, it’s just a way to wrap things in `ReadOnlyArray` or possibly `ReadOnlyStruct`, it’s not even close to the C++ `const` you’re proposing.

> [@Dan\_Micsa](#):
>
> I still don’t understand how a mutable type (one that has mutable fields) will behave using that macro.

The macro would just wrap the mutable instance in an immutable struct instance that forwards field access to the mutable instance. However, mutating `setproperty!` is intentionally sabotaged. Substituting that immutable instance as an input will accomplish some enforcement of immutability, specifically throwing errors at `x.a = value`.

---

<div class="post-metadata">

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

</div>

> [@Dan\_Micsa](#):
>
> I dont feel this is good enough solution by a large margin.

Julia very specifically tries to be more expressive rather than more restrictive.

About the most expressive you can be is to have macros, because then if you want some language feature, you can mostly just build it yourself. If many people want this language feature, then it becomes maybe part of a standard library. This is more or less the Julian way.

> [@Dan\_Micsa](#):
>
> What macro we have that works?

It depends much on what you mean by “works”. And I still don’t understand the behavior you want, whether it’s a runtime behavior or a parse time behavior or a compile time behavior… these are all different things in Julia.

> [@Dan\_Micsa](#):
>
> What is mutable here: g!(a, b, c) ?

the solution to this is `? g!`

---

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

</div>

It still seems unlikely that Julia, the language and default toolchain, will be able to effectively meet your request at the moment. Essentially the issue is that we do not have a distinct code analysis step in the default workflow.

What may be possible, if you are willing to add an additonal step, would be for a code analysis tool to perform this check given sufficient annotation.

The leading code analysis tool is JET.jl.

> **[GitHub - aviatesk/JET.jl: An experimental code analyzer for Julia. No need...](https://github.com/aviatesk/JET.jl)**
>
> An experimental code analyzer for Julia. No need for additional type annotations. - GitHub - aviatesk/JET.jl: An experimental code analyzer for Julia. No need for additional type annotations.

[![](https://global.discourse-cdn.com/julialang/original/3X/f/1/f171f02347437a73b130ff34dccf8093d349f374.jpeg "JET.jl: The next generation of code checker for Julia | Shuhei Kadowaki | JuliaCon2021") ](https://www.youtube.com/watch?v=7eOiGc8wfE0)

Code analysis tools should become easier to build as well with JuliaSyntax.jl:

> **[GitHub - JuliaLang/JuliaSyntax.jl: A Julia frontend, written in Julia](https://github.com/JuliaLang/JuliaSyntax.jl)**
>
> A Julia frontend, written in Julia. Contribute to JuliaLang/JuliaSyntax.jl development by creating an account on GitHub.

[![](https://global.discourse-cdn.com/julialang/original/3X/f/e/fee5b1ef21fc791fd9e1290dceec45ef54359e1f.jpeg "JuliaSyntax.jl: A new Julia compiler frontend in Julia | Chris Foster | JuliaCon 2022") ](https://www.youtube.com/watch?v=CIiGng9Brrk)

This could be integrated with testing and continuous integration. While this means that the workflow may become similar to that of statically compiled langauges, perhaps this is not something you would not mind?

---

<div class="post-metadata">

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

</div>

> [@mkitti](#):
>
> Essentially the issue is that we do not have a distinct code analysis step in the default workflow.

It’s not impossible to write a macro that does very specific code analysis though. Like if a group has some coding conventions they want to enforce and can describe them as syntax requirements (like don’t put certain vars on the left side of assignment operators etc) then you could write a macro

```julia
@enforce_reqmts function a(b,c,d)
...
end

```

This could also insert runtime checks as well.

This is, more or less, the Julian way.

---

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

</div>

> [@dlakelan](#):
>
> or right after something like this:
> 
> ```julia
> function foo!(a,const b)
> 
> ```

Something like that. Normally after agreeing over an interface in implementation the compiler should not compile if something not complies with the interface like it does in other languages. I would preffer the reversed behaviour of C/C++ everything is const until explicit specified otherwise feels more natural and short.

Or something like this:

```julia
function foo(a!, b) #or foo(mut a, b), whatever
  a[1] = 1
end

```

---

<div class="post-metadata">

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

</div>

I think the Julian way to handle this will be a macro. Note that julia **compiles** the code at runtime when you first **call** it. But I doubt you’re looking for a “runtime” error in the middle of testing your code, you’re probably hoping for something that errors out as soon as you’re done inputting the code, and that’s _parse_ time.

I’m not sure exactly what such macros would look like, but they would really vary from one developer group to another. Another way to go would be the Jet route. Though I’m not familiar with Jet, I probably need to get familiar with it.

I’m guessing you want something like:

```julia
@enforce_rules function foo!(a,b!)
...
a[1] = 2
end

```

The `@enforce_rules` macro would walk through the code and see if there were any instances of you doing things you shouldn’t do according to whatever your own rules are for what you want to enforce.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [August 22, 2022, 7:08pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/89 "2022-08-22T19:08:46Z")

</div>

If catching syntactic sugar like `a[1] = 2` or `a.x = 3` was all it needed, then this would be a far simpler task that could be done at parse-time. But the big problem is most mutating methods are just function calls. They do eventually dispatch down to a handful of fundamentals like `setindex!`, `setproperty!`, `push!`, etc., but method dispatch is something that is only figured out at compile-time, long after parse-time. And sometimes, the compiler can’t even find the methods at compile-time, it needs runtime types to do runtime dispatch.

---

<div class="post-metadata">

**Author:** ![dlakelan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlakelan/32/8491_2.png) [@dlakelan](https://discourse.julialang.org/u/dlakelan)\
**Post date:** [August 22, 2022, 7:11pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/90 "2022-08-22T19:11:44Z")

</div>

Yes, agreed. But I think the OP is really looking for something simpler than “we have a formal proof that Julia will never mutate this thing”.

A macro could in fact lower the code and then go through and make sure you don’t call setindex! or setproperty! on any variable that appears in the argument list of the function which doesn’t end in ! for example. I think that is the kind of thing OP wants?

Note, I’m not entirely clear on how a macro would force the code to be lowered. I’m guessing there is some `lower_code(expr)` function in julia but I don’t know details. In this case, perhaps it could simply replace = with setindex! or setproperty! calls itself.

it would also be tricky to handle things like:

```julia
function foo(a)
  b = a
  b[1] = 2
end

```

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [August 22, 2022, 7:31pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/91 "2022-08-22T19:31:00Z")

</div>

> [@dlakelan](#):
>
> But I think the OP is really looking for something simpler than “we have a formal proof that Julia will never mutate this thing”.

Considering the C++ comparisons and that repeated offers of immutable types weren’t enough, I think OP really is going for something that solid.

> [@dlakelan](#):
>
> it would also be tricky to handle things like:
> 
> ```julia
> function foo(a)
> b = a
> b[1] = 2
> end
> 
> ```

The parser could figure out that `a` and `b` must have the same instance. If you want a real problem, feast your eyes on this:

```julia
function abba!(a!, b) # mutate a!, do not mutate b
    a![1] = sum(b)
    return nothing
end

x = [1,2,3]
abba!(x, x) # uh oh

```

---

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

</div>

I read your first answer on this thread and really got the filling that what you wrote here is was what you really wanted to write from the beginning…

---

<div class="post-metadata">

**Author:** ![dlakelan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlakelan/32/8491_2.png) [@dlakelan](https://discourse.julialang.org/u/dlakelan)\
**Post date:** [August 22, 2022, 8:08pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/93 "2022-08-22T20:08:11Z")

</div>

> [@Benny](#):
>
> Considering the C++ comparisons

One thing that is often not obvious to those comparing is that in C++ it is possible for the compiler to know everything about a function or about all “methods” from a template all at once.

In Julia, at runtime someone can redefine a method or define a new method that operates on new types. At any moment the meaning of foo(a,b) can change. It is approximately like you are compiling a program in C++ which is free to write out files in C++, call g++ on them, link them into the program, and then edit all the jumps in existing code to jump to the new definition. And, furthermore this can all be triggered by user input…

---

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

</div>

I don’t know how we should be done best. But as strong enforcement as possible and simple as possible will be recomended.

Let’s take the swap case. The simplest way of solving it and will still work in 1.x too is:

```julia
#instead of:
swap!(a, b)...

#let's postfix the mutable variables with an '!'
swap!(a!, b!)...

#I like with the 
swap(a!, b!)... 
# but is not named using current Julia conv to have the '!' at end.

```

In future this variables can be better checked and enforced as the time passes.

---

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

</div>

> [@dlakelan](#):
>
> eone can redefine a method

I would dare to say that Julia is very similar with C++ at compile time. All this post was about enforcing and clarifying (im)mutability of fields in each function. So is relevant and shound check and behave similarly at the moment of compilation as I pointed before trying to compile an offending C++ example.

Reminder:

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

error C3892: 'r': you cannot assign to a variable that is const

```

---

<div class="post-metadata">

**Author:** ![dlakelan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlakelan/32/8491_2.png) [@dlakelan](https://discourse.julialang.org/u/dlakelan)\
**Post date:** [August 22, 2022, 10:09pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/96 "2022-08-22T22:09:58Z")

</div>

> [@Dan\_Micsa](#):
>
> I would dare to say that Julia is very similar with C++ at compile time.

But when is “compile time”? You’re aware that it’s the moment during the running of the code that the function is **first called** right? And that, any arbitrary amount of time could have passed since the initial start-up of your program. Like it could be 3 years after starting your program that the function is finally compiled.

---

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

</div>

whenever the template is consumed or specialized.

Is pretty much the same in both languages. Julia model is just the C++ compile time polymorphism that is not implemented safe enough yet and this is what I want to discuss and improve.

We call it in Julia multiple dispatching and are proud because de C++ don’t bother with this. 😄

---

<div class="post-metadata">

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

</div>

> [@Dan\_Micsa](#):
>
> whenever the template is consumed or specialized.

Right, which is when the function is **first called**. So for example

```julia
function foo(a,b)
   bar(a) + baz(b)
end

```

as long as bar and baz don’t mutate anything, this is a non-mutating function…

So we start our program running… 3 years later it’s running on a Mars rover and someone sends some sort of command which causes us to call foo(a,b) on two values which have never been seen before, perhaps they’re specialized structs, and perhaps we’ve sent the mars rover a file and it “include(“thefile.jl”)” which defined those structs, and also defined `bar(::ThatStruct)` and it did so in such a way that now bar is mutating things…

How would C++ handle that? (hint: it wouldn’t)

Note also that Julia multiple dispatch is NOT the same as C++ templates. Because C++ templates all have the same code… it’s ONE template specialized to multiple types. In Julia every method can do something entirely different. 100% different code.

```julia
function quux(a::Int64)
   a+1
end

function quux(a::Float64)
   sqrt(a+1e6)
end

```

---

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

</div>

> > How would C++ handle that? (hint: it wouldn’t)

C++ is a serious and mature language. We can complain about some attrocities that came from C era but now at C++21 is a very serious language and CT polymorphism is solved for a long time. Let’s dont open this topic here.

Very simple in C++ f(const T&) and f(T&) are too different functions this should be in Julia too. If at a given moment a function calls f(const T) a code that requires f(T) needs to see f(T) implementation.

In your case with quux example you don’t modify the a variable.

---

<div class="post-metadata">

**Author:** ![dlakelan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlakelan/32/8491_2.png) [@dlakelan](https://discourse.julialang.org/u/dlakelan)\
**Post date:** [August 22, 2022, 10:41pm UTC](https://discourse.julialang.org/t/why-i-cant-set-what-parameters-are-mutable-explicitly/86091/100 "2022-08-22T22:41:54Z")

</div>

So now there are two issues…

1. When do you get the error: In Julia it will be 3 years after you launch the Mars Rover

2. How do we distinguish between `f(::MyType)` and something let’s call it `f(::Const{MyType})`

Is 1) satisfactory to you? 3 years after launching your rover you finally discover that your code did something stupid under some circumstances?

And part (2) has already been shown further up thread. Julia can mostly handle this, you just create “wrapper types” which prevent setindex! and setproperty! from working right, but it’s up to the **caller** to call your “separate function” by handing it things of the right type, namely constant structures.

---

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

</div>

> [@dlakelan](#):
>
> When do you get the error: In Julia it will be 3 years after you launch the Mars Rover

1. When do you get the error: In Julia it will be 3 years after you launch the Mars Rover.

The Mars rover will work perfectly for 3 reasons:

1. Will not recieve soon code in Julia if the language is so imature.
2. The application will be already compiled and tested on Earth and sent as an executable how Julia will do it in 2 years.
3. It can’t compile wrong code that uses a function that tries to specialised an undefined function f(T) instead f(const T).

---

<div class="post-metadata">

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

</div>

> [@Dan\_Micsa](#):
>
> Let’s dont open this topic here.

I think you are missing my point. C++ just **does not** handle the case where “3 years after launching the rover we send the rover a code file that defines some new types and a bunch of new functions that operate on those types but with the same names as other functions”. When you run g++ it sees the entire code all at once and links everything, and then it’s all static. Julia **by design** does not have this “all at once ahead of time static compiled” design.

> [@Dan\_Micsa](#):
>
> In your case with quux example you don’t modify the a variable.

But the point of that example was that quux does **totally different code** depending on what the type of the argument was… In C++ templates the code is the same it’s just specialized during compile time to know exact offsets of certain struct values and etc.

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

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