Braces in Scala 3 aren't just Optional, they're Consistent :: Sep 5, 2021

Scala 3 adds Optional Braces to the language. At first I was concerned the two different styles would cause confusion and ambiguity, but over time I’ve realized the new scheme actually makes the language more consistent.

For example, consider a one-line method declaration. In both Scala 2 & 3, braces are optional:

def helloWorld: Unit = println("Hello, world!")

If requirements change and you have to refactor, Scala 2 costs several keystrokes to add braces:

def helloWorld: Unit = {
  val name = Properties.propOrElse("user.name", "world")
  println(s"Hello, $name!")
}

But with Scala 3, just insert a line break.

def helloWorld: Unit =
  val name = Properties.propOrElse("user.name", "world")
  println(s"Hello, $name!")

Another example; consider lambdas. Often they are one-liners,

users.map(u => s"Hello, $u!").mkString(", ")

But eventually refactored to multi-line:

users
  .map(u => {
    val name = u.name.trim
    s"Hello, $name!"
  })
  .mkString(", ")

The multi-line version in Scala 2 requires braces that seem downright obnoxious after exposure to Scala 3.

users
  .map(u =>
    val name = u.name.trim
    s"Hello, $name!"
  )
  .mkString(", ")

These same principles extend to all the other braceless constructs, like if-then-else, while, and for-yield.

There are still instances where braces are needed, like by-name parameters, context functions, or pattern matching inside map{}.

But overall, the braceless syntax is faster, easier to refactor, and more beautiful than the alternative. At least we’re not arguing about tabs-vs-spaces.