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
@@ -325,12 +321,64 @@ An _infix type_ ´T_1´ `op` ´T_2´ consists of an infix operator `op` which ge
325
321
The type is equivalent to the type application `op`´[T_1, T_2]´.
326
322
The infix operator `op` may be an arbitrary identifier.
327
323
328
-
All type infix operators have the same precedence; parentheses have to be used for grouping.
329
-
The [associativity](06-expressions.html#prefix,-infix,-and-postfix-operations) of a type operator is determined as for term operators: type operators ending in a colon ‘:’ are right-associative; all other operators are left-associative.
324
+
Type operators follow the same [precedence and associativity as term operators](06-expressions.html#prefix-infix-and-postfix-operations).
325
+
For example, `A + B * C` parses as `A + (B * C)` and `A | B & C` parses as `A | (B & C)`.
326
+
Type operators ending in a colon ‘:’ are right-associative; all other operators are left-associative.
330
327
331
328
In a sequence of consecutive type infix operations ´t_0 \, \mathit{op} \, t_1 \, \mathit{op_2} \, ... \, \mathit{op_n} \, t_n´, all operators ´\mathit{op}\_1, ..., \mathit{op}\_n´ must have the same associativity.
332
329
If they are all left-associative, the sequence is interpreted as ´(... (t_0 \mathit{op_1} t_1) \mathit{op_2} ...) \mathit{op_n} t_n´, otherwise it is interpreted as ´t_0 \mathit{op_1} (t_1 \mathit{op_2} ( ... \mathit{op_n} t_n) ...)´.
333
330
331
+
The type operators `|` and `&` are not really special.
332
+
Nevertheless, unless shadowed, they resolve to `scala.|` and `scala.&`, which represent [union and intersection types](#union-and-intersection-types), respectively.
333
+
334
+
### Union and Intersection Types
335
+
336
+
Syntactically, the types `S | T` and `S & T` are infix types, where the infix operators are `|` and `&`, respectively (see above).
337
+
338
+
However, in this specification, ´S | T´ and ´S & T´ refer to the underlying core concepts of *union and intersection types*, respectively.
339
+
340
+
- The type ´S | T´ represents the set of values that are represented by *either* ´S´ or ´T´.
341
+
- The type ´S & T´ represents the set of values that are represented by *both* ´S´ and ´T´.
342
+
343
+
From the [conformance rules](#conformance) rules on union and intersection types, we can show that ´&´ and ´|´ are *commutative* and *associative*.
344
+
Moreover, `&` is distributive over `|`.
345
+
For any type ´A´, ´B´ and ´C´, all of the following relationships hold:
346
+
347
+
- ´A & B \equiv B & A´,
348
+
- ´A | B \equiv B | A´,
349
+
- ´(A & B) & C \equiv A & (B & C)´,
350
+
- ´(A | B) | C \equiv A | (B | C)´, and
351
+
- ´A & (B | C) \equiv (A & B) | (A & C)´.
352
+
353
+
If ´C´ is a type constructor, then ´C[A] & C[B]´ can be simplified using the following three rules:
354
+
355
+
- If ´C´ is covariant, ´C[A] & C[B] \equiv C[A & B]´
356
+
- If ´C´ is contravariant, ´C[A] & C[B] \equiv C[A | B]´
357
+
- If ´C´ is invariant, emit a compile error
358
+
359
+
From the above rules, we can derive the following conformance relationships:
360
+
361
+
- When ´C´ is covariant, ´C[A & B] <: C[A] & C[B]´.
362
+
- When ´C´ is contravariant, ´C[A | B] <: C[A] & C[B]´.
363
+
364
+
#### Join of a union type
365
+
366
+
In some situations, a union type might need to be widened to a non-union type.
367
+
For this purpose, we define the _join_ of a union type ´T_1 | ... | T_n´ as the smallest intersection type of base class instances of ´T_1, ..., T_n´.
368
+
Note that union types might still appear as type arguments in the resulting type, this guarantees that the join is always finite.
369
+
370
+
For example, given
371
+
372
+
```scala
373
+
traitC[+T]
374
+
traitD
375
+
traitE
376
+
classAextendsC[A] withD
377
+
classBextendsC[B] withDwithE
378
+
```
379
+
380
+
The join of ´A | B´ is ´C[A | B] & D´
381
+
334
382
### Function Types
335
383
336
384
```ebnf
@@ -574,6 +622,8 @@ If ´T´ is a possibly parameterized class type, where ´T´'s class is defined
574
622
1. The _member bindings_ of a type ´T´ are
575
623
1. all bindings ´d´ such that there exists a type instance of some class ´C´ among the base types of ´T´ and there exists a definition or declaration ´d'´ in ´C´ such that ´d´ results from ´d'´ by replacing every type ´T'´ in ´d'´ by ´T'´ in ´C´ seen from ´T´, and
576
624
2. all bindings of the type's [refinement](#compound-types), if it has one.
625
+
2. The member bindinds of ´S & T´ are all the binds of ´S´ *and* all the bindins of ´T´.
626
+
3. The member bindings of ´S | T´ are the member bindings of its [join](#join-of-a-union-type).
577
627
578
628
The _definition_ of a type projection `S#T` is the member binding ´d_T´ of the type `T` in `S`.
579
629
In that case, we also say that `S#T`_is defined by_ ´d_T´.
@@ -630,6 +680,10 @@ The conformance relation ´(<:)´ is the smallest transitive relation that satis
630
680
1. If the ´i´'th type parameter of ´T´ is declared neither covariant nor contravariant, then ´U_i \equiv T_i´.
631
681
- A compound type `´T_1´ with ... with ´T_n´ {´R\,´}` conforms to each of its component types ´T_i´.
632
682
- If ´T <: U_i´ for ´i \in \{ 1, ..., n \}´ and for every binding ´d´ of a type or value ´x´ in ´R´ there exists a member binding of ´x´ in ´T´ which subsumes ´d´, then ´T´ conforms to the compound type `´U_1´ with ... with ´U_n´ {´R\,´}`.
683
+
- If ´T <: U´, then ´T <: U | W´ and ´T <: W | U´.
684
+
- If ´T <: W´ and ´U <: W´, then ´T | U <: W´.
685
+
- If ´T <: U´ and ´T <: W´, then ´T <: U & W´.
686
+
- If ´T <: W´, then ´T & U <: W´ and ´U & T <: W´.
633
687
- If ´T_i \equiv T_i'´ for ´i \in \{ 1, ..., n\}´ and ´U´ conforms to ´U'´ then the method type ´(p_1:T_1, ..., p_n:T_n) U´ conforms to ´(p_1':T_1', ..., p_n':T_n') U'´.
634
688
- The polymorphic type ´[a_1 >: L_1 <: U_1, ..., a_n >: L_n <: U_n] T´ conforms to the polymorphic type ´[a_1 >: L_1' <: U_1', ..., a_n >: L_n' <: U_n'] T'´ if, assuming ´L_1' <: a_1 <: U_1', ..., L_n' <: a_n <: U_n'´ one has ´T <: T'´ and ´L_i <: L_i'´ and ´U_i' <: U_i´ for ´i \in \{ 1, ..., n \}´.
635
689
- Type constructors ´T´ and ´T'´ follow a similar discipline.
@@ -648,28 +702,15 @@ A declaration or definition in some compound type of class type ´C´ _subsumes_
648
702
- A type declaration `type ´t´[´T_1´, ..., ´T_n´] >: ´L´ <: ´U´` subsumes a type declaration `type ´t´[´T_1´, ..., ´T_n´] >: ´L'´ <: ´U'´` if ´L' <: L´ and ´U <: U'´.
649
703
- A type or class definition that binds a type name ´t´ subsumes an abstract type declaration `type t[´T_1´, ..., ´T_n´] >: L <: U` if ´L <: t <: U´.
650
704
651
-
652
705
#### Least upper bounds and greatest lower bounds
706
+
653
707
The ´(<:)´ relation forms pre-order between types, i.e. it is transitive and reflexive.
654
708
This allows us to define _least upper bounds_ and _greatest lower bounds_ of a set of types in terms of that order.
655
-
The least upper bound or greatest lower bound of a set of types does not always exist.
656
-
For instance, consider the class definitions:
657
-
658
-
```scala
659
-
classA[+T] {}
660
-
classBextendsA[B]
661
-
classCextendsA[C]
662
-
```
663
-
664
-
Then the types `A[Any], A[A[Any]], A[A[A[Any]]], ...` form a descending sequence of upper bounds for `B` and `C`.
665
-
The least upper bound would be the infinite limit of that sequence, which does not exist as a Scala type.
666
-
Since cases like this are in general impossible to detect, a Scala compiler is free to reject a term which has a type specified as a least upper or greatest lower bound, and that bound would be more complex than some compiler-set limit [^4].
667
709
668
-
The least upper bound or greatest lower bound might also not be unique.
669
-
For instance `A with B` and `B with A` are both greatest lower bounds of `A` and `B`.
670
-
If there are several least upper bounds or greatest lower bounds, the Scala compiler is free to pick any one of them.
710
+
- the _least upper bound_ of `A` and `B` is the smallest type `L` such that `A` <: `L` and `B` <: `L`.
711
+
- the _greatest lower bound_ of `A` and `B` is the largest type `G` such that `G` <: `A` and `G` <: `B`.
671
712
672
-
[^4]: The current Scala compiler limits the nesting level of parameterization in such bounds to be at most two deeper than the maximum nesting level of the operand types
713
+
By construction, for all types `A` and `B`, the least upper bound of `A` and `B` is `A | B`, and their greatest lower bound is `A & B`.
673
714
674
715
### Weak Conformance
675
716
@@ -747,7 +788,29 @@ The erasure mapping is defined as follows.
747
788
- The erasure of a singleton type `´p´.type` is the erasure of the type of ´p´.
748
789
- The erasure of a type projection `´T´#´x´` is `|´T´|#´x´`.
749
790
- The erasure of a compound type `´T_1´ with ... with ´T_n´ {´R\,´}` is the erasure of the intersection dominator of ´T_1, ..., T_n´.
791
+
- The erasure of a union type ´S | T´ is the _erased least upper bound_ (_elub_) of the erasures of ´S´ and ´T´.
792
+
- The erasure of an intersection type ´S & T´ is the _eglb_ (erased greatest lower bound) of the erasures of ´S´ and ´T´.
793
+
794
+
The erased LUB is computed as follows:
795
+
796
+
- if both argument are arrays of objects, an array of the erased LUB of the element types
797
+
- if both arguments are arrays of same primitives, an array of this primitive
798
+
- if one argument is array of primitives and the other is array of objects, [`Object`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Object.html)
799
+
- if one argument is an array, [`Object`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Object.html)
800
+
- otherwise a common superclass or trait S of the argument classes, with the following two properties:
801
+
- S is minimal: no other common superclass or trait derives from S, and
802
+
- S is last: in the linearization of the first argument type ´|A|´ there are no minimal common superclasses or traits that come after S.
803
+
The reason to pick last is that we prefer classes over traits that way, which leads to more predictable bytecode and (?) faster dynamic dispatch.
750
804
751
-
The _intersection dominator_ of a list of types ´T_1, ..., T_n´ is computed as follows.
752
-
Let ´T_{i_1}, ..., T_{i_m}´ be the subsequence of types ´T_i´ which are not supertypes of some other type ´T_j´.
753
-
If this subsequence contains a type designator ´T_c´ that refers to a class which is not a trait, the intersection dominator is ´T_c´. Otherwise, the intersection dominator is the first element of the subsequence, ´T_{i_1}´.
805
+
The rules for ´eglb(A, B)´ are given below in pseudocode:
@@ -503,7 +503,7 @@ Each case consists of a (possibly guarded) pattern ´p_i´ and a block ´b_i´.
503
503
Each ´p_i´ might be complemented by a guard `if ´e´` where ´e´ is a boolean expression.
504
504
The scope of the pattern variables in ´p_i´ comprises the pattern's guard and the corresponding block ´b_i´.
505
505
506
-
Let ´T´ be the type of the selector expression ´e´ and let ´a_1, ..., a_m´ be the type parameters of all methods enclosing the pattern matching expression.
506
+
Let ´T´ be the type of the selector expression ´e´ and let ´a_1, ..., a_m´ be the type parameters of all methods enclosing the pattern matching expression.
507
507
For every ´a_i´, let ´L_i´ be its lower bound and ´U_i´ be its higher bound.
508
508
Every pattern ´p \in \{p_1,, ..., p_n\}´ can be typed in two ways.
509
509
First, it is attempted to type ´p´ with ´T´ as its expected type.
@@ -537,7 +537,7 @@ In the interest of efficiency the evaluation of a pattern matching expression ma
537
537
This might affect evaluation through side effects in guards.
538
538
However, it is guaranteed that a guard expression is evaluated only if the pattern it guards matches.
539
539
540
-
If the selector of a pattern match is an instance of a [`sealed` class](05-classes-and-objects.html#modifiers), the compilation of pattern matching can emit warnings which diagnose that a given set of patterns is not exhaustive, i.e. that there is a possibility of a `MatchError` being raised at run-time.
540
+
If the selector of a pattern match is an instance of a [`sealed` class](05-classes-and-objects.html#modifiers), a [union type](03-types#union-and-intersection-types), or a combination thereof, the compilation of pattern matching can emit warnings which diagnose that a given set of patterns is not exhaustive, i.e. that there is a possibility of a `MatchError` being raised at run-time.
541
541
542
542
###### Example
543
543
@@ -569,7 +569,7 @@ def eval[T](t: Term[T]): T = t match {
569
569
570
570
Note that the evaluator makes crucial use of the fact that type parameters of enclosing methods can acquire new bounds through pattern matching.
571
571
572
-
For instance, the type of the pattern in the second case, `Succ(u)`, is `Int`.
572
+
For instance, the type of the pattern in the second case, `Succ(u)`, is `Int`.
573
573
It conforms to the selector type `T` only if we assume an upper and lower bound of `Int` for `T`.
574
574
Under the assumption `Int <: T <: Int` we can also verify that the type right hand side of the second case, `Int` conforms to its expected type, `T`.
Copy file name to clipboardExpand all lines: docs/_spec/A2-scala-2-compatibility.md
+6-1Lines changed: 6 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -32,4 +32,9 @@ def f(): Unit = { ... }
32
32
Scala 3 accepts the old syntax under the `-source:3.0-migration` option.
33
33
If the `-migration` option is set, it can even rewrite old syntax to new.
34
34
The [Scalafix](https://scalacenter.github.io/scalafix/) tool also
35
-
can rewrite procedure syntax to make it Scala 3 compatible.
35
+
can rewrite procedure syntax to make it Scala 3 compatible.
36
+
37
+
## Compound Types (`with`)
38
+
39
+
Intersection types `A & B` replace compound types `A with B` in Scala 2.
40
+
For the moment, the syntax `A with B` is still allowed and interpreted as `A & B`, but its usage as a type (as opposed to in a `new` or `extends` clause) will be deprecated and removed in the future.
0 commit comments