From 78c4da65b880d2511aa1cb1e61f01b937b336445 Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Wed, 11 Mar 2020 17:48:53 +0100 Subject: [PATCH 01/20] doc(desugar-enum): fix listing --- docs/docs/reference/enums/desugarEnums.md | 33 ++++++++++++----------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/docs/docs/reference/enums/desugarEnums.md b/docs/docs/reference/enums/desugarEnums.md index b8826717907e..21a45ea3117d 100644 --- a/docs/docs/reference/enums/desugarEnums.md +++ b/docs/docs/reference/enums/desugarEnums.md @@ -30,22 +30,23 @@ There are nine desugaring rules. Rule (1) desugar enum definitions. Rules are missing them. Rules (7) to (9) define how such cases with extends clauses map into case classes or vals. -1. An `enum` definition - ```scala - enum E ... { } - ``` - expands to a `sealed` `abstract` class that extends the `scala.Enum` trait and - an associated companion object that contains the defined cases, expanded according - to rules (2 - 8). The enum trait starts with a compiler-generated import that imports - the names `` of all cases so that they can be used without prefix in the trait. - ```scala - sealed abstract class E ... extends with scala.Enum { - import E.{ } +1. An `enum` definition + ```scala + enum E ... { } + ``` + expands to a `sealed` `abstract` class that extends the `scala.Enum` trait and + an associated companion object that contains the defined cases, expanded according + to rules (2 - 8). The enum trait starts with a compiler-generated import that imports + the names `` of all cases so that they can be used without prefix in the trait. + ```scala + sealed abstract class E ... extends with scala.Enum { + import E.{ } - } - object E { } - ``` -2. A simple case consisting of a comma-separated list of enum names + } + object E { } + ``` + +2. A simple case consisting of a comma-separated list of enum names ```scala case C_1, ..., C_n ``` @@ -201,4 +202,4 @@ Cases such as `case C` expand to a `@static val` as opposed to a `val`. This all explicitly declared in it. - If an enum case has an extends clause, the enum class must be one of the - classes that's extended. \ No newline at end of file + classes that's extended. From 502bae2aca23cd523318a431c06d7009f8f78f4d Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Wed, 11 Mar 2020 18:20:15 +0100 Subject: [PATCH 02/20] doc(enum-desugar): fix lower bound an invariance --- docs/docs/reference/enums/desugarEnums.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/docs/reference/enums/desugarEnums.md b/docs/docs/reference/enums/desugarEnums.md index 21a45ea3117d..7ab1460c44ef 100644 --- a/docs/docs/reference/enums/desugarEnums.md +++ b/docs/docs/reference/enums/desugarEnums.md @@ -19,22 +19,22 @@ some terminology and notational conventions: - _Class cases_ are those cases that are parameterized, either with a type parameter section `[...]` or with one or more (possibly empty) parameter sections `(...)`. - _Simple cases_ are cases of a non-generic enum that have neither parameters nor an extends clause or body. That is, they consist of a name only. - - _Value cases_ are all cases that do not have a parameter section but that do have a (possibly generated) extends clause and/or a body. + - _Value cases_ are all cases that do not have a parameter section but that do have a (possibly generated) `extends` clause and/or a body. Simple cases and value cases are collectively called _singleton cases_. The desugaring rules imply that class cases are mapped to case classes, and singleton cases are mapped to `val` definitions. There are nine desugaring rules. Rule (1) desugar enum definitions. Rules -(2) and (3) desugar simple cases. Rules (4) to (6) define extends clauses for cases that -are missing them. Rules (7) to (9) define how such cases with extends clauses -map into case classes or vals. +(2) and (3) desugar simple cases. Rules (4) to (6) define `extends` clauses for cases that +are missing them. Rules (7) to (9) define how such cases with `extends` clauses +map into `case class`es or `val`s. 1. An `enum` definition ```scala enum E ... { } ``` - expands to a `sealed` `abstract` class that extends the `scala.Enum` trait and + expands to a `sealed abstract` class that extends the `scala.Enum` trait and an associated companion object that contains the defined cases, expanded according to rules (2 - 8). The enum trait starts with a compiler-generated import that imports the names `` of all cases so that they can be used without prefix in the trait. @@ -70,7 +70,7 @@ map into case classes or vals. 4. If `E` is an enum with type parameters ```scala - V1 T1 > L1 <: U1 , ... , Vn Tn >: Ln <: Un (n > 0) + V1 T1 >: L1 <: U1 , ... , Vn Tn >: Ln <: Un (n > 0) ``` where each of the variances `Vi` is either `'+'` or `'-'`, then a simple case ```scala @@ -82,7 +82,7 @@ map into case classes or vals. ``` where `Bi` is `Li` if `Vi = '+'` and `Ui` if `Vi = '-'`. This result is then further rewritten with rule (8). Simple cases of enums with non-variant type - parameters are not permitted. + parameters are not permitted (however value cases with explicit `extends` clause are) 5. A class case without an extends clause ```scala From b76d25411d5a51cd3dd29e73ca738c07d03e6479 Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Thu, 12 Mar 2020 15:06:28 +0100 Subject: [PATCH 03/20] doc(opaque): always uses `alias` in `opaque type alias` --- docs/docs/reference/contextual/context-functions.md | 2 +- .../reference/dropped-features/package-objects.md | 2 +- .../reference/other-new-features/opaques-details.md | 12 ++++++------ docs/docs/reference/soft-modifier.md | 4 ++++ 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/docs/docs/reference/contextual/context-functions.md b/docs/docs/reference/contextual/context-functions.md index bd20a6de022a..758aae7288b6 100644 --- a/docs/docs/reference/contextual/context-functions.md +++ b/docs/docs/reference/contextual/context-functions.md @@ -112,7 +112,7 @@ With that setup, the table construction code above compiles and expands to: ``` ### Example: Postconditions -As a larger example, here is a way to define constructs for checking arbitrary postconditions using an extension method `ensuring` so that the checked result can be referred to simply by `result`. The example combines opaque aliases, context function types, and extension methods to provide a zero-overhead abstraction. +As a larger example, here is a way to define constructs for checking arbitrary postconditions using an extension method `ensuring` so that the checked result can be referred to simply by `result`. The example combines opaque type aliases, context function types, and extension methods to provide a zero-overhead abstraction. ```scala object PostConditions { diff --git a/docs/docs/reference/dropped-features/package-objects.md b/docs/docs/reference/dropped-features/package-objects.md index 22ba96eb5f86..fc8a5fccbded 100644 --- a/docs/docs/reference/dropped-features/package-objects.md +++ b/docs/docs/reference/dropped-features/package-objects.md @@ -31,7 +31,7 @@ The compiler generates synthetic objects that wrap toplevel definitions falling - all pattern, value, method, and type definitions, - implicit classes and objects, - - companion objects of opaque types. + - companion objects of opaque type aliases. If a source file `src.scala` contains such toplevel definitions, they will be put in a synthetic object named `src$package`. The wrapping is transparent, however. The definitions in `src` can still be accessed as members of the enclosing package. diff --git a/docs/docs/reference/other-new-features/opaques-details.md b/docs/docs/reference/other-new-features/opaques-details.md index 2b0d9707e84a..6d65f4aa7eee 100644 --- a/docs/docs/reference/other-new-features/opaques-details.md +++ b/docs/docs/reference/other-new-features/opaques-details.md @@ -20,14 +20,14 @@ The general form of a (monomorphic) opaque type alias is ```scala opaque type T >: L <: U = R ``` -where the lower bound `L` and the upper bound `U` may be missing, in which case they are assumed to be `scala.Nothing` and `scala.Any`, respectively. If bounds are given, it is checked that the right hand side `R` conforms to them, i.e. `L <: R` and `R <: U`. F-bounds are not supported for opaque types: `T` is not allowed to appear in `L` or `U`. +where the lower bound `L` and the upper bound `U` may be missing, in which case they are assumed to be `scala.Nothing` and `scala.Any`, respectively. If bounds are given, it is checked that the right hand side `R` conforms to them, i.e. `L <: R` and `R <: U`. F-bounds are not supported for opaque type aliases: `T` is not allowed to appear in `L` or `U`. 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 ``` -A special case arises if the opaque type is defined in an object. Example: +A special case arises if the opaque type alias is defined in an object. Example: ``` object o { opaque type T = R @@ -35,7 +35,7 @@ object o { ``` In this case we have inside the object (also for non-opaque types) that `o.T` is equal to `T` or its expanded form `o.this.T`. Equality is understood here as mutual subtyping, i.e. -`o.T <: o.this.T` and `o.this.T <: T`. Furthermore, we have by the rules of opaque types +`o.T <: o.this.T` and `o.this.T <: T`. Furthermore, we have by the rules of opaque type aliases that `o.this.T` equals `R`. The two equalities compose. That is, inside `o`, it is also known that `o.T` is equal to `R`. This means the following code type-checks: ```scala @@ -48,7 +48,7 @@ def id(x: o.T): o.T = x ### Toplevel Opaque Types -An opaque type on the toplevel is transparent in all other toplevel definitions in the sourcefile where it appears, but is opaque in nested +An opaque type alias on the toplevel is transparent in all other toplevel definitions in the sourcefile where it appears, but is opaque in nested objects and classes and in all other source files. Example: ```scala // in test1.scala @@ -69,10 +69,10 @@ object test1$package { val x: A = "abc" } object obj { - val y: A = "abc" // error: cannot assign "abc" to opaque type A + val y: A = "abc" // error: cannot assign "abc" to opaque type alias A } ``` -The opaque type `A` is transparent in its scope, which includes the definition of `x`, but not the definitions of `obj` and `y`. +The opaque type alias `A` is transparent in its scope, which includes the definition of `x`, but not the definitions of `obj` and `y`. ### Relationship to SIP 35 diff --git a/docs/docs/reference/soft-modifier.md b/docs/docs/reference/soft-modifier.md index 524ef1a40536..e896df1c916d 100644 --- a/docs/docs/reference/soft-modifier.md +++ b/docs/docs/reference/soft-modifier.md @@ -4,6 +4,10 @@ title: Soft Modifiers --- A soft modifier is one of the identifiers `opaque` and `inline`. + It is treated as a potential modifier of a definition, if it is followed by a hard modifier or a keyword combination starting a definition (`def`, `val`, `var`, `type`, `class`, `case class`, `trait`, `object`, `case object`, `enum`). Between the two words there may be a sequence of newline tokens and soft modifiers. From 6a70f8ff13ba07a89a44fb8a983419709e0d8cdd Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Thu, 12 Mar 2020 17:38:19 +0100 Subject: [PATCH 04/20] doc(open-class): typo --- docs/docs/reference/other-new-features/open-classes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/reference/other-new-features/open-classes.md b/docs/docs/reference/other-new-features/open-classes.md index 21d3659974ae..38d95d6c4158 100644 --- a/docs/docs/reference/other-new-features/open-classes.md +++ b/docs/docs/reference/other-new-features/open-classes.md @@ -13,7 +13,7 @@ open class Writer[T] { /** Sends to stdout, can be overridden */ def send(x: T) = println(x) - /** Send all arguments using `send` */ + /** Sends all arguments using `send` */ def sendAll(xs: T*) = xs.foreach(send) } From 71f11b0d98823178c0e66d3236914473cfea5550 Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Thu, 12 Mar 2020 17:48:31 +0100 Subject: [PATCH 05/20] doc(untupling): typos --- .../other-new-features/parameter-untupling-spec.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/docs/reference/other-new-features/parameter-untupling-spec.md b/docs/docs/reference/other-new-features/parameter-untupling-spec.md index 4ea76891fb2d..77e6fff32691 100644 --- a/docs/docs/reference/other-new-features/parameter-untupling-spec.md +++ b/docs/docs/reference/other-new-features/parameter-untupling-spec.md @@ -43,14 +43,14 @@ parameter `pi`. Then `f` will conform to the function type `ProductN[T1, ..., Tn A type `Ti` fits a parameter `pi` if one of the following two cases is `true`: * `pi` comes without a type, i.e. it is a simple identifier or `_`. -* `pi` is of the form `x: Ui` or `_: Ui` and `Ti` conforms to `Ui`. +* `pi` is of the form `x: Ui` or `_: Ui` and `Ti <: Ui`. Auto-tupling composes with eta-expansion. That is an n-ary function generated by eta-expansion can in turn be adapted to the expected type with auto-tupling. -#### Term addaptation +#### Term adaptation -If the a function +If the function ```scala (p1: T1, ..., pn: Tn) => e ``` @@ -73,7 +73,7 @@ Translation of such a tuples would use the `apply` method on the tuple to access ### Migration -Code like this could not be written before, hence the new notation would not be ambigouous after adoption. +Code like this could not be written before, hence the new notation would not be ambiguous after adoption. Though it is possible that someone has written an implicit conversion form `(T1, ..., Tn) => R` to `TupleN[T1, ..., Tn] => R` for some `n`. This change could be detected and fixed by `Scalafix`. Furthermore, such conversion would probably From 61c342f36382cc6c7babd580b9de388048f454a2 Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Thu, 12 Mar 2020 22:32:04 +0100 Subject: [PATCH 06/20] doc(match-types): fix Concat example, X is invariant at least according to the compiler it cannot be covariant as it occurs in invariant position --- 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 d22c373d8d2f..d27aeafde084 100644 --- a/docs/docs/reference/new-types/match-types.md +++ b/docs/docs/reference/new-types/match-types.md @@ -39,7 +39,7 @@ type LeafElem[X] = X match { ``` Recursive match type definitions can also be given an upper bound, like this: ```scala -type Concat[+Xs <: Tuple, +Ys <: Tuple] <: Tuple = Xs match { +type Concat[Xs <: Tuple, +Ys <: Tuple] <: Tuple = Xs match { case Unit => Ys case x *: xs => x *: Concat[xs, Ys] } From a6d2312b8c828b3e5785c9f6def78c6825371fc2 Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Thu, 12 Mar 2020 22:46:48 +0100 Subject: [PATCH 07/20] doc(match-type): fix type lambda syntax and mention that the typing rules are not yet defined --- docs/docs/reference/new-types/match-types.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/docs/docs/reference/new-types/match-types.md b/docs/docs/reference/new-types/match-types.md index d27aeafde084..b524764fb508 100644 --- a/docs/docs/reference/new-types/match-types.md +++ b/docs/docs/reference/new-types/match-types.md @@ -124,17 +124,21 @@ The third rule states that a match type conforms to its upper bound Within a match type `Match(S, Cs) <: B`, all occurrences of type variables count as covariant. By the nature of the cases `Ci` this means that occurrences in pattern position are contravarant (since patterns are represented as function type arguments). -## Typing Rules for Match Expressions + + +## Future Typing Rules for Match Expressions + + Typing rules for match expressions are tricky. First, they need some new form of GADT matching for value parameters. Second, they have to account for the difference between sequential match on the term level and parallel match on the type level. As a running example consider: ```scala -type M[+X] = X match { +type M[X] = X match { case A => 1 case B => 2 } ``` -We'd like to be able to typecheck +We would like to be able to typecheck ```scala def m[X](x: X): M[X] = x match { case _: A => 1 // type error @@ -144,14 +148,14 @@ def m[X](x: X): M[X] = x match { Unfortunately, this goes nowhere. Let's try the first case. We have: `x.type <: A` and `x.type <: X`. This tells us nothing useful about `X`, so we cannot reduce `M` in order to show that the right hand side of the case is valid. -The following variant is more promising: +The following variant is more promising but does not compile either: ```scala def m(x: Any): M[x.type] = x match { case _: A => 1 case _: B => 2 } ``` -To make this work, we'd need a new form of GADT checking: If the scrutinee is a term variable `s`, we can make use of +To make this work, we would need a new form of GADT checking: If the scrutinee is a term variable `s`, we can make use of the fact that `s.type` must conform to the pattern's type and derive a GADT constraint from that. For the first case above, this would be the constraint `x.type <: A`. The new aspect here is that we need GADT constraints over singleton types where before we just had constraints over type parameters. From 221898ab36fe59cd27c33e8c3305fc1868f15e2c Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Fri, 13 Mar 2020 06:42:47 +0100 Subject: [PATCH 08/20] doc(match-type): mark typing as work in progress --- docs/docs/reference/new-types/match-types.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/reference/new-types/match-types.md b/docs/docs/reference/new-types/match-types.md index b524764fb508..0f3ea15427b4 100644 --- a/docs/docs/reference/new-types/match-types.md +++ b/docs/docs/reference/new-types/match-types.md @@ -126,9 +126,9 @@ Within a match type `Match(S, Cs) <: B`, all occurrences of type variables count -## Future Typing Rules for Match Expressions +## Typing Rules for Match Expressions (Work in Progress) - + Typing rules for match expressions are tricky. First, they need some new form of GADT matching for value parameters. Second, they have to account for the difference between sequential match on the term level and parallel match on the type level. As a running example consider: From 0d696478dcf717613dd58d7781fdb507f09c2273 Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Fri, 13 Mar 2020 06:47:29 +0100 Subject: [PATCH 09/20] doc(tupled): typo --- docs/docs/reference/other-new-features/tupled-function.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/reference/other-new-features/tupled-function.md b/docs/docs/reference/other-new-features/tupled-function.md index 38a68bd77e69..d8ad747d9e0f 100644 --- a/docs/docs/reference/other-new-features/tupled-function.md +++ b/docs/docs/reference/other-new-features/tupled-function.md @@ -26,7 +26,7 @@ sealed trait TupledFunction[F, G] { The compiler will synthesize an instance of `TupledFunction[F, G]` if: * `F` is a function type of arity `N` -* `G` is a function with a single tuple argument of size `N` and it's types are equal to the arguments of `F` +* `G` is a function with a single tuple argument of size `N` and its types are equal to the arguments of `F` * The return type of `F` is equal to the return type of `G` * `F` and `G` are the same kind of function (both are `(...) => R` or both are `(...) ?=> R`) * If only one of `F` or `G` is instantiated the second one is inferred. From eaab007b0ca17cf15715fc9634244031cc661885 Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Fri, 13 Mar 2020 06:50:36 +0100 Subject: [PATCH 10/20] doc(tupled): use `sort` instead of `kind` Since when I read kind in the docs, then I think first about kind in the context of type theory --- docs/docs/reference/other-new-features/tupled-function.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/reference/other-new-features/tupled-function.md b/docs/docs/reference/other-new-features/tupled-function.md index d8ad747d9e0f..08a907c74b4c 100644 --- a/docs/docs/reference/other-new-features/tupled-function.md +++ b/docs/docs/reference/other-new-features/tupled-function.md @@ -28,7 +28,7 @@ The compiler will synthesize an instance of `TupledFunction[F, G]` if: * `F` is a function type of arity `N` * `G` is a function with a single tuple argument of size `N` and its types are equal to the arguments of `F` * The return type of `F` is equal to the return type of `G` -* `F` and `G` are the same kind of function (both are `(...) => R` or both are `(...) ?=> R`) +* `F` and `G` are the same sort of function (both are `(...) => R` or both are `(...) ?=> R`) * If only one of `F` or `G` is instantiated the second one is inferred. Examples From 303411e0296b353c379725a01dfda5280e8619bc Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Fri, 13 Mar 2020 07:04:18 +0100 Subject: [PATCH 11/20] doc(tupled): link to extension method --- docs/docs/reference/other-new-features/tupled-function.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/docs/reference/other-new-features/tupled-function.md b/docs/docs/reference/other-new-features/tupled-function.md index 08a907c74b4c..356fa05f5bdd 100644 --- a/docs/docs/reference/other-new-features/tupled-function.md +++ b/docs/docs/reference/other-new-features/tupled-function.md @@ -33,7 +33,8 @@ The compiler will synthesize an instance of `TupledFunction[F, G]` if: Examples -------- -`TupledFunction` can be used to generalize the `Function1.tupled`, ... `Function22.tupled` methods to functions of any arities ([full example](https://github.com/lampepfl/dotty/blob/master/tests/run/tupled-function-tupled.scala)) +`TupledFunction` can be used to generalize the `Function1.tupled`, ... `Function22.tupled` methods to functions of any arities. +The following defines `tupled` as [extension method](../contextual/extension-methods.html) ([full example](https://github.com/lampepfl/dotty/blob/master/tests/run/tupled-function-tupled.scala)). ```scala /** Creates a tupled version of this function: instead of N arguments, From 51977d7d73b95450fd215265944f7cf3ba9292df Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Fri, 13 Mar 2020 16:20:51 +0100 Subject: [PATCH 12/20] doc(tupled): typos --- .../reference/other-new-features/tupled-function.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/docs/reference/other-new-features/tupled-function.md b/docs/docs/reference/other-new-features/tupled-function.md index 356fa05f5bdd..51a098d68745 100644 --- a/docs/docs/reference/other-new-features/tupled-function.md +++ b/docs/docs/reference/other-new-features/tupled-function.md @@ -38,7 +38,7 @@ The following defines `tupled` as [extension method](../contextual/extension-met ```scala /** Creates a tupled version of this function: instead of N arguments, - * it accepts a single [[scala.Tuple]] argument. + * it accepts a single [[scala.Tuple]]N argument. * * @tparam F the function type * @tparam Args the tuple type with the same types as the function arguments of F @@ -47,11 +47,11 @@ The following defines `tupled` as [extension method](../contextual/extension-met def [F, Args <: Tuple, R](f: F).tupled(using tf: TupledFunction[F, Args => R]): Args => R = tf.tupled(f) ``` -`TupledFunction` can be used to generalize the `Function.untupled` methods to functions of any arities ([full example](https://github.com/lampepfl/dotty/blob/master/tests/run/tupled-function-untupled.scala)) +`TupledFunction` can be used to generalize the `Function.untupled` to a function of any arities ([full example](https://github.com/lampepfl/dotty/blob/master/tests/run/tupled-function-untupled.scala)) ```scala -/** Creates an untupled version of this function: instead of single [[scala.Tuple]] argument, - * it accepts a N arguments. +/** Creates an untupled version of this function: instead of a single [[scala.Tuple]]N argument, + * it accepts N arguments. * * This is a generalization of [[scala.Function.untupled]] that work on functions of any arity * @@ -65,7 +65,7 @@ def [F, Args <: Tuple, R](f: Args => R).untupled(using tf: TupledFunction[F, Arg `TupledFunction` can also be used to generalize the [`Tuple1.compose`](https://github.com/lampepfl/dotty/blob/master/tests/run/tupled-function-compose.scala) and [`Tuple1.andThen`](https://github.com/lampepfl/dotty/blob/master/tests/run/tupled-function-andThen.scala) methods to compose functions of larger arities and with functions that return tuples. ```scala -/** Composes two instances of TupledFunctions in a new TupledFunctions, with this function applied last +/** Composes two instances of TupledFunction into a new TupledFunction, with this function applied last. * * @tparam F a function type * @tparam G a function type From 88db685dc47136d9c0fb50f0aec4f323ba5c8c8a Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Fri, 13 Mar 2020 16:27:29 +0100 Subject: [PATCH 13/20] doc(tupled): improve scaladoc of tupled --- tests/run/tupled-function-tupled.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/run/tupled-function-tupled.scala b/tests/run/tupled-function-tupled.scala index 90b5360c4f33..ce42c13beb32 100644 --- a/tests/run/tupled-function-tupled.scala +++ b/tests/run/tupled-function-tupled.scala @@ -16,7 +16,7 @@ object Test { } /** Creates a tupled version of this function: instead of N arguments, - * it accepts a single [[scala.Tuple]] argument. + * it accepts a single [[scala.Tuple]] with N elements as argument. * * This is a generalization of [[scala.FunctionN.tupled]] that work on functions of any arity * From d4f55481bb0a6c27e485950afa1fd1a4026ac46b Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Fri, 13 Mar 2020 16:29:07 +0100 Subject: [PATCH 14/20] doc(tupled): improve scaladoc of untupled --- tests/run/tupled-function-untupled.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/run/tupled-function-untupled.scala b/tests/run/tupled-function-untupled.scala index 466874e4eda5..576c8aa14052 100644 --- a/tests/run/tupled-function-untupled.scala +++ b/tests/run/tupled-function-untupled.scala @@ -95,8 +95,8 @@ object Test { } - /** Creates an untupled version of this function: instead of single [[scala.Tuple]] argument, - * it accepts a N arguments. + /** Creates an untupled version of this function: instead of a single argument of type [[scala.Tuple]] with N elements, + * it accepts N arguments. * * This is a generalization of [[scala.Function.untupled]] that work on functions of any arity * From a3e2621d0abfdbddcf90285a3e671c7149a912d1 Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Fri, 13 Mar 2020 16:31:08 +0100 Subject: [PATCH 15/20] doc(tupled): improve scaladoc of tupled/untupled --- docs/docs/reference/other-new-features/tupled-function.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/reference/other-new-features/tupled-function.md b/docs/docs/reference/other-new-features/tupled-function.md index 51a098d68745..d89aef2cde0e 100644 --- a/docs/docs/reference/other-new-features/tupled-function.md +++ b/docs/docs/reference/other-new-features/tupled-function.md @@ -38,7 +38,7 @@ The following defines `tupled` as [extension method](../contextual/extension-met ```scala /** Creates a tupled version of this function: instead of N arguments, - * it accepts a single [[scala.Tuple]]N argument. + * it accepts a single [[scala.Tuple]] with N elements as argument. * * @tparam F the function type * @tparam Args the tuple type with the same types as the function arguments of F @@ -50,7 +50,7 @@ def [F, Args <: Tuple, R](f: F).tupled(using tf: TupledFunction[F, Args => R]): `TupledFunction` can be used to generalize the `Function.untupled` to a function of any arities ([full example](https://github.com/lampepfl/dotty/blob/master/tests/run/tupled-function-untupled.scala)) ```scala -/** Creates an untupled version of this function: instead of a single [[scala.Tuple]]N argument, +/** Creates an untupled version of this function: instead of a single argument of type [[scala.Tuple]] with N elements, * it accepts N arguments. * * This is a generalization of [[scala.Function.untupled]] that work on functions of any arity From 5dcc5a6a83a8c5210325a618b63b8ba45927e16f Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Fri, 13 Mar 2020 16:37:57 +0100 Subject: [PATCH 16/20] doc(threadSafe): wrap lazy val into `` --- .../reference/other-new-features/threadUnsafe-annotation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/reference/other-new-features/threadUnsafe-annotation.md b/docs/docs/reference/other-new-features/threadUnsafe-annotation.md index db7d164d0f99..85b8d66259c3 100644 --- a/docs/docs/reference/other-new-features/threadUnsafe-annotation.md +++ b/docs/docs/reference/other-new-features/threadUnsafe-annotation.md @@ -3,8 +3,8 @@ layout: doc-page title: threadUnsafe annotation --- -A new annotation `@threadUnsafe` can be used on a field which defines a lazy -val. When this annotation is used, the initialization of the lazy val will use a +A new annotation `@threadUnsafe` can be used on a field which defines a `lazy +val`. When this annotation is used, the initialization of the lazy val will use a faster mechanism which is not thread-safe. ### Example From 576b265bcc31566fe587b4521d9b205bc34fd8f8 Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Fri, 13 Mar 2020 16:43:14 +0100 Subject: [PATCH 17/20] doc(control-syntax): remove superfluous `with` --- docs/docs/reference/other-new-features/control-syntax.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/reference/other-new-features/control-syntax.md b/docs/docs/reference/other-new-features/control-syntax.md index e43c89f8a06f..d20c19a5a255 100644 --- a/docs/docs/reference/other-new-features/control-syntax.md +++ b/docs/docs/reference/other-new-features/control-syntax.md @@ -39,4 +39,4 @@ The rules in detail are: ### Rewrites The Dotty compiler can rewrite source code from old syntax and new syntax and back. -When invoked with options `-rewrite -new-syntax` it will rewrite from old to new syntax, dropping parentheses and braces in conditions and enumerators. When invoked with with options `-rewrite -old-syntax` it will rewrite in the reverse direction, inserting parentheses and braces as needed. +When invoked with options `-rewrite -new-syntax` it will rewrite from old to new syntax, dropping parentheses and braces in conditions and enumerators. When invoked with options `-rewrite -old-syntax` it will rewrite in the reverse direction, inserting parentheses and braces as needed. From e050b4c4afb4013ef94dcb7982587e2bbf6edc25 Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Fri, 13 Mar 2020 16:47:15 +0100 Subject: [PATCH 18/20] doc(braces): mention -noindent in the teaser --- docs/docs/reference/other-new-features/indentation.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/docs/reference/other-new-features/indentation.md b/docs/docs/reference/other-new-features/indentation.md index e4dc8074d323..fbaaa856a29d 100644 --- a/docs/docs/reference/other-new-features/indentation.md +++ b/docs/docs/reference/other-new-features/indentation.md @@ -4,9 +4,10 @@ title: Optional Braces --- As an experimental feature, Scala 3 enforces some rules on indentation and allows -some occurrences of braces `{...}` to be optional. +some occurrences of braces `{...}` to be optional. +It can be turned off with the compiler flag `-noindent`. - - First, some badly indented programs are ruled out, which means they are flagged with warnings. + - First, some badly indented programs are flagged with warnings. - Second, some occurrences of braces `{...}` are made optional. Generally, the rule is that adding a pair of optional braces will not change the meaning of a well-indented program. From a67e43c8e51847e8c7e58c19b8fed99055a96271 Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Fri, 13 Mar 2020 16:52:28 +0100 Subject: [PATCH 19/20] doc(explicit-nulls): remove repetition of `opt-in` --- docs/docs/reference/other-new-features/explicit-nulls.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/reference/other-new-features/explicit-nulls.md b/docs/docs/reference/other-new-features/explicit-nulls.md index 7b31a0b4ad41..463f7daed4a0 100644 --- a/docs/docs/reference/other-new-features/explicit-nulls.md +++ b/docs/docs/reference/other-new-features/explicit-nulls.md @@ -17,7 +17,7 @@ Instead, to mark a type as nullable we use a [type union](https://dotty.epfl.ch/ val x: String|Null = null // ok ``` -Explicit nulls are enabled via a `-Yexplicit-nulls` flag, so they're an opt-in feature. +Explicit nulls are enabled via a `-Yexplicit-nulls` flag. Read on for details. From abc35b78c6f678b9b880461c76776cb170137972 Mon Sep 17 00:00:00 2001 From: Robert Stoll Date: Fri, 13 Mar 2020 16:54:44 +0100 Subject: [PATCH 20/20] doc(explicit-nulls): typos --- docs/docs/reference/other-new-features/explicit-nulls.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/reference/other-new-features/explicit-nulls.md b/docs/docs/reference/other-new-features/explicit-nulls.md index 463f7daed4a0..cc9cb00c0df0 100644 --- a/docs/docs/reference/other-new-features/explicit-nulls.md +++ b/docs/docs/reference/other-new-features/explicit-nulls.md @@ -23,7 +23,7 @@ Read on for details. ## New Type Hierarchy -When explicit nulls are enabled, the type hierarchy changes so that `Null` is subtype only of +When explicit nulls are enabled, the type hierarchy changes so that `Null` is only a subtype of `Any`, as opposed to every reference type. This is the new type hierarchy: @@ -33,7 +33,7 @@ After erasure, `Null` remains a subtype of all reference types (as forced by the ## Unsoundness -The new type system is unsound with respect to `null`. This means there are still instances where an expressions has a non-nullable type like `String`, but its value is `null`. +The new type system is unsound with respect to `null`. This means there are still instances where an expression has a non-nullable type like `String`, but its value is actually `null`. The unsoundness happens because uninitialized fields in a class start out as `null`: ```scala