From 7b4c9b7bdf7dbdc851923c0a230b46a627c5e859 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Micheloud?= Date: Wed, 23 Dec 2020 22:46:46 +0100 Subject: [PATCH 1/4] rebased with upstream --- .../implicit-conversions-spec.md | 2 +- .../reference/changed-features/operators.md | 2 +- .../changed-features/structural-types-spec.md | 2 +- .../changed-features/structural-types.md | 2 +- .../changed-features/vararg-patterns.md | 2 +- .../reference/contextual/derivation-macro.md | 2 +- docs/docs/reference/contextual/derivation.md | 19 ++--- .../reference/contextual/given-imports.md | 1 + docs/docs/reference/contextual/motivation.md | 8 ++- .../contextual/multiversal-equality.md | 3 +- .../contextual/relationship-implicits.md | 4 +- docs/docs/reference/enums/desugarEnums.md | 11 +-- docs/docs/reference/enums/enums.md | 6 +- .../docs/reference/features-classification.md | 2 +- .../metaprogramming/erased-terms-spec.md | 4 +- docs/docs/reference/metaprogramming/inline.md | 4 +- .../reference/metaprogramming/macros-spec.md | 2 +- docs/docs/reference/metaprogramming/macros.md | 70 +++++++++++-------- .../reference/metaprogramming/simple-smp.md | 8 +-- .../docs/reference/metaprogramming/staging.md | 7 +- .../new-types/dependent-function-types.md | 5 +- docs/docs/reference/new-types/match-types.md | 11 ++- .../new-types/polymorphic-function-types.md | 8 +-- .../reference/new-types/union-types-spec.md | 8 +-- docs/docs/reference/new-types/union-types.md | 2 +- .../creator-applications.md | 1 + .../reference/other-new-features/export.md | 8 +-- .../other-new-features/open-classes.md | 5 +- .../other-new-features/safe-initialization.md | 4 +- .../other-new-features/targetName.md | 3 +- .../other-new-features/trait-parameters.md | 2 +- .../other-new-features/transparent-traits.md | 6 +- docs/docs/reference/overview.md | 4 +- docs/docs/reference/syntax.md | 3 +- 34 files changed, 124 insertions(+), 107 deletions(-) diff --git a/docs/docs/reference/changed-features/implicit-conversions-spec.md b/docs/docs/reference/changed-features/implicit-conversions-spec.md index e468c8ba2f43..df76c0b7dbfe 100644 --- a/docs/docs/reference/changed-features/implicit-conversions-spec.md +++ b/docs/docs/reference/changed-features/implicit-conversions-spec.md @@ -102,7 +102,7 @@ val x: String = 1 // Scala 2: assigns "abc" to x This snippet contains a type error. The right hand side of `val x` does not conform to type `String`. In Scala 2, the compiler will use `m` as an implicit conversion from `Int` to `String`, whereas Scala 3 -will report a type error, because Map isn't an instance of +will report a type error, because `Map` isn't an instance of `Conversion`. ## Migration path diff --git a/docs/docs/reference/changed-features/operators.md b/docs/docs/reference/changed-features/operators.md index f471d28efd1e..d98da3bed317 100644 --- a/docs/docs/reference/changed-features/operators.md +++ b/docs/docs/reference/changed-features/operators.md @@ -1,6 +1,6 @@ --- layout: doc-page -title: Rules for Operators +title: "Rules for Operators" --- The rules for infix operators have changed in some parts: diff --git a/docs/docs/reference/changed-features/structural-types-spec.md b/docs/docs/reference/changed-features/structural-types-spec.md index 248675c4c372..489dd795bc9d 100644 --- a/docs/docs/reference/changed-features/structural-types-spec.md +++ b/docs/docs/reference/changed-features/structural-types-spec.md @@ -20,7 +20,7 @@ The standard library defines a universal marker trait `Selectable` in the packag trait Selectable extends Any ``` -An implementation of `Selectable` that relies on Java reflection is +An implementation of `Selectable` that relies on [Java reflection](https://www.oracle.com/technical-resources/articles/java/javareflection.html) is available in the standard library: `scala.reflect.Selectable`. Other implementations can be envisioned for platforms where Java reflection is not available. diff --git a/docs/docs/reference/changed-features/structural-types.md b/docs/docs/reference/changed-features/structural-types.md index 072f78f9108d..0ffbd3f37f8f 100644 --- a/docs/docs/reference/changed-features/structural-types.md +++ b/docs/docs/reference/changed-features/structural-types.md @@ -71,7 +71,7 @@ Besides `selectDynamic`, a `Selectable` class sometimes also defines a method `a ## Using Java Reflection -Structural types can also be accessed using Java reflection. Example: +Structural types can also be accessed using [Java reflection](https://www.oracle.com/technical-resources/articles/java/javareflection.html). Example: ```scala type Closeable = { def close(): Unit } diff --git a/docs/docs/reference/changed-features/vararg-patterns.md b/docs/docs/reference/changed-features/vararg-patterns.md index 25f457d44dd5..6d467e69233c 100644 --- a/docs/docs/reference/changed-features/vararg-patterns.md +++ b/docs/docs/reference/changed-features/vararg-patterns.md @@ -35,7 +35,7 @@ The change to the grammar is: ## Compatibility considerations -To enable smooth cross compilation between Scala 2 and Scala 3, Dotty will +To enable smooth cross compilation between Scala 2 and Scala 3, the compiler will accept both the old and the new syntax. Under the `-source 3.1` setting, an error will be emitted when the old syntax is encountered. They will be enabled by default in version 3.1 of the language. diff --git a/docs/docs/reference/contextual/derivation-macro.md b/docs/docs/reference/contextual/derivation-macro.md index 999f07fca774..46c1d66c573d 100644 --- a/docs/docs/reference/contextual/derivation-macro.md +++ b/docs/docs/reference/contextual/derivation-macro.md @@ -106,7 +106,7 @@ check we want to generate is the following: && Eq[Int].eqv(x.productElement(1), y.productElement(1)) ``` -### Calling the derived method inside the macro +## Calling the derived method inside the macro Following the rules in [Macros](../metaprogramming/toc.md) we create two methods. One that hosts the top-level splice `eqv` and one that is the implementation. diff --git a/docs/docs/reference/contextual/derivation.md b/docs/docs/reference/contextual/derivation.md index f2183cdd01ed..1c9c510f83bb 100644 --- a/docs/docs/reference/contextual/derivation.md +++ b/docs/docs/reference/contextual/derivation.md @@ -125,12 +125,12 @@ Note the following properties of `Mirror` types, + The kinds of `MirroredType` and `MirroredElemTypes` match the kind of the data type the mirror is an instance for. This allows `Mirrors` to support ADTs of all kinds. + There is no distinct representation type for sums or products (ie. there is no `HList` or `Coproduct` type as in - Scala 2 versions of shapeless). Instead the collection of child types of a data type is represented by an ordinary, + Scala 2 versions of Shapeless). Instead the collection of child types of a data type is represented by an ordinary, possibly parameterized, tuple type. Scala 3's metaprogramming facilities can be used to work with these tuple types as-is, and higher level libraries can be built on top of them. + For both product and sum types, the elements of `MirroredElemTypes` are arranged in definition order (i.e. `Branch[T]` precedes `Leaf[T]` in `MirroredElemTypes` for `Tree` because `Branch` is defined before `Leaf` in the source file). - This means that `Mirror.Sum` differs in this respect from shapeless's generic representation for ADTs in Scala 2, + This means that `Mirror.Sum` differs in this respect from Shapeless's generic representation for ADTs in Scala 2, where the constructors are ordered alphabetically by name. + The methods `ordinal` and `fromProduct` are defined in terms of `MirroredMonoType` which is the type of kind-`*` which is obtained from `MirroredType` by wildcarding its type parameters. @@ -159,7 +159,7 @@ Type class authors will most likely use higher level derivation or generic progr described above and Scala 3's general metaprogramming features is provided below. It is not anticipated that type class authors would normally implement a `derived` method in this way, however this walkthrough can be taken as a guide for authors of the higher level derivation libraries that we expect typical type class authors will use (for a fully -worked out example of such a library, see [shapeless 3](https://github.com/milessabin/shapeless/tree/shapeless-3)). +worked out example of such a library, see [Shapeless 3](https://github.com/milessabin/shapeless/tree/shapeless-3)). #### How to write a type class `derived` method using low level mechanisms @@ -307,7 +307,7 @@ Alternative approaches can be taken to the way that `derived` methods can be def inlined variants using Scala 3 macros, whilst being more involved for type class authors to write than the example above, can produce code for type classes like `Eq` which eliminate all the abstraction artefacts (eg. the `Lists` of child instances in the above) and generate code which is indistinguishable from what a programmer might write by hand. -As a third example, using a higher level library such as shapeless the type class author could define an equivalent +As a third example, using a higher level library such as Shapeless the type class author could define an equivalent `derived` method as, ```scala @@ -317,9 +317,12 @@ given eqSum[A](using inst: => K0.CoproductInstances[Eq, A]): Eq[A] with given eqProduct[A](using inst: K0.ProductInstances[Eq, A]): Eq[A] with def eqv(x: A, y: A): Boolean = inst.foldLeft2(x, y)(true: Boolean)( - [t] => (acc: Boolean, eqt: Eq[t], t0: t, t1: t) => Complete(!eqt.eqv(t0, t1))(false)(true) + [t] => (acc: Boolean, eqt: Eq[t], t0: t, t1: t) => + Complete(!eqt.eqv(t0, t1))(false)(true) + ) -inline def derived[A](using gen: K0.Generic[A]) as Eq[A] = gen.derive(eqSum, eqProduct) +inline def derived[A](using gen: K0.Generic[A]) as Eq[A] = + gen.derive(eqSum, eqProduct) ``` The framework described here enables all three of these approaches without mandating any of them. @@ -385,6 +388,6 @@ written these casts will never fail. As mentioned, however, the compiler-provided mechanism is intentionally very low level and it is anticipated that higher level type class derivation and generic programming libraries will build on this and Scala 3's other metaprogramming facilities to hide these low-level details from type class authors and general users. Type class -derivation in the style of both shapeless and Magnolia are possible (a prototype of shapeless 3, which combines -aspects of both shapeless 2 and Magnolia has been developed alongside this language feature) as is a more aggressively +derivation in the style of both Shapeless and Magnolia are possible (a prototype of Shapeless 3, which combines +aspects of both Shapeless 2 and Magnolia has been developed alongside this language feature) as is a more aggressively inlined style, supported by Scala 3's new quote/splice macro and inlining facilities. diff --git a/docs/docs/reference/contextual/given-imports.md b/docs/docs/reference/contextual/given-imports.md index d76055fb822b..a6d813d06ee6 100644 --- a/docs/docs/reference/contextual/given-imports.md +++ b/docs/docs/reference/contextual/given-imports.md @@ -80,6 +80,7 @@ import Instances.{im, given Ordering[?]} ``` would import `im`, `intOrd`, and `listOrd` but leave out `ec`. + ### Migration The rules for imports stated above have the consequence that a library diff --git a/docs/docs/reference/contextual/motivation.md b/docs/docs/reference/contextual/motivation.md index 0730e09592e1..33cf8110c557 100644 --- a/docs/docs/reference/contextual/motivation.md +++ b/docs/docs/reference/contextual/motivation.md @@ -8,7 +8,7 @@ title: "Overview" Scala's implicits are its most distinguished feature. They are _the_ fundamental way to abstract over context. They represent a unified paradigm with a great variety of use cases, among them: implementing type classes, establishing context, dependency injection, expressing capabilities, computing new types and proving relationships between them. Following Haskell, Scala was the second popular language to have some form of implicits. Other languages have followed suit. E.g [Rust's traits](https://doc.rust-lang.org/rust-by-example/trait.html) or [Swift's protocol extensions](https://docs.swift.org/swift-book/LanguageGuide/Protocols.html#ID521). Design proposals are also on the table for Kotlin as [compile time dependency resolution](https://github.com/Kotlin/KEEP/blob/e863b25f8b3f2e9b9aaac361c6ee52be31453ee0/proposals/compile-time-dependency-resolution.md), for C# as [Shapes and Extensions](https://github.com/dotnet/csharplang/issues/164) -or for F# as [Traits](https://github.com/MattWindsor91/visualfsharp/blob/hackathon-vs/examples/fsconcepts.md). Implicits are also a common feature of theorem provers such as Coq or [Agda](https://agda.readthedocs.io/en/latest/language/implicit-arguments.html). +or for F# as [Traits](https://github.com/MattWindsor91/visualfsharp/blob/hackathon-vs/examples/fsconcepts.md). Implicits are also a common feature of theorem provers such as [Coq](https://coq.inria.fr/refman/language/extensions/implicit-arguments.html) or [Agda](https://agda.readthedocs.io/en/latest/language/implicit-arguments.html). Even though these designs use widely different terminology, they are all variants of the core idea of _term inference_. Given a type, the compiler synthesizes a "canonical" term that has that type. Scala embodies the idea in a purer form than most other languages: An implicit parameter directly leads to an inferred argument term that could also be written down explicitly. By contrast, type class based designs are less direct since they hide term inference behind some form of type classification and do not offer the option of writing the inferred quantities (typically, dictionaries) explicitly. @@ -30,12 +30,14 @@ Particular criticisms are: 3. The syntax of implicit definitions is too minimal. It consists of a single modifier, `implicit`, that can be attached to a large number of language constructs. A problem with this for newcomers is that it conveys mechanism instead of intent. For instance, a type class instance is an implicit object or val if unconditional and an implicit def with implicit parameters referring to some class if conditional. This describes precisely what the implicit definitions translate to -- just drop the `implicit` modifier, and that's it! But the cues that define intent are rather indirect and can be easily misread, as demonstrated by the definitions of `i1` and `i2` above. 4. The syntax of implicit parameters also has shortcomings. While implicit _parameters_ are designated specifically, arguments are not. Passing an argument to an implicit parameter looks like a regular application `f(arg)`. This is problematic because it means there can be confusion regarding what parameter gets instantiated in a call. For instance, in + ```scala def currentMap(implicit ctx: Context): Map[String, Int] ``` - one cannot write `currentMap("abc")` since the string "abc" is taken as explicit argument to the implicit `ctx` parameter. One has to write `currentMap.apply("abc")` instead, which is awkward and irregular. For the same reason, a method definition can only have one implicit parameter section and it must always come last. This restriction not only reduces orthogonality, but also prevents some useful program constructs, such as a method with a regular parameter whose type depends on an implicit value. Finally, it's also a bit annoying that implicit parameters must have a name, even though in many cases that name is never referenced. - 5. Implicits pose challenges for tooling. The set of available implicits depends on context, so command completion has to take context into account. This is feasible in an IDE but docs like ScalaDoc that are based static web pages can only provide an approximation. Another problem is that failed implicit searches often give very unspecific error messages, in particular if some deeply recursive implicit search has failed. Note that the Scala 3 compiler has already made a lot of progress in the error diagnostics area. If a recursive search fails some levels down, it shows what was constructed and what is missing. Also, it suggests imports that can bring missing implicits in scope. + one cannot write `currentMap("abc")` since the string `"abc"` is taken as explicit argument to the implicit `ctx` parameter. One has to write `currentMap.apply("abc")` instead, which is awkward and irregular. For the same reason, a method definition can only have one implicit parameter section and it must always come last. This restriction not only reduces orthogonality, but also prevents some useful program constructs, such as a method with a regular parameter whose type depends on an implicit value. Finally, it's also a bit annoying that implicit parameters must have a name, even though in many cases that name is never referenced. + + 5. Implicits pose challenges for tooling. The set of available implicits depends on context, so command completion has to take context into account. This is feasible in an IDE but tools like [Scaladoc](https://docs.scala-lang.org/overviews/scaladoc/overview.html) that are based on static web pages can only provide an approximation. Another problem is that failed implicit searches often give very unspecific error messages, in particular if some deeply recursive implicit search has failed. Note that the Scala 3 compiler has already made a lot of progress in the error diagnostics area. If a recursive search fails some levels down, it shows what was constructed and what is missing. Also, it suggests imports that can bring missing implicits in scope. None of the shortcomings is fatal, after all implicits are very widely used, and many libraries and applications rely on them. But together, they make code using implicits a lot more cumbersome and less clear than it could be. diff --git a/docs/docs/reference/contextual/multiversal-equality.md b/docs/docs/reference/contextual/multiversal-equality.md index c776981a8d4a..fdd429943844 100644 --- a/docs/docs/reference/contextual/multiversal-equality.md +++ b/docs/docs/reference/contextual/multiversal-equality.md @@ -96,7 +96,8 @@ class Box[T](x: T) derives CanEqual By the usual rules of [type class derivation](./derivation.md), this generates the following `CanEqual` instance in the companion object of `Box`: ```scala -given [T, U](using CanEqual[T, U]): CanEqual[Box[T], Box[U]] = CanEqual.derived +given [T, U](using CanEqual[T, U]): CanEqual[Box[T], Box[U]] = + CanEqual.derived ``` That is, two boxes are comparable with `==` or `!=` if their elements are. Examples: ```scala diff --git a/docs/docs/reference/contextual/relationship-implicits.md b/docs/docs/reference/contextual/relationship-implicits.md index cefaa0c1f8f9..c9a0020fbf63 100644 --- a/docs/docs/reference/contextual/relationship-implicits.md +++ b/docs/docs/reference/contextual/relationship-implicits.md @@ -95,7 +95,7 @@ mirroring the definition syntax. E.g, `max(2, 3)(using IntOrd)`. Scala 2 uses normal applications `max(2, 3)(IntOrd)` instead. The Scala 2 syntax has some inherent ambiguities and restrictions which are overcome by the new syntax. For instance, multiple implicit parameter lists are not available in the old syntax, even though they can be simulated using auxiliary objects in the "Aux" pattern. The `summon` method corresponds to `implicitly` in Scala 2. -It is precisely the same as the `the` method in Shapeless. +It is precisely the same as the `the` method in [Shapeless](https://github.com/milessabin/shapeless). The difference between `summon` (or `the`) and `implicitly` is that `summon` can return a more precise type than the type that was asked for. @@ -129,7 +129,7 @@ Abstract extension methods in traits that are implemented in given instances hav ### Type Class Derivation -Type class derivation has no direct counterpart in the Scala 2 language. Comparable functionality can be achieved by macro-based libraries such as Shapeless, Magnolia, or scalaz-deriving. +Type class derivation has no direct counterpart in the Scala 2 language. Comparable functionality can be achieved by macro-based libraries such as [Shapeless](https://github.com/milessabin/shapeless), [Magnolia](https://propensive.com/opensource/magnolia), or [scalaz-deriving](https://github.com/scalaz/scalaz-deriving). ### Context Function Types diff --git a/docs/docs/reference/enums/desugarEnums.md b/docs/docs/reference/enums/desugarEnums.md index 35c40bfb2ac9..ea8faf1774ad 100644 --- a/docs/docs/reference/enums/desugarEnums.md +++ b/docs/docs/reference/enums/desugarEnums.md @@ -25,7 +25,7 @@ some terminology and notational conventions: 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 +There are nine desugaring rules. Rule (1) desugars 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 class`es or `val`s. @@ -176,10 +176,11 @@ If `E` contains at least one simple case, its companion object will define in ad follows. ```scala - private def $new(_$ordinal: Int, $name: String) = new E with runtime.EnumValue: - def ordinal = _$ordinal - override def productPrefix = $name // if not overridden in `E` - override def toString = $name // if not overridden in `E` + private def $new(_$ordinal: Int, $name: String) = + new E with runtime.EnumValue: + def ordinal = _$ordinal + override def productPrefix = $name // if not overridden in `E` + override def toString = $name // if not overridden in `E` ``` The anonymous class also implements the abstract `Product` methods that it inherits from `Enum`. diff --git a/docs/docs/reference/enums/enums.md b/docs/docs/reference/enums/enums.md index 2fbff1faf0bc..278036272731 100644 --- a/docs/docs/reference/enums/enums.md +++ b/docs/docs/reference/enums/enums.md @@ -44,7 +44,7 @@ The companion object of an enum also defines three utility methods. The `valueOf` method obtains an enum value by its name. The `values` method returns all enum values defined in an enumeration in an `Array`. The `fromOrdinal` -method obtains an enum value from its ordinal (Int) value. +method obtains an enum value from its ordinal (`Int`) value. ```scala scala> Color.valueOf("Blue") @@ -63,7 +63,7 @@ It is possible to add your own definitions to an enum. Example: enum Planet(mass: Double, radius: Double): private final val G = 6.67300E-11 def surfaceGravity = G * mass / (radius * radius) - def surfaceWeight(otherMass: Double) = otherMass * surfaceGravity + def surfaceWeight(otherMass: Double) = otherMass * surfaceGravity case Mercury extends Planet(3.303e+23, 2.4397e6) case Venus extends Planet(4.869e+24, 6.0518e6) @@ -72,7 +72,7 @@ enum Planet(mass: Double, radius: Double): case Jupiter extends Planet(1.9e+27, 7.1492e7) case Saturn extends Planet(5.688e+26, 6.0268e7) case Uranus extends Planet(8.686e+25, 2.5559e7) - case Neptune extends Planet(1.024e+26, 2.4746e7) + case Neptune extends Planet(1.024e+26, 2.4746e7) end Planet ``` diff --git a/docs/docs/reference/features-classification.md b/docs/docs/reference/features-classification.md index 58b89fe799ff..70fe386323ec 100644 --- a/docs/docs/reference/features-classification.md +++ b/docs/docs/reference/features-classification.md @@ -162,7 +162,7 @@ Being new features, existing code migrates without changes. To be sure, sometime ## Metaprogramming -The following constructs together aim to put metaprogramming in Scala on a new basis. So far, metaprogramming was achieved by a combination of macros and libraries such as Shapeless that were in turn based on some key macros. Current Scala 2 macro mechanisms are a thin veneer on top the current Scala 2 compiler, which makes them fragile and in many cases impossible to port to Scala 3. +The following constructs together aim to put metaprogramming in Scala on a new basis. So far, metaprogramming was achieved by a combination of macros and libraries such as [Shapeless](https://github.com/milessabin/shapeless) that were in turn based on some key macros. Current Scala 2 macro mechanisms are a thin veneer on top the current Scala 2 compiler, which makes them fragile and in many cases impossible to port to Scala 3. It's worth noting that macros were never included in the Scala 2 language specification and were so far made available only under an `-experimental` flag. This has not prevented their widespread usage. diff --git a/docs/docs/reference/metaprogramming/erased-terms-spec.md b/docs/docs/reference/metaprogramming/erased-terms-spec.md index 059044c15e05..0d84fa93afaf 100644 --- a/docs/docs/reference/metaprogramming/erased-terms-spec.md +++ b/docs/docs/reference/metaprogramming/erased-terms-spec.md @@ -3,9 +3,9 @@ layout: doc-page title: "Erased Terms Spec" --- -# Implementation +## Implementation -## Rules +### Rules 1. The `erased` modifier can appear: * At the start of a parameter block of a method, function or class diff --git a/docs/docs/reference/metaprogramming/inline.md b/docs/docs/reference/metaprogramming/inline.md index 07bb3b5deac5..cdbedaa9d48d 100644 --- a/docs/docs/reference/metaprogramming/inline.md +++ b/docs/docs/reference/metaprogramming/inline.md @@ -84,7 +84,7 @@ def factorial(n: BigInt): BigInt = result ``` -Note, that the by-value parameter `msg` is evaluated only once, per the usual Scala +Note that the by-value parameter `msg` is evaluated only once, per the usual Scala semantics, by binding the value and reusing the `msg` through the body of `factorial`. Also, note the special handling of the assignment to the private var `indent`. It is achieved by generating a setter method `def inline$indent_=` and calling it instead. @@ -236,7 +236,7 @@ It is also possible to have inline vals of types that do not have a syntax, such trait InlineConstants: inline val myShort: Short -object Constants extends InlineConstants +object Constants extends InlineConstants: inline val myShort/*: Short(4)*/ = 4 ``` diff --git a/docs/docs/reference/metaprogramming/macros-spec.md b/docs/docs/reference/metaprogramming/macros-spec.md index aa3c59014949..8bdee4ba1eba 100644 --- a/docs/docs/reference/metaprogramming/macros-spec.md +++ b/docs/docs/reference/metaprogramming/macros-spec.md @@ -156,7 +156,7 @@ environments and terms. ---------------- Es |- 't: expr T ``` -The meta theory of a slightly simplified variant 2-stage variant of this calculus +The meta theory of a slightly simplified 2-stage variant of this calculus is studied [separately](./simple-smp.md). ## Going Further diff --git a/docs/docs/reference/metaprogramming/macros.md b/docs/docs/reference/metaprogramming/macros.md index 046bf797c3fc..6fb53a245d1c 100644 --- a/docs/docs/reference/metaprogramming/macros.md +++ b/docs/docs/reference/metaprogramming/macros.md @@ -42,7 +42,7 @@ def assertImpl(expr: Expr[Boolean])(using Quotes) = '{ } def showExpr(expr: Expr[Boolean])(using Quotes): Expr[String] = - '{ "" } // Better implementation later in this document + '{ "" } // Better implementation later in this document ``` If `e` is an expression, then `'{e}` represents the typed @@ -256,15 +256,16 @@ The compiler takes an environment that maps variable names to Scala `Expr`s. ```scala import scala.quoted._ -def compile(e: Exp, env: Map[String, Expr[Int]])(using Quotes): Expr[Int] = e match - case Num(n) => - Expr(n) - case Plus(e1, e2) => - '{ ${ compile(e1, env) } + ${ compile(e2, env) } } - case Var(x) => - env(x) - case Let(x, e, body) => - '{ val y = ${ compile(e, env) }; ${ compile(body, env + (x -> 'y)) } } +def compile(e: Exp, env: Map[String, Expr[Int]])(using Quotes): Expr[Int] = + e match + case Num(n) => + Expr(n) + case Plus(e1, e2) => + '{ ${ compile(e1, env) } + ${ compile(e2, env) } } + case Var(x) => + env(x) + case Let(x, e, body) => + '{ val y = ${ compile(e, env) }; ${ compile(body, env + (x -> 'y)) } } ``` Running `compile(letExp, Map())` would yield the following Scala code: @@ -431,8 +432,8 @@ should be treated by the compiler as if it was quoted: ```scala @main def program = '{ - val x = 1 - ${ Macros.assertImpl('{ x != 0 }) } + val x = 1 + ${ Macros.assertImpl('{ x != 0 }) } } ``` @@ -527,7 +528,8 @@ function `f` and one `sum` that performs a sum by delegating to `map`. ```scala object Macros: - def map[T](arr: Expr[Array[T]], f: Expr[T] => Expr[Unit])(using Type[T], Quotes): Expr[Unit] = '{ + def map[T](arr: Expr[Array[T]], f: Expr[T] => Expr[Unit]) + (using Type[T], Quotes): Expr[Unit] = '{ var i: Int = 0 while i < ($arr).length do val element: T = ($arr)(i) @@ -582,7 +584,7 @@ val arr: Array[Int] = Array.apply(1, [2,3 : Int]:Int*) var sum = 0 val f = x => '{sum += $x} var i: Int = 0 -while i < (arr).length do +while i < arr.length do val element: Int = (arr)(i) sum += element i += 1 @@ -624,7 +626,8 @@ inline method that can calculate either a value of type `Int` or a value of type `String`. ```scala -transparent inline def defaultOf(inline str: String) = ${ defaultOfImpl('str) } +transparent inline def defaultOf(inline str: String) = + ${ defaultOfImpl('str) } def defaultOfImpl(strExpr: Expr[String])(using Quotes): Expr[Any] = strExpr.valueOrError match @@ -693,14 +696,16 @@ optimize { ```scala def sum(args: Int*): Int = args.sum inline def optimize(inline arg: Int): Int = ${ optimizeExpr('arg) } -private def optimizeExpr(body: Expr[Int])(using Quotes): Expr[Int] = body match - // Match a call to sum without any arguments - case '{ sum() } => Expr(0) - // Match a call to sum with an argument $n of type Int. n will be the Expr[Int] representing the argument. - case '{ sum($n) } => n - // Match a call to sum and extracts all its args in an `Expr[Seq[Int]]` - case '{ sum(${Varargs(args)}: _*) } => sumExpr(args) - case body => body +private def optimizeExpr(body: Expr[Int])(using Quotes): Expr[Int] = + body match + // Match a call to sum without any arguments + case '{ sum() } => Expr(0) + // Match a call to sum with an argument $n of type Int. + // n will be the Expr[Int] representing the argument. + case '{ sum($n) } => n + // Match a call to sum and extracts all its args in an `Expr[Seq[Int]]` + case '{ sum(${Varargs(args)}: _*) } => sumExpr(args) + case body => body private def sumExpr(args1: Seq[Expr[Int]])(using Quotes): Expr[Int] = def flatSumArgs(arg: Expr[Int]): Seq[Expr[Int]] = arg match @@ -717,13 +722,15 @@ private def sumExpr(args1: Seq[Expr[Int]])(using Quotes): Expr[Int] = Sometimes it is necessary to get a more precise type for an expression. This can be achived using the following pattern match. ```scala -def f(expr: Expr[Any])(using Quotes) = - expr match - case '{ $x: t } => - // If the pattern match succeeds, then there is some type `t` such that - // - `x` is bound to a variable of type `Expr[t]` - // - `t` is bound to a new type `t` and a given instance `Type[t]` is provided for it - // That is, we have `x: Expr[t]` and `given Type[t]`, for some (unknown) type `t`. +def f(expr: Expr[Any])(using Quotes) = expr match + case '{ $x: t } => + // If the pattern match succeeds, then there is + // some type `t` such that + // - `x` is bound to a variable of type `Expr[t]` + // - `t` is bound to a new type `t` and a given + // instance `Type[t]` is provided for it + // That is, we have `x: Expr[t]` and `given Type[t]`, + // for some (unknown) type `t`. ``` This might be used to then perform an implicit search as in: @@ -787,7 +794,8 @@ inline def eval(inline e: Int): Int = ${ evalExpr('e) } private def evalExpr(e: Expr[Int])(using Quotes): Expr[Int] = e match case '{ val y: Int = $x; $body(y): Int } => - // body: Expr[Int => Int] where the argument represents references to y + // body: Expr[Int => Int] where the argument represents + // references to y evalExpr(Expr.betaReduce('{$body(${evalExpr(x)})})) case '{ ($x: Int) * ($y: Int) } => (x.value, y.value) match diff --git a/docs/docs/reference/metaprogramming/simple-smp.md b/docs/docs/reference/metaprogramming/simple-smp.md index ec5709ed8f45..b2f09ed8ab87 100644 --- a/docs/docs/reference/metaprogramming/simple-smp.md +++ b/docs/docs/reference/metaprogramming/simple-smp.md @@ -123,9 +123,9 @@ Proof by structural induction over terms. To prove (1): - - the cases for variables, lambdas and applications are as in STL. + - the cases for variables, lambdas and applications are as in [STL](https://en.wikipedia.org/wiki/Simply_typed_lambda_calculus). - If `t = ’t2`, then by inversion we have ` ’ E1 |- t2: T2` for some type `T2`. - By the second I.H., we have one of: + By the second [induction hypothesis](https://en.wikipedia.org/wiki/Mathematical_induction) (I.H.), we have one of: - `t2 = u`, hence `’t2` is a value, - `t2 ==> t3`, hence `’t2 --> ’t3`. - The case `t = ~t2` is not typable. @@ -138,8 +138,8 @@ To prove (2): - If `t = t1 t2` then one of three cases applies: - `t1` and `t2` are a simple term, then `t` is as well a simple term. - - `t1` is not a simple term. Then by the second IH, `t1 ==> t12`, hence `t ==> t12 t2`. - - `t1` is a simple term but `t2` is not. Then by the second IH. `t2 ==> t22`, hence `t ==> t1 t22`. + - `t1` is not a simple term. Then by the second I.H., `t1 ==> t12`, hence `t ==> t12 t2`. + - `t1` is a simple term but `t2` is not. Then by the second I.H. `t2 ==> t22`, hence `t ==> t1 t22`. - The case `t = ’t2` is not typable. - If `t = ~t2` then by inversion we have `E2 ~ |- t2: ’T2`, for some type `T2`. diff --git a/docs/docs/reference/metaprogramming/staging.md b/docs/docs/reference/metaprogramming/staging.md index e1239afc7d88..af657f7e0e7a 100644 --- a/docs/docs/reference/metaprogramming/staging.md +++ b/docs/docs/reference/metaprogramming/staging.md @@ -77,11 +77,11 @@ def withQuotes[T](thunk: Quotes ?=> T)(using toolbox: Toolbox): T = ... sbt new scala/scala3-staging.g8 ``` -From [scala/scala3-staging.g8](https://github.com/scala/scala3-staging.g8). +From [`scala/scala3-staging.g8`](https://github.com/scala/scala3-staging.g8). It will create a project with the necessary dependencies and some examples. -In case you prefer to create the project on your own, make sure to define the following dependency in your build.sbt +In case you prefer to create the project on your own, make sure to define the following dependency in your [`build.sbt` build definition](https://www.scala-sbt.org/1.x/docs/Basic-Def.html) ```scala libraryDependencies += "org.scala-lang" %% "scala3-staging" % scalaVersion.value @@ -110,7 +110,8 @@ import scala.quoted.staging._ given Toolbox = Toolbox.make(getClass.getClassLoader) val f: Array[Int] => Int = run { - val stagedSum: Expr[Array[Int] => Int] = '{ (arr: Array[Int]) => ${sum('arr)}} + val stagedSum: Expr[Array[Int] => Int] = + '{ (arr: Array[Int]) => ${sum('arr)}} println(stagedSum.show) // Prints "(arr: Array[Int]) => { var sum = 0; ... }" stagedSum } diff --git a/docs/docs/reference/new-types/dependent-function-types.md b/docs/docs/reference/new-types/dependent-function-types.md index e5cb25e65ac9..8e7a79ae2b37 100644 --- a/docs/docs/reference/new-types/dependent-function-types.md +++ b/docs/docs/reference/new-types/dependent-function-types.md @@ -38,8 +38,7 @@ analogously for functions with more parameters. Dependent functions are also represented as instances of these traits, but they get an additional refinement. In fact, the dependent function type above is just syntactic sugar for ```scala -Function1[Entry, Entry#Key] { - def apply(e: Entry): e.Key -} +Function1[Entry, Entry#Key]: + def apply(e: Entry): e.Key ``` [More details](./dependent-function-types-spec.md) diff --git a/docs/docs/reference/new-types/match-types.md b/docs/docs/reference/new-types/match-types.md index 019b6c67eade..72ee3f87384c 100644 --- a/docs/docs/reference/new-types/match-types.md +++ b/docs/docs/reference/new-types/match-types.md @@ -171,9 +171,7 @@ and constraints. if - ``` - S match { P1 => T1 ... Pn => Tn } reduces-to U - ``` + `S match { P1 => T1 ... Pn => Tn }` reduces to `U` 3. The third rule states that a match type conforms to its upper bound: @@ -202,13 +200,14 @@ def g[X]: L[X] = ??? | ^ |Recursion limit exceeded. |Maybe there is an illegal cyclic reference? - |If that's not the case, you could also try to increase the stacksize using the -Xss JVM option. + |If that's not the case, you could also try to + |increase the stacksize using the -Xss JVM option. |A recurring operation is (inner to outer): | | subtype LazyRef(Test.L[Int]) <:< Int ``` -Internally, `scalac` detects these cycles by turning selected stack overflows into +Internally, the Scala compiler detects these cycles by turning selected stack overflows into type errors. If there is a stack overflow during subtyping, the exception will be caught and turned into a compile-time error that indicates a trace of the subtype tests that caused the overflow without showing a full stack trace. @@ -218,7 +217,7 @@ NOTE: This section does not reflect the current implementation. 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 +pattern position are contravariant (since patterns are represented as function type arguments). ## Related Work diff --git a/docs/docs/reference/new-types/polymorphic-function-types.md b/docs/docs/reference/new-types/polymorphic-function-types.md index 24393e9512e7..9b6abb9b6dd5 100644 --- a/docs/docs/reference/new-types/polymorphic-function-types.md +++ b/docs/docs/reference/new-types/polymorphic-function-types.md @@ -33,7 +33,7 @@ then take a list of type `List[A]`, and return a list of the same type `List[A]` [More details](https://github.com/lampepfl/dotty/pull/4672) -### Example Usage +## Example Usage Polymorphic function type are particularly useful when callers of a method are required to provide a @@ -42,7 +42,7 @@ meaning that it should accept arbitrary types as part of its inputs. For instance, consider the situation where we have a data type to represent the expressions of a simple language -(consisting only of variables and function application) +(consisting only of variables and function applications) in a strongly-typed way: ```scala @@ -75,9 +75,7 @@ val e1 = mapSubexpressions(e0)( println(e1) // Apply(Apply(Var(wrap),Var(f)),Apply(Var(wrap),Var(a))) ``` - - -### Relationship With Type Lambdas +## Relationship With Type Lambdas Polymorphic function types are not to be confused with [_type lambdas_](type-lambdas.md). diff --git a/docs/docs/reference/new-types/union-types-spec.md b/docs/docs/reference/new-types/union-types-spec.md index ec616af32c60..ad1fe6b8f57e 100644 --- a/docs/docs/reference/new-types/union-types-spec.md +++ b/docs/docs/reference/new-types/union-types-spec.md @@ -38,14 +38,14 @@ case _: (A | B) => ... A & (B | C) =:= A & B | A & C ``` -From these rules it follows that the _least upper bound_ (lub) of a set of types +From these rules it follows that the _least upper bound_ (LUB) of a set of types is the union of these types. This replaces the [definition of least upper bound in the Scala 2 specification](https://www.scala-lang.org/files/archive/spec/2.12/03-types.html#least-upper-bounds-and-greatest-lower-bounds). ## Motivation The primary reason for introducing union types in Scala is that they allow us to -guarantee that for every set of types, we can always form a finite lub. This is +guarantee that for every set of types, we can always form a finite LUB. This is both useful in practice (infinite lubs in Scala 2 were approximated in an ad-hoc way, resulting in imprecise and sometimes incredibly long types) and in theory (the type system of Scala 3 is based on the @@ -145,9 +145,9 @@ exhaustive if all parts of the union are covered. The erased type for `A | B` is the _erased least upper bound_ of the erased types of `A` and `B`. Quoting from the documentation of `TypeErasure#erasedLub`, -the erased lub is computed as follows: +the erased LUB is computed as follows: -- if both argument are arrays of objects, an array of the erased lub of the element types +- if both argument are arrays of objects, an array of the erased LUB of the element types - if both arguments are arrays of same primitives, an array of this primitive - 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) diff --git a/docs/docs/reference/new-types/union-types.md b/docs/docs/reference/new-types/union-types.md index c0a03907df75..4de0fd842421 100644 --- a/docs/docs/reference/new-types/union-types.md +++ b/docs/docs/reference/new-types/union-types.md @@ -21,7 +21,7 @@ Union types are duals of intersection types. `|` is _commutative_: `A | B` is the same type as `B | A`. The compiler will assign a union type to an expression only if such a -type is explicitly given. This can be seen in the following REPL transcript: +type is explicitly given. This can be seen in the following [REPL](https://docs.scala-lang.org/overviews/repl/overview.html) transcript: ```scala scala> val password = Password(123) diff --git a/docs/docs/reference/other-new-features/creator-applications.md b/docs/docs/reference/other-new-features/creator-applications.md index 2b7cce294d50..4ac09f49e84f 100644 --- a/docs/docs/reference/other-new-features/creator-applications.md +++ b/docs/docs/reference/other-new-features/creator-applications.md @@ -39,6 +39,7 @@ Constructor proxy companions cannot be used as values by themselves. A proxy com Constructor proxies are also not allowed to shadow normal definitions. That is, if an identifier resolves to a constructor proxy, and the same identifier is also defined or imported in some other scope, an ambiguity is reported. + ### Motivation Leaving out `new` hides an implementation detail and makes code more pleasant to read. Even though it requires a new rule, it will likely increase the perceived regularity of the language, since case classes already provide function call creation syntax (and are often defined for this reason alone). diff --git a/docs/docs/reference/other-new-features/export.md b/docs/docs/reference/other-new-features/export.md index 8abd71e68936..b770cbf99c03 100644 --- a/docs/docs/reference/other-new-features/export.md +++ b/docs/docs/reference/other-new-features/export.md @@ -89,18 +89,18 @@ Export clauses can appear in classes or they can appear at the top-level. An exp (\*) Note: Unless otherwise stated, the term "class" in this discussion also includes object and trait definitions. -### Motivation +## Motivation It is a standard recommendation to prefer composition over inheritance. This is really an application of the principle of least power: Composition treats components as blackboxes whereas inheritance can affect the internal workings of components through overriding. Sometimes the close coupling implied by inheritance is the best solution for a problem, but where this is not necessary the looser coupling of composition is better. -So far, object oriented languages including Scala made it much easier to use inheritance than composition. Inheritance only requires an `extends` clause whereas composition required a verbose elaboration of a sequence of forwarders. So in that sense, OO languages are pushing +So far, object oriented languages including Scala made it much easier to use inheritance than composition. Inheritance only requires an `extends` clause whereas composition required a verbose elaboration of a sequence of forwarders. So in that sense, object-oriented languages are pushing programmers to a solution that is often too powerful. Export clauses redress the balance. They make composition relationships as concise and easy to express as inheritance relationships. Export clauses also offer more flexibility than extends clauses since members can be renamed or omitted. Export clauses also fill a gap opened by the shift from package objects to top-level definitions. One occasionally useful idiom that gets lost in this shift is a package object inheriting from some class. The idiom is often used in a facade like pattern, to make members of internal compositions available to users of a package. Top-level definitions are not wrapped in a user-defined object, so they can't inherit anything. However, top-level definitions can be export clauses, which supports the facade design pattern in a safer and more flexible way. -### Syntax changes: +## Syntax changes: ``` TemplateStat ::= ... @@ -110,7 +110,7 @@ TopStat ::= ... Export ::= ‘export’ [‘given’] ImportExpr {‘,’ ImportExpr} ``` -### Elaboration of Export Clauses +## Elaboration of Export Clauses Export clauses raise questions about the order of elaboration during type checking. Consider the following example: diff --git a/docs/docs/reference/other-new-features/open-classes.md b/docs/docs/reference/other-new-features/open-classes.md index 19b4fe6584c4..c1ee2def453b 100644 --- a/docs/docs/reference/other-new-features/open-classes.md +++ b/docs/docs/reference/other-new-features/open-classes.md @@ -34,13 +34,14 @@ Classes that are not open can still be extended, but only if at least one of two ```scala import scala.language.adhocExtensions ``` - Alternatively, the feature can be enabled by the command line option `-language:adhocExtensions`. + Alternatively, the feature can be enabled by the compiler option `-language:adhocExtensions`. If the feature is not enabled, the compiler will issue a "feature" warning. For instance, if the `open` modifier on class `Writer` is dropped, compiling `EncryptedWriter` would produce a warning: ``` -- Feature Warning: EncryptedWriter.scala:6:14 ---- |class EncryptedWriter[T: Encryptable] extends Writer[T] | ^ - |Unless class Writer is declared 'open', its extension in a separate file should be enabled + |Unless class Writer is declared 'open', its extension + | in a separate file should be enabled |by adding the import clause 'import scala.language.adhocExtensions' |or by setting the compiler option -language:adhocExtensions. ``` diff --git a/docs/docs/reference/other-new-features/safe-initialization.md b/docs/docs/reference/other-new-features/safe-initialization.md index 8bf27653bc84..bc035d3eb898 100644 --- a/docs/docs/reference/other-new-features/safe-initialization.md +++ b/docs/docs/reference/other-new-features/safe-initialization.md @@ -300,5 +300,5 @@ Java or Scala 2 is always safe. ## References -- Fähndrich, M. and Leino, K.R.M., 2003, July. _Heap monotonic typestates_. In International Workshop on Aliasing, Confinement and Ownership in object-oriented programming (IWACO). -- Lucassen, J.M. and Gifford, D.K., 1988, January. _Polymorphic effect systems_. In Proceedings of the 15th ACM SIGPLAN-SIGACT symposium on Principles of programming languages (pp. 47-57). ACM. +- Fähndrich, M. and Leino, K.R.M., 2003, July. [_Heap monotonic typestates_](https://www.microsoft.com/en-us/research/publication/heap-monotonic-typestate/). In International Workshop on Aliasing, Confinement and Ownership in object-oriented programming (IWACO). +- Lucassen, J.M. and Gifford, D.K., 1988, January. [_Polymorphic effect systems_](https://dl.acm.org/doi/10.1145/73560.73564). In Proceedings of the 15th ACM SIGPLAN-SIGACT symposium on Principles of programming languages (pp. 47-57). ACM. diff --git a/docs/docs/reference/other-new-features/targetName.md b/docs/docs/reference/other-new-features/targetName.md index e95a54405296..865ebaa0ef69 100644 --- a/docs/docs/reference/other-new-features/targetName.md +++ b/docs/docs/reference/other-new-features/targetName.md @@ -83,7 +83,8 @@ The compiler reports here: 6 | @targetName("g") def f(): Int = 2 | ^ |error overriding method f in class A of type (): Int; - | method f of type (): Int should not have a @targetName annotation since the overridden member hasn't one either + | method f of type (): Int should not have a @targetName + | annotation since the overridden member hasn't one either ``` The relevant overriding rules can be summarized as follows: diff --git a/docs/docs/reference/other-new-features/trait-parameters.md b/docs/docs/reference/other-new-features/trait-parameters.md index 416b47fc08bc..c82c1e225f1c 100644 --- a/docs/docs/reference/other-new-features/trait-parameters.md +++ b/docs/docs/reference/other-new-features/trait-parameters.md @@ -52,6 +52,6 @@ The correct way to write `E` is to extend both `Greeting` and class E extends Greeting("Bob"), FormalGreeting ``` -### Reference +## Reference For more info, see [Scala SIP 25](http://docs.scala-lang.org/sips/pending/trait-parameters.html). diff --git a/docs/docs/reference/other-new-features/transparent-traits.md b/docs/docs/reference/other-new-features/transparent-traits.md index 8e3ce78a16f4..babe8537e480 100644 --- a/docs/docs/reference/other-new-features/transparent-traits.md +++ b/docs/docs/reference/other-new-features/transparent-traits.md @@ -17,7 +17,7 @@ val x = Set(if condition then Val else Var) ``` Here, the inferred type of `x` is `Set[Kind & Product & Serializable]` whereas one would have hoped it to be `Set[Kind]`. The reasoning for this particular type to be inferred is as follows: - - The type of the conditional above is the union type `Val | Var`. + - The type of the conditional above is the [union type](new-types/union-types.md) `Val | Var`. - A union type is widened in type inference to the least supertype that is not a union type. In the example, this type is `Kind & Product & Serializable` since all three traits are traits of both `Val` and `Var`. So that type becomes the inferred element type of the set. @@ -33,7 +33,7 @@ val x = Set(if condition then Val else Var) Now `x` has inferred type `Set[Kind]`. The common transparent trait `S` does not appear in the inferred type. -### Transparent Traits +## Transparent Traits The traits `scala.Product`, `java.lang.Serializable` and `java.lang.Comparable` are treated automatically as transparent. Other traits are turned into transparent traits using the modifier `transparent`. Scala 2 traits can also be made transparent @@ -49,7 +49,7 @@ that influence the implementation of inheriting classes and traits that are not Generally, any trait that is extended recursively is a good candidate to be declared transparent. -### Rules for Inference +## Rules for Inference Transparent traits can be given as explicit types as usual. But they are often elided when types are inferred. Roughly, the rules for type inference say that transparent traits are dropped from intersections where possible. diff --git a/docs/docs/reference/overview.md b/docs/docs/reference/overview.md index 89904661a18c..38c27f0622d1 100644 --- a/docs/docs/reference/overview.md +++ b/docs/docs/reference/overview.md @@ -88,7 +88,7 @@ The date when these constructs are dropped varies. The current status is: - Supported under `-source 3.0-migration`: - procedure syntax, class shadowing, symbol literals, auto application, auto tupling in a restricted form. - Supported in 3.0, to be deprecated and phased out later: - - XML literals, compound types. + - [XML literals](dropped-features/xml.md), compound types. ## Changes @@ -126,7 +126,7 @@ To enable porting most uses of macros, we are experimenting with the advanced la by itself a straightforward implementation of some simple macros and is at the same time an essential building block for the implementation of complex macros. - [Quotes and Splices](metaprogramming/macros.md) provide a principled way to express macros and staging with a unified set of abstractions. - [Type class derivation](contextual/derivation.md) provides an in-language implementation of the `Gen` macro in Shapeless and other foundational libraries. The new implementation is more robust, efficient and easier to use than the macro. -- [Implicit by-name parameters](contextual/implicit-by-name-parameters.md) provide a more robust in-language implementation of the `Lazy` macro in Shapeless. +- [Implicit by-name parameters](contextual/implicit-by-name-parameters.md) provide a more robust in-language implementation of the `Lazy` macro in [Shapeless](https://github.com/milessabin/shapeless). ## See Also diff --git a/docs/docs/reference/syntax.md b/docs/docs/reference/syntax.md index a3841db7da50..6764ed477179 100644 --- a/docs/docs/reference/syntax.md +++ b/docs/docs/reference/syntax.md @@ -103,8 +103,9 @@ type val var while with yield ### Soft keywords ``` -derives end extension inline infix opaque open transparent using | * + - +derives end extension infix inline opaque open transparent using | * + - ``` + See the [separate section on soft keywords](./soft-modifier.md) for additional details on where a soft keyword is recognized. From adda26750544c22ed4e63cc77df7a68648b0fb4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Micheloud?= Date: Wed, 23 Dec 2020 22:52:34 +0100 Subject: [PATCH 2/4] addressed review comment (STL->STLC) --- docs/docs/reference/metaprogramming/simple-smp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/reference/metaprogramming/simple-smp.md b/docs/docs/reference/metaprogramming/simple-smp.md index b2f09ed8ab87..7335135869c7 100644 --- a/docs/docs/reference/metaprogramming/simple-smp.md +++ b/docs/docs/reference/metaprogramming/simple-smp.md @@ -123,7 +123,7 @@ Proof by structural induction over terms. To prove (1): - - the cases for variables, lambdas and applications are as in [STL](https://en.wikipedia.org/wiki/Simply_typed_lambda_calculus). + - the cases for variables, lambdas and applications are as in [STLC](https://en.wikipedia.org/wiki/Simply_typed_lambda_calculus). - If `t = ’t2`, then by inversion we have ` ’ E1 |- t2: T2` for some type `T2`. By the second [induction hypothesis](https://en.wikipedia.org/wiki/Mathematical_induction) (I.H.), we have one of: - `t2 = u`, hence `’t2` is a value, From 04a6ede7da2302068bca5a8222c494555939e20d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Micheloud?= Date: Wed, 23 Dec 2020 22:56:55 +0100 Subject: [PATCH 3/4] addressed review comment (removed 'Implementation') --- docs/docs/reference/metaprogramming/erased-terms-spec.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/docs/reference/metaprogramming/erased-terms-spec.md b/docs/docs/reference/metaprogramming/erased-terms-spec.md index 0d84fa93afaf..2813ab9941d8 100644 --- a/docs/docs/reference/metaprogramming/erased-terms-spec.md +++ b/docs/docs/reference/metaprogramming/erased-terms-spec.md @@ -3,9 +3,7 @@ layout: doc-page title: "Erased Terms Spec" --- -## Implementation - -### Rules +## Rules 1. The `erased` modifier can appear: * At the start of a parameter block of a method, function or class From 5d5a066fe5316e52535fa977740278e6ddae9c09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Micheloud?= Date: Thu, 24 Dec 2020 00:12:26 +0100 Subject: [PATCH 4/4] fixed indentation in object Mirror --- docs/docs/reference/contextual/derivation.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/docs/reference/contextual/derivation.md b/docs/docs/reference/contextual/derivation.md index 1c9c510f83bb..366f208ee6ca 100644 --- a/docs/docs/reference/contextual/derivation.md +++ b/docs/docs/reference/contextual/derivation.md @@ -59,13 +59,13 @@ sealed trait Mirror: object Mirror: - /** The Mirror for a product type */ - trait Product extends Mirror: + /** The Mirror for a product type */ + trait Product extends Mirror: - /** Create a new instance of type `T` with elements - * taken from product `p`. - */ - def fromProduct(p: scala.Product): MirroredMonoType + /** Create a new instance of type `T` with elements + * taken from product `p`. + */ + def fromProduct(p: scala.Product): MirroredMonoType trait Sum extends Mirror: