Skip to content

Commit 97112c2

Browse files
committed
More docs on endmarkers
1 parent 8062c41 commit 97112c2

File tree

2 files changed

+107
-4
lines changed

2 files changed

+107
-4
lines changed

docs/docs/reference/other-new-features/indentation.md

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ println(".")
187187

188188
Indentation-based syntax has many advantages over other conventions. But one possible problem is that it makes it hard to discern when a large indentation region ends, since there is no specific token that delineates the end. Braces are not much better since a brace by itself also contains no information about what region is closed.
189189

190-
To solve this problem, Scala 3 offers an optional `end` marker. Example
190+
To solve this problem, Scala 3 offers an optional `end` marker. Example:
191191
```scala
192192
def largeMethod(...) =
193193
...
@@ -214,9 +214,66 @@ End markers are allowed in statement sequences. The specifier token `s` of an en
214214
- If the statement is a package clause that refers to package `p`, then `s` must be the same identifier `p`.
215215
- If the statement is an `if`, `while`, `for`, `try`, or `match` statement, then `s` must be that same token.
216216

217-
It is recommended that `end` markers are used for code where the extent of an indentation region is not immediately apparent "at a glance". Typically this is the case if an indentation region spans 20 lines or more.
217+
For instance, the following end markers are all legal:
218+
```scala
219+
package p1.p2:
220+
221+
abstract class C():
222+
223+
def this(x: Int) =
224+
this()
225+
if x > 0 then
226+
val a :: b =
227+
x :: Nil
228+
end val
229+
var y =
230+
x
231+
end y
232+
while y > 0 do
233+
println(y)
234+
y -= 1
235+
end while
236+
try
237+
x match
238+
case 0 => println("0")
239+
case _ =>
240+
end match
241+
finally
242+
println("done")
243+
end try
244+
end if
245+
end this
246+
247+
def f: String
248+
end C
249+
250+
object C:
251+
given C =
252+
new C:
253+
def f = "!"
254+
end f
255+
end new
256+
end given
257+
end C
258+
259+
extension on (x: C):
260+
def ff: String = x.f ++ x.f
261+
end extension
262+
263+
end p2
264+
```
265+
266+
#### When to Use End Markers
267+
268+
It is recommended that `end` markers are used for code where the extent of an indentation region is not immediately apparent "at a glance". People will have different preferences what this means, but one can nevertheless give some guidelines that stem from experience. An end marker makes sense if
269+
270+
- the construct contains blank lines, or
271+
- the construct is long, say 15-20 lines or more,
272+
- the construct ends heavily indented, say 4 indentation levels or more.
273+
274+
If none of these criteria apply, it's often better to not use an end marker since the code will be just as clear and more concise. If there are several ending regions that satisfy one of the criteria above, we usually need an end marker only for the outermost closed reason. So cascades of end markers as in the example above are usually better avoided.
218275

219-
**Syntax**
276+
#### Syntax
220277

221278
```
222279
EndMarker ::= ‘end’ EndMarkerTag -- when followed by EOL

tests/pos/endmarkers.scala

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,50 @@ trait T:
99
end T
1010

1111
object T
12-
end T
12+
end T
13+
14+
package p1.p2:
15+
16+
abstract class C():
17+
18+
def this(x: Int) =
19+
this()
20+
if x > 0 then
21+
val a :: b =
22+
x :: Nil
23+
end val
24+
var y =
25+
x
26+
end y
27+
while y > 0 do
28+
println(y)
29+
y -= 1
30+
end while
31+
try
32+
x match
33+
case 0 => println("0")
34+
case _ =>
35+
end match
36+
finally
37+
println("done")
38+
end try
39+
end if
40+
end this
41+
42+
def f: String
43+
end C
44+
45+
object C:
46+
given C =
47+
new C:
48+
def f = "!"
49+
end f
50+
end new
51+
end given
52+
end C
53+
54+
extension on (x: C):
55+
def ff: String = x.f
56+
end extension
57+
58+
end p2

0 commit comments

Comments
 (0)