# Function argument, binding, name, assignment, mutation

**URL:** <https://discourse.julialang.org/t/function-argument-binding-name-assignment-mutation/132916>\
**Category:** New to Julia\
**Created:** [October 6, 2025, 2:39pm UTC](https://discourse.julialang.org/t/function-argument-binding-name-assignment-mutation/132916 "2025-10-06T14:39:34Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![WalterMadelim](https://avatars.discourse-cdn.com/v4/letter/w/3e96dc/32.png) [@WalterMadelim](https://discourse.julialang.org/u/WalterMadelim)\
**Post date:** [October 6, 2025, 2:39pm UTC](https://discourse.julialang.org/t/function-argument-binding-name-assignment-mutation/132916/1 "2025-10-06T14:39:34Z")

</div>

I reviewed the very first lesson people learned from doc [Functions · The Julia Language](https://docs.julialang.org/en/v1/manual/functions/#man-argument-passing)

```julia
julia> function f(x, y)
           x[1] = 42 # mutates x
           y = 7 + y # new binding for y, no mutation
           return y
       end;

julia> @code_warntype f([1], 5.0)
MethodInstance for f(::Vector{Int64}, ::Float64)
Arguments
  y@_3::Float64
Locals
  y@_4::Float64
Body::Float64
1 ─ (y@_4 = y@_3)
│ %3 = Main.:+::Core.Const(+)
│ %4 = y@_4::Float64
│ (y@_4 = (%3)(7, %4))
│ %6 = y@_4::Float64
└── return %6

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/3/8/385b0e9fd96a5c28ea130e2df6d423cb24c7cb52.jpeg)

According to my knowledge

- A _binding_ is an association / a relationship / a fact that _a name refers to an object_
- A _name_ is merely a name (some other people also call it a “variable”)

So what does the operation `y = 7 + y` do?  
It changes the old binding `y@_4 = 5.0` to the new binding `y@_4 = 12.0`.  
But in both bindings, the name is `y@_4` at both places.

I don’t think the existing doc reads coherent—`y` itself is not a binding; and `y` is not changed

---

<div class="post-metadata">

**Author:** ![WalterMadelim](https://avatars.discourse-cdn.com/v4/letter/w/3e96dc/32.png) [@WalterMadelim](https://discourse.julialang.org/u/WalterMadelim)\
**Post date:** [October 6, 2025, 3:17pm UTC](https://discourse.julialang.org/t/function-argument-binding-name-assignment-mutation/132916/2 "2025-10-06T15:17:54Z")

</div>

My intuition suggests (do not constitute an advice):

- Had best not reuse a name from an argument. Do not do the `y = somethingElse` above, since `y` is already a name of an argument.
- If intend to, had best add a `let`:

Instead of doing

```julia
function f(x, y)
    x[1] = 43
    y = y * 1.0
    y = y * 1.0
    () -> y
end

```

, had best do

```julia
function f(x, y)
    let y = y
        x[1] = 43
        y = y * 1.0
        y = y * 1.0
        () -> y
    end
end

```

I have no idea which one has better performance. But the latter one looks a lot neater.  
The former has `y@_7::Union{Int64, Core.Box}`,  
whereas the latter only has `y@_5::Core.Box`.

---

<div class="post-metadata">

**Author:** ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)\
**Post date:** [October 6, 2025, 3:42pm UTC](https://discourse.julialang.org/t/function-argument-binding-name-assignment-mutation/132916/3 "2025-10-06T15:42:53Z")

</div>

> [@WalterMadelim](#):
>
> It changes the old binding `y@_4 = 5.0` to the new binding `y@_4 = 12.0`.  
> But in both bindings, the name is `y@_4` at both places.

I’m not sure it makes sense to mix the lowered code with the semantics of julia code in this way. A lot of transformations are done on the way to native code. In particular, one intermediate representation is SSA (Static Single Assignment), the one you see with `@code_typed`. Then «bindings» are something completely different.

---

<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:** [October 6, 2025, 7:20pm UTC](https://discourse.julialang.org/t/function-argument-binding-name-assignment-mutation/132916/4 "2025-10-06T19:20:15Z")

</div>

I see it as when you call a function, you pass it objects, not names.  
So, in this example, the function initially bind the name `y` to the object with which it is called, and then it rebinds it to a totally new object.  
There isn’t anything wrong in doing that..

---

<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:** [October 6, 2025, 7:27pm UTC](https://discourse.julialang.org/t/function-argument-binding-name-assignment-mutation/132916/5 "2025-10-06T19:27:11Z")

</div>

> [@WalterMadelim](#):
>
> A _binding_ is an association / a relationship / a fact that _a name refers to an object_

Don’t all names _always_ refer to some object, though? In this case there’s no difference between a binding and a name…

---

<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:** [October 6, 2025, 10:08pm UTC](https://discourse.julialang.org/t/function-argument-binding-name-assignment-mutation/132916/6 "2025-10-06T22:08:39Z")

</div>

> [@WalterMadelim](#):
>
> Had best not reuse a name from an argument. Do not do the `y = somethingElse` above

I’m going to hazard a guess that you’re thinking of the Performance Tips section on captured variables, which you commented in another thread yesterday. That issue only applies to captured variables like `() -> y`, it’s otherwise fine and typical to reassign method arguments. Don’t exaggerate contextual implementation limitations, which can change, to unidiomatic code practices.

> [@WalterMadelim](#):
>
> the old binding `y@_4 = 5.0`

`y@_4` is an implementation detail of code lowering, not a name/binding/variable on the language level that the Manual describes.

> [@WalterMadelim](#):
>
> According to my knowledge
> 
> - A _binding_ is an association / a relationship / a fact that _a name refers to an object_

That would be a reasonable colloquial usage, but another reasonable usage is the name that has been bound to a value. For example, we also call the materials for the binding of a book its binding. English words are ambiguous by nature, it’s futile to apply the same rigor to them as a programming language specification. You have to consider the context as well, and “the binding (“name”) `y`” clearly considers binding to be synonymous with name in Julia. I would prefer to describe reassignments without involving any form of the word “bind”, but it is what it is.

---

<div class="post-metadata">

**Author:** ![WalterMadelim](https://avatars.discourse-cdn.com/v4/letter/w/3e96dc/32.png) [@WalterMadelim](https://discourse.julialang.org/u/WalterMadelim)\
**Post date:** [October 6, 2025, 10:38pm UTC](https://discourse.julialang.org/t/function-argument-binding-name-assignment-mutation/132916/7 "2025-10-06T22:38:32Z")

</div>

> [@ForceBru](#):
>
> Don’t all names _always_ refer to some object, though?

No. Can you tell the difference between declaration, read, write?

```julia
function f1()
    # This function only declares about the name `x`
    # There is no read, nor write (assignment)
    local x
    local x
end;
@assert isnothing(f1())
function f2() # this function reads `x`
    x
end
function f3() # this function binds `x` to `3`
    local x
    x = 3
end

```

> [@ForceBru](#):
>
> In this case there’s no difference between a binding and a name…

If `the_English_word_binding === the English_word_name`, then why do you abuse the word `binding`?

> [@sylvaticus](#):
>
> I see it as when you call a function, you pass it objects, not names.

~~I fail to understand your idea. It really pass the name, see the `x[1] = 42` usage.~~

> [@sylvaticus](#):
>
> There isn’t anything wrong in doing that..

I didn’t mean it conducts a wrong behavior, I was talking about his inaccurate _language_.

> [@sgaure](#):
>
> Then «bindings» are something completely different.

I fail to get your meaning. Could you elaborate the full idea?  
I use `@code_warntype` because it teaches me how to understand the behavior of my code.  
I don’t know if there is any substitute.

> [@Benny](#):
>
> For example, we also call the materials for the binding of a book its binding. English words are ambiguous by nature

Okay, I believe you if you are a native speaker.  
But here is what I found

 ![image](https://global.discourse-cdn.com/julialang/original/3X/b/1/b1672184d2210535400c086987bdfeba6c0c8a07.png)

---

<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:** [October 6, 2025, 11:25pm UTC](https://discourse.julialang.org/t/function-argument-binding-name-assignment-mutation/132916/8 "2025-10-06T23:25:18Z")

</div>

I think you’re right that a name is only one part of a binding, and that the quoted sentence in the manual could be made a bit more precise.

On the other hand, my impression is that using just the name to refer to a binding is pretty common, the same way that we (and maybe you as well?) would use `y` to refer to both a variable and the value it refers to.

> [@WalterMadelim](#):
>
> It really pass the name, see the `x[1] = 42` usage.

This, I don’t get. To pass the name, you should use a `String` or a `Symbol`. The thing that is passed to the function is a value/object, which is then bound to the name `x`.

As for reusing the name `y`, you may have a point, but mainly for performance. Doing something like `y = 1.0 * y` can easily change the type of `y`, which, at least in the past, used to have negative performance implications.

> [@WalterMadelim](#):
>
> I fail to get your meaning. Could you elaborate the full idea?

I can’t elaborate too much, but the compiler is allowed to make a number of changes to your code, as long as it produces the same output. Looking at compiler output might not tell you what your code ‘really’ means.

---

<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:** [October 6, 2025, 11:52pm UTC](https://discourse.julialang.org/t/function-argument-binding-name-assignment-mutation/132916/9 "2025-10-06T23:52:46Z")

</div>

> [@WalterMadelim](#):
>
> But here is what I found

Don’t learn semantics from an LLM, and don’t forget that the same English word can have multiple meanings. Again, this is why I would’ve preferred not to use any form of the word “bind” to describe names and reassignments.

---

<div class="post-metadata">

**Author:** ![WalterMadelim](https://avatars.discourse-cdn.com/v4/letter/w/3e96dc/32.png) [@WalterMadelim](https://discourse.julialang.org/u/WalterMadelim)\
**Post date:** [October 7, 2025, 1:53am UTC](https://discourse.julialang.org/t/function-argument-binding-name-assignment-mutation/132916/10 "2025-10-07T01:53:27Z")

</div>

> [@DNF](#):
>
> use `y` to refer to both a variable and the value it refers to

Yes.

> [@DNF](#):
>
> > [@WalterMadelim](#):
> >
> > It really pass the name, see the `x[1] = 42` usage.
> 
> This, I don’t get.

You’re right. My language was vague. I withdrew that. It shares the underlying object. An outer name cannot be seen within a function in case like this

```julia
x = [43]
f(x, y) # Then from within the body of `f`, the outer `x` cannot be seen

```

> [@Benny](#):
>
> this is why I would’ve preferred not to use any form of the word “bind” to describe names and reassignments.

I dislike it either. Because the past participle of `bind` is `bound`. And the phrase `bound to` has other meanings… I feel super strange to read “an `y` is bound to `7`”, when I started to learn julia. Until later I realized that “bound” is the past participle of “bind”.

* * *

> [@DNF](#):
>
> I can’t elaborate too much, but the compiler is allowed to make a number of changes to your code, as long as it produces the same output.

This is convincing,

The only thing I’m worrying about is:

while I write `x = some_object` in my text editor, I hope that julia will never ever stealthily lower my code to some code like `Core.set_box_content!(x, some_object)`. This really changes my intention (from an assignment to a mutation!), which would be very dishonest. But the upside is that I receive the final behavior as expected after all.

---

<div class="post-metadata">

**Author:** ![WalterMadelim](https://avatars.discourse-cdn.com/v4/letter/w/3e96dc/32.png) [@WalterMadelim](https://discourse.julialang.org/u/WalterMadelim)\
**Post date:** [October 7, 2025, 2:13am UTC](https://discourse.julialang.org/t/function-argument-binding-name-assignment-mutation/132916/11 "2025-10-07T02:13:34Z")

</div>

> [@WalterMadelim](#):
>
> The only thing I’m worrying about is:

To be more concise, I mean the following test

```julia
import Random.seed! as seed!
N::Int = 999
function gen(cnt)
    if cnt % 2 == 1
        seed!(1)
        return rand(Int128, N, N)
    else
        seed!(3)
        return rand(Int128, N, N)
    end
end;
function check(s)
    if s == gen(0)
        println(0)
    elseif s == gen(1)
        println(1)
    else # I cannot see this in practice
        println("\tEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE")
    end
end;

function test(m)
    for c = 1:10000000
        for j = 1:14
            Threads.@spawn check(m)
        end
        println("c=$c")
        m .= gen(c) # Core.setfield!(m, :contents, %51)
    end
end

test(gen(0))

```

If you write `m .= gen(c)`, then you can observe “EEEEEEEEEEEEEEEEEEEEEEEEE”  
But if you write `m = gen(c)`, then you cannot observe “EEEEEEEEEEEEEEEEEEEEEEE”.

tested with julia - -threads=4

---

<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:** [October 7, 2025, 4:09am UTC](https://discourse.julialang.org/t/function-argument-binding-name-assignment-mutation/132916/12 "2025-10-07T04:09:56Z")

</div>

> [@WalterMadelim](#):
>
> while I write `x = some_object` in my text editor, I hope that julia will never ever stealthily lower my code to some code like `Core.set_box_content!(x, some_object)` . This really changes my intention (from an assignment to a mutation!)

That’s not how `Core.Box` works, and that distinction between assignment and mutation doesn’t make sense. Mutation of Julia objects implemented on the Julia level involves assignment, and whether an assignment mutates an internal Julia object is an implementation detail. Again, be careful to not mix up implementation with language semantics; a variable is still a variable whether it’s internally implemented by `Core.Box`, a spot on a call stack, or whatever other structure on the Julia or C level.

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [October 7, 2025, 4:24am UTC](https://discourse.julialang.org/t/function-argument-binding-name-assignment-mutation/132916/13 "2025-10-07T04:24:11Z")

</div>

Hi @WalterMadelim, speaking as a moderator here.  
The Julia documentation is written in natural language (English), as opposed to a formal programming language. Therefore, it can never be 100% unambiguous, and some terms may be used in ways that differ from what you expect. That is especially true if you’re a non-native English speaker (I am too).  
However, I suggest you ask yourself whether these minor nitpicks deserve a new topic every time. While we of course encourage active forum participation, your rate of creating new topics over reading existing topics is very high. For example, all the other people in this conversation create new topics at a rate that is anywhere from 2 to 20 times lower than yours. Discussions like this one, on concepts that you already understand, take community time away from other users that could genuinely benefit from some help. Please keep that in mind.

---

<div class="post-metadata">

**Author:** ![WalterMadelim](https://avatars.discourse-cdn.com/v4/letter/w/3e96dc/32.png) [@WalterMadelim](https://discourse.julialang.org/u/WalterMadelim)\
**Post date:** [October 7, 2025, 4:32am UTC](https://discourse.julialang.org/t/function-argument-binding-name-assignment-mutation/132916/14 "2025-10-07T04:32:19Z")

</div>

> [@gdalle](#):
>
> Discussions like this one, on concepts that you already understand

Because I encounter problems, I post here. If the language works as expected, we wouldn’t ask questions. Because both of our time are precious.

> [@gdalle](#):
>
> ake community time away from other users

They have confusion either! They also discover/learn something new.

> [@WalterMadelim](#):
>
> > [@ForceBru](#):
> >
> > Don’t all names _always_ refer to some object, though?
> 
> No. Can you tell the difference between declaration, read, write?
> 
> ```julia-auto
> function f1()
> # This function only declares about the name `x`
> # There is no read, nor write (assignment)
> local x
> local x
> end;
> @assert isnothing(f1())
> function f2() # this function reads `x`
> x
> end
> function f3() # this function binds `x` to `3`
> local x
> x = 3
> end
> 
> ```

* * *

Anyway, thank you for your participation.

---

<div class="post-metadata">

**Author:** ![WalterMadelim](https://avatars.discourse-cdn.com/v4/letter/w/3e96dc/32.png) [@WalterMadelim](https://discourse.julialang.org/u/WalterMadelim)\
**Post date:** [October 7, 2025, 4:40am UTC](https://discourse.julialang.org/t/function-argument-binding-name-assignment-mutation/132916/15 "2025-10-07T04:40:15Z")

</div>

> [@Benny](#):
>
> whether an assignment mutates an internal Julia object is an implementation detail.

The point is:

when I write assignments like

```julia
x = [0, 0, 0]
sleep(1)
x = [1, 1, 1]

```

I am expecting that: At _any_ time on _any_ threads, when anyone read `x`, they should either read `[0, 0, 0]` or `[1, 1, 1]` (The 2-point Bernoulli distribution).

while when I write mutation like

```julia
x = [0, 0, 0]
set_content!(x, [1, 1, 1])

```

At an arbitrary time, I am _prepared to_ receive an undesired `[0, 1, 1]`-like intermediate state.

I don’t expect julia to alter my intention. i.e., an assignment is merely an assignment, which cannot allow intermediate states to happen.

---

<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:** [October 7, 2025, 5:23am UTC](https://discourse.julialang.org/t/function-argument-binding-name-assignment-mutation/132916/16 "2025-10-07T05:23:03Z")

</div>

If you explicitly perform mutation instead of simple assignment on an object you may observe behavior that is visibly different (as in your example `test`).

Are you saying that you are concerned that if the compiler optimizes an assignment to a mutation, you may also observe this?

But that would mean that optimization was invalid. My understanding is that the compiler cannot make these changes willy-nilly, but must prove that they are equivalent.

Can you create an example were this happens?

---

<div class="post-metadata">

**Author:** ![WalterMadelim](https://avatars.discourse-cdn.com/v4/letter/w/3e96dc/32.png) [@WalterMadelim](https://discourse.julialang.org/u/WalterMadelim)\
**Post date:** [October 7, 2025, 5:54am UTC](https://discourse.julialang.org/t/function-argument-binding-name-assignment-mutation/132916/17 "2025-10-07T05:54:51Z")

</div>

> [@DNF](#):
>
> If you explicitly perform mutation instead of simple assignment on an object you may observe behavior that is visibly different (as in your example `test`).

If I wrote `set_content!(x, [1, 1, 1])` on my text editor, then it means I intend to do so.  
So I’m okay with receiving an intermediate state like `[1, 1, 0]`.  
And in my practical test above I _do_ observed this.

But in practice, since this is unsafe, I will _have to_ carry out locks, i.e. using `@lock` in every threads, which is inconvenient.

> [@DNF](#):
>
> if the compiler optimizes an assignment to a mutation

It cannot do this. This is altering the user’s intention, which is invalid.  
Assignment is in no way the same concept as mutation.  
The former is changing a continuous block of memory, while the latter is just a re-associating action.

e.g.

```julia
x = [0, 0, 0]
x = [1, 1, 1]

```

The expected action for the second assignment is:

1. create the object [1, 1, 1] in the memory
2. let the name `x` refer to the established object [1,1,1]. (But before this happens, the `x` was referring to [0, 0, 0])

* * *

Unfortunately, the `test` code in my #11 post serves only as a necessary condition—it is not sufficient. By observing the results, I can only infer that julia currently is not violating my intention, which is agreeable. But I can not prove that julia is doing everything all right.

> [@DNF](#):
>
> Can you create an example were this happens?

Unfortunately I can’t. This is somehow like to ask one person to come up with an instance to prove `NP = P`. (a nonserious statement)

---

<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:** [October 7, 2025, 5:57am UTC](https://discourse.julialang.org/t/function-argument-binding-name-assignment-mutation/132916/18 "2025-10-07T05:57:06Z")

</div>

> [@WalterMadelim](#):
>
> an assignment is merely an assignment, which cannot allow intermediate states to happen.

You’re talking about a kind of data race, an implementation detail. Languages don’t specify how assignments are implemented, so there are no guarantees about data races. Use proper locks and atomic operations on a variable shared by multiple tasks, or refactor around sharing it to begin with.

---

<div class="post-metadata">

**Author:** ![WalterMadelim](https://avatars.discourse-cdn.com/v4/letter/w/3e96dc/32.png) [@WalterMadelim](https://discourse.julialang.org/u/WalterMadelim)\
**Post date:** [October 7, 2025, 6:00am UTC](https://discourse.julialang.org/t/function-argument-binding-name-assignment-mutation/132916/19 "2025-10-07T06:00:18Z")

</div>

> [@Benny](#):
>
> so there are no guarantees about data races

I see. But how can you explain that I cannot observe the unexpected behavior in my #11 post?  
Can you come up with an counterexample to give a definite answer?

> [@Benny](#):
>
> refactor around sharing it

What do you mean by “refactor around”?

* * *

> [@DNF](#):
>
> if the compiler optimizes an assignment to a mutation, you may also observe this?

In large possibility I should can observe this.  
But as my test in #11 post, I do not observe.

---

<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:** [October 7, 2025, 6:06am UTC](https://discourse.julialang.org/t/function-argument-binding-name-assignment-mutation/132916/20 "2025-10-07T06:06:49Z")

</div>

> [@WalterMadelim](#):
>
> how can you explain

I can’t, and I’m not going to bother digging into how any particular version of Julia implements that example. The point is that the language doesn’t specify what happens, and any demonstration of undefined behavior doesn’t describe the language.

> [@WalterMadelim](#):
>
> What do you mean by “refactor around”?

Rewriting the program for tasks to not share a variable (or element, field), yet reach the same result.

[Next page](https://discourse.julialang.org/t/function-argument-binding-name-assignment-mutation/132916.md?page=2)
