This is the start of my tour of changes in Scala 3.
Let’s start with optional braces, which make Scala code look more like Python or Haskell, replacing curly braces with significant indentation. Here are some examples, adapted from an Appendix that will be in the forthcoming Third Edition of Programming Scala.
Optional Braces: Examples
First, here is a type declaration in old and new syntax. It works the same for scoped package declarations (as opposed to one package declaration for the whole file):
The new syntax is very similar to Python, although when things are so similar, yet not exactly the same, it can be confusing if you switch back and forth between languages.
You can mix and match these styles. Both definitions will compile fine with the Dotty compiler and REPL (soon to be renamed Scala 3).
Here are method declarations, but note that
= is used instead of
: to mark the start of the body.
Python developers will type
: until they get used to Scala! Compared to the older syntax, this looks like you can now drop braces for methods that have more than one expression, but there is an important difference. The indentation has be consistent at each level, using tabs or spaces.
Even partial functions, match expressions, and try-catch-finally clauses (not shown) can be written this way:
Historically, Scala has stayed close to Java syntax, so why such a dramatic change? It’s not uncommon today for people who know Python to find themselves learning Scala. Perhaps they learned Python in school, but their employer uses Scala. Many data-oriented projects mix Python-based data science with Scala-based data engineering. For these reasons, having Scala look closer to Python can be appealing.
However, this change is controversial. You could argue that the old syntax works fine and adding a second syntax just feeds perceptions that Scala is complex. There’s another small drawback, illustrated next:
A cool feature of the curly brace syntax is the ability to define your own “control” structures. Here,
loop looks like the built-in
while loop. However, the attempt shown to use a braceless alternative doesn’t work. (This might be possible in a future release.)
When I first started working on the third edition of Programming Scala, I was opposed to this new syntax and planned to only mention it, sticking with the original syntax. However, since the book is focused on Scala 3, I later decided to use the new syntax almost exclusively. Now that I’m accustomed to it, I like it. It makes Scala code that much more concise. Besides, we really shouldn’t ignore industry trends. If this syntax makes Scala more appealing to Python (and Haskell) programmers, that’s a good thing.
New, Optional Control Syntax
Finally, there is also an optional new control syntax for
while expressions. Again, you can mix and match:
for loops and
while loops, you can remove parentheses and curly braces, then mark the end of the expressions with the
do keyword. For
for comprehensions, you end the expressions with the
yield keyword. Similarly, for
if expressions, you remove parentheses and use
then after the condition.
You can mix forms or require the new syntax only with the compiler flag
—new-syntax. If you prefer to require the old syntax, use
—old-syntax. There is also an interesting new
-rewrite flag. Combine it with one of the others to have the compiler convert your code to the new syntax or back to the old syntax.
There are lots of details and examples I’ve omitted to keep this reasonably short. See the links to the documentation above for more details.
If you have an existing Scala 2 code base, there is no requirement to adopt any of these new conventions. I certainly wouldn’t recommend mixing them in your code. Pick one or the other. It seems unlikely that the older Java-like syntax will be deprecated, but time will tell.
That said, these changes have grown on me, now that I’ve worked with them a bit. I’ll use them with any new personal projects I do.
You can start reading the rough draft of Programming Scala, Third Edition on the O’Reilly Learning Platform. Currently, the first six chapters are available, including the two (five and six) that cover contextual abstractions.