All control structures should be written with a space following thedefining keyword:
// right!
if (foo) bar else baz
for (i <- 0 to 10) { ... }
while (true) { println("Hello, World!") }
// wrong!
if(foo) bar else baz
for(i <- 0 to 10) { ... }
while(true) { println("Hello, World!") }
Curly-Braces
Curly-braces should be omitted in cases where the control structurerepresents a pure-functional operation and all branches of the controlstructure (relevant to if
/else
) are single-line expressions.Remember the following guidelines:
if
- Omit braces if you have anelse
clause. Otherwise, surroundthe contents with curly braces even if the contents are only asingle line.while
- Never omit braces (while
cannot be used in apure-functional manner).for
- Omit braces if you have ayield
clause. Otherwise,surround the contents with curly-braces, even if the contents areonly a single line.case
- Always omit braces in case clauses.
val news = if (foo)
goodNews()
else
badNews()
if (foo) {
println("foo was true")
}
news match {
case "good" => println("Good news!")
case "bad" => println("Bad news!")
}
Comprehensions
Scala has the ability to represent for
-comprehensions with more thanone generator (usually, more than one <-
symbol). In such cases, thereare two alternative syntaxes which may be used:
// wrong!
for (x <- board.rows; y <- board.files)
yield (x, y)
// right!
for {
x <- board.rows
y <- board.files
} yield (x, y)
While the latter style is more verbose, it is generally consideredeasier to read and more “scalable” (meaning that it does not becomeobfuscated as the complexity of the comprehension increases). You shouldprefer this form for all for
-comprehensions of more than onegenerator. Comprehensions with only a single generator (e.g.for (i <- 0 to 10) yield i
) should use the first form (parenthesesrather than curly braces).
The exceptions to this rule are for
-comprehensions which lack ayield
clause. In such cases, the construct is actually a loop ratherthan a functional comprehension and it is usually more readable tostring the generators together between parentheses rather than using thesyntactically-confusing } {
construct:
// wrong!
for {
x <- board.rows
y <- board.files
} {
printf("(%d, %d)", x, y)
}
// right!
for (x <- board.rows; y <- board.files) {
printf("(%d, %d)", x, y)
}
Finally, for
comprehensions are preferred to chained calls to map
,flatMap
, and filter
, as this can get difficult to read (this is oneof the purposes of the enhanced for
comprehension).
Trivial Conditionals
There are certain situations where it is useful to create a shortif
/else
expression for nested use within a larger expression. InJava, this sort of case would traditionally be handled by the ternaryoperator (?
/:
), a syntactic device which Scala lacks. In thesesituations (and really any time you have a extremely brief if
/else
expression) it is permissible to place the “then” and “else” branches onthe same line as the if
and else
keywords:
val res = if (foo) bar else baz
The key here is that readability is not hindered by moving both branchesinline with the if
/else
. Note that this style should never be usedwith imperative if
expressions nor should curly braces be employed.