diff --git a/docs/docs/reference/contextual-implicit/conversions.md b/docs/docs/reference/contextual-implicit/conversions.md index 8676ec6037f6..ca828a82cf62 100644 --- a/docs/docs/reference/contextual-implicit/conversions.md +++ b/docs/docs/reference/contextual-implicit/conversions.md @@ -59,9 +59,9 @@ object Completions { // // CompletionArg.fromStatusCode(statusCode) - implicit fromString for Conversion[String, CompletionArg] = Error(_) - implicit fromFuture for Conversion[Future[HttpResponse], CompletionArg] = Response(_) - implicit fromStatusCode for Conversion[Future[StatusCode], CompletionArg] = Status(_) + implicit fromString for Conversion[String, CompletionArg] = Error(_) + implicit fromFuture for Conversion[Future[HttpResponse], CompletionArg] = Response(_) + implicit fromStatusCode for Conversion[Future[StatusCode], CompletionArg] = Status(_) } import CompletionArg._ diff --git a/docs/docs/reference/contextual-implicit/derivation.md b/docs/docs/reference/contextual-implicit/derivation.md index 9840c7e19ad6..6f33b7235762 100644 --- a/docs/docs/reference/contextual-implicit/derivation.md +++ b/docs/docs/reference/contextual-implicit/derivation.md @@ -3,18 +3,18 @@ layout: doc-page title: Typeclass Derivation --- -Typeclass derivation is a way to generate instances of certain type classes automatically or with minimal code hints. A type class in this sense is any trait or class with a type parameter that describes the type being operated on. Commonly used examples are `Eql`, `Ordering`, `Show`, or `Pickling`. Example: +Typeclass derivation is a way to generate implicit instances for certain type classes automatically or with minimal code hints. A type class in this sense is any trait or class with a type parameter that describes the type being operated on. Commonly used examples are `Eql`, `Ordering`, `Show`, or `Pickling`. Example: ```scala enum Tree[T] derives Eql, Ordering, Pickling { case Branch(left: Tree[T], right: Tree[T]) case Leaf(elem: T) } ``` -The `derives` clause generates implicits for the `Eql`, `Ordering`, and `Pickling` traits in the companion object `Tree`: +The `derives` clause generates implicit instances for the `Eql`, `Ordering`, and `Pickling` traits in the companion object `Tree`: ```scala -implicit [T: Eql] for Eql[Tree[T]] = Eql.derived -implicit [T: Ordering] for Ordering[Tree[T]] = Ordering.derived -implicit [T: Pickling] for Pickling[Tree[T]] = Pickling.derived +implicit [T: Eql] for Eql[Tree[T]] = Eql.derived +implicit [T: Ordering] for Ordering[Tree[T]] = Ordering.derived +implicit [T: Pickling] for Pickling[Tree[T]] = Pickling.derived ``` ### Deriving Types @@ -42,8 +42,7 @@ A trait or class can appear in a `derives` clause if its companion object define ```scala def derived[T] given Generic[T] = ... ``` -That is, the `derived` method takes an implicit parameter of type `Generic` that determines the _shape_ of the deriving type `T` and it computes the typeclass implementation according to that shape. Implicits for `Generic` are generated automatically for any type that derives a typeclass with a `derived` -method that refers to `Generic`. One can also derive `Generic` alone, which means a `Generic` instance is generated without any other type class instances. E.g.: +That is, the `derived` method takes an implicit parameter of type `Generic` that determines the _shape_ of the deriving type `T` and it computes the typeclass implementation according to that shape. An implicit `Generic` instance is generated automatically for any type that derives a typeclass with a `derived` method that refers to `Generic`. One can also derive `Generic` alone, which means a `Generic` instance is generated without any other type class instances. E.g.: ```scala sealed trait ParseResult[T] derives Generic ``` @@ -94,7 +93,7 @@ is represented as `T *: Unit` since there is no direct syntax for such tuples: ` ### The Generic Typeclass -For every class `C[T_1,...,T_n]` with a `derives` clause, the compiler generates in the companion object of `C` an implicit for `Generic[C[T_1,...,T_n]]` that follows the outline below: +For every class `C[T_1,...,T_n]` with a `derives` clause, the compiler generates in the companion object of `C` an implicit instance for `Generic[C[T_1,...,T_n]]` that follows the outline below: ```scala implicit [T_1, ..., T_n] for Generic[C[T_1,...,T_n]] { type Shape = ... @@ -214,8 +213,8 @@ trait Eql[T] { def eql(x: T, y: T): Boolean } ``` -We need to implement a method `Eql.derived` that produces an implicit value of type `Eql[T]` provided -there exists an implicit value of type `Generic[T]`. Here's a possible solution: +We need to implement a method `Eql.derived` that produces an implicit instance of type `Eql[T]` provided +there exists an implicit instance of type `Generic[T]`. Here's a possible solution: ```scala inline def derived[T] given (ev: Generic[T]): Eql[T] = new Eql[T] { def eql(x: T, y: T): Boolean = { @@ -333,21 +332,22 @@ implicit [T] for Eql[Tree[T]] given (elemEq: Eql[T]) { } ``` -One important difference between this approach and Scala-2 typeclass derivation frameworks such as Shapeless or Magnolia is that no automatic attempt is made to generate typeclass instances of elements recursively using the generic derivation framework. There must be an implicit value of type `Eql[T]` (which can of course be produced in turn using `Eql.derived`), or the compilation will fail. The advantage of this more restrictive approach to typeclass derivation is that it avoids uncontrolled transitive typeclass derivation by design. This keeps code sizes smaller, compile times lower, and is generally more predictable. +One important difference between this approach and Scala-2 typeclass derivation frameworks such as Shapeless or Magnolia is that no automatic attempt is made to generate typeclass instances of elements recursively using the generic derivation framework. There must be an implicit instance of type `Eql[T]` (which can of course be produced in turn using `Eql.derived`), or the compilation will fail. The advantage of this more restrictive approach to typeclass derivation is that it avoids uncontrolled transitive typeclass derivation by design. This keeps code sizes smaller, compile times lower, and is generally more predictable. -### Derived Instances Elsewhere +### Deriving Instances Elsewhere Sometimes one would like to derive a typeclass instance for an ADT after the ADT is defined, without being able to change the code of the ADT itself. -To do this, simply define an instance with the `derived` method of the typeclass as right-hand side. E.g, to implement `Ordering` for `Option`, define: +To do this, simply define an implicit instance with the `derived` method of the typeclass as right-hand side. E.g, to implement `Ordering` for `Option`, define: ```scala -implicit [T: Ordering]: Ordering[Option[T]] = Ordering.derived +implicit [T: Ordering] for Ordering[Option[T]] = Ordering.derived ``` Usually, the `Ordering.derived` clause has an implicit parameter of type `Generic[Option[T]]`. Since the `Option` trait has a `derives` clause, -the necessary implicit is already present in the companion object of `Option`. -If the ADT in question does not have a `derives` clause, an implicit for `Generic` +the necessary implicit instance is already present in the companion object of `Option`. +If the ADT in question does not have a `derives` clause, an implicit instance for `Generic` would still be synthesized by the compiler at the point where `derived` is called. -This is similar to the situation with type tags or class tags: If no implicit is found, the compiler will synthesize it. +This is similar to the situation with type tags or class tags: If no implicit instance is found, +the compiler will synthesize one. ### Syntax diff --git a/docs/docs/reference/contextual-implicit/extension-methods.md b/docs/docs/reference/contextual-implicit/extension-methods.md index d580bdd72b97..37efad933a54 100644 --- a/docs/docs/reference/contextual-implicit/extension-methods.md +++ b/docs/docs/reference/contextual-implicit/extension-methods.md @@ -36,7 +36,7 @@ When is an extension method applicable? There are two possibilities. - An extension method is applicable if it is visible under a simple name, by being defined or inherited or imported in a scope enclosing the application. - - An extension method is applicable if it is a member of some implicit value at the point of the application. + - An extension method is applicable if it is a member of some implicit instance at the point of the application. As an example, consider an extension method `longestStrings` on `String` defined in a trait `StringSeqOps`. @@ -48,7 +48,7 @@ trait StringSeqOps { } } ``` -We can make the extension method available by defining an implicit for `StringSeqOps`, like this: +We can make the extension method available by defining an implicit instance for `StringSeqOps`, like this: ```scala implicit ops1 for StringSeqOps ``` @@ -76,7 +76,7 @@ and where `T` is the expected type. The following two rewritings are tried in or from `T` to a type containing `m`. If there is more than one way of rewriting, an ambiguity error results. So `circle.circumference` translates to `CircleOps.circumference(circle)`, provided -`circle` has type `Circle` and `CircleOps` is an eligible implicit value (i.e. it is visible at the point of call or it is defined in the companion object of `Circle`). +`circle` has type `Circle` and `CircleOps` is an eligible implicit (i.e. it is visible at the point of call or it is defined in the companion object of `Circle`). ### Implicits for Extension Methods @@ -144,7 +144,3 @@ to the [current syntax](https://github.com/lampepfl/dotty/blob/master/docs/docs/ DefSig ::= ... | ‘(’ DefParam ‘)’ [nl] id [DefTypeParamClause] DefParamClauses ``` - - - - diff --git a/docs/docs/reference/contextual-implicit/import-implied.md b/docs/docs/reference/contextual-implicit/import-implied.md index 8e4c1232498c..84a3a70e1891 100644 --- a/docs/docs/reference/contextual-implicit/import-implied.md +++ b/docs/docs/reference/contextual-implicit/import-implied.md @@ -3,7 +3,7 @@ layout: doc-page title: "Import Implicit" --- -A special form of import is used to import implicit values. Example: +A special form of import is used to import implicit instances. Example: ```scala object A { class TC @@ -16,16 +16,16 @@ object B { } ``` In the code above, the `import A._` clause of object `B` will import all members -of `A` _except_ the implicit `tc`. Conversely, the second import `import implicit A._` will import _only_ that implicit. +of `A` _except_ the implicit `tc`. Conversely, the second import `import implicit A._` will import _only_ that implicit instance. -Generally, a normal import clause brings all members except implicit values into scope whereas an `import implicit` clause brings only implicit values into scope. +Generally, a normal import clause brings all members except implicit instances into scope whereas an `import implicit` clause brings only implicit instances into scope. There are two main benefits arising from these rules: - - It is made clearer where implicit values in scope are coming from. In particular, it is not possible to hide imported implicit values in a long list of regular imports. - - It enables importing all implicit values + - It is made clearer where implicit instances in scope are coming from. In particular, it is not possible to hide imported implicit instances in a long list of regular imports. + - It enables importing all implicit instances without importing anything else. This is particularly important since implicit - values can be anonymous, so the usual recourse of using named imports is not + instances can be anonymous, so the usual recourse of using named imports is not practical. ### Migration @@ -41,6 +41,8 @@ To make gradual migration possible, we adapt the following scheme. 3. In some version after 3.1, an old-style implicit accessed implicitly through a normal import will give a compiler error. +New-style implicit instance definitions always need to be imported with `import implicit`. + These rules mean that library users can use `import implicit` to access old-style implicits in Scala 3.0, and will be gently nudged and then forced to do so in later versions. Libraries can then switch to new-style implicit definitions once their user base has migrated. diff --git a/docs/docs/reference/contextual-implicit/inferable-by-name-parameters.md b/docs/docs/reference/contextual-implicit/inferable-by-name-parameters.md index d1230978e771..7c8280d6d988 100644 --- a/docs/docs/reference/contextual-implicit/inferable-by-name-parameters.md +++ b/docs/docs/reference/contextual-implicit/inferable-by-name-parameters.md @@ -33,14 +33,14 @@ if this is necessary to prevent an otherwise diverging expansion. The precise steps for synthesizing an argument for a by-name parameter of type `=> T` are as follows. - 1. Create a new implicit for type `T`: + 1. Create a new implicit instance for type `T`: ```scala implicit lv for T = ??? ``` where `lv` is an arbitrary fresh name. - 1. This implicit is not immediately available as a candidate for argument inference (making it immediately available could result in a loop in the synthesized computation). But it becomes available in all nested contexts that look again for an implicit argument to a by-name parameter. + 1. This instance is not immediately available as a candidate implicit (making it immediately available could result in a loop in the synthesized computation). But it becomes available in all nested contexts that look again for an implicit argument to a by-name parameter. 1. If this search succeeds with expression `E`, and `E` contains references to the implicit `lv`, replace `E` by diff --git a/docs/docs/reference/contextual-implicit/inferable-params.md b/docs/docs/reference/contextual-implicit/inferable-params.md index 235e21645af5..fd726a0e4838 100644 --- a/docs/docs/reference/contextual-implicit/inferable-params.md +++ b/docs/docs/reference/contextual-implicit/inferable-params.md @@ -30,12 +30,16 @@ max(List(1, 2, 3), Nil) ## Anonymous Implicit Parameters -In many situations, the name of an implicit parameter of a method need not be mentioned explicitly at all, since it is only used as a synthesized argument for other implicit parameters. In that case one can avoid defining a parameter name and just provide its type. Example: +In many situations, the name of an implicit parameter of a method need not be +mentioned explicitly at all, since it is only used in synthesized arguments for +other implicit parameters. In that case one can avoid defining a parameter name +and just provide its type. Example: ```scala def maximum[T](xs: List[T]) given Ord[T]: T = xs.reduceLeft(max) ``` -`maximum` takes an implicit parameter of type `Ord` only to pass it on as an implicit argument to `max`. The name of the parameter is left out. +`maximum` takes an implicit parameter of type `Ord` only to pass it on as a +synthesized argument to `max`. The name of the parameter is left out. Generally, implicit parameters may be given either as a parameter list `(p_1: T_1, ..., p_n: T_n)` or as a sequence of types, separated by commas. @@ -79,9 +83,9 @@ f("abc").given(ctx) f.given(global)("abc").given(ctx) ``` -## Summoning an Implicit +## Summoning Implicit Instances -A method `the` in `Predef` returns an implicit instance of a given type. For example, the implicit for `Ord[List[Int]]` is generated by +A method `the` in `Predef` returns an implicit instance for a given type. For example, the implicit for `Ord[List[Int]]` is generated by ```scala the[Ord[List[Int]]] // reduces to ListOrd given IntOrd ``` diff --git a/docs/docs/reference/contextual-implicit/instance-defs.md b/docs/docs/reference/contextual-implicit/instance-defs.md index 690f0b9b30a4..f5b7690a6ac5 100644 --- a/docs/docs/reference/contextual-implicit/instance-defs.md +++ b/docs/docs/reference/contextual-implicit/instance-defs.md @@ -4,8 +4,8 @@ title: "Implicit Instances" --- Implicit instances define "canonical" values of given types -that can be synthesized by the compiler. Typically, such values are -used as arguments to [given clauses](./inferable-params.html). Example: +that can be synthesized by the compiler as arguments for +[given clauses](./inferable-params.html). Example: ```scala trait Ord[T] { def compare(x: T, y: T): Int @@ -18,7 +18,7 @@ implicit IntOrd for Ord[Int] { if (x < y) -1 else if (x > y) +1 else 0 } -implicit ListOrd[T] for Ord[List[T]] given (ord: Ord[T]){ +implicit ListOrd[T] for Ord[List[T]] given (ord: Ord[T]) { def compare(xs: List[T], ys: List[T]): Int = (xs, ys) match { case (Nil, Nil) => 0 case (Nil, _) => -1 @@ -30,10 +30,10 @@ implicit ListOrd[T] for Ord[List[T]] given (ord: Ord[T]){ } ``` This code defines a trait `Ord` and two implicit definitions. `IntOrd` defines -an implicit value of the type `Ord[Int]` whereas `ListOrd[T]` defines implicit values of types `Ord[List[T]]` -for all types `T` that come with implicit values for `Ord[T]` themselves. -The `given` clause in `ListOrd` defines an [implicit parameter](./inferable-params.html). -Given clauses are further explained in the next section. +an implicit instance of the type `Ord[Int]` whereas `ListOrd[T]` defines implicit instances of type `Ord[List[T]]` +for all types `T` that come with an implicit instance for `Ord[T]` themselves. +The `given` clause in `ListOrd` defines an implicit parameter. +Given clauses are further explained in the [next section](./inferable-params.html). ## Anonymous Implicit Instances @@ -43,12 +43,12 @@ of the last section can also be expressed like this: implicit for Ord[Int] { ... } implicit [T] for Ord[List[T]] given (ord: Ord[T]) { ... } ``` -If the name of an implicit is missing, the compiler will synthesize a name from +If the name of an implicit instance is missing, the compiler will synthesize a name from the type(s) in the `for` clause. ## Alias Implicits -An alias can be used to define an implicit value that is equal to some expression. E.g.: +An alias can be used to define an implicit instance that is equal to some expression. E.g.: ```scala implicit global for ExecutionContext = new ForkJoinPool() ``` @@ -64,7 +64,7 @@ An alias implicit can have type and context parameters just like any other impli ## Implicit Instance Creation -An implicit instance without type parameters or given clause is created on-demand, the first time it is accessed. It is not required to ensure safe publication, which means that different threads might create different instances for the same `implicit` clause. If an `implicit` definition has type parameters or a given clause, a fresh instance is created for each reference. +An implicit instance without type parameters or given clause is created on-demand, the first time it is accessed. It is not required to ensure safe publication, which means that different threads might create different instances for the same `implicit` definition. If an `implicit` definition has type parameters or a given clause, a fresh instance is created for each reference. ## Syntax diff --git a/docs/docs/reference/contextual-implicit/motivation.md b/docs/docs/reference/contextual-implicit/motivation.md index 0f50bdfe3637..a2609a110a18 100644 --- a/docs/docs/reference/contextual-implicit/motivation.md +++ b/docs/docs/reference/contextual-implicit/motivation.md @@ -53,14 +53,14 @@ The following pages introduce a redesign of contextual abstractions in Scala. Th 3. [Import Implicit](./import-implied.html) is new form of import that specifically imports implicit definitions and nothing else. New-style implicit instances _must be_ imported with `import implicit`, a plain import will no longer bring them into scope. Old-style implicit definitions can be imported with either form. - 4. [Implicit Conversions](./conversions.html) are now expressed as implicit values of a standard `Conversion` class. All other forms of implicit conversions will be phased out. + 4. [Implicit Conversions](./conversions.html) are now expressed as implicit instances of a standard `Conversion` class. All other forms of implicit conversions will be phased out. This section also contains pages describing other language features that are related to context abstraction. These are: - [Context Bounds](./context-bounds.html), which carry over unchanged. - [Extension Methods](./extension-methods.html) replace implicit classes in a way that integrates better with typeclasses. - [Implementing Typeclasses](./typeclasses.html) demonstrates how some common typeclasses can be implemented using the new constructs. - - [Typeclass Derivation](./derivation.html) introduces constructs to automatically derive typeclasses for ADTs. + - [Typeclass Derivation](./derivation.html) introduces constructs to automatically derive implicit typeclass instances for ADTs. - [Multiversal Equality](./multiversal-equality.html) introduces a special typeclass to support type safe equality. - [Implicit Function Types](./query-types.html) introduce a way to abstract over implicit parameterization. @@ -79,4 +79,3 @@ Could we achieve the same goals by tweaking existing implicits? After having tri - Third, even if we would somehow succeed with migration, we still have the problem how to teach this. We cannot make existing tutorials go away. Almost all existing tutorials start with implicit conversions, which will go away; they use normal imports, which will go away, and they explain calls to methods with implicit parameters by expanding them to plain applications, which will also go away. This means that we'd have to add modifications and qualifications to all existing literature and courseware, likely causing more confusion with beginners instead of less. By contrast, with a new syntax there is a clear criterion: Any book or courseware that mentions `implicit` is outdated and should be updated. - diff --git a/docs/docs/reference/contextual-implicit/multiversal-equality.md b/docs/docs/reference/contextual-implicit/multiversal-equality.md index 0aefc971b437..4f7ee6cf8306 100644 --- a/docs/docs/reference/contextual-implicit/multiversal-equality.md +++ b/docs/docs/reference/contextual-implicit/multiversal-equality.md @@ -31,7 +31,7 @@ that derives `Eql`, e.g. ```scala class T derives Eql ``` -Alternatively, one can also define an `Eql` implicit directly, like this: +Alternatively, one can also define an `Eql` instance directly, like this: ```scala implicit for Eql[T, T] = Eql.derived ``` @@ -136,12 +136,12 @@ Explanations: ## Predefined Eql Instances -The `Eql` object defines implicits for comparing +The `Eql` object defines implicit instances for comparing - the primitive types `Byte`, `Short`, `Char`, `Int`, `Long`, `Float`, `Double`, `Boolean`, and `Unit`, - `java.lang.Number`, `java.lang.Boolean`, and `java.lang.Character`, - `scala.collection.Seq`, and `scala.collection.Set`. -Implicits are defined so that every one of these types has a reflexive `Eql` implicit, and the following holds: +Implicit instances are defined so that every one of these types has a reflexive `Eql` instance, and the following holds: - Primitive numeric types can be compared with each other. - Primitive numeric types can be compared with subtypes of `java.lang.Number` (and _vice versa_). diff --git a/docs/docs/reference/contextual-implicit/query-types.md b/docs/docs/reference/contextual-implicit/query-types.md index 0b21c7ca6d03..89a3b975b928 100644 --- a/docs/docs/reference/contextual-implicit/query-types.md +++ b/docs/docs/reference/contextual-implicit/query-types.md @@ -138,7 +138,7 @@ object Test { ``` **Explanations**: We use a implicit function type `given WrappedResult[T] => Boolean` as the type of the condition of `ensuring`. An argument to `ensuring` such as -`(result == 6)` will therefore have an implicit of type `WrappedResult[T]` in +`(result == 6)` will therefore have an implicit for `WrappedResult[T]` in scope to pass along to the `result` method. `WrappedResult` is a fresh type, to make sure that we do not get unwanted implicits in scope (this is good practice in all cases where implicit parameters are involved). Since `WrappedResult` is an opaque type alias, its diff --git a/docs/docs/reference/contextual-implicit/relationship-implicits.md b/docs/docs/reference/contextual-implicit/relationship-implicits.md index 399dcde7ff9f..3eecbf99c95e 100644 --- a/docs/docs/reference/contextual-implicit/relationship-implicits.md +++ b/docs/docs/reference/contextual-implicit/relationship-implicits.md @@ -9,7 +9,7 @@ Many, but not all, of the new contextual abstraction features in Scala 3 can be ### Implicit Instances -Implicit instances can be mapped to combinations of implicit objects, classes and implicit methods. +Implicit instances can be mapped to combinations of implicit objects and implicit methods together with normal classes. 1. Implicit instances without parameters are mapped to implicit objects. E.g., ```scala @@ -57,9 +57,9 @@ Implicit instances can be mapped to combinations of implicit objects, classes an final implicit def Context_repr = ctx ``` -### Anonymous Implicits +### Anonymous Implicit Instances -Anonymous implicits get compiler synthesized names, which are generated in a reproducible way from the implemented type(s). For example, if the names of the `IntOrd` and `ListOrd` implicits above were left out, the following names would be synthesized instead: +Anonymous implicit instances get compiler synthesized names, which are generated in a reproducible way from the implemented type(s). For example, if the names of the `IntOrd` and `ListOrd` implicits above were left out, the following names would be synthesized instead: ```scala implicit Ord_Int_ev for Ord[Int] { ... } implicit Ord_List_ev[T] for Ord[List[T]] { ... } @@ -70,7 +70,7 @@ The synthesized type names are formed from - the simple name(s) of the toplevel argument type constructors to these types - the suffix `_ev`. -Anonymous implicit values that define extension methods without also implementing a type +Anonymous implicit instances that define extension methods without also implementing a type get their name from the name of the first extension method and the toplevel type constructor of its first parameter. For example, the implicit ```scala @@ -139,8 +139,8 @@ Implicit by-name parameters are not supported in Scala 2, but can be emulated to ### Implicit Conversions -Implicit conversion methods in Scala 2 can be expressed as implicit instances of class -`scala.Conversion` in Dotty. E.g. instead of +Implicit conversion methods in Scala 2 can be expressed as implicit instances of the +`scala.Conversion` class in Dotty. E.g. instead of ```scala implicit def stringToToken(str: String): Token = new Keyword(str) ``` @@ -153,7 +153,7 @@ one can write ### Implicit Classes -Implicit classes in Scala 2 are often used to define extension methods, which are directly supported in Dotty. Other uses of implicit classes can be simulated by a pair of a regular class and a conversion instance. +Implicit classes in Scala 2 are often used to define extension methods, which are directly supported in Dotty. Other uses of implicit classes can be simulated by a pair of a regular class and an implicit `Conversion` instance. ### Abstract Implicits diff --git a/docs/docs/reference/contextual-repr/derivation.md b/docs/docs/reference/contextual-repr/derivation.md index 2fc0ae078353..f4167863a9a2 100644 --- a/docs/docs/reference/contextual-repr/derivation.md +++ b/docs/docs/reference/contextual-repr/derivation.md @@ -339,7 +339,7 @@ One important difference between this approach and Scala-2 typeclass derivation Sometimes one would like to derive a typeclass representative for an ADT after the ADT is defined, without being able to change the code of the ADT itself. To do this, simply define a representative with the `derived` method of the typeclass as right-hand side. E.g, to implement `Ordering` for `Option`, define: ```scala -repr [T: Ordering]: Ordering[Option[T]] = Ordering.derived +repr [T: Ordering] of Ordering[Option[T]] = Ordering.derived ``` Usually, the `Ordering.derived` clause has an implicit parameter of type `Generic[Option[T]]`. Since the `Option` trait has a `derives` clause, diff --git a/docs/docs/reference/contextual-repr/instance-defs.md b/docs/docs/reference/contextual-repr/instance-defs.md index 67343267944a..0df31b30825e 100644 --- a/docs/docs/reference/contextual-repr/instance-defs.md +++ b/docs/docs/reference/contextual-repr/instance-defs.md @@ -4,8 +4,8 @@ title: "Representatives" --- Representatives define "canonical" values of given types -that serve for synthesizing arguments to [given clauses](./inferable-params.html). Example: - +that can be synthesized by the compiler as arguments for +[given clauses](./inferable-params.html). Example: ```scala trait Ord[T] { def compare(x: T, y: T): Int diff --git a/docs/docs/reference/contextual-repr/motivation.md b/docs/docs/reference/contextual-repr/motivation.md index 034d7de17ba2..460ded31b6d4 100644 --- a/docs/docs/reference/contextual-repr/motivation.md +++ b/docs/docs/reference/contextual-repr/motivation.md @@ -47,7 +47,7 @@ Existing Scala programmers by and large have gotten used to the status quo and s The following pages introduce a redesign of contextual abstractions in Scala. They introduce four fundamental changes: - 1. [Representatives](./instance-defs.html) are a new way to define basic terms that can be synthesized. They replace implicit definitions. The core principle of the proposal is that, rather than mixing the `implicit` modifier with a large number of features, we have a single way to define terms that can be synthesized for types. + 1. [Representatives](./instance-defs.html) are a new way to define basic terms that can be synthesized. They replace implicit definitions. The core principle is that, rather than mixing the `implicit` modifier with a large number of features, we have a single way to define terms that can be synthesized for types. 2. [Given Clauses](./inferable-params.html) are a new syntax for implicit _parameters_ and their _arguments_. Both are introduced with the same keyword, `given`. This unambiguously aligns parameters and arguments, solving a number of language warts. It also allows us to have several implicit parameter sections, and to have implicit parameters followed by normal ones. @@ -79,4 +79,3 @@ Could we achieve the same goals by tweaking existing implicits? After having tri - Third, even if we would somehow succeed with migration, we still have the problem how to teach this. We cannot make existing tutorials go away. Almost all existing tutorials start with implicit conversions, which will go away; they use normal imports, which will go away, and they explain calls to methods with implicit parameters by expanding them to plain applications, which will also go away. This means that we'd have to add modifications and qualifications to all existing literature and courseware, likely causing more confusion with beginners instead of less. By contrast, with a new syntax there is a clear criterion: Any book or courseware that mentions `implicit` is outdated and should be updated. - diff --git a/docs/docs/reference/contextual-repr/relationship-implicits.md b/docs/docs/reference/contextual-repr/relationship-implicits.md index 17745b6dbda6..6261c7f3653d 100644 --- a/docs/docs/reference/contextual-repr/relationship-implicits.md +++ b/docs/docs/reference/contextual-repr/relationship-implicits.md @@ -9,7 +9,7 @@ Many, but not all, of the new contextual abstraction features in Scala 3 can be ### Representatives -Representative clauses can be mapped to combinations of implicit objects, classes and implicit methods. +Representative clauses can be mapped to combinations of implicit objects and implicit methods together with normal classes. 1. Representatives without parameters are mapped to implicit objects. E.g., ```scala @@ -30,7 +30,7 @@ Representative clauses can be mapped to combinations of implicit objects, classe ``` 3. Alias representatives map to implicit methods. If the representative has neither type parameters nor a given clause, the result of creating an instance is cached in a variable. There are two cases that can be optimized: - - If the right hand side is a simple reference, we can simply + - If the right hand side is a simple reference, we can use a forwarder to that reference without caching it. - If the right hand side is more complex, but still known to be pure, we can create a `val` that computes it ahead of time.