You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If an `<outdent>` is inserted, the top element if popped from `IW`.
80
+
If an `<outdent>` is inserted, the top element is popped from `IW`.
79
81
If the indentation width of the token on the next line is still less than the new current indentation width, step (2) repeats. Therefore, several `<outdent>` tokens
80
82
may be inserted in a row.
81
83
@@ -84,12 +86,14 @@ There are two rules:
84
86
An `<outdent>` is finally inserted in front of a comma that follows a statement sequence starting with an `<indent>` if the indented region is itself enclosed in parentheses
85
87
86
88
It is an error if the indentation width of the token following an `<outdent>` does not match the indentation of some previous line in the enclosing indentation region. For instance, the following would be rejected.
89
+
87
90
```scala
88
91
if x <0
89
92
-x
90
93
else// error: `else` does not align correctly
91
94
x
92
95
```
96
+
93
97
Indentation tokens are only inserted in regions where newline statement separators are also inferred:
94
98
at the toplevel, inside braces `{...}`, but not inside parentheses `(...)`, patterns or types.
95
99
@@ -105,6 +109,7 @@ that can start an indentation region. The Scala grammar is changed so an optiona
105
109
Analogous rules apply forenumbodies, typerefinements, definitions in an instance creation expressions, and local packages containing nested definitions.
106
110
107
111
With these new rules, the following constructs are all valid:
Here, `colonEol` stands for": at end of line", asdescribed above.
147
154
The lexical analyzer is modified so that a `:` at the end of a line
148
155
is reported as `colonEol` if the parser is at a point where a `colonEol` is
@@ -166,13 +173,14 @@ Indentation can be mixed freely with braces. For interpreting indentation inside
166
173
167
174
The indentation rules for `match` expressions and `catch` clauses are refined asfollows:
168
175
169
-
-An indentation region is opened after a `match` or `catch` also if the following `case`
170
-
appears at the indentation width that's current for the `match` itself.
171
-
-In that case, the indentation region closes at the first token at that
172
-
same indentation width that is not a `case`, or at any token with a smaller
173
-
indentation width, whichever comes first.
176
+
-An indentation region is opened after a `match` or `catch` also if the following `case`
177
+
appears at the indentation width that's current for the `match` itself.
178
+
-In that case, the indentation region closes at the first token at that
179
+
same indentation width that is not a `case`, or at any token with a smaller
180
+
indentation width, whichever comes first.
174
181
175
182
The rules allow to write `match` expressions where cases are not indented themselves, asin the example below:
183
+
176
184
```scala
177
185
x match
178
186
case1=> print("I")
@@ -189,6 +197,7 @@ println(".")
189
197
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.
190
198
191
199
To solve this problem, Scala3 offers an optional `end` marker. Example:
200
+
192
201
```scala
193
202
deflargeMethod(...) =
194
203
...
@@ -199,80 +208,84 @@ def largeMethod(...) =
199
208
... // more code
200
209
endlargeMethod
201
210
```
211
+
202
212
An `end` marker consists of the identifier `end` and a follow-on specifier token that together constitute all the tokes of a line. Possible specifier tokens are
203
213
identifiers or one of the following keywords
214
+
204
215
```scala
205
216
ifwhileformatchtrynewthisvalgiven
206
217
```
218
+
207
219
End markers are allowed in statement sequences. The specifier token `s` of an end marker must correspond to the statement that precedes it. Thismeans:
208
220
209
-
-If the statement defines a member `x` then `s` must be the same identifier `x`.
210
-
-If the statement defines a constructor then `s` must be `this`.
211
-
-If the statement defines an anonymous given, then `s` must be `given`.
212
-
-If the statement defines an anonymous extension, then `s` must be `extension`.
213
-
-If the statement defines an anonymous class, then `s` must be `new`.
214
-
-If the statement is a `val` definition binding a pattern, then `s` must be `val`.
215
-
-If the statement is a packageclausethatreferstopackage`p`, then`s`mustbethesameidentifier`p`.
216
-
-If the statement is an `if`, `while`, `for`, `try`, or `match` statement, then `s` must be that same token.
221
+
-If the statement defines a member `x` then `s` must be the same identifier `x`.
222
+
-If the statement defines a constructor then `s` must be `this`.
223
+
-If the statement defines an anonymous given, then `s` must be `given`.
224
+
-If the statement defines an anonymous extension, then `s` must be `extension`.
225
+
-If the statement defines an anonymous class, then `s` must be `new`.
226
+
-If the statement is a `val` definition binding a pattern, then `s` must be `val`.
227
+
-If the statement is a packageclausethatreferstopackage`p`, then`s`mustbethesameidentifier`p`.
228
+
-If the statement is an `if`, `while`, `for`, `try`, or `match` statement, then `s` must be that same token.
217
229
218
230
For instance, the following end markers are all legal:
219
-
```scala
220
-
packagep1.p2:
221
-
222
-
abstractclassC():
223
-
224
-
defthis(x: Int) =
225
-
this()
226
-
if x >0then
227
-
vala:: b =
228
-
x ::Nil
229
-
end val
230
-
vary=
231
-
x
232
-
endy
233
-
while y >0do
234
-
println(y)
235
-
y -=1
236
-
end while
237
-
try
238
-
x match
239
-
case0=> println("0")
240
-
case _ =>
241
-
end match
242
-
finally
243
-
println("done")
244
-
end try
245
-
end if
246
-
endthis
247
-
248
-
deff:String
249
-
endC
250
-
251
-
objectC:
252
-
givenC=
253
-
newC:
254
-
deff="!"
255
-
endf
256
-
endnew
257
-
endgiven
258
-
endC
259
-
260
-
extension (x: C)
261
-
defff:String= x.f ++ x.f
262
-
endextension
263
-
264
-
endp2
231
+
232
+
```scala
233
+
packagep1.p2:
234
+
235
+
abstractclassC():
236
+
237
+
defthis(x: Int) =
238
+
this()
239
+
if x >0then
240
+
vala:: b =
241
+
x ::Nil
242
+
end val
243
+
vary=
244
+
x
245
+
endy
246
+
while y >0do
247
+
println(y)
248
+
y -=1
249
+
end while
250
+
try
251
+
x match
252
+
case0=> println("0")
253
+
case _ =>
254
+
end match
255
+
finally
256
+
println("done")
257
+
end try
258
+
end if
259
+
endthis
260
+
261
+
deff:String
262
+
endC
263
+
264
+
objectC:
265
+
givenC=
266
+
newC:
267
+
deff="!"
268
+
endf
269
+
endnew
270
+
endgiven
271
+
endC
272
+
273
+
extension (x: C)
274
+
defff:String= x.f ++ x.f
275
+
endextension
276
+
277
+
endp2
265
278
```
266
279
267
280
####When to UseEndMarkers
268
281
269
282
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
270
283
271
-
- the construct contains blank lines, or
272
-
- the construct is long, say 15-20 lines or more,
273
-
- the construct ends heavily indented, say 4 indentation levels or more.
284
+
- the construct contains blank lines, or
285
+
- the construct is long, say 15-20 lines or more,
286
+
- the construct ends heavily indented, say 4 indentation levels or more.
274
287
275
-
If none of these criteria apply, it's often better to not use an end marker since the code will be just asclear 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 asin the example above are usually better avoided.
288
+
If none of these criteria apply, it's often better to not use an end marker since the code will be just asclear 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 region. So cascades of end markers asin the example above are usually better avoided.
276
289
277
290
####Syntax
278
291
@@ -359,14 +372,16 @@ times(10):
359
372
println("ah")
360
373
println("ha")
361
374
```
375
+
362
376
or
377
+
363
378
```scala
364
379
xs.map:
365
380
x =>
366
381
valy= x -1
367
382
y * y
368
383
```
384
+
369
385
Colons at the end of lines are their own token, distinct from normal `:`.
370
386
TheScala grammar is changed in this variant so that colons at end of lines are accepted at all points
371
387
where an opening brace enclosing a function argument is legal. Special provisions are taken so that method result types can still use a colon on the end of a line, followed by the actual typeon the next.
0 commit comments