# A possible change for Julia 2.0: per-argument mutation ! marks?

**URL:** https://discourse.julialang.org/t/a-possible-change-for-julia-2-0-per-argument-mutation-marks/119631
**Category:** Internals & Design
**Created:** [September 20, 2024, 12:26am UTC](https://discourse.julialang.org/t/a-possible-change-for-julia-2-0-per-argument-mutation-marks/119631 "2024-09-20T00:26:34Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)
#### Post date: [September 20, 2024, 12:26am UTC](https://discourse.julialang.org/t/a-possible-change-for-julia-2-0-per-argument-mutation-marks/119631/1 "2024-09-20T00:26:34Z")

</div>

This is just a brain-dump.

I find the convention of putting a `!` in a function name to _indicate_ a parameter might get changed to be less than satisfactory.

Because consider this `change!(a, b)`. What if the function changes `b` but not `a`? What if it changes both `a` and `b`? There’s no way to indicate that.

For example in Julia 2.0, could we do something like this

- using the keyword `not` instead of `!` for negation
- allow the `!` to be specified per argument and dispatch on that; explained below

For bullet point 2 I am thinking

`function change(a, b)` doesn’t mutate the input args at all  
`function change(!a, b)` is a function that mutates `a` and must be called by `change(!a, b)`

similarly `function change(a, !b)` only mutates b and `function (!a, !b)` mutates both `a` and `b` and the compiler can check within the body if `a` or `b` are mutated.

Obviously not a language designer. So might have missed something big.

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [September 20, 2024, 12:30am UTC](https://discourse.julialang.org/t/a-possible-change-for-julia-2-0-per-argument-mutation-marks/119631/2 "2024-09-20T00:30:45Z")

</div>

> [@xiaodai](#):
>
> `function change(!a, b)` is a function that mutates `a` and must be called by `change(!a, b)`

That would be such an enormous change to how the language works that I think this applies: [PSA: Julia is not at that stage of development anymore](https://discourse.julialang.org/t/psa-julia-is-not-at-that-stage-of-development-anymore/44872)

---

<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: [September 20, 2024, 12:53am UTC](https://discourse.julialang.org/t/a-possible-change-for-julia-2-0-per-argument-mutation-marks/119631/3 "2024-09-20T00:53:28Z")

</div>

> [@xiaodai](#):
>
> `function change(a, !b)` only mutates b and `function (!a, !b)`

Unlike function names, argument names in the definition are not visible in the function call, so it’s a much worse hint. Maybe it’s not a hint at all because we have to actually look up the function, figure out its dispatch at that call, and check the method’s arguments. At that point, I could just read the docstring and figure out which argument is mutated or possibly mutated, and there’s no need to write `!` everywhere.

If I really needed to indicate what gets mutated throughout my code, it should be apparent in the variable name or a comment. If I for some reason want an indication on every variable, there’s no need to change the parser to allow leading `!` because I can just append any number of them to variable names.

> [@xiaodai](#):
>
> the compiler can check within the body if `a` or `b` are mutated.

Why is this useful? What happens when the mutations are runtime decisions? We could instead say that `!a` means that `a` _could_ be mutated by the method, but that’s a very significant difference.

> [@stevengj](#):
>
> Julia is not at that stage

But the totally original language 2lia is at that stage.

---

<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: [September 20, 2024, 1:15am UTC](https://discourse.julialang.org/t/a-possible-change-for-julia-2-0-per-argument-mutation-marks/119631/4 "2024-09-20T01:15:37Z")

</div>

Some time ago I proposed using `change(a!, b)` (or `change2(a, b!)`) to indicate what was getting changed. It is perfectly legal to use right now.

---

<div class="post-metadata">

### Author: ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)
#### Post date: [September 20, 2024, 1:52am UTC](https://discourse.julialang.org/t/a-possible-change-for-julia-2-0-per-argument-mutation-marks/119631/5 "2024-09-20T01:52:49Z")

</div>

Ah nice one. Putting it in the back makes sense and is not breaking.

---

<div class="post-metadata">

### Author: ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)
#### Post date: [September 20, 2024, 1:54am UTC](https://discourse.julialang.org/t/a-possible-change-for-julia-2-0-per-argument-mutation-marks/119631/6 "2024-09-20T01:54:53Z")

</div>

> [@Benny](#):
>
> If I really needed to indicate what gets mutated throughout my code, it should be apparent in the variable name or a comment. If I for some reason want an indication on every variable, there’s no need to change the parser to allow leading `!` because I can just append any number of them to variable names.

No need to sound harsh. Makes me feel stupid. Like “why would u even do that?!”

I mean like statics analysis and conventions help prevent mistakes.

Just because there are alternative eg read up fix strings doesn’t mean an idea is totally bad. Like python can call numba and so why need Julia? Imagine someone making such a claim.

---

<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: [September 20, 2024, 2:10am UTC](https://discourse.julialang.org/t/a-possible-change-for-julia-2-0-per-argument-mutation-marks/119631/7 "2024-09-20T02:10:55Z")

</div>

> [@xiaodai](#):
>
> No need to sound harsh. Makes me feel stupid. Like “why would u even do that?!”

I don’t understand why you had such a negative reaction to the exact same suggestion as that offered by the following comment. If it was my inability to imagine a reason for a convention marking variables assigned to mutables, then it’s not at all an insult of anyone else. If you’d like, you could provide a reason, perhaps an example of the mistakes that could be prevented by static analysis of such a convention.

---

<div class="post-metadata">

### Author: ![kapple](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kapple/32/218915_2.png) [@kapple](https://discourse.julialang.org/u/kapple)
#### Post date: [September 20, 2024, 2:55am UTC](https://discourse.julialang.org/t/a-possible-change-for-julia-2-0-per-argument-mutation-marks/119631/8 "2024-09-20T02:55:29Z")

</div>

On a tangent, I wish we had gone the route of functions appended with `?` return a boolean.

> <https://github.com/JuliaLang/julia/issues/1910>
>
> This will allow us to have functions like \`contains?\` and \`empty?\`.

---

<div class="post-metadata">

### Author: ![xiaoxi](https://avatars.discourse-cdn.com/v4/letter/x/a9adbd/32.png) [@xiaoxi](https://discourse.julialang.org/u/xiaoxi)
#### Post date: [September 20, 2024, 6:05am UTC](https://discourse.julialang.org/t/a-possible-change-for-julia-2-0-per-argument-mutation-marks/119631/9 "2024-09-20T06:05:42Z")

</div>

I like the way Swift does it, but I am aware that Julia can’t adopt it.

```swift
func doubleInPlace(number: inout Int) {
    number *= 2
}
var myNum = 10 
doubleInPlace(number: &myNum)

```

> **[inout parameters - a free Hacking with Swift tutorial](https://www.hackingwithswift.com/sixty/5/10/inout-parameters)**
>
> Learn Swift coding for iOS with these free tutorials

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [September 20, 2024, 1:29pm UTC](https://discourse.julialang.org/t/a-possible-change-for-julia-2-0-per-argument-mutation-marks/119631/10 "2024-09-20T13:29:31Z")

</div>

> [@xiaoxi](#):
>
> I like the way Swift does it, but I am aware that Julia can’t adopt it.

This is a bit different — this is to pass an argument by reference, so that you can mutate the _binding_ of the argument when the argument is otherwise an immutable value. It’s not needed, even in Swift I believe, if the argument “points” to a mutable object whose _contents_ you want to change. (Make sure you understand the [difference between assignment and mutation](https://docs.julialang.org/en/v1/manual/variables/#man-assignment-expressions).)

The analogue of `&arg` in Swift (which comes from C) in Julia is `Ref(arg)`, though you then have to access its contents in the function as `arg[]` (much like `*arg` in C).

In fact, it would be perfectly possible to make `&x` valid syntax for `Ref(x)`, since this is invalid syntax at the moment. I once created a PR to do just that — [make &x sugar for RefValue(x) by stevengj · Pull Request #27608 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/27608) — but no consensus was reached.

Part of the reason is that this is simply not needed much in Julia. If you have multiple immutable things you want to return, you just return a tuple (unlike C which has no easy way to return multiple values from a function), and this is cheap. As a result, people hardly ever use `Ref` to simulate mutable arguments in Julia (except when doing `ccall` to other languages).

---

<div class="post-metadata">

### Author: ![rayegun](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rayegun/32/26729_2.png) [@rayegun](https://discourse.julialang.org/u/rayegun)
#### Post date: [September 20, 2024, 7:52pm UTC](https://discourse.julialang.org/t/a-possible-change-for-julia-2-0-per-argument-mutation-marks/119631/11 "2024-09-20T19:52:43Z")

</div>

It’s possible we can do this without breaking the language with better tooling!

I can imagine a world in which the `?` help menu, or docs in general can query the mutation of various arguments. Then our documentation and other tooling can display mutation in some way (highlighting, inserting a grayed out character like a bang at the end as you’re saying).

It’s then also possible that the compiler tools could propagate this mutation info around and display it in more places.

---

<div class="post-metadata">

### Author: ![FHell](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fhell/32/2421_2.png) [@FHell](https://discourse.julialang.org/u/FHell)
#### Post date: [September 25, 2024, 2:29pm UTC](https://discourse.julialang.org/t/a-possible-change-for-julia-2-0-per-argument-mutation-marks/119631/12 "2024-09-25T14:29:16Z")

</div>

Others have already commented that enforcing something like this is a pretty fundamental change in the language. But your intuition that this type of stuff is potentially desirable is of course correct, as evidenced by many experiments and languages that are trying to innovate in this field.

Rust, for example, distinguishes between passing (borrowing) an argument in a mutable and immutable way in order to make sure that there either is only one reference to an object, or all references are immutable. This “shared-xor-mutable” rule has profound consequences (e.g.: [Captcha Check](https://graydon2.dreamwidth.org/312681.html)) in making it possible to verify properties of your code locally. It’s also shared by the other two examples:

Mojo also intends to follow the Rust model, but make it more palatable and simplify it for the programmer: [Ownership and borrowing | Modular Docs](https://docs.modular.com/mojo/manual/values/ownership) I haven’t played with it enough to say whether I’d consider this successful.

The language that I know of that seems to most directly go in the direction you envision is hylo ( [https://www.hylo-lang.org/](https://www.hylo-lang.org/) ) which explores mutable value semantics. It actually requires explicit markers whenever a value is mutated. A function has to declare that it wants to mutate a particular variable (inout) and when you call the function, you have to denote that the function may mutate the argument with an &:

> **[Functions and methods | Language tour](https://docs.hylo-lang.org/language-tour/functions-and-methods#inout-parameters)**

```julia
fun offset_inout(_ target: inout Vector2, by delta: Vector2) {
  &target.x += delta.x
  &target.y += delta.y
}

# Arguments to inout parameters must be mutable and marked with an ampersand (&) at the call site:

fun main() {
  var v = (x: 3, y: 4) // v is mutable.
  offset_inout(&v, by: (x: 1, y: 1)) // ampersand indicates mutation.
}

# [...]

```

> The compiler guarantees that the behavior of target in the body of offset\_inout is as though it had been declared to be a local var, with a value that is truly independent from everything else in the program: only offset\_inout can observe or modify target during the call. Just as with the immutability of let parameters, this independence upholds local reasoning and guarantees freedom from data races.

---

<div class="post-metadata">

### Author: ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)
#### Post date: [September 25, 2024, 2:39pm UTC](https://discourse.julialang.org/t/a-possible-change-for-julia-2-0-per-argument-mutation-marks/119631/13 "2024-09-25T14:39:31Z")

</div>

Thanks for the info. Interesting to see hop doing this
