|
| 1 | +--- |
| 2 | +layout: doc-page |
| 3 | +title: "Fewer Braces" |
| 4 | +--- |
| 5 | + |
| 6 | +By and large, the possible indentation regions coincide with those regions where braces `{...}` are also legal, no matter whether the braces enclose an expression or a set of definitions. There is one exception, though: Arguments to function can be enclosed in braces but they cannot be simply indented instead. Making indentation always significant for function arguments would be too restrictive and fragile. |
| 7 | + |
| 8 | +To allow such arguments to be written without braces, a variant of the indentation scheme is implemented under language import |
| 9 | +```scala |
| 10 | +import language.experimental.fewerBraces |
| 11 | +``` |
| 12 | +Alternatively, it can be enabled with command line option `-language:experimental.fewerBraces`. |
| 13 | + |
| 14 | +This variant is more contentious and less stable than the rest of the significant indentation scheme. It allows to replace a function argument in braces by a `:` at the end of a line and indented code, similar to the convention for class bodies. It also allows to leave out braces around arguments that are multi-line function values. |
| 15 | + |
| 16 | +## Using `:` At End Of Line |
| 17 | + |
| 18 | + |
| 19 | +Similar to what is done for classes and objects, a `:` that follows a function reference at the end of a line means braces can be omitted for function arguments. Example: |
| 20 | +```scala |
| 21 | +times(10): |
| 22 | + println("ah") |
| 23 | + println("ha") |
| 24 | +``` |
| 25 | + |
| 26 | +Function calls that take multiple argument lists can also be handled this way: |
| 27 | + |
| 28 | +```scala |
| 29 | +val firstLine = files.get(fileName).fold: |
| 30 | + val fileNames = files.values |
| 31 | + s"""no file named $fileName found among |
| 32 | + |${values.mkString(\n)}""".stripMargin |
| 33 | + : |
| 34 | + f => |
| 35 | + val lines = f.iterator.map(_.readLine) |
| 36 | + lines.mkString("\n) |
| 37 | +``` |
| 38 | +
|
| 39 | +
|
| 40 | +## Lambda Arguments Without Braces |
| 41 | +
|
| 42 | +Braces can also be omitted around multiple line function value arguments. Examples |
| 43 | +```scala |
| 44 | +val xs = elems.map x => |
| 45 | + val y = x - 1 |
| 46 | + y * y |
| 47 | +xs.foldLeft (x, y) => |
| 48 | + x + y |
| 49 | +``` |
| 50 | +Braces can be omitted if the lambda starts with a parameter list and `=>` or `=>?` at the end of one line and it has an indented body on the following lines. |
| 51 | +
|
| 52 | +## Syntax Changes |
| 53 | +
|
| 54 | +``` |
| 55 | +SimpleExpr ::= ... |
| 56 | + | SimpleExpr : indent (CaseClauses | Block) outdent |
| 57 | + | SimpleExpr FunParams (‘=>’ | ‘?=>’) indent Block outdent |
| 58 | +``` |
| 59 | +
|
| 60 | +Note that indented blocks after `:` or `=>` only work when following a simple expression, they are not allowed after an infix operator. So the following examples |
| 61 | +would be incorrect: |
| 62 | +
|
| 63 | +```scala |
| 64 | + x + : // error |
| 65 | + y |
| 66 | +
|
| 67 | + f `andThen` y => // error |
| 68 | + y + 1 |
| 69 | +``` |
| 70 | +
|
| 71 | +Note also that a lambda argument must have the `=>` at the end of a line for braces |
| 72 | +to be optional. For instance, the following would also be incorrect: |
| 73 | +
|
| 74 | +```scala |
| 75 | + xs.map x => x + 1 // error: braces or parentheses are required |
| 76 | + xs.map(x => x + 1) // ok |
| 77 | +``` |
0 commit comments