Sorry for the long post.
I took a look at the longer Scala 3 examples, and also the Python code.
By and large I found the Scala code to be okay to read. I think that it is probably better than having brackets everywhere, but subjectively not as clear as it could be. I.e. I would still choose to use {} and () is more places because I think that it would make the code more readable.
There were a couple of cases where the code is laid out in a way that I really dislike (sorry):
I find this code really jarring where the second clause of the condition is indented to the same level as the if:
if !excludeDef(tree.pid.symbol)
&& tree.pid.span.hasLength then
tree.pid match
I think that I find the conditional case statements to be equally jarring:
case tree: (DefDef | ValDef)
if tree.symbol.isSyntheticWithIdent =>
tree match
Generally, in terms of the indentation based syntax:
I find the use of keywords to sometimes introduce blocks and colons in other cases to be inconsistent. I also have some concern that colon is used both to ascribe a type and to introduce a block, although it does seem to me that using colon is a pragmatic choice, given that it already used in that way in other languages (e.g., Python).
What I find stranger is that in some ways the Scala code looks much closer to Python except that Python uses :
rather than then
or do
. I.e. one of the most frequent constructs is arguably more verbose than before. Having said that I really do like the ability to remove the unnecessary brackets in many if conditions.
There are some cases where brackets have been removed, but personally I think brackets make the code clearer. E.g. the top level class/object definitions and anonymous classes. E.g. I would probably have used brackets for the following code because I just find it more intuitive:
private val symsAtOffset = new mutable.HashMap[Int, Set[Symbol]]():
override def default(key: Int) = Set[Symbol]()
One suggestion for a potentially way to solve the inconsistency on block marker would be to always have keywords available to introduce blocks, but also allow colon to be used in place of any of those keywords. E.g., allow
if cond then
stuff
else
more stuff
And also
if cond:
stuff
else:
more stuff
For classes, it could be:
class Foo where
def ...
Or
class Foo:
def ...
But perhaps having a third way of introducing blocks is too much …
Overall, my main concern is that I’m not sure whether the Scala 3 indentation syntax has had enough time and community usage to really be sure that it is right and doesn’t need to change again. As mentioned previously, I would prefer if it is marked as an experimental feature that could be changed or be refined based on community feedback and experience. Even if it is an experimental feature then I do not mind if it is enabled by default, since I suspect that it won’t be possible to get enough feedback without it.
My expectation is that I will structure my code to use a combination of brackets (e.g. top level classes) and longer methods, and then use the quieter syntax for shorter methods. I’m also still not sure about the end statement. I can see that in some cases it would also be helpful to annotate what is being ended (e.g., a class). However, when used for method bodies, I think that I would probably prefer to see it indented to the same level as the method statements rather than at the same indentation level as the def statement. I suspect that in all other cases I would naturally have it at the same indentation level as construct that it is ending, i.e., I’m being inconsistent. But I’m really not sure whether I will use the end statement at all, or just use brackets in those cases where methods are long enough to need an end marker.
But I really do appreciate the efforts that Martin and others have gone to try and improve the Scala language syntax both making it more pleasurable to read/write and hopefully better for newcomers. And so far, Scala 3 looks like an exciting new version of the Scala language.