From ec15527aa93bff47e17f3bd7bf36d000dc535e29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Micheloud?= Date: Thu, 17 Dec 2020 00:25:20 +0100 Subject: [PATCH 1/3] more fixes in Markdown files --- .../changed-features/eta-expansion-spec.md | 8 +++--- .../implicit-conversions-spec.md | 7 ++--- .../changed-features/implicit-resolution.md | 8 +++--- .../changed-features/pattern-matching.md | 8 +++--- .../reference/contextual/context-functions.md | 9 ++++--- docs/docs/reference/contextual/conversions.md | 5 ++-- .../reference/contextual/derivation-macro.md | 26 ++++++++++--------- docs/docs/reference/contextual/derivation.md | 26 ++++++++++++------- .../reference/contextual/extension-methods.md | 3 ++- docs/docs/reference/contextual/motivation.md | 2 +- .../contextual/relationship-implicits.md | 12 +++++---- .../reference/dropped-features/auto-apply.md | 4 +-- .../dropped-features/class-shadowing-spec.md | 4 +-- .../dropped-features/existential-types.md | 6 +++-- .../dropped-features/package-objects.md | 2 +- .../dropped-features/procedure-syntax.md | 4 +-- .../dropped-features/weak-conformance-spec.md | 5 ++-- docs/docs/reference/enums/enums.md | 2 +- .../reference/metaprogramming/erased-terms.md | 18 +++++++------ .../reference/metaprogramming/macros-spec.md | 4 +-- docs/docs/reference/metaprogramming/macros.md | 8 +++--- .../docs/reference/metaprogramming/staging.md | 2 +- .../metaprogramming/tasty-inspect.md | 2 +- .../metaprogramming/tasty-reflect.md | 9 ++++--- docs/docs/reference/metaprogramming/toc.md | 2 +- .../reference/new-types/type-lambdas-spec.md | 2 +- .../reference/new-types/union-types-spec.md | 7 ++--- .../other-new-features/control-syntax.md | 2 +- .../other-new-features/explicit-nulls.md | 1 + .../other-new-features/indentation.md | 2 +- .../reference/other-new-features/opaques.md | 12 ++++++--- .../other-new-features/open-classes.md | 2 +- .../parameter-untupling-spec.md | 3 +-- .../other-new-features/targetName.md | 2 +- docs/docs/reference/overview.md | 16 +++++++----- docs/docs/reference/syntax.md | 2 +- 36 files changed, 133 insertions(+), 104 deletions(-) diff --git a/docs/docs/reference/changed-features/eta-expansion-spec.md b/docs/docs/reference/changed-features/eta-expansion-spec.md index bcfe488607ad..28ac11eef2e8 100644 --- a/docs/docs/reference/changed-features/eta-expansion-spec.md +++ b/docs/docs/reference/changed-features/eta-expansion-spec.md @@ -3,11 +3,13 @@ layout: doc-page title: "Automatic Eta Expansion - More Details" --- -### Motivation +## Motivation Scala maintains a convenient distinction between _methods_ and _functions_. Methods are part of the definition of a class that can be invoked in objects while functions are complete objects themselves, making them first-class entities. For example, they can be assigned to variables. -These two mechanisms are bridged in Scala by a mechanism called _eta-expansion_ (also called eta-abstraction), which converts a reference to a method into a function. Intuitively, a method `m` can be passed around by turning it into an object: the function `x => m(x)`. +These two mechanisms are bridged in Scala by a mechanism called +[_eta-expansion_](https://www.scala-lang.org/files/archive/spec/2.13/06-expressions.html#eta-expansion-section) +(also called eta-abstraction), which converts a reference to a method into a function. Intuitively, a method `m` can be passed around by turning it into an object: the function `x => m(x)`. In this snippet which assigns a method to a `val`, the compiler will perform _automatic eta-expansion_, as shown in the comment: @@ -69,6 +71,6 @@ Thus, an unapplied method with an empty argument list is only converted to a fun The method value syntax `m _` is deprecated. -### Reference +## Reference For more info, see [PR #2701](https://github.com/lampepfl/dotty/pull/2701). diff --git a/docs/docs/reference/changed-features/implicit-conversions-spec.md b/docs/docs/reference/changed-features/implicit-conversions-spec.md index 0c6a90444150..007c05f1cd4e 100644 --- a/docs/docs/reference/changed-features/implicit-conversions-spec.md +++ b/docs/docs/reference/changed-features/implicit-conversions-spec.md @@ -16,7 +16,8 @@ The standard library defines an abstract class `Conversion`: ```scala package scala @java.lang.FunctionalInterface -abstract class Conversion[-T, +U] extends Function1[T, U] +abstract class Conversion[-T, +U] extends Function1[T, U]: + def apply(x: T): U ``` Function literals are automatically converted to `Conversion` values. @@ -80,8 +81,8 @@ implicit val myConverter: Int => String = _.toString implicit val myConverter: Conversion[Int, String] = _.toString ``` -Note that implicit conversions are also affected by the [changes to -implicit resolution](implicit-resolution.md) between Scala 2 and +Note that implicit conversions are also affected by the +[changes to implicit resolution](implicit-resolution.md) between Scala 2 and Scala 3. ## Motivation for the changes diff --git a/docs/docs/reference/changed-features/implicit-resolution.md b/docs/docs/reference/changed-features/implicit-resolution.md index 911a3a2697c2..732a9f5c4785 100644 --- a/docs/docs/reference/changed-features/implicit-resolution.md +++ b/docs/docs/reference/changed-features/implicit-resolution.md @@ -2,7 +2,7 @@ layout: doc-page title: "Changes in Implicit Resolution" --- -This page describes changes to the implicit resolution that apply both to the new `given`s and to the old-style `implicit`s in Scala 3. +This section describes changes to the implicit resolution that apply both to the new `given`s and to the old-style `implicit`s in Scala 3. Implicit resolution uses a new algorithm which caches implicit results more aggressively for performance. There are also some changes that affect implicits on the language level. @@ -20,8 +20,8 @@ where the type may still be inferred: /*!*/ implicit def y = ... // error: type must be given explicitly val y = { - implicit val ctx = this.ctx // ok - ... + implicit val ctx = this.ctx // ok + ... } ``` **2.** Nesting is now taken into account for selecting an implicit. Consider for instance the following scenario: @@ -114,7 +114,7 @@ the implicit search for `Q` fails. **5.** The treatment of divergence errors has also changed. A divergent implicit is treated as a normal failure, after which alternatives are still tried. This also makes sense: Encountering a divergent implicit means that we assume that no finite solution can be found on the corresponding path, but another path can still be tried. By contrast, most (but not all) divergence errors in Scala 2 would terminate the implicit search as a whole. -**6.** Scala-2 gives a lower level of priority to implicit conversions with call-by-name parameters relative to implicit conversions with call-by-value parameters. Scala 3 drops this distinction. So the following code snippet would be ambiguous in Scala 3: +**6.** Scala 2 gives a lower level of priority to implicit conversions with call-by-name parameters relative to implicit conversions with call-by-value parameters. Scala 3 drops this distinction. So the following code snippet would be ambiguous in Scala 3: ```scala implicit def conv1(x: Int): A = new A(x) diff --git a/docs/docs/reference/changed-features/pattern-matching.md b/docs/docs/reference/changed-features/pattern-matching.md index cb389db5f3b3..71b82a91cfcc 100644 --- a/docs/docs/reference/changed-features/pattern-matching.md +++ b/docs/docs/reference/changed-features/pattern-matching.md @@ -16,8 +16,8 @@ def unapply[A](x: T)(implicit x: B): U def unapplySeq[A](x: T)(implicit x: B): U ``` -Extractors expose the method `unapply` are called fixed-arity extractors, which -work with patterns of fixed arity. Extractors expose the method `unapplySeq` are +Extractors that expose the method `unapply` are called fixed-arity extractors, which +work with patterns of fixed arity. Extractors that expose the method `unapplySeq` are called variadic extractors, which enables variadic patterns. ### Fixed-Arity Extractors @@ -93,7 +93,7 @@ A usage of a variadic extractor is irrefutable if one of the following condition ## Boolean Match - `U =:= Boolean` -- Pattern-matching on exactly `0` patterns +- Pattern-matching on exactly `0` pattern For example: @@ -250,4 +250,4 @@ Abstract type testing with `ClassTag` is replaced with `TypeTest` or the alias ` - pattern `_: X` for an abstract type requires a `TypeTest` in scope - pattern `x @ X()` for an unapply that takes an abstract type requires a `TypeTest` in scope -[More details on TypeTest](../other-new-features/type-test.md) +[More details on `TypeTest`](../other-new-features/type-test.md) diff --git a/docs/docs/reference/contextual/context-functions.md b/docs/docs/reference/contextual/context-functions.md index 130c0d1333c1..36eb1caf2f1d 100644 --- a/docs/docs/reference/contextual/context-functions.md +++ b/docs/docs/reference/contextual/context-functions.md @@ -125,10 +125,11 @@ object PostConditions { def result[T](using r: WrappedResult[T]): T = r - extension [T](x: T) def ensuring(condition: WrappedResult[T] ?=> Boolean): T = { - assert(condition(using x)) - x - } + extension [T](x: T) + def ensuring(condition: WrappedResult[T] ?=> Boolean): T = { + assert(condition(using x)) + x + } } import PostConditions.{ensuring, result} diff --git a/docs/docs/reference/contextual/conversions.md b/docs/docs/reference/contextual/conversions.md index 234a6cae7f87..4e255d7f53f8 100644 --- a/docs/docs/reference/contextual/conversions.md +++ b/docs/docs/reference/contextual/conversions.md @@ -6,7 +6,8 @@ title: "Implicit Conversions" Implicit conversions are defined by given instances of the `scala.Conversion` class. This class is defined in package `scala` as follows: ```scala -abstract class Conversion[-T, +U] extends (T => U) +abstract class Conversion[-T, +U] extends (T => U): + def apply (x: T): U ``` For example, here is an implicit conversion from `String` to `Token`: ```scala @@ -41,7 +42,7 @@ given int2Integer: Conversion[Int, java.lang.Integer] = java.lang.Integer.valueOf(_) ``` -2. The "magnet" pattern is sometimes used to express many variants of a method. Instead of defining overloaded versions of the method, one can also let the method take one or more arguments of specially defined "magnet" types, into which various argument types can be converted. E.g. +2. The "magnet" pattern is sometimes used to express many variants of a method. Instead of defining overloaded versions of the method, one can also let the method take one or more arguments of specially defined "magnet" types, into which various argument types can be converted. Example: ```scala object Completions { diff --git a/docs/docs/reference/contextual/derivation-macro.md b/docs/docs/reference/contextual/derivation-macro.md index 810332ddbf22..b37fd9529d6f 100644 --- a/docs/docs/reference/contextual/derivation-macro.md +++ b/docs/docs/reference/contextual/derivation-macro.md @@ -91,12 +91,13 @@ The implementation of `summonAll` as a macro can be show below assuming that we have the given instances for our primitive types: ```scala - def summonAll[T: Type](using Quotes): List[Expr[Eq[_]]] = Type.of[T] match { - case '[String *: tpes] => '{ summon[Eq[String]] } :: summonAll[tpes] - case '[Int *: tpes] => '{ summon[Eq[Int]] } :: summonAll[tpes] - case '[tpe *: tpes] => derived[tpe] :: summonAll[tpes] - case '[EmptyTuple] => Nil - } + def summonAll[T: Type](using Quotes): List[Expr[Eq[_]]] = + Type.of[T] match { + case '[String *: tpes] => '{ summon[Eq[String]] } :: summonAll[tpes] + case '[Int *: tpes] => '{ summon[Eq[Int]] } :: summonAll[tpes] + case '[tpe *: tpes] => derived[tpe] :: summonAll[tpes] + case '[EmptyTuple] => Nil + } ``` One additional difference with the body of `derived` here as opposed to the one @@ -169,12 +170,13 @@ object Eq { def eqv(x: T, y: T): Boolean = body(x, y) } - def summonAll[T: Type](using Quotes): List[Expr[Eq[_]]] = Type.of[T] match { - case '[String *: tpes] => '{ summon[Eq[String]] } :: summonAll[tpes] - case '[Int *: tpes] => '{ summon[Eq[Int]] } :: summonAll[tpes] - case '[tpe *: tpes] => derived[tpe] :: summonAll[tpes] - case '[EmptyTuple] => Nil - } + def summonAll[T: Type](using Quotes): List[Expr[Eq[_]]] = + Type.of[T] match { + case '[String *: tpes] => '{ summon[Eq[String]] } :: summonAll[tpes] + case '[Int *: tpes] => '{ summon[Eq[Int]] } :: summonAll[tpes] + case '[tpe *: tpes] => derived[tpe] :: summonAll[tpes] + case '[EmptyTuple] => Nil + } given derived[T: Type](using q: Quotes): Expr[Eq[T]] = { import quotes.reflect._ diff --git a/docs/docs/reference/contextual/derivation.md b/docs/docs/reference/contextual/derivation.md index 3d2ec69ee6a8..1fec9cd62e58 100644 --- a/docs/docs/reference/contextual/derivation.md +++ b/docs/docs/reference/contextual/derivation.md @@ -63,12 +63,16 @@ object Mirror { /** The Mirror for a product type */ trait Product extends Mirror { - /** Create a new instance of type `T` with elements taken from product `p`. */ + /** Create a new instance of type `T` with elements + * taken from product `p`. + */ def fromProduct(p: scala.Product): MirroredMonoType } trait Sum extends Mirror { self => - /** The ordinal number of the case class of `x`. For enums, `ordinal(x) == x.ordinal` */ + /** The ordinal number of the case class of `x`. + * For enums, `ordinal(x) == x.ordinal` + */ def ordinal(x: MirroredMonoType): Int } } @@ -199,10 +203,11 @@ implementation of `summonAll` is `inline` and uses Scala 3's `summonInline` cons ```scala -inline def summonAll[T <: Tuple]: List[Eq[_]] = inline erasedValue[T] match { - case _: EmptyTuple => Nil - case _: (t *: ts) => summonInline[Eq[t]] :: summonAll[ts] -} +inline def summonAll[T <: Tuple]: List[Eq[_]] = + inline erasedValue[T] match { + case _: EmptyTuple => Nil + case _: (t *: ts) => summonInline[Eq[t]] :: summonAll[ts] + } ``` with the instances for children in hand the `derived` method uses an `inline match` to dispatch to methods which can @@ -243,10 +248,11 @@ Pulling this all together we have the following complete implementation, import scala.deriving._ import scala.compiletime.{erasedValue, summonInline} -inline def summonAll[T <: Tuple]: List[Eq[_]] = inline erasedValue[T] match { - case _: EmptyTuple => Nil - case _: (t *: ts) => summonInline[Eq[t]] :: summonAll[ts] -} +inline def summonAll[T <: Tuple]: List[Eq[_]] = + inline erasedValue[T] match { + case _: EmptyTuple => Nil + case _: (t *: ts) => summonInline[Eq[t]] :: summonAll[ts] + } trait Eq[T] { def eqv(x: T, y: T): Boolean diff --git a/docs/docs/reference/contextual/extension-methods.md b/docs/docs/reference/contextual/extension-methods.md index 587e833a015d..f2ba15d8db8e 100644 --- a/docs/docs/reference/contextual/extension-methods.md +++ b/docs/docs/reference/contextual/extension-methods.md @@ -215,7 +215,8 @@ object List: def < (ys: List[T]): Boolean = ... end List -// extension method available since it is in the implicit scope of List[List[Int]] +// extension method available since it is in the implicit scope +// of List[List[Int]] List(List(1, 2), List(3, 4)).flatten // extension method available since it is in the given Ordering[List[T]], diff --git a/docs/docs/reference/contextual/motivation.md b/docs/docs/reference/contextual/motivation.md index ecaf2bedd361..0730e09592e1 100644 --- a/docs/docs/reference/contextual/motivation.md +++ b/docs/docs/reference/contextual/motivation.md @@ -7,7 +7,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 or Swift's protocol extensions. 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) +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). 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. diff --git a/docs/docs/reference/contextual/relationship-implicits.md b/docs/docs/reference/contextual/relationship-implicits.md index dced9015adf4..8928f492b3a9 100644 --- a/docs/docs/reference/contextual/relationship-implicits.md +++ b/docs/docs/reference/contextual/relationship-implicits.md @@ -33,7 +33,8 @@ Given instances can be mapped to combinations of implicit objects, classes and i ```scala class listOrd[T](implicit ord: Ord[T]) extends Ord[List[T]] { ... } - final implicit def listOrd[T](implicit ord: Ord[T]): listOrd[T] = new listOrd[T] + final implicit def listOrd[T](implicit ord: Ord[T]): listOrd[T] = + new listOrd[T] ``` 3. Alias givens map to implicit methods or implicit lazy vals. If an alias has neither type nor context parameters, @@ -76,7 +77,7 @@ Tuples are treated as transparent, i.e. a type `F[(X, Y)]` would get the synthes ### Using Clauses -Using clauses correspond largely to Scala-2's implicit parameter clauses. E.g. +Using clauses correspond largely to Scala 2's implicit parameter clauses. E.g. ```scala def max[T](x: T, y: T)(using ord: Ord[T]): T @@ -112,7 +113,8 @@ will map to using clauses instead. Extension methods have no direct counterpart in Scala 2, but they can be simulated with implicit classes. For instance, the extension method ```scala -extension (c: Circle) def circumference: Double = c.radius * math.Pi * 2 +extension (c: Circle) + def circumference: Double = c.radius * math.Pi * 2 ``` could be simulated to some degree by @@ -123,7 +125,7 @@ implicit class CircleDecorator(c: Circle) extends AnyVal { } ``` -Abstract extension methods in traits that are implemented in given instances have no direct counterpart in Scala-2. The only way to simulate these is to make implicit classes available through imports. The Simulacrum macro library can automate this process in some cases. +Abstract extension methods in traits that are implemented in given instances have no direct counterpart in Scala 2. The only way to simulate these is to make implicit classes available through imports. The Simulacrum macro library can automate this process in some cases. ### Type Class Derivation @@ -197,7 +199,7 @@ given SymDecorator = symDecorator ## Implementation Status and Timeline -The Scala 3 implementation implements both Scala-2's implicits and the new abstractions. In fact, support for Scala-2's implicits is an essential part of the common language subset between 2.13/2.14 and Scala 3. +The Scala 3 implementation implements both Scala 2's implicits and the new abstractions. In fact, support for Scala 2's implicits is an essential part of the common language subset between 2.13/2.14 and Scala 3. Migration to the new abstractions will be supported by making automatic rewritings available. Depending on adoption patterns, old style implicits might start to be deprecated in a version following Scala 3.0. diff --git a/docs/docs/reference/dropped-features/auto-apply.md b/docs/docs/reference/dropped-features/auto-apply.md index db21008cd0a4..d7aa18ffcef3 100644 --- a/docs/docs/reference/dropped-features/auto-apply.md +++ b/docs/docs/reference/dropped-features/auto-apply.md @@ -4,7 +4,7 @@ title: "Dropped: Auto-Application" --- Previously an empty argument list `()` was implicitly inserted when -calling a nullary method without arguments. E.g. +calling a nullary method without arguments. Example: ```scala def next(): T = ... next // is expanded to next() @@ -69,7 +69,7 @@ class B extends A { def next: Int // overriding error: incompatible type } ``` -Methods overriding Java or Scala-2 methods are again exempted from this +Methods overriding Java or Scala 2 methods are again exempted from this requirement. ### Migrating code diff --git a/docs/docs/reference/dropped-features/class-shadowing-spec.md b/docs/docs/reference/dropped-features/class-shadowing-spec.md index 84e4cfdba9ce..427337a63df8 100644 --- a/docs/docs/reference/dropped-features/class-shadowing-spec.md +++ b/docs/docs/reference/dropped-features/class-shadowing-spec.md @@ -3,7 +3,7 @@ layout: doc-page title: "Dropped: Class Shadowing - More Details" --- -Spec diff: in section [5.1.4 Overriding](https://www.scala-lang.org/files/archive/spec/2.12/05-classes-and-objects.html), add *M' must not be a class*. +Spec diff: in section [5.1.4 Overriding](https://www.scala-lang.org/files/archive/spec/2.13/05-classes-and-objects.html#Overriding), add *M' must not be a class*. > Why do we want to make this change to the language? @@ -12,7 +12,7 @@ Class shadowing is irregular compared to other types of overrides. Indeed, inner > How much existing code is going to be affected? -From all the code compiled so far with Dotty the only instance of this I could find is in the stdlib. Looking at [this commit](https://github.com/lampepfl/scala/commit/68f13bf39979b631ed211ec1751934306ceb5d6c#diff-7aa508b70e055b47c823764e3e5646b8) it seems like the usage of class shadowing was accidental. +From all the code compiled so far with Scala 3 the only instance of this I could find is in the stdlib. Looking at [this commit](https://github.com/lampepfl/scala/commit/68f13bf39979b631ed211ec1751934306ceb5d6c#diff-7aa508b70e055b47c823764e3e5646b8) it seems like the usage of class shadowing was accidental. > How exactly is existing code going to be affected? diff --git a/docs/docs/reference/dropped-features/existential-types.md b/docs/docs/reference/dropped-features/existential-types.md index 606a712a619b..6969feac33dc 100644 --- a/docs/docs/reference/dropped-features/existential-types.md +++ b/docs/docs/reference/dropped-features/existential-types.md @@ -3,7 +3,9 @@ layout: doc-page title: "Dropped: Existential Types" --- -Existential types using `forSome` have been dropped. The reasons for dropping them are: +Existential types using `forSome` (as in +[SLS §3.2.12](https://www.scala-lang.org/files/archive/spec/2.13/03-types.html#existential-types)) +have been dropped. The reasons for dropping them are: - Existential types violate a type soundness principle on which DOT and Scala 3 are constructed. That principle says that every @@ -27,6 +29,6 @@ is treated as the type `Map`, where the first type parameter is upper-bounded by `AnyRef` and the second type parameter is an alias of `Int`. -When reading classfiles compiled with _scalac_, Scala 3 will do a best +When reading class files compiled with Scala 2, Scala 3 will do a best effort to approximate existential types with its own types. It will issue a warning that a precise emulation is not possible. diff --git a/docs/docs/reference/dropped-features/package-objects.md b/docs/docs/reference/dropped-features/package-objects.md index beb304a48b16..fda87f9044f0 100644 --- a/docs/docs/reference/dropped-features/package-objects.md +++ b/docs/docs/reference/dropped-features/package-objects.md @@ -12,7 +12,7 @@ package object p { ``` will be dropped. They are still available in Scala 3.0, but will be deprecated and removed afterwards. -Package objects are no longer needed since all kinds of definitions can now be written at the top-level. E.g. +Package objects are no longer needed since all kinds of definitions can now be written at the top-level. Example: ```scala package p type Labelled[T] = (String, T) diff --git a/docs/docs/reference/dropped-features/procedure-syntax.md b/docs/docs/reference/dropped-features/procedure-syntax.md index 7432069295a2..d6cd9874de07 100644 --- a/docs/docs/reference/dropped-features/procedure-syntax.md +++ b/docs/docs/reference/dropped-features/procedure-syntax.md @@ -12,7 +12,7 @@ has been dropped. You need to write one of the following instead: def f() = { ... } def f(): Unit = { ... } ``` -Scala 3 will accept the old syntax under the `-source:3.0-migration` option. +Scala 3 accepts the old syntax under the `-source:3.0-migration` option. If the `-migration` option is set, it can even rewrite old syntax to new. The [ScalaFix](https://scalacenter.github.io/scalafix/) tool also -can rewrite procedure syntax to make it Scala-3-compatible. +can rewrite procedure syntax to make it Scala 3 compatible. diff --git a/docs/docs/reference/dropped-features/weak-conformance-spec.md b/docs/docs/reference/dropped-features/weak-conformance-spec.md index 9f442c9df80a..e934d43af940 100644 --- a/docs/docs/reference/dropped-features/weak-conformance-spec.md +++ b/docs/docs/reference/dropped-features/weak-conformance-spec.md @@ -1,6 +1,6 @@ --- layout: doc-page -title: Dropped: Weak Conformance - More Details +title: "Dropped: Weak Conformance - More Details" --- To simplify the underlying type theory, Scala 3 drops the notion of weak @@ -13,7 +13,6 @@ assigning a type to a constant expression. The new rule is: - the alternatives of an if-then-else or match expression, or - the body and catch results of a try expression, - and all expressions have primitive numeric types, but they do not all have the same type, then the following is attempted: @@ -32,7 +31,7 @@ assigning a type to a constant expression. The new rule is: if `c.toByte.toInt != c`. For an `Int -> Short` conversion, it occurs if `c.toShort.toInt != c`. -### Examples +## Examples ```scala inline val b = 33 diff --git a/docs/docs/reference/enums/enums.md b/docs/docs/reference/enums/enums.md index acf47d017fe5..a7200980960c 100644 --- a/docs/docs/reference/enums/enums.md +++ b/docs/docs/reference/enums/enums.md @@ -92,7 +92,7 @@ object Planet { ``` ### Compatibility with Java Enums -If you want to use the Scala-defined enums as Java enums, you can do so by extending +If you want to use the Scala-defined enums as [Java enums](https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html), you can do so by extending the class `java.lang.Enum`, which is imported by default, as follows: ```scala diff --git a/docs/docs/reference/metaprogramming/erased-terms.md b/docs/docs/reference/metaprogramming/erased-terms.md index c5d583149eea..2824630b677a 100644 --- a/docs/docs/reference/metaprogramming/erased-terms.md +++ b/docs/docs/reference/metaprogramming/erased-terms.md @@ -173,14 +173,16 @@ final class On extends State final class Off extends State class Machine[S <: State] { - transparent inline def turnOn(): Machine[On] = inline erasedValue[S] match { - case _: Off => new Machine[On] - case _: On => error("Turning on an already turned on machine") - } - transparent inline def turnOff(): Machine[Off] = inline erasedValue[S] match { - case _: On => new Machine[Off] - case _: Off => error("Turning off an already turned off machine") - } + transparent inline def turnOn(): Machine[On] = + inline erasedValue[S] match { + case _: Off => new Machine[On] + case _: On => error("Turning on an already turned on machine") + } + transparent inline def turnOff(): Machine[Off] = + inline erasedValue[S] match { + case _: On => new Machine[Off] + case _: Off => error("Turning off an already turned off machine") + } } object Machine { diff --git a/docs/docs/reference/metaprogramming/macros-spec.md b/docs/docs/reference/metaprogramming/macros-spec.md index 1e954b7c6dbc..fe92ab38a1f1 100644 --- a/docs/docs/reference/metaprogramming/macros-spec.md +++ b/docs/docs/reference/metaprogramming/macros-spec.md @@ -41,7 +41,7 @@ are, after splices nested in the quotes are expanded. If the outermost scope is a quote, we need to generate code that constructs the quoted tree at run-time. We implement this by -serializing the tree as a Tasty structure, which is stored +serializing the tree as a TASTy structure, which is stored in a string literal. At runtime, an unpickler method is called to deserialize the string into a tree. @@ -183,7 +183,7 @@ private def dynamicPower(n: Int, x: Double): Double = else if (n % 2 == 0) dynamicPower(n / 2, x * x) else x * dynamicPower(n - 1, x) ``` ---- + This assumes a `Constant` extractor that maps tree nodes representing constants to their values. diff --git a/docs/docs/reference/metaprogramming/macros.md b/docs/docs/reference/metaprogramming/macros.md index 36ed8616b5ee..df70302b7422 100644 --- a/docs/docs/reference/metaprogramming/macros.md +++ b/docs/docs/reference/metaprogramming/macros.md @@ -288,7 +288,8 @@ package quoted object Expr { ... - def apply[T: ToExpr](x: T)(using Quotes): Expr[T] = summon[ToExpr[T]].toExpr(x) + def apply[T: ToExpr](x: T)(using Quotes): Expr[T] = + summon[ToExpr[T]].toExpr(x) ... } ``` @@ -389,7 +390,7 @@ In fact Scala 2's type tag feature can be understood as a more ad-hoc version of `quoted.Type`. As was the case for type tags, the implicit search for a `quoted.Type` is handled by the compiler, using the algorithm sketched above. -## Relationship with Inline +## Relationship with `inline` Seen by itself, principled metaprogramming looks more like a framework for runtime metaprogramming than one for compile-time metaprogramming with macros. @@ -747,7 +748,8 @@ def f(expr: Expr[Any])(using Quotes) = This might be used to then perform an implicit search as in: ```scala -extension (inline sc: StringContext) inline def showMe(inline args: Any*): String = ${ showMeExpr('sc, 'args) } +extension (inline sc: StringContext) + inline def showMe(inline args: Any*): String = ${ showMeExpr('sc, 'args) } private def showMeExpr(sc: Expr[StringContext], argsExpr: Expr[Seq[Any]])(using Quotes): Expr[String] = { argsExpr match { diff --git a/docs/docs/reference/metaprogramming/staging.md b/docs/docs/reference/metaprogramming/staging.md index c69abf25a82f..1634e64dd883 100644 --- a/docs/docs/reference/metaprogramming/staging.md +++ b/docs/docs/reference/metaprogramming/staging.md @@ -60,7 +60,7 @@ The framework as discussed so far allows code to be staged, i.e. be prepared to be executed at a later stage. To run that code, there is another method in class `Expr` called `run`. Note that `$` and `run` both map from `Expr[T]` to `T` but only `$` is subject to the PCP, whereas `run` is just a normal method. -Run provides a `Quotes` that can be used to show the expression in the scope of `run`. +`run` provides a `Quotes` that can be used to show the expression in its scope. On the other hand `withQuotes` provides a `Quotes` without evaluating the expression. ```scala diff --git a/docs/docs/reference/metaprogramming/tasty-inspect.md b/docs/docs/reference/metaprogramming/tasty-inspect.md index c268a82451e7..42fffc0b5789 100644 --- a/docs/docs/reference/metaprogramming/tasty-inspect.md +++ b/docs/docs/reference/metaprogramming/tasty-inspect.md @@ -4,7 +4,7 @@ title: "TASTy Inspection" --- ```scala -libraryDependencies += "ch.epfl.lamp" %% "dotty-tasty-inspector" % scalaVersion.value +libraryDependencies += "ch.epfl.lamp" %% "scala3-tasty-inspector" % scalaVersion.value ``` TASTy files contain the full typed tree of a class including source positions diff --git a/docs/docs/reference/metaprogramming/tasty-reflect.md b/docs/docs/reference/metaprogramming/tasty-reflect.md index 7b64e706f43b..bdf3fe6a52ec 100644 --- a/docs/docs/reference/metaprogramming/tasty-reflect.md +++ b/docs/docs/reference/metaprogramming/tasty-reflect.md @@ -103,10 +103,11 @@ example, collects the pattern variables of a tree. ```scala def collectPatternVariables(tree: Tree)(implicit ctx: Context): List[Symbol] = { val acc = new TreeAccumulator[List[Symbol]] { - def apply(syms: List[Symbol], tree: Tree)(implicit ctx: Context) = tree match { - case Bind(_, body) => apply(tree.symbol :: syms, body) - case _ => foldOver(syms, tree) - } + def apply(syms: List[Symbol], tree: Tree)(implicit ctx: Context) = + tree match { + case Bind(_, body) => apply(tree.symbol :: syms, body) + case _ => foldOver(syms, tree) + } } acc(Nil, tree) } diff --git a/docs/docs/reference/metaprogramming/toc.md b/docs/docs/reference/metaprogramming/toc.md index 773491e67583..81722aa96b79 100644 --- a/docs/docs/reference/metaprogramming/toc.md +++ b/docs/docs/reference/metaprogramming/toc.md @@ -33,7 +33,7 @@ introduce the following fundamental facilities: 4. [TASTy Reflection](./tasty-reflect.md) Quotations are a "black-box" representation of code. They can be parameterized and composed using - splices, but their structure cannot be analyzed from the outside. Tasty + splices, but their structure cannot be analyzed from the outside. TASTy reflection gives a way to analyze code structure by partly revealing the representation type of a piece of code in a standard API. The representation type is a form of typed abstract syntax tree, which gives rise to the `TASTy` moniker. diff --git a/docs/docs/reference/new-types/type-lambdas-spec.md b/docs/docs/reference/new-types/type-lambdas-spec.md index 6d44e493988e..a7f21014ba10 100644 --- a/docs/docs/reference/new-types/type-lambdas-spec.md +++ b/docs/docs/reference/new-types/type-lambdas-spec.md @@ -79,7 +79,7 @@ instead of type T >: ([X] =>> Nothing) <: ([X] =>> X => X) ``` -The same expansions apply to type parameters. E.g. +The same expansions apply to type parameters. For instance, ```scala [F[X] <: Coll[X]] ``` diff --git a/docs/docs/reference/new-types/union-types-spec.md b/docs/docs/reference/new-types/union-types-spec.md index 4f08aab7fad1..ec616af32c60 100644 --- a/docs/docs/reference/new-types/union-types-spec.md +++ b/docs/docs/reference/new-types/union-types-spec.md @@ -117,7 +117,7 @@ The members of a union type are the members of its join. ### Example -The following code does not typecheck, because `hello` is not a member of +The following code does not typecheck, because method `hello` is not a member of `AnyRef` which is the join of `A | B`. ```scala @@ -149,8 +149,9 @@ 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 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 -- if one argument is an array, Object +- 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) +- if one argument is an array, [`Object`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Object.html) - otherwise a common superclass or trait S of the argument classes, with the following two properties: * S is minimal: no other common superclass or trait derives from S diff --git a/docs/docs/reference/other-new-features/control-syntax.md b/docs/docs/reference/other-new-features/control-syntax.md index 73a3774e13bb..89b214e14b90 100644 --- a/docs/docs/reference/other-new-features/control-syntax.md +++ b/docs/docs/reference/other-new-features/control-syntax.md @@ -38,7 +38,7 @@ The rules in detail are: - The enumerators of a `for`-expression can be written without enclosing parentheses or braces if they are followed by a `yield` or `do`. - A `do` in a `for`-expression expresses a `for`-loop. - A `catch` can be followed by a single case on the same line. - If there are multiple cases, these have to be appear within braces (just like in Scala-2) + If there are multiple cases, these have to be appear within braces (just like in Scala 2) or an indented block. ### Rewrites diff --git a/docs/docs/reference/other-new-features/explicit-nulls.md b/docs/docs/reference/other-new-features/explicit-nulls.md index 8abc2fd6c087..221d4bec108e 100644 --- a/docs/docs/reference/other-new-features/explicit-nulls.md +++ b/docs/docs/reference/other-new-features/explicit-nulls.md @@ -27,6 +27,7 @@ When explicit nulls are enabled, the type hierarchy changes so that `Null` is on `Any`, as opposed to every reference type. This is the new type hierarchy: + ![](../../../images/explicit-nulls/explicit-nulls-type-hierarchy.png "Type Hierarchy for Explicit Nulls") After erasure, `Null` remains a subtype of all reference types (as forced by the JVM). diff --git a/docs/docs/reference/other-new-features/indentation.md b/docs/docs/reference/other-new-features/indentation.md index 77f4575bf3a3..e7a2125accea 100644 --- a/docs/docs/reference/other-new-features/indentation.md +++ b/docs/docs/reference/other-new-features/indentation.md @@ -28,7 +28,7 @@ The compiler enforces two rules for well-indented programs, flagging violations println("done") // error: indented too far to the left ``` - 2. If significant indentation is turned off (i.e. under Scala-2 mode or under `-noindent`) and we are at the start of an indented sub-part of an expression, and the indented part ends in a newline, the next statement must start at an indentation width less than the sub-part. This prevents errors where an opening brace was forgotten, as in + 2. If significant indentation is turned off (i.e. under Scala 2 mode or under `-noindent`) and we are at the start of an indented sub-part of an expression, and the indented part ends in a newline, the next statement must start at an indentation width less than the sub-part. This prevents errors where an opening brace was forgotten, as in ```scala if (x < 0) diff --git a/docs/docs/reference/other-new-features/opaques.md b/docs/docs/reference/other-new-features/opaques.md index c5840fb34e15..9569fc6446d5 100644 --- a/docs/docs/reference/other-new-features/opaques.md +++ b/docs/docs/reference/other-new-features/opaques.md @@ -67,10 +67,14 @@ object Access { opaque type PermissionChoice = Int opaque type Permission <: Permissions & PermissionChoice = Int - extension (x: Permissions) def & (y: Permissions): Permissions = x | y - extension (x: PermissionChoice) def | (y: PermissionChoice): PermissionChoice = x | y - extension (granted: Permissions) def is(required: Permissions) = (granted & required) == required - extension (granted: Permissions) def isOneOf(required: PermissionChoice) = (granted & required) != 0 + extension (x: Permissions) + def & (y: Permissions): Permissions = x | y + extension (x: PermissionChoice) + def | (y: PermissionChoice): PermissionChoice = x | y + extension (granted: Permissions) + def is(required: Permissions) = (granted & required) == required + extension (granted: Permissions) + def isOneOf(required: PermissionChoice) = (granted & required) != 0 val NoPermission: Permission = 0 val Read: Permission = 1 diff --git a/docs/docs/reference/other-new-features/open-classes.md b/docs/docs/reference/other-new-features/open-classes.md index 8711e992f6df..ff641f116135 100644 --- a/docs/docs/reference/other-new-features/open-classes.md +++ b/docs/docs/reference/other-new-features/open-classes.md @@ -31,7 +31,7 @@ Classes that are not open can still be extended, but only if at least one of two - The extending class is in the same source file as the extended class. In this case, the extension is usually an internal implementation matter. - - The language feature `adhocExtensions` is enabled for the extending class. This is typically enabled by an import statement in the source file of the extension: + - The language feature `adhocExtensions` is enabled for the extending class. This is typically enabled by an import clause in the source file of the extension: ```scala import scala.language.adhocExtensions ``` 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 77e6fff32691..8622ddde6d8b 100644 --- a/docs/docs/reference/other-new-features/parameter-untupling-spec.md +++ b/docs/docs/reference/other-new-features/parameter-untupling-spec.md @@ -81,5 +81,4 @@ be doing the same translation (semantically) but in a less efficient way. ### Reference -For more info see: -* [Issue #897](https://github.com/lampepfl/dotty/issues/897). +For more info see [Issue #897](https://github.com/lampepfl/dotty/issues/897). diff --git a/docs/docs/reference/other-new-features/targetName.md b/docs/docs/reference/other-new-features/targetName.md index 3d0ef00b9182..6ade68c7b29d 100644 --- a/docs/docs/reference/other-new-features/targetName.md +++ b/docs/docs/reference/other-new-features/targetName.md @@ -54,7 +54,7 @@ def f(x: => Int): Int = x + 1 // error: double definition ``` The two definitions above clash since their erased parameter types are both `Function0`, which is the type of the translation of a by-name-parameter. Hence -they have the same names and signatures. But we can avoid the clash by adding a `@targetName` annotation to either method or to both of them. E.g. +they have the same names and signatures. But we can avoid the clash by adding a `@targetName` annotation to either method or to both of them. Example: ```scala @targetName("f_string") diff --git a/docs/docs/reference/overview.md b/docs/docs/reference/overview.md index 29727b119924..2b572f3ab8df 100644 --- a/docs/docs/reference/overview.md +++ b/docs/docs/reference/overview.md @@ -10,12 +10,14 @@ In this reference, we discuss design decisions and present important differences The language redesign was guided by three main goals: - Strengthen Scala's foundations. - Make the full programming language compatible with the foundational work on the DOT calculus and apply the lessons learned from that work. + Make the full programming language compatible with the foundational work on the + [DOT calculus](https://infoscience.epfl.ch/record/227176/files/soundness_oopsla16.pdf) + and apply the lessons learned from that work. - Make Scala easier and safer to use. Tame powerful constructs such as implicits to provide a gentler learning curve. Remove warts and puzzlers. - Further improve the consistency and expressiveness of Scala's language constructs. Corresponding to these goals, the language changes fall into seven categories: -(1) Core constructs to strengthen foundations, (2) simplifications and (3) restrictions, to make the language easier and safer to use, (4) dropped constructs to make the language smaller and more regular, (5) changed constructs to remove warts, and increase consistency and usability, (6) new constructs to fill gaps and increase expressiveness, (7) a new, principled approach to metaprogramming that replaces today's experimental macros. +(1) Core constructs to strengthen foundations, (2) simplifications and (3) [restrictions](#restrictions), to make the language easier and safer to use, (4) dropped constructs to make the language smaller and more regular, (5) [changed constructs](#changes) to remove warts, and increase consistency and usability, (6) [new constructs](#new_constructs) to fill gaps and increase expressiveness, (7) a new, principled approach to metaprogramming that replaces today's experimental macros. ## Essential Foundations @@ -24,18 +26,18 @@ These new constructs directly model core features of DOT, higher-kinded types, a - [Intersection types](new-types/intersection-types.md), replacing compound types, - [Union types](new-types/union-types.md), - [Type lambdas](new-types/type-lambdas.md), replacing encodings using structural types and type projection. - - [Context Functions](contextual/context-functions.md), offering abstraction over given parameters. + - [Context functions](contextual/context-functions.md), offering abstraction over given parameters. ## Simplifications These constructs replace existing constructs with the aim of making the language safer and simpler to use, and to promote uniformity in code style. - - [Trait Parameters](other-new-features/trait-parameters.md) replace [early initializers](dropped-features/early-initializers.md) with a more generally useful construct. - - [Given Instances](contextual/givens.md) + - [Trait parameters](other-new-features/trait-parameters.md) replace [early initializers](dropped-features/early-initializers.md) with a more generally useful construct. + - [Given instances](contextual/givens.md) replace implicit objects and defs, focussing on intent over mechanism. - - [Using Clauses](contextual/using-clauses.md) replace implicit parameters, avoiding their ambiguities. + - [Using clauses](contextual/using-clauses.md) replace implicit parameters, avoiding their ambiguities. - [Extension Methods](contextual/extension-methods.md) replace implicit classes with a clearer and simpler mechanism. - - [Opaque Type Aliases](other-new-features/opaques.md) replace most uses + - [Opaque type aliases](other-new-features/opaques.md) replace most uses of value classes while guaranteeing absence of boxing. - [Toplevel definitions](dropped-features/package-objects.md) replace package objects, dropping syntactic boilerplate. - [Export clauses](other-new-features/export.md) diff --git a/docs/docs/reference/syntax.md b/docs/docs/reference/syntax.md index 60ce4ed0b693..bc5f76295727 100644 --- a/docs/docs/reference/syntax.md +++ b/docs/docs/reference/syntax.md @@ -6,7 +6,7 @@ title: "Scala 3 Syntax Summary" The following descriptions of Scala tokens uses literal characters `‘c’` when referring to the ASCII fragment `\u0000` – `\u007F`. -_Unicode escapes_ are used to represent the Unicode character with the given +_Unicode escapes_ are used to represent the [Unicode character](https://www.w3.org/International/articles/definitions-characters/) with the given hexadecimal code: ```ebnf From b6f0affa3e983c64f1e5518836b5249fdd37bd36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Micheloud?= Date: Thu, 17 Dec 2020 18:03:57 +0100 Subject: [PATCH 2/3] updated power example (metaprogramming) --- .../reference/contextual/context-bounds.md | 2 +- .../reference/metaprogramming/macros-spec.md | 46 +++++++++++-------- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/docs/docs/reference/contextual/context-bounds.md b/docs/docs/reference/contextual/context-bounds.md index 0b85f1a3a0fc..3c1e2e3b3aa7 100644 --- a/docs/docs/reference/contextual/context-bounds.md +++ b/docs/docs/reference/contextual/context-bounds.md @@ -9,7 +9,7 @@ A context bound is a shorthand for expressing the common pattern of a context pa def maximum[T: Ord](xs: List[T]): T = xs.reduceLeft(max) ``` -A bound like `: Ord` on a type parameter `T` of a method or class indicates a context parameter `with Ord[T]`. The context parameter(s) generated from context bounds come last in the definition of the containing method or class. E.g., +A bound like `: Ord` on a type parameter `T` of a method or class indicates a context parameter `with Ord[T]`. The context parameter(s) generated from context bounds come last in the definition of the containing method or class. For instance, ```scala def f[T: C1 : C2, U: C3](x: T)(using y: U, z: V): R diff --git a/docs/docs/reference/metaprogramming/macros-spec.md b/docs/docs/reference/metaprogramming/macros-spec.md index fe92ab38a1f1..8ed479938d33 100644 --- a/docs/docs/reference/metaprogramming/macros-spec.md +++ b/docs/docs/reference/metaprogramming/macros-spec.md @@ -166,26 +166,36 @@ in that it does not allow for the inspection of quoted expressions and types. It’s possible to work around this by providing all necessary information as normal, unquoted inline parameters. But we would gain more flexibility by allowing for the inspection of quoted code with -pattern matching. This opens new possibilities. For instance, here is a -version of `power` that generates the multiplications directly if the -exponent is statically known and falls back to the dynamic -implementation of power otherwise. +pattern matching. This opens new possibilities. + +For instance, here is a version of `power` that generates the multiplications +directly if the exponent is statically known and falls back to the dynamic +implementation of `power` otherwise. ```scala -inline def power(n: Int, x: Double): Double = ${ - 'n match { - case Constant(n1) => powerCode(n1, 'x) - case _ => '{ dynamicPower(n, x) } - } -} +import scala.quoted.Expr +import scala.quoted.Quotes -private def dynamicPower(n: Int, x: Double): Double = - if (n == 0) 1.0 - else if (n % 2 == 0) dynamicPower(n / 2, x * x) - else x * dynamicPower(n - 1, x) -``` +inline def power(x: Double, n: Int): Double = + ${ powerExpr('x, 'n) } -This assumes a `Constant` extractor that maps tree nodes representing -constants to their values. +private def powerExpr(x: Expr[Double], n: Expr[Int]) + (using Quotes): Expr[Double] = + n.value match + case Some(m) => powerExpr(x, m) + case _ => '{ dynamicPower($x, $n) } + +private def powerExpr(x: Expr[Double], n: Int) + (using Quotes): Expr[Double] = + if n == 0 then '{ 1.0 } + else if n == 1 then x + else if n % 2 == 0 then '{ val y = $x * $x; ${ powerExpr('y, n / 2) } } + else '{ $x * ${ powerExpr(x, n - 1) } } + +private def dynamicPower(x: Double, n: Int): Double = + if n == 0 then 1.0 + else if n % 2 == 0 then dynamicPower(x * x, n / 2) + else x * dynamicPower(x, n - 1) +``` With the right extractors, the "AsFunction" conversion that maps expressions over functions to functions over expressions can @@ -216,7 +226,7 @@ This would allow constructing applications from lists of arguments without having to match the arguments one-by-one with the corresponding formal parameter types of the function. We then need "at the end" a method to convert an `Expr[Any]` to an `Expr[T]` where `T` is -given from the outside. E.g. if `code` yields a `Expr[Any]`, then +given from the outside. For instance, if `code` yields a `Expr[Any]`, then `code.atType[T]` yields an `Expr[T]`. The `atType` method has to be implemented as a primitive; it would check that the computed type structure of `Expr` is a subtype of the type structure representing From 649be2353284b25c3dd15025a5568e7d455122b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Micheloud?= Date: Thu, 17 Dec 2020 18:20:46 +0100 Subject: [PATCH 3/3] updated import clause --- docs/docs/reference/metaprogramming/macros-spec.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/docs/reference/metaprogramming/macros-spec.md b/docs/docs/reference/metaprogramming/macros-spec.md index 8ed479938d33..f8d0bcfef899 100644 --- a/docs/docs/reference/metaprogramming/macros-spec.md +++ b/docs/docs/reference/metaprogramming/macros-spec.md @@ -172,8 +172,7 @@ For instance, here is a version of `power` that generates the multiplications directly if the exponent is statically known and falls back to the dynamic implementation of `power` otherwise. ```scala -import scala.quoted.Expr -import scala.quoted.Quotes +import scala.quoted._ inline def power(x: Double, n: Int): Double = ${ powerExpr('x, 'n) }