Skip to content

Commit 0c57527

Browse files
committed
More tests
1 parent e5fd587 commit 0c57527

File tree

4 files changed

+122
-1
lines changed

4 files changed

+122
-1
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
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+
```

tests/neg/indent-colons.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import language.experimental.fewerBraces
2+
3+
val x = 1.+ : // ok
4+
2
5+
6+
val y = 1 + : // error // error
7+
2 // error

tests/neg/indent-experimental.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import language.experimental.fewerBraces
2+
3+
val x =
4+
if true then: // error
5+
1
6+
else: // error
7+
2
8+
9+
10+
val credentials = List("OK")
11+
val all = credentials ++ : // error
12+
val file = "file" // error
13+
if file.isEmpty // error
14+
then Seq("none")
15+
else Seq(file)

tests/pos/indent-colons.scala

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,26 @@ class Coder(words: List[String]):
116116
end Coder
117117

118118
object Test22:
119-
def foo: Int = 22
119+
def foo: Int = 22
120+
121+
def tryEither[T](x: T)(y: Int => T): T = ???
122+
123+
def test1 =
124+
tryEither:
125+
"hello"
126+
:
127+
y => y.toString
128+
129+
def test2 =
130+
tryEither:
131+
"hello"
132+
:
133+
_.toString
134+
135+
136+
val o =
137+
Some(3).fold:
138+
"nothing"
139+
:
140+
x => x.toString
141+

0 commit comments

Comments
 (0)