On braces and indentation-based syntax

Okay I found the specification I had seen in the past days when I was reviewing Scala 3:

https://dotty.epfl.ch/docs/reference/other-new-features/indentation.html

So my memory was correct that the colon is optional in some cases and there are some complex rules about what line endings can trigger an eligible indentation block. This sort of complexity is what I am railing against.

Much simpler would be that indentations always begin at 3 spaces and if the parser detects a block where there shouldn’t be one, then error. Then we do not need all these special cases in the aforelinked specification. Also as an additional benefit line continuations will be enabled, just don’t indent them to a multiple of 3 spaces. Please simplify. The current design is repeating the same mistake made in the past that makes Scala so unnecessarily abstruse. Pick the simpler rule please. It is known as the Keep It Simple Stupid principle (mods please do not blame me as I did not coin the term and it actually doesn’t have derogatory meaning).

@martijnhoekstra, I share your cognitive dissonance that seems to stem from how unintuitive it is for a function to take a block as an input parameter. This is quite strange. And putting long lambdas in curly brace blocks to make them input parameters is also strange. Granted a necessary power user feature, yet still strange. Any newbie is going to stumble on that.

Yet your example is even more weird because it isn’t a lambda. I suppose it is passing a Unit type? It seems to me that Unit types should always be passed as some delimited block, yet for you the colon does not connote a block, because it has a different usage in other programming language contexts you are familiar with. Where in Scala has the colon been used to delimit a name and its definition? I am not familiar with that usage. Or maybe you are referring to a different language?

So the attempt to make it more natural by putting the parameter list of the lambda and arrow on the same line as the function makes the block body that follows somewhat more intuitive but it is a special case that has inconsistencies such as the single line case requires parentheses because the parser can’t easily distinguish it and the multiple parameter list function (which Odersky argues is non-idiomatic code, at least with the arrival of Scala 3, although others disagreed) seems to have no indented style that isn’t fugly and non-intuitive. And the non-lambda Unit block as a function parameter are a different case.

My thought is that Unit parameters are power user material. Maybe they should remain curly braces? To make it very explicit that they are blocks. Passing Unit to a function is very weird to someone who is new to Scala. Maybe we should explicitly call that out to the newbies who are adopting the braceless style.

If you adopt my suggestion for hardcoding the indent for braceless blocks then you do not need the prefixed colon for lambdas, as either you will have a line continuation or an indented block defined by the next line’s indentation. Single-line lambdas (and I suppose maybe also line continuations?) require parentheses presumably as they always did?

Multiple parameter lists (and I guess actually any comma-delimited parameter list) taking a block lambda or Unit block as any but the last parameter should be required to take curly braces which would accomplish both Odersky’s objective to discourage them (the multiple parameter lists) as much as possible and address the complaints of others about how unreadable they are otherwise in convoluted braceless styles?

EDIT: comma (or colon) delimited braceless blocks are also fugly, hard-to-read and shouldn’t be allowed? Tl;dr Unit parameter blocks are always curly braced. Lambda (and counterparts) braceless blocks allowed but only as the last parameter, otherwise must be curly braced.

EDIT#2: Regarding my suggestion to adopt 3 spaces as the standard and enforced indent, it would resolve the potential bug pointed out in that long January discussion thread which is closed so I can’t reply there:

class A
 object B