Skip to content

Commit c4d12cc

Browse files
author
Dean Wampler
committed
Examples of the 3.3 feature that allows fewer braces.
1 parent 5ac83e5 commit c4d12cc

File tree

1 file changed

+122
-0
lines changed

1 file changed

+122
-0
lines changed
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
// src/script/scala/progscala3/IndentationSyntax-FewerBraces.scala
2+
3+
// Scala 3.2 introduced an experimental feature to allow indentation syntax
4+
// in more situations, instead of braces. This extension will be offered as
5+
// a supported feature in 3.3. This file explores the differences, where each
6+
// example is repeated twice, once with braces as required for Scala 3.0 to 3.2
7+
// and again with the new syntax that eliminates the braces.
8+
//
9+
// In essense, a `:` (colon) token is also recognized where a function
10+
// argument would be expected. The examples below are adapted from the Dotty
11+
// documentation page:
12+
// https://dotty.epfl.ch/docs/reference/other-new-features/indentation.html
13+
14+
// The next import is required for pre-3.3 releases, but not for 3.3+.
15+
// However, Scala disallows experimental imports except in _snapshot_ builds of
16+
// Scala itself. Hence, you'll need to build a snapshot of Scala and run the
17+
// interpreter with it to try the braceless examples below:
18+
// 1. Clone the Dotty repo: https://github.com/lampepfl/dotty
19+
// 2. Run `sbt dist/packArchive`
20+
// 3. Copy the `*.zip` or `*.tar.gz` file created in `dist/target` somewhere convenient
21+
// 4. Expand the archive in the new directory
22+
// 5. Run `.../bin/scala`
23+
// 6. Copy and paste the following examples.
24+
25+
import language.experimental.fewerBraces
26+
27+
// A helper method:
28+
29+
def times(n: Int)(f: => Unit): Unit =
30+
for i <- 0 until n do f
31+
32+
// Use braces to define and pass the function:
33+
times(3) {
34+
println("one")
35+
println("two")
36+
}
37+
// (Output shown as comments)
38+
// one
39+
// two
40+
// one
41+
// two
42+
// one
43+
// two
44+
45+
// New braceless syntax to define and pass the function. Now the compiler interprets
46+
// the trailing colon, followed by indented lines, as the beginning and definition of
47+
// the anonymous function:
48+
times(3):
49+
println("one")
50+
println("two")
51+
// one
52+
// two
53+
// ...
54+
55+
import java.io.File
56+
val dir = new File(".")
57+
// val dir: java.io.File = .
58+
59+
// Another example, where the `++` method expects a function argument:
60+
val paths1 = Seq(dir) `++` {
61+
dir.listFiles
62+
}
63+
// val paths1: Seq[java.io.File] = List(., ./scala3-3.3.0-RC1-bin-SNAPSHOT, ./scala3-3.3.0-RC1-bin-SNAPSHOT.zip)
64+
65+
val paths2 = Seq(dir) `++`:
66+
dir.listFiles
67+
// val paths2: Seq[java.io.File] = List(., ./scala3-3.3.0-RC1-bin-SNAPSHOT, ./scala3-3.3.0-RC1-bin-SNAPSHOT.zip)
68+
69+
val xs = 0 until 10
70+
// val xs: Range = Range 0 until 10
71+
72+
// What about function arguments? They can either go on the next line after the
73+
// colon or on the same line:
74+
val map1a = xs.map {
75+
x =>
76+
val y = x - 1
77+
y * y
78+
}
79+
// val map1a: IndexedSeq[Int] = Vector(1, 0, 1, 4, 9, 16, 25, 36, 49, 64)
80+
81+
val map2a = xs.map:
82+
x =>
83+
val y = x - 1
84+
y * y
85+
// val map2a: IndexedSeq[Int] = Vector(1, 0, 1, 4, 9, 16, 25, 36, 49, 64)
86+
87+
val map1b = xs.map { x =>
88+
val y = x - 1
89+
y * y
90+
}
91+
// val map1b: IndexedSeq[Int] = Vector(1, 0, 1, 4, 9, 16, 25, 36, 49, 64)
92+
93+
val map2b = xs.map: x =>
94+
val y = x - 1
95+
y * y
96+
// val map2b: IndexedSeq[Int] = Vector(1, 0, 1, 4, 9, 16, 25, 36, 49, 64)
97+
98+
// It looks odd, but the arrow can be on the next line, separated from the arguments:
99+
val map3b = xs.map: x
100+
=>
101+
val y = x - 1
102+
y * y
103+
// val map3b: IndexedSeq[Int] = Vector(1, 0, 1, 4, 9, 16, 25, 36, 49, 64)
104+
105+
// Here are multiple arguments:
106+
107+
val fold1 = xs.foldLeft(0) { (x, y) =>
108+
x + y
109+
}
110+
// val fold1: Int = 45
111+
112+
val fold2a = xs.foldLeft(0): (x, y) =>
113+
x + y
114+
// val fold2a: Int = 45
115+
116+
// BUT, you can't put the function body on the same line:
117+
// scala> val fold2b = xs.foldLeft(0): (x, y) => x + y
118+
// |
119+
// -- Error: ---------------------------------------------------------------------------------------------------------------------------------------------------
120+
// 1 |val fold2b = xs.foldLeft(0): (x, y) => x + y
121+
// | ^^^^^^^^^^^^^^^^^^^^^^
122+
// | not a legal formal parameter for a function literal

0 commit comments

Comments
 (0)