# On using \`=\` vs \`:=\` for assignment

**URL:** <https://discourse.julialang.org/t/on-using-vs-for-assignment/110302>\
**Category:** Offtopic\
**Created:** [February 8, 2024, 3:46pm UTC](https://discourse.julialang.org/t/on-using-vs-for-assignment/110302 "2024-02-08T15:46:21Z")\
**Posts on this page:** 20\
**Page:** 3

<div class="post-metadata">

**Author:** ![jkopper](https://avatars.discourse-cdn.com/v4/letter/j/958977/32.png) [@jkopper](https://discourse.julialang.org/u/jkopper)\
**Post date:** [February 28, 2024, 2:49am UTC](https://discourse.julialang.org/t/on-using-vs-for-assignment/110302/41 "2024-02-28T02:49:41Z")

</div>

Here’s my favorite manifestation of Python’s weird scoping rules:

```python
 def f():
     x = 10
 
     def g():
         print(x)
 
     def h():
         print(x)
         x = 20
 
     g() # prints 10
     h() # UnboundLocalError

```

Editing to add: this error doesn’t occur in Julia because of its different (better) scoping, but some version of the ambiguity will necessarily exist as long as declaration and assignment have the same syntax.

I’d argue that this is the more fundamental point than the aesthetics of `=` vs `:=`. For example, C _does_ make this distinction: variable declaration includes a type, whereas reassignment does not. Consequently I consider C to be in the `:=` camp, even though that is not the actual syntax.

That’s not to say that I think Julia should adopt `:=`. In my experience, these scoping footguns are rarely encountered in practice

---

<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:** [February 28, 2024, 2:33pm UTC](https://discourse.julialang.org/t/on-using-vs-for-assignment/110302/42 "2024-02-28T14:33:42Z")

</div>

> [@mkitti](#):
>
> most but perhaps not necessarily all “Julia 1” code should continue to work under “Julia 2”.

I don’t know if it is reasonable to talk about Julia 2 at this point, but based on past experience with much more minor changes, I would bet that if there are significant alterations to the language, there will be tooling to convert existing code with minimum effort whenever possible.

So it is not something I would worry about. Just keep coding. 🕶

---

<div class="post-metadata">

**Author:** ![bertschi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bertschi/32/33462_2.png) [@bertschi](https://discourse.julialang.org/u/bertschi)\
**Post date:** [February 28, 2024, 3:20pm UTC](https://discourse.julialang.org/t/on-using-vs-for-assignment/110302/43 "2024-02-28T15:20:13Z")

</div>

Even Haskell uses `==` for equality and `=` for binding, i.e., introducing names as in `let x = 4`. Obviously, assignment does not exist in Haskell – except within some monads.  
On the other hand, I think that Lisp was right in explicitly distinguishing between binding via `let` and assignment via `setf` and maybe also of not eating up `=` syntax-wise for any of these …

---

<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:** [February 28, 2024, 3:38pm UTC](https://discourse.julialang.org/t/on-using-vs-for-assignment/110302/44 "2024-02-28T15:38:46Z")

</div>

> [@mkitti](#):
>
> I do get the sense that a similar PSA is needed regarding what “Julia 2” might be

That post already talked about this:

> But despite what it sounds like, this is not the time to make all the random changes that anyone might want to. Frankly, that time has passed for Julia and will never come again. There will probably be a few renamings of unfortunately named things. But that’s not what the 2.0 release is really about.

> What the 2.0 release is about is thinking about big challenges and figuring out how to address them in novel ways without having to worry about how it fits into the existing language design. […] But often one finds that in order to implement a really radical solution to a hard problem, at least some corner cases of the language have to change in breaking ways. _That_ is why 2.0 will be breaking, not because we want everyone to have to change their code because something should be spelled slightly differently.

---

<div class="post-metadata">

**Author:** ![mnemnion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mnemnion/32/206596_2.png) [@mnemnion](https://discourse.julialang.org/u/mnemnion)\
**Post date:** [February 28, 2024, 3:39pm UTC](https://discourse.julialang.org/t/on-using-vs-for-assignment/110302/45 "2024-02-28T15:39:17Z")

</div>

> [@bertschi](#):
>
> On the other hand, I think that Lisp was right in explicitly distinguishing between binding via `let` and assignment via `setf` and maybe also of not eating up `=` syntax-wise for any of these …

This is the part of this discussion which I most firmly agree with: declaration and assignment are different operations, and using a single syntax for both conflates distinct operations. When you do two things with one syntax, it’s always possible to do one while thinking you’re doing the other.

Has this lead me to write a lot of bugs in Julia? Actually no. The scope rules are somewhat complex, but in a way which (mostly) comports with my intuitions, and I reuse variable names sparingly. One time I left out a `global` declaration, but this was a shallow bug, easily fixed.

Where I do feel the burden is in _reading_ code which I didn’t write. Concentrating on the algorithm takes all of my attention, and when I see an `l = r` I have to switch to ‘scope mode’ to figure out what’s going on.

`=` for declaration and `<-` for assignment creates some known (if surmountable) problems for the compiler, but I actually prefer that syntax, and it’s a safe bet there are more declarations than assignments in the wild, so it would change less code.

What I know for sure is that a syntactic distinction between the two would improve an already excellent language in concrete ways, it’s not window dressing or the color of a bikeshed at all. This is worth keeping in the back pocket, in case an opportunity to make the change arises.

---

<div class="post-metadata">

**Author:** ![mnemnion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mnemnion/32/206596_2.png) [@mnemnion](https://discourse.julialang.org/u/mnemnion)\
**Post date:** [February 28, 2024, 3:51pm UTC](https://discourse.julialang.org/t/on-using-vs-for-assignment/110302/46 "2024-02-28T15:51:57Z")

</div>

> [@stevengj](#):
>
> _That_ is why 2.0 will be breaking, not because we want everyone to have to change their code because something should be spelled slightly differently.

This is a good policy, but I really want to stress that the topic of discussion is not about syntax, it’s entirely about semantics, and their impact on program correctness and comprehensibility.

I’ll compare it to division in Python. In Python 2, `/` was a homonym: for integers it was truncating, for floats, ordinary division. Python 3 decided to introduce `//` as the exclusive spelling of truncating divison, such that it applied to floats as well, and `/` on integers performs ordinary division, converting to floats in the process.

There are many rational arguments against separating assignment and declaration in hypothetical Julia 2, but it shouldn’t be compared to, say, wanting to spell `function` as `lambda` or `fn`. It isn’t a trivial change, it’s a real distinction which is worth fully exploring when the time comes. I’d expect the outcome to be a decision against making the change, in fact, but the idea deserves to be in-bounds.

---

<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:** [February 28, 2024, 3:56pm UTC](https://discourse.julialang.org/t/on-using-vs-for-assignment/110302/47 "2024-02-28T15:56:46Z")

</div>

> [@mnemnion](#):
>
> My favorite choice for assignment is `<-`

Oh, that is another assignment syntax I particularly hate. I recall that when I was teaching R, 90% of student kvetching came from the `<-` syntax. Even R allows `=` as an alternative (maybe only at the toplevel, I cannot recall exactly). (And of course they had to go overboard, so there is `x -> y`, equivalent to `y <- x`).

I think that there are two local optima:

1. Julia’s DWIM `=`, with reasonable semantics about scoping. Yes, sometimes `=` creates a new variable and sometimes it assigns, and further complications arise with `x[i] =` and `x.y = `, but the language deals with all of them in a more or less sane way so we can get work done.

2. Common Lisps `let` & friends with `setf`, where the latter can be [extended by the user](https://www.lispworks.com/documentation/lw50/CLHS/Body/05_aa.htm). That’s just so neat.

---

<div class="post-metadata">

**Author:** ![mnemnion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mnemnion/32/206596_2.png) [@mnemnion](https://discourse.julialang.org/u/mnemnion)\
**Post date:** [February 28, 2024, 4:08pm UTC](https://discourse.julialang.org/t/on-using-vs-for-assignment/110302/48 "2024-02-28T16:08:34Z")

</div>

> [@Tamas\_Papp](#):
>
> Oh, that is another assignment syntax I particularly hate. I recall that when I was teaching R, 90% of student kvetching came from the `<-` syntax. Even R allows `=` as an alternative (maybe only at the toplevel, I cannot recall exactly). (And of course they had to go overboard, so there is `x -> y`, equivalent to `y <- x`).

I’ve barely ever used `R`, but it looks like it doesn’t distinguish declaration and assignment, it just offers three ways to conflate them, which is obviously bad.

“`⊢` means declaration and `⊣` means assignment” is not at all difficult to teach or understand, to pick a couple random symbols to stand in for the distinction. Plenty of languages have this distinction without a reputation for being hard to learn, and the syntax is mostly disliked by people who don’t actually use it.

But variations on “making everyone learn the new syntax isn’t worth the benefits it could offer” is probably the best argument against this line of inquiry, and I expect it would carry the day, in the event. Purely aesthetic objections are somewhat weaker but deserve consideration nonetheless.

---

<div class="post-metadata">

**Author:** ![mcmuffin6o](https://avatars.discourse-cdn.com/v4/letter/m/9f8e36/32.png) [@mcmuffin6o](https://discourse.julialang.org/u/mcmuffin6o)\
**Post date:** [February 28, 2024, 4:37pm UTC](https://discourse.julialang.org/t/on-using-vs-for-assignment/110302/49 "2024-02-28T16:37:36Z")

</div>

> [@mnemnion](#):
>
> mathematical purity is a bad reason to frustrate developers.

Don’t even get me started on sacrificing familiarity for mathematical purity. Julia uses `*` instead of `+` for string concatenation, and [the documentation justifies it by going on a rant about abstract algebra and monoids](https://docs.julialang.org/en/v1/manual/strings/#man-concatenation).

Still, if there is a language to be a stickler for mathematical purity, I guess Julia would have a reasonable claim to striving for it – It does have support and good tooling for unicode symbols commonly used in mathematics. I just wish they would have committed by enforcing `:=` and `*` or going with the flow by allowing `=` and `+`. It’s unfortunate that it’s sort of halfway committed to mathematical purity.

---

<div class="post-metadata">

**Author:** ![adienes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adienes/32/37459_2.png) [@adienes](https://discourse.julialang.org/u/adienes)\
**Post date:** [February 28, 2024, 4:42pm UTC](https://discourse.julialang.org/t/on-using-vs-for-assignment/110302/50 "2024-02-28T16:42:43Z")

</div>

> [@mcmuffin6o](#):
>
> sacrificing familiarity for mathematical purity. Julia uses `*` instead of `+` for string concatenation

depends on what you’re familiar with… `+` for concentation is by no means a universal convention. it just happens to be the convention of the most popular language

I made this list some time ago

> [@Why are there all these strange stumbling blocks in Julia?](https://discourse.julialang.org/t/why-are-there-all-these-strange-stumbling-blocks-in-julia/92644/7):
>
> Not really trying to pile on, but I just got curious so I compiled a list of string concatenation operators across a bunch of languages. If any of these are incorrect, blame ChatGPT slight_smile Some languages (C,, Lisp-y ones) do not have infix operators for string concatenation at all. Maple uses || Mathematica and Gap use \<\> Agda, Idris, Erlang, Haskell, Elm, Zig all use ++ F#, OCaml use ^ Ada, Nim use & Fortran uses // Lua has .. Perl has . Smalltalk has , And of cour…

---

<div class="post-metadata">

**Author:** ![mnemnion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mnemnion/32/206596_2.png) [@mnemnion](https://discourse.julialang.org/u/mnemnion)\
**Post date:** [February 28, 2024, 4:43pm UTC](https://discourse.julialang.org/t/on-using-vs-for-assignment/110302/51 "2024-02-28T16:43:22Z")

</div>

> [@mcmuffin6o](#):
>
> Don’t even get me started on sacrificing familiarity for mathematical purity. Julia uses `*` instead of `+` for string concatenation, and [the documentation justifies it by going on a rant about abstract algebra and monoids](https://github.com/FedeClaudi/Term.jl).

This is off topic (and extensively discussed elsewhere) but I 100% endorse this decision. `one(String)`, try it! It’s a bit of surface syntax which is a trivial part of the cost of learning the language, and it’s _correct_ in a way that people with mathematical backgrounds appreciate. If you’re going to use a mathematical operator (rather than distinct syntax like Lua’s `..`) for concatenation, why use the popular one when you can use the correct one?

---

<div class="post-metadata">

**Author:** ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)\
**Post date:** [February 28, 2024, 4:57pm UTC](https://discourse.julialang.org/t/on-using-vs-for-assignment/110302/52 "2024-02-28T16:57:17Z")

</div>

In my dreams, `=` would be equality comparison, and assignment would require a keyword `let` or `set` for declaration or reassignment, so that code would read more like math proofs. This would improve legibility imo. For example:

```julia
let a, b=2 # declaration & assignment within current scope
set a=2, b=3 # (re)assignments of whatever is visible to this scope
(a=2, b=2) # tuple of Bool's (true, false)
(; a=2, b=2) # named tuple of Int's
for i=1:10 # loop
    set a+=i # reassign
end
let (x,y) = (1,2) # itr destruct
set (;x,y) = (;y=2,x=1) # prop destruct
let typed c = (;a=1,b=2) # like c::NamedTuple{(:a,:b),Tuple{Int,Int}} = (;a=1,b=2)
set d[k] = v # setindex!(d, v, k)

```

Semantics similar to Julia 1.x’s `let` block could be satisfied by `with`:

```julia
with a=2, b=3
    #= ... =#
end

```

`with` could serve double-duty:

```julia
with my_object
    my_object.a = a # true
    set a=1 # setproperty!(my_object, :a, 1)
end

```

I’d also have `do...end` to replace `begin...end`, and I’d replace `&&` and `||` with `and` and `or`.

---

<div class="post-metadata">

**Author:** ![mnemnion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mnemnion/32/206596_2.png) [@mnemnion](https://discourse.julialang.org/u/mnemnion)\
**Post date:** [February 28, 2024, 5:07pm UTC](https://discourse.julialang.org/t/on-using-vs-for-assignment/110302/53 "2024-02-28T17:07:44Z")

</div>

> [@uniment](#):
>
> In my dreams, `=` would be equality comparison, and assignment would require a keyword `let` or `set` for declaration or reassignment, so that code would read more like math proofs. This would improve legibility imo. For example:

yikes, I don’t like any of this 😅

But it’s a good demonstration of the difference between dressing Julia’s semantics in new syntax, and proposing new syntax to address a different semantics, so thanks for that.

---

<div class="post-metadata">

**Author:** ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)\
**Post date:** [February 28, 2024, 5:12pm UTC](https://discourse.julialang.org/t/on-using-vs-for-assignment/110302/54 "2024-02-28T17:12:33Z")

</div>

Try writing code assuming that was the rule, I think you’ll like it 😉

---

<div class="post-metadata">

**Author:** ![mnemnion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mnemnion/32/206596_2.png) [@mnemnion](https://discourse.julialang.org/u/mnemnion)\
**Post date:** [February 28, 2024, 5:15pm UTC](https://discourse.julialang.org/t/on-using-vs-for-assignment/110302/55 "2024-02-28T17:15:58Z")

</div>

With respect, I am quite sure I wouldn’t. I dislike it on a “I would not use a language which looks like this” level.

This?

```julia
(a=2, b=2) # tuple of Bool's (true, false)
(; a=2, b=2) # named tuple of Int's

```

No! No way! Kill it with fire!

---

<div class="post-metadata">

**Author:** ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)\
**Post date:** [February 28, 2024, 5:21pm UTC](https://discourse.julialang.org/t/on-using-vs-for-assignment/110302/56 "2024-02-28T17:21:46Z")

</div>

> [@mcmuffin6o](#):
>
> Julia uses `*` instead of `+` for string concatenation, and [the documentation justifies it by going on a rant about abstract algebra and monoids](https://github.com/FedeClaudi/Term.jl).

You meant [this link](https://docs.julialang.org/en/v1/manual/strings/#man-concatenation).

In the theory of finite state machines, the “multiplication” operator is used for concatenation of regular expressions. Since regular expressions describe strings, it’s pretty natural to extend this to strings. I think the docs would be better off simply saying this.

> [@mnemnion](#):
>
> I am quite sure I wouldn’t

Maybe I should’ve left that example out—I was playing around to see how it’d interact with named tuple syntax 😅

Again, try writing code and see how it looks and feels. Other than named tuples, it feels pretty good.

---

<div class="post-metadata">

**Author:** ![mcmuffin6o](https://avatars.discourse-cdn.com/v4/letter/m/9f8e36/32.png) [@mcmuffin6o](https://discourse.julialang.org/u/mcmuffin6o)\
**Post date:** [February 28, 2024, 5:31pm UTC](https://discourse.julialang.org/t/on-using-vs-for-assignment/110302/57 "2024-02-28T17:31:50Z")

</div>

See now I’m actually on board with `*` for concatenation. I guess my initial aversion to it was due to getting an error and then looking it up only to encounter a grandiose explanation that isn’t relevant to the overwhelming majority of programmers. Regex is its own can of worms, but it’s definitely something most are familiar with!

Thanks for helping me fix my link.

---

<div class="post-metadata">

**Author:** ![mnemnion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mnemnion/32/206596_2.png) [@mnemnion](https://discourse.julialang.org/u/mnemnion)\
**Post date:** [February 28, 2024, 5:36pm UTC](https://discourse.julialang.org/t/on-using-vs-for-assignment/110302/58 "2024-02-28T17:36:44Z")

</div>

> [@uniment](#):
>
> Again, try writing code and see how it looks and feels. Other than named tuples, it feels pretty good.

Nope, I’m not going to like it, and I can explain why while keeping this thread on topic, so I will.

You’ve made `=` a homonym, and that’s the same conflation I’ve been on about in the second half of this thread. When you have a homonym, it’s too easy to think you’re using it one way when the compiler thinks you’re using it the other way.

And you’re applying modifiers to every use of `=` as (still conflated! it’s a triple homonym! nonono) either declaration or assignment. `set` this, `let` that. This means that `set x = y`, the set/let is 'modifying `=`, not `x`, this is hard to scan. It’s noisy, you’d need this on every line with declaration or assignment, and `set` and `let` differ by one letter, so it would just sort of smear together on the screen. Leave it out and you get a boolean, which is the sort of fun that ruins my whole day.

In `:=` vs `=`, the `:` is what modifies `=` to be declaration, and they’re touching; that’s easy to read. It also eliminates the `global` and `local` modifiers, which are infrequent enough that their syntactic weight isn’t so burdensome, but I’d still call it a win. They also more clearly modify the variable they’re next to, rather than the operator.

If you completely dumped the connection to Julia and went for a syntax like this from first principles, you’d end up with something like OCaml, which a lot of people like. It’s consistent, this isn’t.

---

<div class="post-metadata">

**Author:** ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)\
**Post date:** [February 28, 2024, 5:55pm UTC](https://discourse.julialang.org/t/on-using-vs-for-assignment/110302/59 "2024-02-28T17:55:09Z")

</div>

I don’t think I can engage in good faith if you refuse to try it, but I’ll briefly inform you that `=` is already a homonym in Julia.

```julia
julia> for i=0:9
           print(i)
       end
0123456789

julia> ((i for i=0:9)...,)
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

```

---

<div class="post-metadata">

**Author:** ![mnemnion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mnemnion/32/206596_2.png) [@mnemnion](https://discourse.julialang.org/u/mnemnion)\
**Post date:** [February 28, 2024, 6:11pm UTC](https://discourse.julialang.org/t/on-using-vs-for-assignment/110302/60 "2024-02-28T18:11:59Z")

</div>

> [@uniment](#):
>
> but I’ll briefly inform you that `=` is already a homonym in Julia.
> 
> ```julia
> julia> for i=0:9
> print(i)
> end
> 0123456789
> 
> julia> ((i for i=0:9)...,)
> (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
> 
> ```

`=` has an identical meaning in both of these constructs.

[Previous page](https://discourse.julialang.org/t/on-using-vs-for-assignment/110302.md?page=2)

[Next page](https://discourse.julialang.org/t/on-using-vs-for-assignment/110302.md?page=4)
