# Extra token, on same line as for loop start, is valid?

**URL:** <https://discourse.julialang.org/t/extra-token-on-same-line-as-for-loop-start-is-valid/20185>\
**Category:** Internals & Design\
**Created:** [January 28, 2019, 3:46pm UTC](https://discourse.julialang.org/t/extra-token-on-same-line-as-for-loop-start-is-valid/20185 "2019-01-28T15:46:29Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![BioTurboNick](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bioturbonick/32/6380_2.png) [@BioTurboNick](https://discourse.julialang.org/u/BioTurboNick)\
**Post date:** [January 28, 2019, 3:46pm UTC](https://discourse.julialang.org/t/extra-token-on-same-line-as-for-loop-start-is-valid/20185/1 "2019-01-28T15:46:29Z")

</div>

The following is considered valid, but should it be?

```julia
for i in 1:3 4
   print("hi")
end
# output: "hihihi"

```

This enables one-line for expressions without semicolons, of course:

```julia
for i in 1:3 print("hi") end

```

I encountered this potential issue when I temporarily replaced the upper index of the range but forgot to comment out the old range.

Perhaps semicolons should be required if attempting to place another statement on the same line as a for loop initiator? IMO would make the one-line code more clear.

---

<div class="post-metadata">

**Author:** ![BioTurboNick](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bioturbonick/32/6380_2.png) [@BioTurboNick](https://discourse.julialang.org/u/BioTurboNick)\
**Post date:** [February 5, 2019, 2:13am UTC](https://discourse.julialang.org/t/extra-token-on-same-line-as-for-loop-start-is-valid/20185/2 "2019-02-05T02:13:03Z")

</div>

Bumped, with edits for clarity.

---

<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 5, 2019, 8:14am UTC](https://discourse.julialang.org/t/extra-token-on-same-line-as-for-loop-start-is-valid/20185/3 "2019-02-05T08:14:08Z")

</div>

> [@BioTurboNick](#):
>
> Perhaps semicolons should be required

FWIW, I would prefer if semicolons were only required when there is an ambiguity on the parser level (not for protecting against user mistakes).

That said, for one-line loop bodies I would either go for

```julia
foreach(_ -> print("hi"), 1:3)

```

or

```julia
for _ in 1:3
    print("hi")
end

```

as squeezing a `for` or `if` onto one line is rarely worth it IMO.

---

<div class="post-metadata">

**Author:** ![BioTurboNick](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bioturbonick/32/6380_2.png) [@BioTurboNick](https://discourse.julialang.org/u/BioTurboNick)\
**Post date:** [February 5, 2019, 6:36pm UTC](https://discourse.julialang.org/t/extra-token-on-same-line-as-for-loop-start-is-valid/20185/4 "2019-02-05T18:36:13Z")

</div>

I understand. In that case, would it make any sense, and not break anything, to require a return character after the for loop range and similar block declarations? (apologies if I’m abusing terminology)

Or maybe a warning would be useful?

---

<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 5, 2019, 6:49pm UTC](https://discourse.julialang.org/t/extra-token-on-same-line-as-for-loop-start-is-valid/20185/5 "2019-02-05T18:49:30Z")

</div>

> [@BioTurboNick](#):
>
> not break anything

But it _would_ break existing code.

While I don’t use one-liners, some people do and I don’t feel like enforcing my own style upon them (for one thing, my own style underwent quite a few changes already 😉). So I don’t think this should be invalid syntax.

However, this would be the perfect job for a _linter_, eg

```julia
for a in 1:10 print(a + 1)
    print(a + 2)
end

```

could warn because it is mixing the two styles. Or one could ask the linter to warn about

```julia
for a in 1:10 print(a + 1) end

```

if an internal style guide for an organization considers it undesirable.

---

<div class="post-metadata">

**Author:** ![BioTurboNick](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bioturbonick/32/6380_2.png) [@BioTurboNick](https://discourse.julialang.org/u/BioTurboNick)\
**Post date:** [February 5, 2019, 6:52pm UTC](https://discourse.julialang.org/t/extra-token-on-same-line-as-for-loop-start-is-valid/20185/6 "2019-02-05T18:52:28Z")

</div>

So this linter (new term for me) would be an add-on, probably as part of e.g. Juno?

---

<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 5, 2019, 7:09pm UTC](https://discourse.julialang.org/t/extra-token-on-same-line-as-for-loop-start-is-valid/20185/7 "2019-02-05T19:09:25Z")

</div>

See eg

> **[GitHub - tonyhffong/Lint.jl: A lint tool for Julia code](https://github.com/tonyhffong/Lint.jl)**
>
> A lint tool for Julia code. Contribute to tonyhffong/Lint.jl development by creating an account on GitHub.

---

<div class="post-metadata">

**Author:** ![bennedich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bennedich/32/4894_2.png) [@bennedich](https://discourse.julialang.org/u/bennedich)\
**Post date:** [February 5, 2019, 8:26pm UTC](https://discourse.julialang.org/t/extra-token-on-same-line-as-for-loop-start-is-valid/20185/8 "2019-02-05T20:26:05Z")

</div>

Perhaps it would have made sense to require semicolons. I don’t know why it was done this way, there’s probably a good reason. Several other keywords work this way too, such as `if` and `while`. However, `let` requires a semicolon:

```julia
julia> let a = 3 println(a) end
ERROR: syntax: let variables should end in ";" or newline

```

What’s more surprising to me is that not even a space is required before an `end` statement. This is perfectly valid:

```julia
julia> a = 3; while a > 0 println(a); global a-=1end
3
2
1

```

As for linter and warnings, looking again at the code that troubled you: `for i in 1:3 4`, it might be more effective to detect and warn about that independent `4`, than requiring semicolons after keywords. (Or are there cases where a single number like that would make sense, unless when used as a return value?)

What I think can be said with certainty is that changing this would break an enormous amount of code, and would likely have to be done over a series of releases (like v0.7 and v1.0). I have used this syntax many times, especially when answering questions on this forum to keep my replies more compact – [here’s an example:](https://discourse.julialang.org/t/simple-loop-wont-vectorize/20169/7)

> ```julia
> @btime (s = 0.0; @simd for i in 1:10^9 s += i * 1.23 end; s)
> 
> ```

There’s also plenty of existing code out there using this syntax, [here’s an example in Julia’s sparse matrix library:](https://github.com/JuliaLang/julia/blob/master/stdlib/SparseArrays/src/sparsematrix.jl#L1476)

> ```julia
> for i in (k + 2):(n + 1) colptr[i] = (k + 1) end
> 
> ```

---

<div class="post-metadata">

**Author:** ![BioTurboNick](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bioturbonick/32/6380_2.png) [@BioTurboNick](https://discourse.julialang.org/u/BioTurboNick)\
**Post date:** [February 5, 2019, 8:47pm UTC](https://discourse.julialang.org/t/extra-token-on-same-line-as-for-loop-start-is-valid/20185/9 "2019-02-05T20:47:43Z")

</div>

> As for linter and warnings, looking again at the code that troubled you: `for i in 1:3 4` , it might be more effective to detect and warn about that independent `4` , than requiring semicolons after keywords. (Or are there cases where a single number like that would make sense, unless when used as a return value?)

The number was just for the example. In my real case it was a variable name, and I had overlooked it as a mistake when tracking down why it wasn’t working. E.g.:

```julia
for i in 1:3 nvalues # supposed to be 1:nvalues, temporarily replaced with constant
    #dostuff
end

```

---

<div class="post-metadata">

**Author:** ![bennedich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bennedich/32/4894_2.png) [@bennedich](https://discourse.julialang.org/u/bennedich)\
**Post date:** [February 5, 2019, 9:21pm UTC](https://discourse.julialang.org/t/extra-token-on-same-line-as-for-loop-start-is-valid/20185/10 "2019-02-05T21:21:34Z")

</div>

Well, same thing – would it make sense to just have an unused variable in your code? (Except when used as a return value, in which case it’s not unused of course.)

Just thinking whether it’d be better for a linter to focus on this, than the keyword syntax. Or perhaps both.

---

<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 6, 2019, 8:18am UTC](https://discourse.julialang.org/t/extra-token-on-same-line-as-for-loop-start-is-valid/20185/11 "2019-02-06T08:18:38Z")

</div>

> [@bennedich](#):
>
> However, `let` requires a semicolon

Possibly because the number of assignments following a `let` can vary?

---

<div class="post-metadata">

**Author:** ![bennedich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bennedich/32/4894_2.png) [@bennedich](https://discourse.julialang.org/u/bennedich)\
**Post date:** [February 6, 2019, 8:40am UTC](https://discourse.julialang.org/t/extra-token-on-same-line-as-for-loop-start-is-valid/20185/12 "2019-02-06T08:40:24Z")

</div>

> [@Tamas\_Papp](#):
>
> Possibly because the number of assignments following a `let` can vary?

Maybe? But could you not argue that it’s the same with `for` loops?

```julia
julia> for a=1:2, b=3:4 println(a*b) end
3
4
6
8

```

---

<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 6, 2019, 9:22am UTC](https://discourse.julialang.org/t/extra-token-on-same-line-as-for-loop-start-is-valid/20185/13 "2019-02-06T09:22:33Z")

</div>

I think for `let`, it leads to ambiguous syntax. See [this commit](https://github.com/JuliaLang/julia/commit/049bf7b1e839e53dd78aa919b54ad85b7394c09b) from the dawn of time.

---

<div class="post-metadata">

**Author:** ![bennedich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bennedich/32/4894_2.png) [@bennedich](https://discourse.julialang.org/u/bennedich)\
**Post date:** [February 6, 2019, 1:49pm UTC](https://discourse.julialang.org/t/extra-token-on-same-line-as-for-loop-start-is-valid/20185/14 "2019-02-06T13:49:39Z")

</div>

Nice find! But I don’t see what the ambiguity is, and how it’s different from for loops, do you? Since let assignments must be comma separated (also at the time of that commit), wouldn’t the only way to parse `let x = 1 y = 2` be the let statement `let x = 1` followed by the assignment `y = 2`? Which is confusing and could lead to bugs, but so could for loops:

```julia
julia> for a=1:2, b=3:4
           println("$a, $b")
       end
1, 3
1, 4
2, 3
2, 4

julia> for a=1:2 b=3:4
           println("$a, $b")
       end
1, 3:4
2, 3:4 

```

---

<div class="post-metadata">

**Author:** ![dawbarton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dawbarton/32/215461_2.png) [@dawbarton](https://discourse.julialang.org/u/dawbarton)\
**Post date:** [February 6, 2019, 2:16pm UTC](https://discourse.julialang.org/t/extra-token-on-same-line-as-for-loop-start-is-valid/20185/15 "2019-02-06T14:16:46Z")

</div>

I think the ambiguity comes from the fact that the `let` syntax allows multiple assignments of the form

```julia
let a = b = 1
    println("a = $a, b = $b")
end

```

where as the `for` syntax does not.

---

<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 6, 2019, 2:24pm UTC](https://discourse.julialang.org/t/extra-token-on-same-line-as-for-loop-start-is-valid/20185/16 "2019-02-06T14:24:32Z")

</div>

I am not sure. I could not find any unit tests for the `let` parsing ambiguity. Perhaps @jeff.bezanson could clarify this.

---

<div class="post-metadata">

**Author:** ![jeff.bezanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff.bezanson/32/48_2.png) [@jeff.bezanson](https://discourse.julialang.org/u/jeff.bezanson)\
**Post date:** [February 6, 2019, 4:23pm UTC](https://discourse.julialang.org/t/extra-token-on-same-line-as-for-loop-start-is-valid/20185/17 "2019-02-06T16:23:24Z")

</div>

I’m not really sure, but my best guess is that `let` predated `for` loops with multiple ranges. With a for loop, you knew that anything after the first assignment was in the loop body. But

```julia
let x = 1 y = 2
    ...
end

```

would be highly misleading. Basically, you expect `let` to have multiple variables and a `for` loop to have one. But yes, this is now inconsistent. Oh well.

---

<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:** [February 7, 2019, 7:26pm UTC](https://discourse.julialang.org/t/extra-token-on-same-line-as-for-loop-start-is-valid/20185/18 "2019-02-07T19:26:52Z")

</div>

Could making it consistent qualify as a minor change? Otherwise we should have a 2.0 issue to track changing this.

---

<div class="post-metadata">

**Author:** ![jeff.bezanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff.bezanson/32/48_2.png) [@jeff.bezanson](https://discourse.julialang.org/u/jeff.bezanson)\
**Post date:** [February 7, 2019, 8:39pm UTC](https://discourse.julialang.org/t/extra-token-on-same-line-as-for-loop-start-is-valid/20185/19 "2019-02-07T20:39:10Z")

</div>

I suspect changing this is likely to break a bunch of code. It’s easy to imagine people writing 1-line for loops like the example here. We can change it in 2.0 but it’s a slap-on-the-wrist kind of thing.
