From 72cef2808a8819f53556bde2c9af9e7aff5afb56 Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Wed, 11 Mar 2020 06:54:03 +0100 Subject: [PATCH 01/16] doc(adt): link to enum --- docs/docs/reference/enums/adts.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/docs/reference/enums/adts.md b/docs/docs/reference/enums/adts.md index 4400b03f2255..8e05280384b4 100644 --- a/docs/docs/reference/enums/adts.md +++ b/docs/docs/reference/enums/adts.md @@ -3,8 +3,8 @@ layout: doc-page title: "Algebraic Data Types" --- -The `enum` concept is general enough to also support algebraic data -types (ADTs) and their generalized version (GADTs). Here's an example +The [`enum` concept](./enums.html) is general enough to also support algebraic data +types (ADTs) and their generalized version (GADTs). Here is an example how an `Option` type can be represented as an ADT: ```scala @@ -34,7 +34,7 @@ Note that the parent type of the `None` value is inferred as `Option[Nothing]`. Generally, all covariant type parameters of the enum class are minimized in a compiler-generated extends clause whereas all contravariant type parameters are maximized. If `Option` was non-variant, -you'd need to give the extends clause of `None` explicitly. +you would need to give the extends clause of `None` explicitly. As for normal enum values, the cases of an `enum` are all defined in the `enum`s companion object. So it's `Option.Some` and `Option.None` From a851af0eba47e71103e46792c92b4d079608cb06 Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Wed, 11 Mar 2020 06:46:21 +0100 Subject: [PATCH 02/16] doc(enum): typo --- docs/docs/reference/enums/enums.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/docs/reference/enums/enums.md b/docs/docs/reference/enums/enums.md index b390efcb01ba..c56f733ab5b9 100644 --- a/docs/docs/reference/enums/enums.md +++ b/docs/docs/reference/enums/enums.md @@ -95,9 +95,10 @@ If you want to use the Scala-defined enums as Java enums, you can do so by exten enum Color extends java.lang.Enum[Color] { case Red, Green, Blue } ``` -The type parameter comes from the Java enum [definition](https://docs.oracle.com/javase/8/docs/api/index.html?java/lang/Enum.html) and should be the same as the type of the enum. There is no need to provide constructor arguments (as defined in the API docs) to `java.lang.Enum` when extending it – the compiler will generate them automatically. +The type parameter comes from the Java enum [definition](https://docs.oracle.com/javase/8/docs/api/index.html?java/lang/Enum.html) and should be the same as the type of the enum. +There is no need to provide constructor arguments (as defined in the Java API docs) to `java.lang.Enum` when extending it – the compiler will generate them automatically. -After defining `Color` like that, you can use like you would a Java enum: +After defining `Color` like that, you can use it like you would a Java enum: ```scala scala> Color.Red.compareTo(Color.Green) From d72417dce28b012ad8b09b91a8d48189bb7941cd Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Sun, 8 Mar 2020 21:18:05 +0100 Subject: [PATCH 03/16] doc(dependent-fun): typo --- docs/docs/reference/new-types/dependent-function-types-spec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/reference/new-types/dependent-function-types-spec.md b/docs/docs/reference/new-types/dependent-function-types-spec.md index 555244539599..7b07b8631a97 100644 --- a/docs/docs/reference/new-types/dependent-function-types-spec.md +++ b/docs/docs/reference/new-types/dependent-function-types-spec.md @@ -31,7 +31,7 @@ FunctionN[K1, ..., Kn, R'] { ``` where the result type parameter `R'` is the least upper approximation of the -precise result type `R` without any referance to value parameters `x1, ..., xN`. +precise result type `R` without any reference to value parameters `x1, ..., xN`. The syntax and sementics of anonymous dependent functions is identical to the one of regular functions. Eta expansion is naturally generalized to produce From 8d98f963b09408d8d25ebbda2443b83b6c5d022f Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Sat, 7 Mar 2020 07:52:53 +0100 Subject: [PATCH 04/16] doc(match-type): fix type lambda syntax --- docs/docs/reference/new-types/match-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/reference/new-types/match-types.md b/docs/docs/reference/new-types/match-types.md index 980b85b58205..35a0b08da32f 100644 --- a/docs/docs/reference/new-types/match-types.md +++ b/docs/docs/reference/new-types/match-types.md @@ -54,7 +54,7 @@ S match { P1 => T1 ... Pn => Tn } ``` is `Match(S, C1, ..., Cn) <: B` where each case `Ci` is of the form ``` -[Xs] => P => T +[Xs] =>> P => T ``` Here, `[Xs]` is a type parameter clause of the variables bound in pattern `Pi`. If there are no bound type variables in a case, the type parameter clause is omitted and only the function type `P => T` is kept. So each case is either a unary function type or a type lambda over a unary function type. From 13872b873bf8f9b863a2c4e469f6bcf4b37091c1 Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Sat, 7 Mar 2020 08:12:28 +0100 Subject: [PATCH 05/16] doc(match-type): 2nd fix type lambda syntax --- docs/docs/reference/new-types/match-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/reference/new-types/match-types.md b/docs/docs/reference/new-types/match-types.md index 35a0b08da32f..d22c373d8d2f 100644 --- a/docs/docs/reference/new-types/match-types.md +++ b/docs/docs/reference/new-types/match-types.md @@ -68,7 +68,7 @@ We define match type reduction in terms of an auxiliary relation, `can-reduce`: ``` Match(S, C1, ..., Cn) can-reduce i, T' ``` -if `Ci = [Xs] => P => T` and there are minimal instantiations `Is` of the type variables `Xs` such that +if `Ci = [Xs] =>> P => T` and there are minimal instantiations `Is` of the type variables `Xs` such that ``` S <: [Xs := Is] P T' = [Xs := Is] T From 01cb780671e2d564d3bdc53a54d5aca3e09c65d2 Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Sat, 7 Mar 2020 07:52:11 +0100 Subject: [PATCH 06/16] doc(match-type): fix type lambda syntax --- docs/docs/reference/new-types/match-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/reference/new-types/match-types.md b/docs/docs/reference/new-types/match-types.md index 980b85b58205..35a0b08da32f 100644 --- a/docs/docs/reference/new-types/match-types.md +++ b/docs/docs/reference/new-types/match-types.md @@ -54,7 +54,7 @@ S match { P1 => T1 ... Pn => Tn } ``` is `Match(S, C1, ..., Cn) <: B` where each case `Ci` is of the form ``` -[Xs] => P => T +[Xs] =>> P => T ``` Here, `[Xs]` is a type parameter clause of the variables bound in pattern `Pi`. If there are no bound type variables in a case, the type parameter clause is omitted and only the function type `P => T` is kept. So each case is either a unary function type or a type lambda over a unary function type. From 57121cf2af53fe00e9b1e5dc6ac1f1176c732bea Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Fri, 6 Mar 2020 23:39:00 +0100 Subject: [PATCH 07/16] doc(type-lambda): use U instead of H for upper bound --- docs/docs/reference/new-types/type-lambdas-spec.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/reference/new-types/type-lambdas-spec.md b/docs/docs/reference/new-types/type-lambdas-spec.md index 78ce94ee6356..1e0a49ae5f5c 100644 --- a/docs/docs/reference/new-types/type-lambdas-spec.md +++ b/docs/docs/reference/new-types/type-lambdas-spec.md @@ -15,8 +15,8 @@ TypeBounds ::= [‘>:’ Type] [‘<:’ Type] ### Type Checking A type lambda such as `[X] =>> F[X]` defines a function from types to types. The parameter(s) may carry bounds and variance annotations. -If a parameter is bounded, as in `[X >: L <: H] =>> F[X]` it is checked that arguments to the parameters conform to the bounds `L` and `H`. -Only the upper bound `H` can be F-bounded, i.e. `X` can appear in it. +If a parameter is bounded, as in `[X >: L <: U] =>> F[X]` it is checked that arguments to the parameters conform to the bounds `L` and `U`. +Only the upper bound `U` can be F-bounded, i.e. `X` can appear in it. ## Subtyping Rules From ba8a518eb8f60837322d787d881df00a5f7ad71f Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Sat, 7 Mar 2020 07:37:54 +0100 Subject: [PATCH 08/16] doc(type-lambdas): variance is not supported --- docs/docs/reference/new-types/type-lambdas-spec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/reference/new-types/type-lambdas-spec.md b/docs/docs/reference/new-types/type-lambdas-spec.md index 1e0a49ae5f5c..4717710b5db0 100644 --- a/docs/docs/reference/new-types/type-lambdas-spec.md +++ b/docs/docs/reference/new-types/type-lambdas-spec.md @@ -14,7 +14,7 @@ TypeBounds ::= [‘>:’ Type] [‘<:’ Type] ### Type Checking -A type lambda such as `[X] =>> F[X]` defines a function from types to types. The parameter(s) may carry bounds and variance annotations. +A type lambda such as `[X] =>> F[X]` defines a function from types to types. The parameter(s) may carry bounds. If a parameter is bounded, as in `[X >: L <: U] =>> F[X]` it is checked that arguments to the parameters conform to the bounds `L` and `U`. Only the upper bound `U` can be F-bounded, i.e. `X` can appear in it. From 303353e635b872f0a46283a0a627c72b3f9c80b4 Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Sat, 7 Mar 2020 07:46:16 +0100 Subject: [PATCH 09/16] doc(type-lambda): typos --- docs/docs/reference/new-types/type-lambdas-spec.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/reference/new-types/type-lambdas-spec.md b/docs/docs/reference/new-types/type-lambdas-spec.md index 4717710b5db0..58f57568e738 100644 --- a/docs/docs/reference/new-types/type-lambdas-spec.md +++ b/docs/docs/reference/new-types/type-lambdas-spec.md @@ -31,7 +31,7 @@ Then `TL1 <: TL2`, if `L1 <: L2` and `U2 <: U1`), - `R1 <: R2` -Here we have relied on alpha renaming to bring match the two bound types `X`. +Here we have relied on alpha renaming to match the two bound types `X`. A partially applied type constructor such as `List` is assumed to be equivalent to its eta expansion. I.e, `List = [X] =>> List[X]`. This allows type constructors to be compared with type lambdas. @@ -46,7 +46,7 @@ is regarded as a shorthand for an unparameterized definition with a type lambda ```scala type T = [X] =>> R ``` -If the a type definition carries `+` or `-` variance annotations, +If the type definition carries `+` or `-` variance annotations, it is checked that the variance annotations are satisfied by the type lambda. For instance, ```scala From b7616ae152a198d652407c195e2111ef7b24c663 Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Fri, 6 Mar 2020 23:23:27 +0100 Subject: [PATCH 10/16] doc(type-lamba): remove superfluous `construct` --- docs/docs/reference/new-types/type-lambdas.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/docs/reference/new-types/type-lambdas.md b/docs/docs/reference/new-types/type-lambdas.md index 9881f4c71e80..a10510287beb 100644 --- a/docs/docs/reference/new-types/type-lambdas.md +++ b/docs/docs/reference/new-types/type-lambdas.md @@ -10,9 +10,7 @@ a type definition. [X, Y] =>> Map[Y, X] ``` -For instance, the type above defines a binary type constructor, which -constructor maps arguments `X` and `Y` to `Map[Y, X]`. Type parameters -of type lambdas can have bounds but they cannot carry `+` or `-` variance -annotations. +For instance, the type above defines a binary type constructor, which maps arguments `X` and `Y` to `Map[Y, X]`. +Type parameters of type lambdas can have bounds but they cannot carry `+` or `-` variance annotations. [More details](./type-lambdas-spec.md) From 00a3987d02dd75098e4ee065a37d17099292a569 Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Fri, 6 Mar 2020 19:56:16 +0100 Subject: [PATCH 11/16] doc(givens): mention thread safety --- docs/docs/reference/contextual/givens.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/docs/reference/contextual/givens.md b/docs/docs/reference/contextual/givens.md index 072f3cb4a800..732d6d83d90c 100644 --- a/docs/docs/reference/contextual/givens.md +++ b/docs/docs/reference/contextual/givens.md @@ -34,8 +34,8 @@ a given for the type `Ord[Int]` whereas `listOrd[T]` defines givens for `Ord[List[T]]` for all types `T` that come with a given instance for `Ord[T]` themselves. The `using` clause in `listOrd` defines a condition: There must be a given of type `Ord[T]` for a given of type `List[Ord[T]]` to exist. -Such conditions are expanded by the compiler to context -parameters, which are explained in the [next section](./using-clauses.html). +Such conditions are expanded by the compiler to [context +parameters](./using-clauses.html). ## Anonymous Givens @@ -57,14 +57,16 @@ given global as ExecutionContext = new ForkJoinPool() This creates a given `global` of type `ExecutionContext` that resolves to the right hand side `new ForkJoinPool()`. The first time `global` is accessed, a new `ForkJoinPool` is created, which is then -returned for this and all subsequent accesses to `global`. +returned for this and all subsequent accesses to `global`. This operation is thread-safe. -Alias givens can be anonymous, e.g. +Alias givens can be anonymous as well, e.g. ```scala given Position = enclosingTree.position given (using outer: Context) as Context = outer.withOwner(currentOwner) ``` -An alias given can have type parameters and implicit parameters just like any other given, + + +An alias given can have type parameters and context parameters just like any other given, but it can only implement a single type. ## Given Whitebox Macro Instances From ac85b8bd403652c1cfb5edff82a115630e0d0f29 Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Fri, 6 Mar 2020 22:16:18 +0100 Subject: [PATCH 12/16] doc(opaques-details): typo --- docs/docs/reference/other-new-features/opaques-details.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/reference/other-new-features/opaques-details.md b/docs/docs/reference/other-new-features/opaques-details.md index 9fab5c81b04f..2b0d9707e84a 100644 --- a/docs/docs/reference/other-new-features/opaques-details.md +++ b/docs/docs/reference/other-new-features/opaques-details.md @@ -25,7 +25,7 @@ where the lower bound `L` and the upper bound `U` may be missing, in which case Inside the scope of the alias definition, the alias is transparent: `T` is treated as a normal alias of `R`. Outside its scope, the alias is treated as the abstract type ```scala -type T >: L <: U` +type T >: L <: U ``` A special case arises if the opaque type is defined in an object. Example: ``` From 870173c2311da2b099b37c2f023259d3a3a326fa Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Mon, 2 Mar 2020 12:06:42 +0100 Subject: [PATCH 13/16] doc(opaque type alias): revise text, remove workaround --- .../reference/other-new-features/opaques.md | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/docs/docs/reference/other-new-features/opaques.md b/docs/docs/reference/other-new-features/opaques.md index 7451e95b3a1e..336374b97389 100644 --- a/docs/docs/reference/other-new-features/opaques.md +++ b/docs/docs/reference/other-new-features/opaques.md @@ -12,7 +12,8 @@ object Logarithms { object Logarithm { - // These are the ways to lift to the logarithm type + // These are the two ways to lift to the Logarithm type + def apply(d: Double): Logarithm = math.log(d) def safe(d: Double): Option[Logarithm] = @@ -28,19 +29,22 @@ object Logarithms { } ``` -This introduces `Logarithm` as a new type, which is implemented as `Double` but is different from it. The fact that `Logarithm` is the same as `Double` is only known in the scope where -`Logarithm` is defined which in this case is object `Logarithms`. - -The public API of `Logarithm` consists of the `apply` and `safe` methods that convert from doubles to `Logarithm` values, an extension method `toDouble` that converts the other way, -and operations `+` and `*` on logarithm values. The implementations of these functions -type-check because within object `Logarithms`, the type `Logarithm` is just an alias of `Double`. +This introduces `Logarithm` as a new abstract type, which is implemented as `Double`. +The fact that `Logarithm` is the same as `Double` is only known in the scope where +`Logarithm` is defined which in the above example corresponds to the object `Logarithms`. +Or in other words, within the scope it is treated as type alias, but this is opaque to the outside world +where in consequence `Logarithm` is treated as own type and has nothing to do with `Double`. -Outside its scope, `Logarithm` is treated as a new abstract type. So the -following operations would be valid because they use functionality implemented in the `Logarithm` object. +The public API of `Logarithm` consists of the `apply` and `safe` methods defined in the companion object. +They convert from `Double`s to `Logarithm` values. Moreover, a collective extension `logarithmOps` provides the extension methods `toDouble` that converts the other way, +and operations `+` and `*` on `Logarithm` values. +As a reminder, the implementations of these functions +type-check because within the object `Logarithms`, the type `Logarithm` is just a type alias of `Double`. +Outside of its scope, `Logarithm` is treated as a new abstract type. So the +following operations would be valid because they use functionality implemented in the `Logarithms` object. ```scala -import Logarithms._ -import Predef.{any2stringadd => _, _} +import Logarithms.Logarithm val l = Logarithm(1.0) val l2 = Logarithm(2.0) @@ -54,11 +58,9 @@ But the following operations would lead to type errors: val d: Double = l // error: found: Logarithm, required: Double val l2: Logarithm = 1.0 // error: found: Double, required: Logarithm l * 2 // error: found: Int(2), required: Logarithm -l / l2 // error: `/` is not a member fo Logarithm +l / l2 // error: `/` is not a member of Logarithm ``` -Aside: the `any2stringadd => _` import suppression is necessary since otherwise the universal `+` operation in `Predef` would take precedence over the `+` extension method in `logarithmOps`. We plan to resolve this wart by eliminating `any2stringadd`. - ### Bounds For Opaque Type Aliases Opaque type aliases can also come with bounds. Example: @@ -81,7 +83,7 @@ object Access { val ReadOrWrite: PermissionChoice = Read | Write } ``` -The `Access` object defines three opaque types: +The `Access` object defines three opaque type aliases: - `Permission`, representing a single permission, - `Permissions`, representing a set of permissions with the meaning "all of these permissions granted", @@ -98,7 +100,7 @@ Because of that, the `|` extension method in `Access` does not cause infinite re Also, the definition of `ReadWrite` must use `|`, even though an equivalent definition outside `Access` would use `&`. -All three opaque types have the same underlying representation type `Int`. The +All three opaque type aliases have the same underlying representation type `Int`. The `Permission` type has an upper bound `Permissions & PermissionChoice`. This makes it known outside the `Access` object that `Permission` is a subtype of the other two types. Hence, the following usage scenario type-checks. From 6bc8d00dc4e1573b732e2d39bc9b71b8a0a797e9 Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Thu, 12 Mar 2020 07:45:35 +0100 Subject: [PATCH 14/16] doc(opaque): remove reminder --- docs/docs/reference/other-new-features/opaques.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/docs/docs/reference/other-new-features/opaques.md b/docs/docs/reference/other-new-features/opaques.md index 336374b97389..0c3c28d90dfb 100644 --- a/docs/docs/reference/other-new-features/opaques.md +++ b/docs/docs/reference/other-new-features/opaques.md @@ -38,10 +38,7 @@ where in consequence `Logarithm` is treated as own type and has nothing to do wi The public API of `Logarithm` consists of the `apply` and `safe` methods defined in the companion object. They convert from `Double`s to `Logarithm` values. Moreover, a collective extension `logarithmOps` provides the extension methods `toDouble` that converts the other way, and operations `+` and `*` on `Logarithm` values. -As a reminder, the implementations of these functions -type-check because within the object `Logarithms`, the type `Logarithm` is just a type alias of `Double`. -Outside of its scope, `Logarithm` is treated as a new abstract type. So the -following operations would be valid because they use functionality implemented in the `Logarithms` object. +The following operations would be valid because they use functionality implemented in the `Logarithms` object. ```scala import Logarithms.Logarithm From 97bc111e436dab5841156b6886a27ba77e7a7f5d Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Thu, 12 Mar 2020 07:50:35 +0100 Subject: [PATCH 15/16] doc(givens): change given with using example --- docs/docs/reference/contextual/givens.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/docs/reference/contextual/givens.md b/docs/docs/reference/contextual/givens.md index 732d6d83d90c..909b6e925ec8 100644 --- a/docs/docs/reference/contextual/givens.md +++ b/docs/docs/reference/contextual/givens.md @@ -62,9 +62,8 @@ returned for this and all subsequent accesses to `global`. This operation is thr Alias givens can be anonymous as well, e.g. ```scala given Position = enclosingTree.position -given (using outer: Context) as Context = outer.withOwner(currentOwner) +given (using config: Config) as Factory = MemoizingFactory(config) ``` - An alias given can have type parameters and context parameters just like any other given, but it can only implement a single type. From 1582216ef64b22290f7ae18fc517d5629d9eefb1 Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Thu, 12 Mar 2020 10:59:44 +0100 Subject: [PATCH 16/16] doc(opaque): replace `own type` with `abstract type` --- docs/docs/reference/other-new-features/opaques.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/reference/other-new-features/opaques.md b/docs/docs/reference/other-new-features/opaques.md index 0c3c28d90dfb..69ab27ca367f 100644 --- a/docs/docs/reference/other-new-features/opaques.md +++ b/docs/docs/reference/other-new-features/opaques.md @@ -33,7 +33,7 @@ This introduces `Logarithm` as a new abstract type, which is implemented as `Dou The fact that `Logarithm` is the same as `Double` is only known in the scope where `Logarithm` is defined which in the above example corresponds to the object `Logarithms`. Or in other words, within the scope it is treated as type alias, but this is opaque to the outside world -where in consequence `Logarithm` is treated as own type and has nothing to do with `Double`. +where in consequence `Logarithm` is seen as an abstract type and has nothing to do with `Double`. The public API of `Logarithm` consists of the `apply` and `safe` methods defined in the companion object. They convert from `Double`s to `Logarithm` values. Moreover, a collective extension `logarithmOps` provides the extension methods `toDouble` that converts the other way,