# Syntax of multiple let assignments vs tuples

**URL:** <https://discourse.julialang.org/t/syntax-of-multiple-let-assignments-vs-tuples/130357>\
**Category:** General Usage\
**Created:** [June 30, 2025, 11:36pm UTC](https://discourse.julialang.org/t/syntax-of-multiple-let-assignments-vs-tuples/130357 "2025-06-30T23:36:39Z")\
**Posts on this page:** 11\
**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:** [June 30, 2025, 11:36pm UTC](https://discourse.julialang.org/t/syntax-of-multiple-let-assignments-vs-tuples/130357/1 "2025-06-30T23:36:39Z")

</div>

One question has been continually bothering me—why do we have this syntax `let x = 1, y = 2`?  
Since we used to write `x, y = 1, 2` directly in julia REPL.  
Otherwise it’s invalid as follows

```julia
julia> x = 1, y = 2
ERROR: syntax: invalid assignment location "1" around REPL[7]:1
Stacktrace:
 [1] top-level scope
   @ REPL[7]:1

```

Then why do we need to invent the additional style `x = 1, y = 2` and exclusively associate it to `let`?

My intuition was acute to find that we have this **Cartesian For-loop** usage.

```julia
for i = 1:2, j = 1:3

```

And this fact

```julia
julia> for i = 1 #

ERROR: ParseError:
# Error @ REPL[2]:2:2
for i = 1 #

#└ ── premature end of input
Stacktrace:
 [1] top-level scope
   @ none:1

```

Note that this `ParseError` is not as severe as the one `let x = 1 #` has, because the latter cannot tolerate an `Enter` stroke, whereas the former can.

---

<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:** [June 30, 2025, 11:46pm UTC](https://discourse.julialang.org/t/syntax-of-multiple-let-assignments-vs-tuples/130357/2 "2025-06-30T23:46:27Z")

</div>

> [@WalterMadelim](#):
>
> Then why do we need to invent the additional style `x = 1, y = 2` and exclusively associate it to `let`?

You’re forgetting about the `=` in `()` syntax of named tuples and keyword arguments in function calls, though the latter parses to `:kw` subexpressions instead of `:(=)`.

---

<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:** [June 30, 2025, 11:52pm UTC](https://discourse.julialang.org/t/syntax-of-multiple-let-assignments-vs-tuples/130357/3 "2025-06-30T23:52:47Z")

</div>

> [@Benny](#):
>
> You’re forgetting about

Yes, I do forget them. Because I hardly use them.  
I only write normal functions `function f(a, b ,c)` in my daily code.  
And I almost never use named tuples either. 😅

---

<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:** [July 1, 2025, 2:05am UTC](https://discourse.julialang.org/t/syntax-of-multiple-let-assignments-vs-tuples/130357/4 "2025-07-01T02:05:33Z")

</div>

Seems I understand now. `let`/`for` can create a dependence tree, whereas `x, y = 1, 2` style is not.

```julia
for i = 1:3, j = 1:i, k = 1:i+j
# some body
end

```

```julia
julia> let x = 3, y = 4, x = y, y = x
       println("x = $x, y = $y")
       end
x = 4, y = 4

julia> let x = 3, y = 4, (x, y) = (y, x)
       println("x = $x, y = $y")
       end
x = 4, y = 3

```

---

<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:** [July 2, 2025, 6:46am UTC](https://discourse.julialang.org/t/syntax-of-multiple-let-assignments-vs-tuples/130357/5 "2025-07-02T06:46:51Z")

</div>

Is there a good reason that the second style is not supported?

```julia
julia> for _ = 1:3
           local x, y = 7, 8
           println("x = $x, y = $y")
       end
x = 7, y = 8
x = 7, y = 8
x = 7, y = 8

julia> for _ = 1:3
           local x = 7, y = 8
           println("x = $x, y = $y")
       end
ERROR: syntax: invalid assignment location "7" around REPL[2]:2
Stacktrace:
 [1] top-level scope
   @ REPL[2]: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:** [August 30, 2025, 8:09am UTC](https://discourse.julialang.org/t/syntax-of-multiple-let-assignments-vs-tuples/130357/6 "2025-08-30T08:09:00Z")

</div>

Because resembling `const`, `local` is valid only for the nearest `=`.

---

<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:** [August 30, 2025, 10:31am UTC](https://discourse.julialang.org/t/syntax-of-multiple-let-assignments-vs-tuples/130357/7 "2025-08-30T10:31:11Z")

</div>

`let` and `local` do not signify assignments, but declarations with optional assignments. It’s therefore not very surprising that the rules differ somewhat from assignments. In general, julia’s syntax doesn’t distinguish between declarations and assignments, so it’s a bit fuzzy. `for` neither declares nor assigns, the `=` is merely a convenience because it has been in use for this since fortran 66. (you can use `in` or `∈` instead of `=` in `for` loops).

But there are various strange things in the julia parser, just like in many languages.  
Here we create `h(i) = 1`, `h(i) = 2`, `h(i) = 3` in quick succession:

```julia-auto
julia> for h(i) in 1:3; display(h); end
(::var"#h#h##4"{Int64}) (generic function with 1 method)
(::var"#h#h##4"{Int64}) (generic function with 1 method)
(::var"#h#h##4"{Int64}) (generic function with 1 method)

```

---

<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:** [August 30, 2025, 11:58am UTC](https://discourse.julialang.org/t/syntax-of-multiple-let-assignments-vs-tuples/130357/8 "2025-08-30T11:58:25Z")

</div>

I think `=` in the `for` loop is aesthetically more agreeable than `in`, as we are writing code, not English texts. Moreover, it might make a math reader feel strange to read `for a ∈ 1 println(a) end` since `1::Int` has no chance being a `Set` (but is iteratable).

---

<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:** [August 30, 2025, 1:17pm UTC](https://discourse.julialang.org/t/syntax-of-multiple-let-assignments-vs-tuples/130357/9 "2025-08-30T13:17:23Z")

</div>

> [@WalterMadelim](#):
>
> since `1::Int` has no chance being a `Set` (but is iteratable).

While this is true in plain julia, it’s easy to let `Int`s behave somewhat like a set, in the von Neumann style of natural numbers:

```julia-auto
julia> Base.iterate(i::Int, state=0) = state ≥ i ? nothing : (state, state+1)
julia> Base.IteratorSize(::Type{Int}) = Base.HasLength()
julia> Base.length(i::Int) = i
julia> Base.eltype(::Type{Int}) = Int
julia> for i in 1
           println(i)
       end
0
julia> collect(3)
3-element Vector{Int64}:
 0
 1
 2
```

---

<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:** [September 27, 2025, 4:20am UTC](https://discourse.julialang.org/t/syntax-of-multiple-let-assignments-vs-tuples/130357/10 "2025-09-27T04:20:54Z")

</div>

I thought this was quite clear, but it don’t support. (not a big deal though)

```julia
julia> let r = s ∈ S ? R1 : R2 # Okay

julia> for r = s ∈ S ? R1 : R2 # not Okay
ERROR: ParseError:
# Error @ REPL[6]:1:11
for r = s ∈ S ? R1 : R2
# ╙ ── not a unary operator

```

---

<div class="post-metadata">

**Author:** ![\_bernhard](https://avatars.discourse-cdn.com/v4/letter/_/bc79bd/32.png) [@\_bernhard](https://discourse.julialang.org/u/_bernhard)\
**Post date:** [September 27, 2025, 2:38pm UTC](https://discourse.julialang.org/t/syntax-of-multiple-let-assignments-vs-tuples/130357/11 "2025-09-27T14:38:28Z")

</div>

You just have to wrap it in parentheses.

```julia-auto
julia> let s=1, S=[s]
           for r = (s in S ? "works" : "doesn't")
               print(r)
           end
       end
works

```
