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
Copy file name to clipboardExpand all lines: docs/_spec/04-basic-declarations-and-definitions.md
+54-57Lines changed: 54 additions & 57 deletions
Original file line number
Diff line number
Diff line change
@@ -19,8 +19,8 @@ Def ::= PatVarDef
19
19
| TmplDef
20
20
```
21
21
22
-
A _declaration_ introduces names and assigns them types.
23
-
It can form part of a [class definition](05-classes-and-objects.html#templates) or of a refinement in a [compound type](03-types.html#compound-types).
22
+
A _declaration_ introduces names and assigns them types or type definitions.
23
+
It can form part of a [class definition](05-classes-and-objects.html#templates) or of a refinement in a [refined type](03-types.html#concrete-refined-types).
24
24
25
25
A _definition_ introduces names that denote terms or types.
26
26
It can form part of an object or class definition or it can be local to a block.
A value declaration `val ´x´: ´T´` introduces ´x´ as a name of a value of type ´T´.
64
+
A value declaration `val ´x´: ´T´` introduces ´x´ as a name of a value of _declared type_ ´T´.
65
65
66
66
A value definition `val ´x´: ´T´ = ´e´` defines ´x´ as a name of the value that results from the evaluation of ´e´.
67
-
If the value definition is not recursive, the type ´T´ may be omitted, in which case the [packed type](06-expressions.html#expression-typing) of expression ´e´ is assumed.
68
-
If a type ´T´ is given, then ´e´ is expected to conform to it.
67
+
If the value definition is not recursive, the declared type ´T´ may be omitted, in which case the [packed type](06-expressions.html#expression-typing) of expression ´e´ is assumed.
68
+
If a type ´T´ is given, then it must be a [proper type](03-types.html#proper-types) and ´e´ is expected to [conform to it](06-expressions.html#expression-typing).
69
69
70
70
Evaluation of the value definition implies evaluation of its right-hand side ´e´, unless it has the modifier `lazy`.
71
71
The effect of the value definition is to bind ´x´ to the value of ´e´
@@ -156,7 +156,7 @@ An implementation of a class may _define_ a declared variable using a variable d
156
156
157
157
A variable definition `var ´x´: ´T´ = ´e´` introduces a mutable variable with type ´T´ and initial value as given by the expression ´e´.
158
158
The type ´T´ can be omitted, in which case the type of ´e´ is assumed.
159
-
If ´T´ is given, then ´e´ is expected to [conform to it](06-expressions.html#expression-typing).
159
+
If ´T´ is given, then it must be a [proper type](03-types.html#proper-types) and ´e´ is expected to [conform to it](06-expressions.html#expression-typing).
160
160
161
161
Variable definitions can alternatively have a [pattern](08-pattern-matching.html#patterns) as left-hand side.
162
162
A variable definition `var ´p´ = ´e´` where ´p´ is a pattern other than a simple name or a name followed by a colon and a type is expanded in the same way as a [value definition](#value-declarations-and-definitions)`val ´p´ = ´e´`, except that the free names in ´p´ are introduced as mutable variables, not values.
@@ -217,41 +217,55 @@ A variable definition `var ´x_1, ..., x_n: T´ = ´e´` is a shorthand for the
217
217
218
218
## Type Declarations and Type Aliases
219
219
220
-
<!-- TODO: Higher-kinded tdecls should have a separate section -->
221
-
222
220
```ebnf
223
221
Dcl ::= ‘type’ {nl} TypeDcl
224
222
TypeDcl ::= id [TypeParamClause] [‘>:’ Type] [‘<:’ Type]
225
223
Def ::= ‘type’ {nl} TypeDef
226
224
TypeDef ::= id [TypeParamClause] ‘=’ Type
227
225
```
228
226
227
+
A possibly parameterized _type declaration_`type ´t´[´\mathit{tps}\,´] >: ´L´ <: ´H´` declares ´t´ to be an abstract type.
228
+
If omitted, ´L´ and ´H´ are implied to be `Nothing` and `scala.Any`, respectively.
229
+
230
+
A possibly parameterized _type alias_`type ´t´[´\mathit{tps}\,´] = ´T´` defines ´t´ to be a concrete type member.
231
+
232
+
If a type parameter clause `[´\mathit{tps}\,´]` is present, it is desugared away according to the rules in the following section.
233
+
229
234
### Desugaring of parameterized type declarations
230
-
A parameterized type declaration is desugared into an unparameterized type declaration
231
-
whose bounds are type lambdas with explicit variance annotations.
235
+
236
+
A parameterized type declaration is desugared into an unparameterized type declaration whose bounds are [type lambdas](03-types.html#type-lambdas) with explicit variance annotations.
237
+
238
+
The scope of a type parameter extends over the bounds `>: ´L´ <: ´U´` or the alias `= ´T´` and the type parameter clause ´\mathit{tps}´ itself.
239
+
A higher-order type parameter clause (of an abstract type constructor ´tc´) has the same kind of scope, restricted to the declaration of the type parameter ´tc´.
240
+
241
+
To illustrate nested scoping, these declarations are all equivalent: `type t[m[x] <: Bound[x], Bound[x]]`, `type t[m[x] <: Bound[x], Bound[y]]` and `type t[m[x] <: Bound[x], Bound[_]]`, as the scope of, e.g., the type parameter of ´m´ is limited to the declaration of ´m´.
242
+
In all of them, ´t´ is an abstract type member that abstracts over two type constructors: ´m´ stands for a type constructor that takes one type parameter and that must be a subtype of `Bound`, ´t´'s second type constructor parameter.
243
+
`t[MutableList, Iterable]` is a valid use of ´t´.
232
244
233
245
#### Abstract Type
234
-
An abstract type
246
+
247
+
A parameterized abstract type
235
248
```scala
236
-
type ´t´[´\mathit{tps}\,´] >: ´L´ <: ´U´
249
+
type ´t´[´\mathit{tps}\,´] >: ´L´ <: ´H´
237
250
```
238
251
is desugared into an unparameterized abstract type as follow:
239
252
- If `L` conforms to `Nothing`, then,
240
253
241
254
```scala
242
255
type ´t´ >:Nothing
243
-
<: [´\mathit{tps'}\,´] =>> ´U´
256
+
<: [´\mathit{tps'}\,´] =>> ´H´
244
257
```
245
258
- otherwise,
246
259
247
260
```scala
248
261
type ´t´ >: [´\mathit{tps'}\,´] =>> ´L´
249
-
<: [´\mathit{tps'}\,´] =>> ´U´
262
+
<: [´\mathit{tps'}\,´] =>> ´H´
250
263
```
251
-
252
-
If at least one of the ´\mathit{tps}´ contains an explicit variance annotation, then ´\mathit{tps'} = \mathit{tps}´, otherwise we infer the variance of each type parameter as with the user-written type lambda `[´\mathit{tps}\,´] =>> ´U´`.
253
264
254
-
The same desugaring applies to typeparameters. For instance,
265
+
If at least one of the ´\mathit{tps}´ contains an explicit variance annotation, then ´\mathit{tps'} = \mathit{tps}´, otherwise we infer the variance of each type parameter as with the user-written type lambda `[´\mathit{tps}\,´] =>> ´H´`.
266
+
267
+
The same desugaring applies to typeparameters.
268
+
For instance,
255
269
```scala
256
270
[F[X] <:Coll[X]]
257
271
```
@@ -261,6 +275,7 @@ is treated as a shorthand for
261
275
```
262
276
263
277
####TypeAlias
278
+
264
279
A parameterized typealias
265
280
```scala
266
281
type ´t´[´\mathit{tps}\,´] = ´T´
@@ -271,34 +286,17 @@ type ´t´ = [´\mathit{tps'}\,´] =>> ´T´
271
286
```
272
287
where ´\mathit{tps'}´ is computed as in the previous case.
273
288
274
-
´\color{red}{\text{TODOSCALA3:Everythingelse in this section (and the next one
275
-
on typeparameters) needs to be rewritten to take into account the desugaring described above.}}´
289
+
###Non-ParameterizedTypeDeclarations and TypeAliases
276
290
277
-
A _type declaration_ `type ´t´[´\mathit{tps}\,´] >: ´L´ <: ´U´` declares ´t´ to be an abstracttypewith lower bound type ´L´ and upper bound type ´U´.
278
-
If the typeparameter clause `[´\mathit{tps}\,´]` is omitted, ´t´ abstracts over a proper type, otherwise ´t´ stands for a typeconstructor that accepts typeargumentsasdescribed by the typeparameter clause.
291
+
A _type declaration_ `type ´t´ >: ´L´ <: ´H´` declares ´t´ to be an abstracttypewhose [typedefinition](03-types.html#type-definitions) has the lower bound type ´L´ and upper bound type ´H´.
279
292
280
-
If a typedeclaration appears asa member declaration of a type, implementations of the typemay implement ´t´ with any type ´T´ for which ´L<:T<:U´.
281
-
It is a compile-time error if ´L´ does not conform to ´U´.
282
-
Either or both bounds may be omitted.
283
-
If the lower bound ´L´ is absent, the bottom type`scala.Nothing` is assumed.
284
-
If the upper bound ´U´ is absent, the top type`scala.Any` is assumed.
285
-
286
-
Atypeconstructor declaration imposes additional restrictions on the concrete types for which ´t´ may stand.
287
-
Besides the bounds ´L´ and ´U´, the typeparameter clause may impose higher-order bounds and variances, asgoverned by the [conformance of typeconstructors](03-types.html#conformance).
288
-
289
-
The scope of a typeparameterextends over the bounds `>: ´L´ <: ´U´` and the typeparameter clause ´\mathit{tps}´ itself.
290
-
A higher-order typeparameter clause (of an abstracttypeconstructor ´tc´) has the same kind of scope, restricted to the declaration of the typeparameter ´tc´.
291
-
292
-
To illustrate nested scoping, these declarations are all equivalent: `type t[m[x] <: Bound[x], Bound[x]]`, `type t[m[x] <: Bound[x], Bound[y]]` and `type t[m[x] <: Bound[x], Bound[_]]`, asthe scope of, e.g., the typeparameter of ´m´ is limited to the declaration of ´m´.
293
-
In all of them, ´t´ is an abstracttypemember that abstracts over two typeconstructors: ´m´ stands for a typeconstructor that takes one typeparameter and that must be a subtype of ´Bound´, ´t´'s second typeconstructor parameter.
294
-
`t[MutableList, Iterable]` is a valid use of ´t´.
293
+
If a typedeclaration appears asa member declaration of a type, implementations of the typemay implement ´t´ with any type ´T´ for which ´L<:T<:H´.
294
+
It is a compile-time error if ´L´ does not conform to ´H´.
295
295
296
296
A _type alias_ `type ´t´ = ´T´` defines ´t´ to be an alias name for the type ´T´.
297
-
The left hand side of a typealias may have a typeparameter clause, e.g. `type ´t´[´\mathit{tps}\,´] = ´T´`.
298
-
The scope of a typeparameterextends over the right hand side ´T´ and the typeparameter clause ´\mathit{tps}´ itself.
299
297
300
-
The scope rules for [definitions](#basic-declarations-and-definitions) and [typeparameters](#method-declarations-and-definitions) make it possible that a typename appears in its own bound or in its right-hand side.
301
-
However, it is a static error if a typealias refers recursively to the defined typeconstructoritself.
298
+
The scope rules for [definitions](#basic-declarations-and-definitions) and [typeparameters](#method-declarations-and-definitions) make it possible that a typename appears in its own bounds or in its right-hand side.
299
+
However, it is a static error if a typealias refers recursively to the defined typeitself.
302
300
That is, the type ´T´ in a typealias `type ´t´[´\mathit{tps}\,´] = ´T´` may not refer directly or indirectly to the name ´t´.
303
301
It is also an error if an abstracttypeis directly or indirectly its own upper or lower bound.
304
302
@@ -309,8 +307,8 @@ The following are legal type declarations and definitions:
309
307
```scala
310
308
typeIntList=List[Integer]
311
309
typeT<:Comparable[T]
312
-
typeTwo[A] =Tuple2[A, A]
313
-
typeMyCollection[+X] <:Iterable[X]
310
+
typeTwo[A] =Tuple2[A, A]// desugars to Two = [A] =>> Tuple2[A, A]
311
+
typeMyCollection[+X] <:Iterable[X]// desugars to MyCollection <: [+X] =>> Iterable[X]
314
312
```
315
313
316
314
The following are illegal:
@@ -323,11 +321,11 @@ type T <: S
323
321
324
322
typeT>:Comparable[T.That] // Cannot select from T.
325
323
// T is a type, not a value
326
-
typeMyCollection<:Iterable//Type constructor members must explicitly
327
-
// state their type parameters.
324
+
typeMyCollection<:Iterable//The reference to the type constructor
325
+
//Iterable must explicitly state its type arguments.
328
326
```
329
327
330
-
If a typealias `type ´t´[´\mathit{tps}\,´] = ´S´` refers to a classtype ´S´, the name ´t´ can also be used asa constructor for objects of type ´S´.
328
+
If a typealias `type ´t´ = ´S´` refers to a classtype ´S´ (or to a typelambda that is the eta-expansion of classtype ´S´), the name ´t´ can also be used asa constructor for objects of type ´S´.
331
329
332
330
######Example
333
331
@@ -432,22 +430,21 @@ The variance position changes at the following constructs.
432
430
-The variance position of the lower bound of a typedeclaration or typeparameter is the opposite of the variance position of the typedeclaration or parameter.
433
431
-Thetypeof a mutable variable is always in invariant position.
434
432
-The right-hand side of a typealias is always in invariant position.
435
-
-The prefix ´S´ of a typeselection `´S´#´T´` is always in invariant position.
436
-
-For a typeargument ´T´ of a type`´S´[´... T ...´ ]`:
437
-
If the corresponding typeparameter is invariant, then ´T´ is in invariant position.
438
-
If the corresponding typeparameter is contravariant, the variance position of ´T´ is the opposite of the variance position of the enclosing type`´S´[´... T ...´ ]`.
439
-
440
-
<!--TODO: handle typealiases-->
433
+
-The prefix ´p´ of a typeselection `´p.T´` is always in invariant position.
434
+
-For a typeargument ´T´ of a type`´S´[´..., T, ...´]`:
435
+
-If the corresponding typeparameter of ´S´ is invariant, then ´T´ is in invariant position.
436
+
-If the corresponding typeparameter of ´S´ is contravariant, the variance position of ´T´ is the opposite of the variance position of the enclosing type`´S´[´..., T, ...´]`.
441
437
442
-
References to the typeparameters in [object-privateor object-protectedvalues, types, variables, or methods](05-classes-and-objects.html#modifiers) of the classare not checked for their variance position.
438
+
References to the typeparameters in [object-private values, types, variables, or methods](05-classes-and-objects.html#modifiers) of the classare not checked for their variance position.
443
439
In these members the typeparameter may appear anywhere without restricting its legal variance annotations.
444
440
445
441
######Example
446
442
The following variance annotation is legal.
447
443
448
444
```scala
449
445
abstractclassP[+A, +B] {
450
-
deffst:A; defsnd:B
446
+
deffst:A
447
+
defsnd:B
451
448
}
452
449
```
453
450
@@ -471,14 +468,14 @@ If the mutable variables are object-private, the class definition becomes legal
471
468
472
469
```scala
473
470
abstractclassR[+A, +B](x: A, y: B) {
474
-
private[this]varfst:A= x // OK
475
-
private[this]varsnd:B= y // OK
471
+
privatevarfst:A= x // OK
472
+
privatevarsnd:B= y // OK
476
473
}
477
474
```
478
475
479
476
######Example
480
477
481
-
The following variance annotation is illegal, since ´a´ appears in contravariant position in the parameter of `append`:
478
+
The following variance annotation is illegal, since ´A´ appears in contravariant position in the parameter of `append`:
482
479
483
480
```scala
484
481
abstractclassSequence[+A] {
@@ -591,7 +588,7 @@ ParamType ::= ‘=>’ Type
591
588
```
592
589
593
590
Thetypeof a value parameter may be prefixed by `=>`, e.g. `´x´: => ´T´`.
594
-
Thetypeof such a parameter is then the parameterless method type`=> ´T´`.
591
+
Thetypeof such a parameter is then the [by-name type](./03-types.html#by-name-types) `=> ´T´`.
595
592
This indicates that the corresponding argument is not evaluated at the point of method application, but instead is evaluated at each use within the method.
596
593
That is, the argument is evaluated using _call-by-name_.
0 commit comments