This compiles but shouldn't (we should require then when using indentation syntax)
if cond
fooA()
fooB()
This compiles in Scala 2.13 but not in Dotty, but we should be able to support it:
var i = 0
while
(i < 10) { i += 1 }
/cc @kpbochenek
So just to be on the same page, let's formalize that:
cond can be of 3 forms(that will be used later):
cond <- where there is NO '(' at the beginning(cond) <- where a whole condition is wrapped in ()(cond).cont <- where it starts with '(' but has continuation either via '.method(...)' or via infix operator A few examples from dotty repl:
Statement with (cond) currently works
scala> if (2 < 3)
| println("a")
| println("b")
|
a
b
Statement with cond currently works
scala> if 2 < 3
| println("a")
| println("b")
|
a
b
Statement with (cond).cont currently works
scala> if (1 + 2) < 5
| println("a")
| println("b")
|
a
b
@smarter what 'cond' do you mean in if example, all 3? just a question, trying to clarify as much as possible to have common understanding and move to more interesting things :)
None of these examples should work.
That was quick :+1:
docs might need to be updated: https://dotty.epfl.ch/docs/reference/other-new-features/control-syntax.html
The condition of an if-expression can be written without enclosing parentheses if it is followed by a then or some indented code on a following line (it must be followed by 'then')
I too read the docs recently and liked thenless indented block syntax.
In fact, I would also like doless indented block syntax for while.
if x < 10
println(x)
x += 1
while x < 10
println(x)
x += 1
Full disclosure, last week I wrote one multiline if and used then. Yesterday I wrote only one-liners using then. I wrote no while, only recursive methods.
I agree that it's the other syntax that is problematic, which we should call "legacy parens".
In fact, I'm not sure what work the parser is doing, but the only problem seems to be that it doesn't like an indented condition, which IMHO ought to be (easily) supported:
if
(x < 10) && true
x += 1 // ok
if
(x < 10) && true
x += 1 // you confused me with an indented block, but you didn't even see a condition yet
It seems to me that accepting the indented condition solves all these problems.
if
(x < 10 && true) x += 1 // legacy parens, OK only if not indented (same as reported legacy parens in while syntax)
In sum, it shouldn't matter if the condition begins on the next line, and while should accept optional do the same way if accepts optional then, when followed by an indent block.
I really dislike then-less & paren-less if. Dotty is supposed to simplify the language, so it's already a stretch to introduce a new way of writing conditionals. But then, this would introduce a _third_, totally unnecessary way?
This issue has demonstrated that then-less if is confusing enough, so why not just use then consistently instead? This reads much better to me:
if x < 10 then
println(x)
x += 1
if
(x < 10) && true then
x += 1
if
val tmp = ...
tmp > 0
then
...
I did not consider the third example, a braceless indented block for the condition.
The compelling example is the block condition for while in https://dotty.epfl.ch/docs/reference/dropped-features/do-while.html
It says do-while was rare, and therefore block condition for this usage is rare, so it's not terrible to require braces.
The argument for discouraging block condition is that it's harder to read.
Is it terrible to require then and do always when most conditions are one-liners?
I don't have very strong opinions about this syntax because I'm suspending judgment while I gain more experience.
It's possible "optional then" and "support legacy parens with arbitrary indents" are orthogonal issues.
Potentially worth taking into account as it is about if syntax: #9790
There are three choices here to make for the interplay with indentation and ifs:
allow indentation only after a then. Plus: this is simplest and pushes towards one coding style only. Minus: It leaves out one common case where we can infer braces, so brace inference will look more random and arbitrary to people.
allow indentation after a then and after an old style if (...). Plus: More orthogonality between if syntax ad brace insertions.
Allow indentation to replace then. Plus: least hassle for transitions; some people like the style. Minus: Might be too many different styles.
My tendency would be to go with (2).
@odersky @anatoliykmetyuk Just to be sure, are we keeping it at (2) or at (1)? I see there is still things like https://github.com/lampepfl/dotty/blob/5274c48767c655bcf9d994f649b43f0e7214dde9/compiler/src/dotty/tools/dotc/typer/Checking.scala#L479-L481 so I am guessing it's (2) ?
And isn't this going against what Dotty is trying to do? By which I mean we want reduce the number of ways to do the same thing. We removed the optional = and now we are actually adding optional then
Most helpful comment
There are three choices here to make for the interplay with indentation and ifs:
allow indentation only after a
then. Plus: this is simplest and pushes towards one coding style only. Minus: It leaves out one common case where we can infer braces, so brace inference will look more random and arbitrary to people.allow indentation after a
thenand after an old styleif (...). Plus: More orthogonality between if syntax ad brace insertions.Allow indentation to replace
then. Plus: least hassle for transitions; some people like the style. Minus: Might be too many different styles.My tendency would be to go with (2).