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/03-types.md
+89-22Lines changed: 89 additions & 22 deletions
Original file line number
Diff line number
Diff line change
@@ -364,12 +364,64 @@ An _infix type_ ´T_1´ `op` ´T_2´ consists of an infix operator `op` which ge
364
364
The type is equivalent to the type application `op`´[T_1, T_2]´.
365
365
The infix operator `op` may be an arbitrary identifier.
366
366
367
-
All type infix operators have the same precedence; parentheses have to be used for grouping.
368
-
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.
367
+
Type operators follow the same [precedence and associativity as term operators](06-expressions.html#prefix-infix-and-postfix-operations).
368
+
For example, `A + B * C` parses as `A + (B * C)` and `A | B & C` parses as `A | (B & C)`.
369
+
Type operators ending in a colon ‘:’ are right-associative; all other operators are left-associative.
369
370
370
371
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.
371
372
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) ...)´.
372
373
374
+
The type operators `|` and `&` are not really special.
375
+
Nevertheless, unless shadowed, they resolve to `scala.|` and `scala.&`, which represent [union and intersection types](#union-and-intersection-types), respectively.
376
+
377
+
### Union and Intersection Types
378
+
379
+
Syntactically, the types `S | T` and `S & T` are infix types, where the infix operators are `|` and `&`, respectively (see above).
380
+
381
+
However, in this specification, ´S | T´ and ´S & T´ refer to the underlying core concepts of *union and intersection types*, respectively.
382
+
383
+
- The type ´S | T´ represents the set of values that are represented by *either* ´S´ or ´T´.
384
+
- The type ´S & T´ represents the set of values that are represented by *both* ´S´ and ´T´.
385
+
386
+
From the [conformance rules](#conformance) rules on union and intersection types, we can show that ´&´ and ´|´ are *commutative* and *associative*.
387
+
Moreover, `&` is distributive over `|`.
388
+
For any type ´A´, ´B´ and ´C´, all of the following relationships hold:
389
+
390
+
- ´A & B \equiv B & A´,
391
+
- ´A | B \equiv B | A´,
392
+
- ´(A & B) & C \equiv A & (B & C)´,
393
+
- ´(A | B) | C \equiv A | (B | C)´, and
394
+
- ´A & (B | C) \equiv (A & B) | (A & C)´.
395
+
396
+
If ´C´ is a type constructor, then ´C[A] & C[B]´ can be simplified using the following three rules:
397
+
398
+
- If ´C´ is covariant, ´C[A] & C[B] \equiv C[A & B]´
399
+
- If ´C´ is contravariant, ´C[A] & C[B] \equiv C[A | B]´
400
+
- If ´C´ is invariant, emit a compile error
401
+
402
+
From the above rules, we can derive the following conformance relationships:
403
+
404
+
- When ´C´ is covariant, ´C[A & B] <: C[A] & C[B]´.
405
+
- When ´C´ is contravariant, ´C[A | B] <: C[A] & C[B]´.
406
+
407
+
#### Join of a union type
408
+
409
+
In some situations, a union type might need to be widened to a non-union type.
410
+
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´.
411
+
Note that union types might still appear as type arguments in the resulting type, this guarantees that the join is always finite.
412
+
413
+
For example, given
414
+
415
+
```scala
416
+
traitC[+T]
417
+
traitD
418
+
traitE
419
+
classAextendsC[A] withD
420
+
classBextendsC[B] withDwithE
421
+
```
422
+
423
+
The join of ´A | B´ is ´C[A | B] & D´
424
+
373
425
### Function Types
374
426
375
427
```ebnf
@@ -589,6 +641,8 @@ If ´T´ is a possibly parameterized class type, where ´T´'s class is defined
589
641
1. The _member bindings_ of a type ´T´ are
590
642
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
591
643
2. all bindings of the type's [refinement](#compound-types), if it has one.
644
+
2. The member bindinds of ´S & T´ are all the binds of ´S´ *and* all the bindins of ´T´.
645
+
3. The member bindings of ´S | T´ are the member bindings of its [join](#join-of-a-union-type).
592
646
593
647
The _definition_ of a type projection `S#T` is the member binding ´d_T´ of the type `T` in `S`.
594
648
In that case, we also say that `S#T`_is defined by_ ´d_T´.
@@ -647,6 +701,10 @@ The conformance relation ´(<:)´ is the smallest transitive relation that satis
647
701
1. If ´U_i´ is a wildcard type argument of the form ´\\_ >: L_2 <: U_2´, then ´L_2 <: T_i´ and ´T_i <: U_2´.
648
702
- A compound type `´T_1´ with ... with ´T_n´ {´R\,´}` conforms to each of its component types ´T_i´.
649
703
- 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\,´}`.
704
+
- If ´T <: U´, then ´T <: U | W´ and ´T <: W | U´.
705
+
- If ´T <: W´ and ´U <: W´, then ´T | U <: W´.
706
+
- If ´T <: U´ and ´T <: W´, then ´T <: U & W´.
707
+
- If ´T <: W´, then ´T & U <: W´ and ´U & T <: W´.
650
708
- 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'´.
651
709
- 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 \}´.
652
710
- Type constructors ´T´ and ´T'´ follow a similar discipline.
@@ -667,28 +725,15 @@ A declaration or definition in some compound type of class type ´C´ _subsumes_
667
725
- 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'´.
668
726
- 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´.
669
727
670
-
671
728
#### Least upper bounds and greatest lower bounds
729
+
672
730
The ´(<:)´ relation forms pre-order between types, i.e. it is transitive and reflexive.
673
731
This allows us to define _least upper bounds_ and _greatest lower bounds_ of a set of types in terms of that order.
674
-
The least upper bound or greatest lower bound of a set of types does not always exist.
675
-
For instance, consider the class definitions:
676
-
677
-
```scala
678
-
classA[+T] {}
679
-
classBextendsA[B]
680
-
classCextendsA[C]
681
-
```
682
-
683
-
Then the types `A[Any], A[A[Any]], A[A[A[Any]]], ...` form a descending sequence of upper bounds for `B` and `C`.
684
-
The least upper bound would be the infinite limit of that sequence, which does not exist as a Scala type.
685
-
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].
686
732
687
-
The least upper bound or greatest lower bound might also not be unique.
688
-
For instance `A with B` and `B with A` are both greatest lower bounds of `A` and `B`.
689
-
If there are several least upper bounds or greatest lower bounds, the Scala compiler is free to pick any one of them.
733
+
- the _least upper bound_ of `A` and `B` is the smallest type `L` such that `A` <: `L` and `B` <: `L`.
734
+
- the _greatest lower bound_ of `A` and `B` is the largest type `G` such that `G` <: `A` and `G` <: `B`.
690
735
691
-
[^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
736
+
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`.
692
737
693
738
### Weak Conformance
694
739
@@ -766,7 +811,29 @@ The erasure mapping is defined as follows.
766
811
- The erasure of a singleton type `´p´.type` is the erasure of the type of ´p´.
767
812
- The erasure of a type projection `´T´#´x´` is `|´T´|#´x´`.
768
813
- 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´.
814
+
- The erasure of a union type ´S | T´ is the _erased least upper bound_ (_elub_) of the erasures of ´S´ and ´T´.
815
+
- The erasure of an intersection type ´S & T´ is the _eglb_ (erased greatest lower bound) of the erasures of ´S´ and ´T´.
816
+
817
+
The erased LUB is computed as follows:
818
+
819
+
- if both argument are arrays of objects, an array of the erased LUB of the element types
820
+
- if both arguments are arrays of same primitives, an array of this primitive
821
+
- 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)
822
+
- if one argument is an array, [`Object`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Object.html)
823
+
- otherwise a common superclass or trait S of the argument classes, with the following two properties:
824
+
- S is minimal: no other common superclass or trait derives from S, and
825
+
- S is last: in the linearization of the first argument type ´|A|´ there are no minimal common superclasses or traits that come after S.
826
+
The reason to pick last is that we prefer classes over traits that way, which leads to more predictable bytecode and (?) faster dynamic dispatch.
769
827
770
-
The _intersection dominator_ of a list of types ´T_1, ..., T_n´ is computed as follows.
771
-
Let ´T_{i_1}, ..., T_{i_m}´ be the subsequence of types ´T_i´ which are not supertypes of some other type ´T_j´.
772
-
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}´.
828
+
The rules for ´eglb(A, B)´ are given below in pseudocode:
Copy file name to clipboardExpand all lines: docs/_spec/08-pattern-matching.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -534,7 +534,7 @@ In the interest of efficiency the evaluation of a pattern matching expression ma
534
534
This might affect evaluation through side effects in guards.
535
535
However, it is guaranteed that a guard expression is evaluated only if the pattern it guards matches.
536
536
537
-
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.
537
+
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.
Copy file name to clipboardExpand all lines: docs/_spec/A2-scala-2-compatibility.md
+5Lines changed: 5 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -33,3 +33,8 @@ 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
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