# Inconsistent rebinding rules for function arguments

**URL:** <https://discourse.julialang.org/t/inconsistent-rebinding-rules-for-function-arguments/23990>\
**Category:** Internals & Design\
**Created:** [May 8, 2019, 9:48am UTC](https://discourse.julialang.org/t/inconsistent-rebinding-rules-for-function-arguments/23990 "2019-05-08T09:48:53Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![HFriberg-mosek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hfriberg-mosek/32/8376_2.png) [@HFriberg-mosek](https://discourse.julialang.org/u/HFriberg-mosek)\
**Post date:** [May 8, 2019, 9:48am UTC](https://discourse.julialang.org/t/inconsistent-rebinding-rules-for-function-arguments/23990/1 "2019-05-08T09:48:53Z")

</div>

The function below is a minimal example of a bug I have seen a couple of times:

```julia
function update!(x)
  dx = [1] # Compute change
  x += dx # Update x (developer intended to write x .+= dx)
  # Any tests here show that x is correct.
  return dx
end
x = [5];
update!(x)
# Any tests here show that x is incorrect.

```

What happens is that the local binding of `x` is implicitly changed at the line `x += dx`. It would be nice if julia required one to make this rebinding explicit, as in `local x += dx`, but interestingly this gives:

`ERROR: syntax: local variable name "x" conflicts with an argument`

That is, Julia allows implicit rebinding of function arguments, but not explicit rebinding? To me, explicit rebinding should be mandatory to simplify debugging.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [May 8, 2019, 9:55am UTC](https://discourse.julialang.org/t/inconsistent-rebinding-rules-for-function-arguments/23990/2 "2019-05-08T09:55:32Z")

</div>

I don’t see the problem. `x += dx` is (syntactically) equivalent to `x = x + dx` which clearly rebinds `x` to the object that `x + dx` evaluates to.

Did you mean to use `x .+= dx`?

Here is the lowering:

```nohighlight
julia> Meta.lower(Main, :(x += dx))
...
1 ─ %1 = x + dx
│ x = %1
└── return %1
))))

```

which is equivalent to the lowering of `:(x = x + dx)`.

Edit: Just noticed the `(developer intended to write x .+= dx)` comment which answers one of the questions I had.

---

<div class="post-metadata">

**Author:** ![HFriberg-mosek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hfriberg-mosek/32/8376_2.png) [@HFriberg-mosek](https://discourse.julialang.org/u/HFriberg-mosek)\
**Post date:** [May 8, 2019, 11:06am UTC](https://discourse.julialang.org/t/inconsistent-rebinding-rules-for-function-arguments/23990/3 "2019-05-08T11:06:28Z")

</div>

The inconsistency I am pointing out is that you can do implicit rebinding:

```julia
function update!(x)
  x += dx # or x = 10
end

```

but if you try to make the rebind explicit:

```julia
function update!(x)
  local x += dx # or local x = 10
end

```

you get a syntax error:  
`ERROR: syntax: local variable name "x" conflicts with an argument`

---

<div class="post-metadata">

**Author:** ![HFriberg-mosek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hfriberg-mosek/32/8376_2.png) [@HFriberg-mosek](https://discourse.julialang.org/u/HFriberg-mosek)\
**Post date:** [May 8, 2019, 11:06am UTC](https://discourse.julialang.org/t/inconsistent-rebinding-rules-for-function-arguments/23990/4 "2019-05-08T11:06:44Z")

</div>

Okay, I can see I have been misunderstanding the `local` keyword. I thought

```julia
function foo(x)
  # some code
  local x += dx
  # some more code
end

```

would be the same as

```julia
function foo(x)
  # some code
  let x=x
    x += dx
    # some more code
  end
end

```

That is, the location of `local` decided where the new local scope began. This is not the case, `local x` basically just means _do not look in parent scope for x_. So there is no inconsistency after all… Just a small handful of people that occasionally forgets the dot in `x .+= dx`…

Can you, by any chance, lock a binding so that you got errors coming out if you tried to rebind? This would also be nice for mutable structs…

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [May 8, 2019, 12:28pm UTC](https://discourse.julialang.org/t/inconsistent-rebinding-rules-for-function-arguments/23990/5 "2019-05-08T12:28:52Z")

</div>

There’s an open issue somewhere about implementing `const` in local scope. The same could be allowed for fields in a `mutable struct` to make those fields write-only. They’re both good features that will get implemented at some point but they’re fairly low-priority because they mostly don’t enable anything that can’t already be done. The compiler is able to see whether a local is assigned or not (cf a global where that’s impossible to know statically). The `const` annotation on fields of mutable structs is a bit more useful since you can avoid redoing field lookups if you know you’re accessing the same field in the same object.

---

<div class="post-metadata">

**Author:** ![HFriberg-mosek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hfriberg-mosek/32/8376_2.png) [@HFriberg-mosek](https://discourse.julialang.org/u/HFriberg-mosek)\
**Post date:** [May 9, 2019, 7:15am UTC](https://discourse.julialang.org/t/inconsistent-rebinding-rules-for-function-arguments/23990/6 "2019-05-09T07:15:26Z")

</div>

@StefanKarpinski : Sound very good with the `const`. Will it work like `local` that you just specify it anywhere in scope, and then the binding cannot change within that scope?

```julia
function update!(x)
  const x
  x += dx # could throw "ERROR: x is const, did you mean x .+= dx?"
end

```

From a C-programmers perspective, the choice of keyword `const` can be interpreted both correctly as `char * const a;` (binding cannot change) and incorrectly as `const char * a;` (value cannot be manipulated via the binding). So it may create some confusing. I have no better suggestion though…

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [May 9, 2019, 7:21am UTC](https://discourse.julialang.org/t/inconsistent-rebinding-rules-for-function-arguments/23990/7 "2019-05-09T07:21:14Z")

</div>

> [@HFriberg-mosek](#):
>
> From a C-programmers perspective, the choice of keyword `const` can be interpreted both correctly as `char * const a;` (binding cannot change) and incorrectly as `const char * a;` (value cannot be manipulated via the binding). So it may create some confusing. I have no better suggestion though…

Note that there already is a `const` keyword that can be used on global variables and already means that the binding cannot change.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [May 9, 2019, 7:58am UTC](https://discourse.julialang.org/t/inconsistent-rebinding-rules-for-function-arguments/23990/8 "2019-05-09T07:58:50Z")

</div>

> [@HFriberg-mosek](#):
>
> the choice of keyword `const` can be interpreted both correctly as `char * const a;` (binding cannot change) and incorrectly as `const char * a;` (value cannot be manipulated via the binding). So it may create some confusing.

In Julia, that should not be a problem; as usually we are talking about the value, not the contents. Cf

```julia
julia> struct Foo # immutable
           vec
       end

julia> foo = Foo([1,2,3])
Foo([1, 2, 3])

julia> foo.vec = [4,5,6]
ERROR: setfield! immutable struct of type Foo cannot be changed
Stacktrace:
 [1] setproperty!(::Foo, ::Symbol, ::Array{Int64,1}) at ./Base.jl:21
 [2] top-level scope at REPL[13]:1

julia> foo.vec .= [4,5,6]
3-element Array{Int64,1}:
 4
 5
 6

```

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [May 9, 2019, 10:47am UTC](https://discourse.julialang.org/t/inconsistent-rebinding-rules-for-function-arguments/23990/9 "2019-05-09T10:47:43Z")

</div>

Indeed, it would only refer to the binding, it cannot change the mutability of the value that is bound—that’s not how Julia’s type system works.

---

<div class="post-metadata">

**Author:** ![HFriberg-mosek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hfriberg-mosek/32/8376_2.png) [@HFriberg-mosek](https://discourse.julialang.org/u/HFriberg-mosek)\
**Post date:** [May 9, 2019, 11:06am UTC](https://discourse.julialang.org/t/inconsistent-rebinding-rules-for-function-arguments/23990/10 "2019-05-09T11:06:30Z")

</div>

Just for the record `const char * a;` also does not change the mutability of the value that is pointed to. It only prevents mutations via that particular binding. So the two possible interpretations of `const` still apply to Julia’s type system I believe… Nevertheless, as @kristoffer.carlsson mentions, the meaning of the keyword has already been fixed by its use on globals so I don’t think there is anything more to discuss. Thank you for your time. 😉

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [May 9, 2019, 11:30am UTC](https://discourse.julialang.org/t/inconsistent-rebinding-rules-for-function-arguments/23990/11 "2019-05-09T11:30:30Z")

</div>

> [@HFriberg-mosek](#):
>
> It only prevents mutations via that particular binding. So the two possible interpretations of `const` still apply to Julia’s type system I believe…

Yes, in C you are prevented from doing primitive mutating operations on a const value and if you pass the value to another function, that function must have a compatible signature—i.e. also const—so the restriction is recursive. You can still mutate the value by explicitly casting to a non-const type. How would that kind of constness work in Julia?

---

<div class="post-metadata">

**Author:** ![HFriberg-mosek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hfriberg-mosek/32/8376_2.png) [@HFriberg-mosek](https://discourse.julialang.org/u/HFriberg-mosek)\
**Post date:** [May 9, 2019, 12:59pm UTC](https://discourse.julialang.org/t/inconsistent-rebinding-rules-for-function-arguments/23990/12 "2019-05-09T12:59:57Z")

</div>

Example of what I am thinking:

```julia
mutable struct Foo
    x
    y
    const z
end

foo = Foo([1,2,3])

foo.z = [4,5,6] # error if const has meaning "binding cannot change".
foo.z .= [4,5,6] # error if const has meaning "binding cannot be used to manipulate".

```

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [May 9, 2019, 1:03pm UTC](https://discourse.julialang.org/t/inconsistent-rebinding-rules-for-function-arguments/23990/13 "2019-05-09T13:03:33Z")

</div>

I understand what effect you’re asking for but how would it work? The array `[1,2,3]` is a mutable object which is a property of its type. Marking a field as `const` doesn’t change the type of the value that it refers to—mutability is a property of the value, not the binding.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [May 9, 2019, 1:16pm UTC](https://discourse.julialang.org/t/inconsistent-rebinding-rules-for-function-arguments/23990/14 "2019-05-09T13:16:13Z")

</div>

I am not sure what you are trying to achieve.

Assuming that you would like to prevent accidentally modifying the _elements_ of `z`, you can eg define a wrapper type that has no `setindex!` method. See eg

[https://github.com/bkamins/ReadOnlyArrays.jl](https://github.com/bkamins/ReadOnlyArrays.jl)

---

<div class="post-metadata">

**Author:** ![HFriberg-mosek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hfriberg-mosek/32/8376_2.png) [@HFriberg-mosek](https://discourse.julialang.org/u/HFriberg-mosek)\
**Post date:** [May 9, 2019, 1:33pm UTC](https://discourse.julialang.org/t/inconsistent-rebinding-rules-for-function-arguments/23990/15 "2019-05-09T13:33:03Z")

</div>

@Tamas_Papp: The last 8 posts was created in response to a small remark of mine that can be summarized as:

> [@](#):
>
> The choice of keyword name, `const`, could be confusing to some C-programmers because it can have two meanings there.

I am glad you take the language so serious as to defend the choice of the word, but I am afraid the discussion have gone to technical for me, as I cannot defend how `const` could possibly have the alternative meaning within the Julia type system. Anyway, thanks for Julia!

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [May 9, 2019, 2:05pm UTC](https://discourse.julialang.org/t/inconsistent-rebinding-rules-for-function-arguments/23990/16 "2019-05-09T14:05:09Z")

</div>

I am not sure I am defending anything here, just describing how Julia is.

Given that programming languages are different, I expect that some confusion is inevitable if someone insists on mapping concepts from one to another directly. Fortunately, we have a section in the manual about this:

[https://docs.julialang.org/en/v1/manual/noteworthy-differences/](https://docs.julialang.org/en/v1/manual/noteworthy-differences/)

I you think that the C/C++ part could mention `const`, perhaps consider making a PR.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [May 9, 2019, 2:32pm UTC](https://discourse.julialang.org/t/inconsistent-rebinding-rules-for-function-arguments/23990/17 "2019-05-09T14:32:43Z")

</div>

That comment was addressed pretty simply:

> [@StefanKarpinski](#):
>
> Indeed, it would only refer to the binding, it cannot change the mutability of the value that is bound—that’s not how Julia’s type system works.

The rest was in response to:

> [@HFriberg-mosek](#):
>
> So the two possible interpretations of `const` still apply to Julia’s type system I believe…

The following replies are explanations are about why this is not the case. Specifically, the C meaning of “you may not mutate this value via this binding” is not sensible in Julia because of two facts:

- mutability is a property of the type of something, and
- bindings—expressions in general—do not have types, values have types.

That is because Julia is a dynamic, not a static language. If you want to read more about this, I’ve explained it in depth in this stack overflow post:

> <https://stackoverflow.com/questions/28078089/is-julia-dynamically-typed/28096079#28096079>

If `const` was to affect the mutability of a bound object, it would have to implicitly limit or modify the type of the value being bound. That’s possible, but it’s a significant complexification and it’s unclear if it should be done, let alone how exactly it would work.
