From 049c14a676e458827191c3997ba08c39d984d18a Mon Sep 17 00:00:00 2001 From: Akhtiam Sakaev Date: Wed, 27 May 2020 12:54:32 +0300 Subject: [PATCH] Make the spelling of "type class" consistent --- .../src/dotty/tools/dotc/typer/Deriving.scala | 12 +++++----- ...2019-03-05-13th-dotty-milestone-release.md | 12 +++++----- ...2019-06-11-16th-dotty-milestone-release.md | 6 ++--- ...2020-02-05-22nd-dotty-milestone-release.md | 2 +- .../changed-features/main-functions.md | 2 +- .../changed-features/numeric-literals.md | 2 +- docs/docs/reference/contextual/motivation.md | 12 +++++----- .../contextual/multiversal-equality.md | 4 ++-- .../contextual/relationship-implicits.md | 4 ++-- .../{typeclasses.md => type-classes.md} | 24 +++++++++---------- .../docs/reference/features-classification.md | 2 +- docs/docs/reference/overview.md | 2 +- .../docs/release-notes/syntax-changes-0.22.md | 2 +- docs/sidebar.yml | 6 ++--- .../scala/quoted/Liftable.scala | 2 +- .../scala/quoted/Unliftable.scala | 2 +- library/src/scala/util/FromDigits.scala | 2 +- .../typeclass-derivation2.scala | 2 +- tests/neg/deriving-duplicate.scala | 2 +- tests/neg/i3976.scala | 2 +- tests/pos-special/typeclass-scaling.scala | 4 ++-- tests/pos/anykind.scala | 4 ++-- .../typeclass-derivation2.scala | 10 ++++---- .../typeclass-derivation2c.scala | 12 +++++----- tests/run/extension-methods.scala | 2 +- tests/run/instances-anonymous.scala | 2 +- tests/run/instances.scala | 2 +- tests/run/tagless.scala | 6 ++--- tests/run/typeclass-derivation2a.scala | 12 +++++----- tests/run/typeclass-derivation2b.scala | 12 +++++----- tests/run/typeclass-derivation2d.scala | 8 +++---- tests/run/typeclass-derivation3.scala | 6 ++--- 32 files changed, 92 insertions(+), 92 deletions(-) rename docs/docs/reference/contextual/{typeclasses.md => type-classes.md} (87%) diff --git a/compiler/src/dotty/tools/dotc/typer/Deriving.scala b/compiler/src/dotty/tools/dotc/typer/Deriving.scala index 6b5db29abc8b..42099edbdb1d 100644 --- a/compiler/src/dotty/tools/dotc/typer/Deriving.scala +++ b/compiler/src/dotty/tools/dotc/typer/Deriving.scala @@ -18,7 +18,7 @@ import transform.TypeUtils._ import transform.SymUtils._ import ErrorReporting.errorTree -/** A typer mixin that implements typeclass derivation functionality */ +/** A typer mixin that implements type class derivation functionality */ trait Deriving { this: Typer => @@ -49,7 +49,7 @@ trait Deriving { private def addDerivedInstance(clsName: Name, info: Type, pos: SourcePosition): Unit = { val instanceName = s"derived$$$clsName".toTermName if (ctx.denotNamed(instanceName).exists) - ctx.error(i"duplicate typeclass derivation for $clsName", pos) + ctx.error(i"duplicate type class derivation for $clsName", pos) else // If we set the Synthetic flag here widenGiven will widen too far and the // derived instance will have too low a priority to be selected over a freshly @@ -71,7 +71,7 @@ trait Deriving { * * See detailed descriptions in deriveSingleParameter and deriveEql below. * - * If it passes the checks, enter a typeclass instance for it in the current scope. + * If it passes the checks, enter a type class instance for it in the current scope. * * See test run/typeclass-derivation2, run/poly-kinded-derives and pos/derive-eq * for examples that spell out what would be generated. @@ -210,12 +210,12 @@ trait Deriving { // Procedure: // We construct a two column matrix of the deriving class type parameters - // and the Eql typeclass parameters. + // and the Eql type class parameters. // // Rows: parameters of the deriving class - // Columns: parameters of the Eql typeclass (L/R) + // Columns: parameters of the Eql type class (L/R) // - // Running example: typeclass: class Eql[L, R], deriving class: class A[T, U, V] + // Running example: type class: class Eql[L, R], deriving class: class A[T, U, V] // clsParamss = // T_L T_R // U_L U_R diff --git a/docs/blog/_posts/2019-03-05-13th-dotty-milestone-release.md b/docs/blog/_posts/2019-03-05-13th-dotty-milestone-release.md index 423ded01fd80..d595e5e0d069 100644 --- a/docs/blog/_posts/2019-03-05-13th-dotty-milestone-release.md +++ b/docs/blog/_posts/2019-03-05-13th-dotty-milestone-release.md @@ -107,7 +107,7 @@ communicated more clearly syntactically. Furthermore, the `implicit` keyword is ascribed too many overloaded meanings in the language (implicit vals, defs, objects, parameters). For instance, a newcomer can easily confuse the two examples above, although they demonstrate completely different things, a -typeclass instance is an implicit object or val if unconditional and an implicit +type class instance is an implicit object or val if unconditional and an implicit def with implicit parameters if conditional; arguably all of them are surprisingly similar (syntactically). Another consideration is that the `implicit` keyword annotates a whole parameter section instead of a single @@ -231,8 +231,8 @@ PR chain that originated from implicits are summarized in [#5825](https://github.com/lampepfl/dotty/pull/5825). -This release offers the support for _typeclass derivation_ as a language -feature. Typeclass derivation is a way to generate instances of certain type +This release offers the support for _type class derivation_ as a language +feature. Type class derivation is a way to generate instances of certain type classes automatically or with minimal code hints, and is now supported natively with *dedicated language support*. A type class in this sense is any trait or class with a type parameter that describes the type being operated on. Commonly @@ -267,7 +267,7 @@ which replaces: A extends B with C { ... } ``` -With typeclass derivation we can also derive types. A trait or class can appear +With type class derivation we can also derive types. A trait or class can appear in a derives clause if its companion object defines a method named `derived`. The type and implementation of a `derived` method are arbitrary, but typically it has a definition like this: @@ -276,7 +276,7 @@ it has a definition like this: def derived[T] given Generic[T] = ... ``` -**You can read more about** [Typeclass +**You can read more about** [Type class Derivation](https://dotty.epfl.ch/docs/reference/contextual/derivation.html) or have a deep dive at the relevant PRs: [#5540](https://github.com/lampepfl/dotty/pull/5540) and @@ -291,7 +291,7 @@ provide a derived implicit instance: implied for Eql[Int, String] = Eql.derived ``` -**You can read more about** how we based multiversal equality on typeclass derivation through +**You can read more about** how we based multiversal equality on type class derivation through the relevant PR [#5843](https://github.com/lampepfl/dotty/pull/5843). _Implicit conversions_ are now defined by implied instances of the diff --git a/docs/blog/_posts/2019-06-11-16th-dotty-milestone-release.md b/docs/blog/_posts/2019-06-11-16th-dotty-milestone-release.md index 4b8d6f86f5ec..e3d81f6c3df5 100644 --- a/docs/blog/_posts/2019-06-11-16th-dotty-milestone-release.md +++ b/docs/blog/_posts/2019-06-11-16th-dotty-milestone-release.md @@ -194,14 +194,14 @@ import delegate Delegates.{for Ordering[_], ExecutionContext} would import the `intOrd`, `listOrd`, and `ec` instances but leave out the `im` instance, since it fits none of the specified bounds. -## New typeclass derivation scheme +## New type class derivation scheme Summary of measured differences with the old scheme: - About 100 lines more compiler code - the rest of the lines changed diff is tests. -- About 13-15% more code generated for typeclass instances -- About 3-4% slower to compile typeclass instances +- About 13-15% more code generated for type class instances +- About 3-4% slower to compile type class instances Advantages of new scheme: diff --git a/docs/blog/_posts/2020-02-05-22nd-dotty-milestone-release.md b/docs/blog/_posts/2020-02-05-22nd-dotty-milestone-release.md index c746ca57ef6d..a901e83130d8 100644 --- a/docs/blog/_posts/2020-02-05-22nd-dotty-milestone-release.md +++ b/docs/blog/_posts/2020-02-05-22nd-dotty-milestone-release.md @@ -58,7 +58,7 @@ This syntax is a completely separate one from the `given` syntax and hence is ai For the discussion, see [PR #7917](https://github.com/lampepfl/dotty/pull/7917). For more information on how to use extension methods in general and collective extension methods in particular, see the [documentation](https://dotty.epfl.ch/docs/reference/contextual/extension-methods.html). # Kind projector syntax support -[Kind projector](https://github.com/typelevel/kind-projector) is a popular compiler plugin for Scala 2. It is especially useful in the context of purely functional programming and typeclass derivation – everywhere where you need to work extensively with types. +[Kind projector](https://github.com/typelevel/kind-projector) is a popular compiler plugin for Scala 2. It is especially useful in the context of purely functional programming and type class derivation – everywhere where you need to work extensively with types. As of this release, a subset of the kind projector syntax is now supported in Dotty. Credits for this contribution go to [Travis Brown](https://github.com/travisbrown). diff --git a/docs/docs/reference/changed-features/main-functions.md b/docs/docs/reference/changed-features/main-functions.md index d7c194b9a4ff..b9e933329e11 100644 --- a/docs/docs/reference/changed-features/main-functions.md +++ b/docs/docs/reference/changed-features/main-functions.md @@ -30,7 +30,7 @@ This would generate a main program `happyBirthday` that could be called like thi Happy 23rd Birthday, Lisa and Peter! ``` A `@main` annotated method can be written either at the top-level or in a statically accessible object. The name of the program is in each case the name of the method, without any object prefixes. The `@main` method can have an arbitrary number of parameters. -For each parameter type there must be an instance of the `scala.util.FromString` typeclass +For each parameter type there must be an instance of the `scala.util.FromString` type class that is used to convert an argument string to the required parameter type. The parameter list of a main method can end in a repeated parameter that then takes all remaining arguments given on the command line. diff --git a/docs/docs/reference/changed-features/numeric-literals.md b/docs/docs/reference/changed-features/numeric-literals.md index f53fe44b8dbe..e7ff12aced84 100644 --- a/docs/docs/reference/changed-features/numeric-literals.md +++ b/docs/docs/reference/changed-features/numeric-literals.md @@ -55,7 +55,7 @@ gives a type error, since without an expected type `-10_000_000_000` is treated ### The FromDigits Class To allow numeric literals, a type simply has to define a given instance of the -`scala.util.FromDigits` typeclass, or one of its subclasses. `FromDigits` is defined +`scala.util.FromDigits` type class, or one of its subclasses. `FromDigits` is defined as follows: ```scala trait FromDigits[T] { diff --git a/docs/docs/reference/contextual/motivation.md b/docs/docs/reference/contextual/motivation.md index 4f0516e71b77..2dc2781fdcec 100644 --- a/docs/docs/reference/contextual/motivation.md +++ b/docs/docs/reference/contextual/motivation.md @@ -10,7 +10,7 @@ Scala's implicits are its most distinguished feature. They are _the_ fundamental 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) 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. -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, typeclass 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. +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. Given that term inference is where the industry is heading, and given that Scala has it in a very pure form, how come implicits are not more popular? In fact, it's fair to say that implicits are at the same time Scala's most distinguished and most controversial feature. I believe this is due to a number of aspects that together make implicits harder to learn than necessary and also make it harder to prevent abuses. @@ -27,7 +27,7 @@ Particular criticisms are: 2. Another widespread abuse is over-reliance on implicit imports. This often leads to inscrutable type errors that go away with the right import incantation, leaving a feeling of frustration. Conversely, it is hard to see what implicits a program uses since implicits can hide anywhere in a long list of imports. - 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 typeclass 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. + 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 @@ -59,10 +59,10 @@ The following pages introduce a redesign of contextual abstractions in Scala. Th This section also contains pages describing other language features that are related to context abstraction. These are: - [Context Bounds](./context-bounds.md), which carry over unchanged. - - [Extension Methods](./extension-methods.md) replace implicit classes in a way that integrates better with typeclasses. - - [Implementing Typeclasses](./typeclasses.md) demonstrates how some common typeclasses can be implemented using the new constructs. - - [Typeclass Derivation](./derivation.md) introduces constructs to automatically derive typeclass instances for ADTs. - - [Multiversal Equality](./multiversal-equality.md) introduces a special typeclass to support type safe equality. + - [Extension Methods](./extension-methods.md) replace implicit classes in a way that integrates better with type classes. + - [Implementing Type classes](type-classes.md) demonstrates how some common type classes can be implemented using the new constructs. + - [Type class Derivation](./derivation.md) introduces constructs to automatically derive type class instances for ADTs. + - [Multiversal Equality](./multiversal-equality.md) introduces a special type class to support type safe equality. - [Context Functions](./context-functions.md) provide a way to abstract over context parameters. - [By-Name Context Parameters](./by-name-context-parameters.md) are an essential tool to define recursive synthesized values without looping. - [Relationship with Scala 2 Implicits](./relationship-implicits.md) discusses the relationship between old-style implicits and new-style givens and how to migrate from one to the other. diff --git a/docs/docs/reference/contextual/multiversal-equality.md b/docs/docs/reference/contextual/multiversal-equality.md index c9e5c29b82c4..3fe86e499c17 100644 --- a/docs/docs/reference/contextual/multiversal-equality.md +++ b/docs/docs/reference/contextual/multiversal-equality.md @@ -24,7 +24,7 @@ the program will still typecheck, since values of all types can be compared with But it will probably give unexpected results and fail at runtime. Multiversal equality is an opt-in way to make universal equality -safer. It uses a binary typeclass `Eql` to indicate that values of +safer. It uses a binary type class `Eql` to indicate that values of two given types can be compared with each other. The example above would not typecheck if `S` or `T` was a class that derives `Eql`, e.g. @@ -94,7 +94,7 @@ Instead of defining `Eql` instances directly, it is often more convenient to der ```scala class Box[T](x: T) derives Eql ``` -By the usual rules of [typeclass derivation](./derivation.md), +By the usual rules of [type class derivation](./derivation.md), this generates the following `Eql` instance in the companion object of `Box`: ```scala given [T, U](using Eql[T, U]) as Eql[Box[T], Box[U]] = Eql.derived diff --git a/docs/docs/reference/contextual/relationship-implicits.md b/docs/docs/reference/contextual/relationship-implicits.md index bb4c2bc5d189..12c9ee3eb672 100644 --- a/docs/docs/reference/contextual/relationship-implicits.md +++ b/docs/docs/reference/contextual/relationship-implicits.md @@ -121,9 +121,9 @@ 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. -### Typeclass Derivation +### Type class Derivation -Typeclass 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, Magnolia, or scalaz-deriving. ### Implicit Function Types diff --git a/docs/docs/reference/contextual/typeclasses.md b/docs/docs/reference/contextual/type-classes.md similarity index 87% rename from docs/docs/reference/contextual/typeclasses.md rename to docs/docs/reference/contextual/type-classes.md index e2a265ed4e52..7627889653bd 100644 --- a/docs/docs/reference/contextual/typeclasses.md +++ b/docs/docs/reference/contextual/type-classes.md @@ -1,18 +1,18 @@ --- layout: doc-page -title: "Implementing Typeclasses" +title: "Implementing Type classes" --- -A _typeclass_ is an abstract, parameterized type that lets you add new behavior to any closed data type without using sub-typing. This can be useful in multiple use-cases, for example: +A _type class_ is an abstract, parameterized type that lets you add new behavior to any closed data type without using sub-typing. This can be useful in multiple use-cases, for example: * expressing how a type you don't own (from the standard or 3rd-party library) conforms to such behavior * expressing such a behavior for multiple types without involving sub-typing relationships (one `extends` another) between those types (see: [ad hoc polymorphism](https://en.wikipedia.org/wiki/Ad_hoc_polymorphism) for instance) -Therefore in Scala 3, _typeclasses_ are just _traits_ with one or more parameters whose implementations are not defined through the `extends` keyword, but by **given instances**. -Here are some examples of usual typeclasses: +Therefore in Scala 3, _type classes_ are just _traits_ with one or more parameters whose implementations are not defined through the `extends` keyword, but by **given instances**. +Here are some examples of usual type classes: ### Semigroups and monoids: -Here's the `Monoid` typeclass definition: +Here's the `Monoid` type class definition: ```scala trait SemiGroup[T] { @@ -24,7 +24,7 @@ trait Monoid[T] extends SemiGroup[T] { } ``` -An implementation of this `Monoid` typeclass for the type `String` can be the following: +An implementation of this `Monoid` type class for the type `String` can be the following: ```scala given Monoid[String] { @@ -94,7 +94,7 @@ trait Functor[F[?]] { } ``` -Which could read as follows: "A `Functor` for the type constructor `F[?]` represents the ability to transform `F[A]` to `F[B]` through the application of the `mapper` function whose type is `A => B`". We call the `Functor` definition here a _typeclass_. +Which could read as follows: "A `Functor` for the type constructor `F[?]` represents the ability to transform `F[A]` to `F[B]` through the application of the `mapper` function whose type is `A => B`". We call the `Functor` definition here a _type class_. This way, we could define an instance of `Functor` for the `List` type: ```scala @@ -119,7 +119,7 @@ assertTransformation(List("a1", "b1"), List("a", "b"), elt => s"${elt}1") ``` That's a first step, but in practice we probably would like the `map` function to be a method directly accessible on the type `F`. So that we can call `map` directly on instances of `F`, and get rid of the `summon[Functor[F]]` part. -As in the previous example of Monoids, [`extension` methods](extension-methods.html) help achieving that. Let's re-define the `Functor` _typeclass_ with extension methods. +As in the previous example of Monoids, [`extension` methods](extension-methods.html) help achieving that. Let's re-define the `Functor` _type class_ with extension methods. ```scala trait Functor[F[?]] { @@ -271,8 +271,8 @@ given readerMonad[Ctx] as Monad[[X] =>> Ctx => X] { ### Summary -The definition of a _typeclass_ is expressed via a parameterised type with abstract members, such as a `trait`. -The main difference between object oriented polymorphism, and ad-hoc polymorphism with _typeclasses_, is how the definition of the _typeclass_ is implemented, in relation to the type it acts upon. -In the case of a _typeclass_, its implementation for a concrete type is expressed through a `given` term definition, which is supplied as an implicit argument alongside the value it acts upon. With object oriented polymorphism, the implementation is mixed into the parents of a class, and only a single term is required to perform a polymorphic operation. +The definition of a _type class_ is expressed via a parameterised type with abstract members, such as a `trait`. +The main difference between object oriented polymorphism, and ad-hoc polymorphism with _type classes_, is how the definition of the _type class_ is implemented, in relation to the type it acts upon. +In the case of a _type class_, its implementation for a concrete type is expressed through a `given` term definition, which is supplied as an implicit argument alongside the value it acts upon. With object oriented polymorphism, the implementation is mixed into the parents of a class, and only a single term is required to perform a polymorphic operation. -To conclude, in addition to given instances, other constructs like extension methods, context bounds and type lambdas allow a concise and natural expression of _typeclasses_. +To conclude, in addition to given instances, other constructs like extension methods, context bounds and type lambdas allow a concise and natural expression of _type classes_. diff --git a/docs/docs/reference/features-classification.md b/docs/docs/reference/features-classification.md index cd9a99be9e26..c33d2bbe5460 100644 --- a/docs/docs/reference/features-classification.md +++ b/docs/docs/reference/features-classification.md @@ -172,7 +172,7 @@ To enable porting most uses of macros, we are experimenting with the advanced la - [Inline](metaprogramming/inline.md) provides 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. -- [Typeclass 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. +- [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. **Status: not yet settled** diff --git a/docs/docs/reference/overview.md b/docs/docs/reference/overview.md index 566156b01d50..38dab4587ffa 100644 --- a/docs/docs/reference/overview.md +++ b/docs/docs/reference/overview.md @@ -122,7 +122,7 @@ To enable porting most uses of macros, we are experimenting with the advanced la - [Inline](metaprogramming/inline.md) provides 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. -- [Typeclass 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. +- [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. ## See Also diff --git a/docs/docs/release-notes/syntax-changes-0.22.md b/docs/docs/release-notes/syntax-changes-0.22.md index d0825b29bd4b..64207d72e9d1 100644 --- a/docs/docs/release-notes/syntax-changes-0.22.md +++ b/docs/docs/release-notes/syntax-changes-0.22.md @@ -34,7 +34,7 @@ max(a, b)(using intOrd) ``` The previous syntax that uses `given` also for context parameters and arguments is no longer supported. -Context bounds remain supported as a shorthand for one-parameter typeclass constraints. So the two definitions above could also be written as +Context bounds remain supported as a shorthand for one-parameter type class constraints. So the two definitions above could also be written as ```scala def max[T: Ordering](x: T, y: T): T = ... given [T: Ordering] as Ordering[List[T]] { ... } diff --git a/docs/sidebar.yml b/docs/sidebar.yml index 33cb1c83153b..680a6d6982e9 100644 --- a/docs/sidebar.yml +++ b/docs/sidebar.yml @@ -55,9 +55,9 @@ sidebar: url: docs/reference/contextual/given-imports.html - title: Extension Methods url: docs/reference/contextual/extension-methods.html - - title: Implementing Typeclasses - url: docs/reference/contextual/typeclasses.html - - title: Typeclass Derivation + - title: Implementing Type classes + url: docs/reference/contextual/type-classes.html + - title: Type class Derivation url: docs/reference/contextual/derivation.html - title: Multiversal Equality url: docs/reference/contextual/multiversal-equality.html diff --git a/library/src-bootstrapped/scala/quoted/Liftable.scala b/library/src-bootstrapped/scala/quoted/Liftable.scala index 33e627dd9067..4f6fadf7b5a5 100644 --- a/library/src-bootstrapped/scala/quoted/Liftable.scala +++ b/library/src-bootstrapped/scala/quoted/Liftable.scala @@ -2,7 +2,7 @@ package scala.quoted import scala.reflect.ClassTag -/** A typeclass for types that can be turned to `quoted.Expr[T]` +/** A type class for types that can be turned to `quoted.Expr[T]` * without going through an explicit `'{...}` operation. */ trait Liftable[T] { diff --git a/library/src-bootstrapped/scala/quoted/Unliftable.scala b/library/src-bootstrapped/scala/quoted/Unliftable.scala index 8feb24c064ce..c7d6d891f5ab 100644 --- a/library/src-bootstrapped/scala/quoted/Unliftable.scala +++ b/library/src-bootstrapped/scala/quoted/Unliftable.scala @@ -1,6 +1,6 @@ package scala.quoted -/** A typeclass for types that can be turned from a `quoted.Expr[T]` to a `T` */ +/** A type class for types that can be turned from a `quoted.Expr[T]` to a `T` */ trait Unliftable[T] { /** Return the value of the expression. diff --git a/library/src/scala/util/FromDigits.scala b/library/src/scala/util/FromDigits.scala index 2830818464dc..5fc0d5a6b03b 100644 --- a/library/src/scala/util/FromDigits.scala +++ b/library/src/scala/util/FromDigits.scala @@ -4,7 +4,7 @@ import quoted._ import internal.Chars.digit2int import annotation.internal.sharable -/** A typeclass for types that admit numeric literals. +/** A type class for types that admit numeric literals. */ trait FromDigits[T] { diff --git a/tests/neg-custom-args/typeclass-derivation2.scala b/tests/neg-custom-args/typeclass-derivation2.scala index 7954d1c61151..8c07bf883839 100644 --- a/tests/neg-custom-args/typeclass-derivation2.scala +++ b/tests/neg-custom-args/typeclass-derivation2.scala @@ -107,7 +107,7 @@ object TypeLevel { case Case[T, Elems <: Tuple]() } - /** Every generic derivation starts with a typeclass instance of this type. + /** Every generic derivation starts with a type class instance of this type. * It informs that type `T` has shape `S` and also implements runtime reflection on `T`. */ abstract class Shaped[T, S <: Shape] extends Reflected[T] diff --git a/tests/neg/deriving-duplicate.scala b/tests/neg/deriving-duplicate.scala index 1574d3af6f4e..be87d5a5c37f 100644 --- a/tests/neg/deriving-duplicate.scala +++ b/tests/neg/deriving-duplicate.scala @@ -17,5 +17,5 @@ object Test extends App { val a = new A val a2 = new A2 - case class D() derives a.TC1, a2.TC1 // error: duplicate typeclass derivation + case class D() derives a.TC1, a2.TC1 // error: duplicate type class derivation } \ No newline at end of file diff --git a/tests/neg/i3976.scala b/tests/neg/i3976.scala index dc17fe927d64..52429c3bbeb9 100644 --- a/tests/neg/i3976.scala +++ b/tests/neg/i3976.scala @@ -8,7 +8,7 @@ object Test { A == A A == (B: Hoge[_]) - A == B // should be error: cannot be compared, needs proper typeclass drivation of `Eql` to get there. + A == B // should be error: cannot be compared, needs proper type class drivation of `Eql` to get there. class C diff --git a/tests/pos-special/typeclass-scaling.scala b/tests/pos-special/typeclass-scaling.scala index d7073c5f5556..1c3c9fe33075 100644 --- a/tests/pos-special/typeclass-scaling.scala +++ b/tests/pos-special/typeclass-scaling.scala @@ -208,7 +208,7 @@ object datatypes { object typeclasses { import compiletime.summonFrom - // A typeclass + // A type class trait Eq[T] { def eql(x: T, y: T): Boolean } @@ -260,7 +260,7 @@ object typeclasses { } } - // Another typeclass + // Another type class trait Pickler[T] { def pickle(buf: mutable.ListBuffer[Int], x: T): Unit def unpickle(buf: mutable.ListBuffer[Int]): T diff --git a/tests/pos/anykind.scala b/tests/pos/anykind.scala index 81edae26a920..2e40ae070e13 100644 --- a/tests/pos/anykind.scala +++ b/tests/pos/anykind.scala @@ -7,7 +7,7 @@ object Test { // PoC of controlled KindPolymorphism in Scala // // The idea is NOT to provide universal kind-polymorphism that would be a bad idea anyway - // but to bring a "controlled" kind-polymorphism relying on accepted kinds defined by typeclass implicits + // but to bring a "controlled" kind-polymorphism relying on accepted kinds defined by type class implicits // Thus, kind-polymorphism is strictly scoped to your domain and is what you expect to be, nothing else. // // `Ykind-polymorphism` flag aims at deferring just a bit Scalac type inference when encountering AnyKind higher bounds @@ -16,7 +16,7 @@ object Test { // // Here are code-samples that work now: // - basic kind polymorphism controlled by implicits - // - Kindness proofs based on typeclasses (specially SameKind) + // - Kindness proofs based on type classes (specially SameKind) // - Kind-Polymorphic list (on type & value) (2 different implementations) // - Some weird cases we don't want the compiler to authorize diff --git a/tests/run-custom-args/typeclass-derivation2.scala b/tests/run-custom-args/typeclass-derivation2.scala index 4902977954de..772e31d7cdee 100644 --- a/tests/run-custom-args/typeclass-derivation2.scala +++ b/tests/run-custom-args/typeclass-derivation2.scala @@ -1,7 +1,7 @@ import scala.collection.mutable import scala.annotation.tailrec -// A typeclass derivation encoding using Shape/Shaped scheme, now superseded by +// A type class derivation encoding using Shape/Shaped scheme, now superseded by // typeclass-derivation2a object TypeLevel { /** @param caseLabels The case and element labels of the described ADT as encoded strings. @@ -109,7 +109,7 @@ object TypeLevel { case Case[T, Elems <: Tuple]() } - /** Every generic derivation starts with a typeclass instance of this type. + /** Every generic derivation starts with a type class instance of this type. * It informs that type `T` has shape `S` and also implements runtime reflection on `T`. */ abstract class Shaped[T, S <: Shape] extends Reflected[T] @@ -218,7 +218,7 @@ object Either { implicit def derived$Show[L: Show, R: Show]: Show[Either[L, R]] = Show.derived } -// A typeclass +// A type class trait Eq[T] { def eql(x: T, y: T): Boolean } @@ -274,7 +274,7 @@ object Eq { } } -// Another typeclass +// Another type class trait Pickler[T] { def pickle(buf: mutable.ListBuffer[Int], x: T): Unit def unpickle(buf: mutable.ListBuffer[Int]): T @@ -368,7 +368,7 @@ object Pickler { } } -// A third typeclass, making use of labels +// A third type class, making use of labels trait Show[T] { def show(x: T): String } diff --git a/tests/run-custom-args/typeclass-derivation2c.scala b/tests/run-custom-args/typeclass-derivation2c.scala index 782da7b9239d..fcd83b6c45ee 100644 --- a/tests/run-custom-args/typeclass-derivation2c.scala +++ b/tests/run-custom-args/typeclass-derivation2c.scala @@ -2,7 +2,7 @@ import scala.collection.mutable import scala.annotation.tailrec import scala.compiletime.summonInline -// Simulation of an alternative typeclass derivation scheme proposed in #6153 +// Simulation of an alternative type class derivation scheme proposed in #6153 // -- Classes and Objects of the Derivation Framework ---------------------------------- @@ -189,11 +189,11 @@ object Right extends Generic.Product[Right[_]] { // -- Type classes ------------------------------------------------------------ -// Everything here is hand-written by the authors of the derivable typeclasses +// Everything here is hand-written by the authors of the derivable type classes // The same schema is used throughout. // -// - A typeclass implements an inline `derived` method, given a `Generic` instance. -// - Each implemented typeclass operation `xyz` calls 4 inline helper methods: +// - A type class implements an inline `derived` method, given a `Generic` instance. +// - Each implemented type class operation `xyz` calls 4 inline helper methods: // 1. `xyzCases` for sums, // 2. `xyzProduct` for products, // 3. `xyzElems` stepping through the elements of a product, @@ -203,7 +203,7 @@ object Right extends Generic.Product[Right[_]] { // the second parameter list contains parameters that show up in the // generated code. (This is done just to make things clearer). -// Equality typeclass +// Equality type class trait Eq[T] { def eql(x: T, y: T): Boolean } @@ -253,7 +253,7 @@ object Eq { } } -// Pickling typeclass +// Pickling type class trait Pickler[T] { def pickle(buf: mutable.ListBuffer[Int], x: T): Unit def unpickle(buf: mutable.ListBuffer[Int]): T diff --git a/tests/run/extension-methods.scala b/tests/run/extension-methods.scala index 82552aaf9e82..ae5a9c4c2d2c 100644 --- a/tests/run/extension-methods.scala +++ b/tests/run/extension-methods.scala @@ -41,7 +41,7 @@ object Test extends App { def unit: String = "" } - // Abstracting over a typeclass with a context bound: + // Abstracting over a type class with a context bound: def sum[T: Monoid](xs: List[T]): T = xs.foldLeft(implicitly[Monoid[T]].unit)(_.combine(_)) diff --git a/tests/run/instances-anonymous.scala b/tests/run/instances-anonymous.scala index c012e0926d80..b71d2e775ddf 100644 --- a/tests/run/instances-anonymous.scala +++ b/tests/run/instances-anonymous.scala @@ -50,7 +50,7 @@ object Test extends App { def unit: String = "" } - // Abstracting over a typeclass with a context bound: + // Abstracting over a type class with a context bound: def sum[T: Monoid](xs: List[T]): T = xs.foldLeft(implicitly[Monoid[T]].unit)(_.combine(_)) diff --git a/tests/run/instances.scala b/tests/run/instances.scala index c8533fad9225..c56054aeeb06 100644 --- a/tests/run/instances.scala +++ b/tests/run/instances.scala @@ -51,7 +51,7 @@ object Test extends App { def (x: String).combine(y: String): String = x.concat(y) def unit: String = "" - // Abstracting over a typeclass with a context bound: + // Abstracting over a type class with a context bound: def sum[T: Monoid](xs: List[T]): T = xs.foldLeft(implicitly[Monoid[T]].unit)(_.combine(_)) diff --git a/tests/run/tagless.scala b/tests/run/tagless.scala index 3147c7c8020b..334a5a692e40 100644 --- a/tests/run/tagless.scala +++ b/tests/run/tagless.scala @@ -27,7 +27,7 @@ object Test extends App { def tf0[T](using e: Exp[T]): T = e.add(e.lit(8), e.neg(e.add(e.lit(1), e.lit(2)))) - // Typeclass-style Exp syntax + // Type class style Exp syntax object ExpSyntax { def lit[T](i: Int) (using e: Exp[T]): T = e.lit(i) def neg[T](t: T) (using e: Exp[T]): T = e.neg(t) @@ -39,7 +39,7 @@ object Test extends App { def tf1[T](using Exp[T]): T = add(lit(8), neg(add(lit(1), lit(2)))) - // Base operations as typeclasses + // Base operations as type classes given Exp[Int] { def lit(i: Int): Int = i def neg(t: Int): Int = -t @@ -243,7 +243,7 @@ object Test extends App { case Add(l, r) => e.add(finalize[T](l), finalize[T](r)) } - // Abstracting over multiple typeclasses + // Abstracting over multiple type classes type Ring[T] = Exp[T] ?=> Mult[T] ?=> T def tfm1a[T]: Ring[T] = add(lit(7), neg(mul(lit(1), lit(2)))) diff --git a/tests/run/typeclass-derivation2a.scala b/tests/run/typeclass-derivation2a.scala index c126fd1cf4e2..371b66ddb5bc 100644 --- a/tests/run/typeclass-derivation2a.scala +++ b/tests/run/typeclass-derivation2a.scala @@ -1,8 +1,8 @@ import scala.collection.mutable import scala.annotation.tailrec -// Simulation of typeclass derivation encoding that's currently implemented. -// The real typeclass derivation is tested in typeclass-derivation3.scala. +// Simulation of type class derivation encoding that's currently implemented. +// The real type class derivation is tested in typeclass-derivation3.scala. object TypeLevel { /** @param caseLabels The case and element labels of the described ADT as encoded strings. */ @@ -94,7 +94,7 @@ object TypeLevel { case Case[T, Elems <: Tuple]() } - /** Every generic derivation starts with a typeclass instance of this type. + /** Every generic derivation starts with a type class instance of this type. * It informs that type `T` has shape `S` and also implements runtime reflection on `T`. */ abstract class Generic[T] { @@ -213,7 +213,7 @@ object Either { implicit def derived$Show[L: Show, R: Show]: Show[Either[L, R]] = Show.derived } -// A typeclass +// A type class trait Eq[T] { def eql(x: T, y: T): Boolean } @@ -261,7 +261,7 @@ object Eq { } } -// Another typeclass +// Another type class trait Pickler[T] { def pickle(buf: mutable.ListBuffer[Int], x: T): Unit def unpickle(buf: mutable.ListBuffer[Int]): T @@ -346,7 +346,7 @@ object Pickler { } } -// A third typeclass, making use of labels +// A third type class, making use of labels trait Show[T] { def show(x: T): String } diff --git a/tests/run/typeclass-derivation2b.scala b/tests/run/typeclass-derivation2b.scala index ed3d9eb1d864..ceb71f70c676 100644 --- a/tests/run/typeclass-derivation2b.scala +++ b/tests/run/typeclass-derivation2b.scala @@ -1,8 +1,8 @@ import scala.collection.mutable import scala.annotation.tailrec -// Simulation of typeclass derivation encoding that's currently implemented. -// The real typeclass derivation is tested in typeclass-derivation3.scala. +// Simulation of type class derivation encoding that's currently implemented. +// The real type class derivation is tested in typeclass-derivation3.scala. object TypeLevel { object EmptyProduct extends Product { @@ -85,7 +85,7 @@ object Lst { //implicit def derived$Show[T: Show]: Show[Lst[T]] = Show.derived } -// A typeclass +// A type class trait Eq[T] { def eql(x: T, y: T): Boolean } @@ -222,7 +222,7 @@ object Either { implicit def derived$Show[L: Show, R: Show]: Show[Either[L, R]] = Show.derived } -// A typeclass +// A type class trait Eq[T] { def eql(x: T, y: T): Boolean } @@ -272,7 +272,7 @@ object Eq { } } -// Another typeclass +// Another type class trait Pickler[T] { def pickle(buf: mutable.ListBuffer[Int], x: T): Unit def unpickle(buf: mutable.ListBuffer[Int]): T @@ -361,7 +361,7 @@ object Pickler { } } -// A third typeclass, making use of labels +// A third type class, making use of labels trait Show[T] { def show(x: T): String } diff --git a/tests/run/typeclass-derivation2d.scala b/tests/run/typeclass-derivation2d.scala index 15f144da4113..a67e55d584d9 100644 --- a/tests/run/typeclass-derivation2d.scala +++ b/tests/run/typeclass-derivation2d.scala @@ -1,7 +1,7 @@ import scala.collection.mutable import scala.annotation.tailrec -// Simulation of an alternative typeclass derivation scheme +// Simulation of an alternative type class derivation scheme // -- Classes and Objects of the Derivation Framework ---------------------------------- @@ -190,7 +190,7 @@ object Right extends Mirror.Product { } = this.asInstanceOf } -// --------------- Equality typeclass --------------------------------- +// --------------- Equality type class --------------------------------- trait Eq[T] { def eql(x: T, y: T): Boolean @@ -241,7 +241,7 @@ object Eq { } } -// ----------- Another typeclass ----------------------------------- +// ----------- Another type class ----------------------------------- trait Pickler[T] { def pickle(buf: mutable.ListBuffer[Int], x: T): Unit @@ -336,7 +336,7 @@ object Pickler { } } -// ----------- A third typeclass, making use of labels -------------------------- +// ----------- A third type class, making use of labels -------------------------- trait Show[T] { def show(x: T): String diff --git a/tests/run/typeclass-derivation3.scala b/tests/run/typeclass-derivation3.scala index 68a6c2cf1ffd..d855ecd79f4c 100644 --- a/tests/run/typeclass-derivation3.scala +++ b/tests/run/typeclass-derivation3.scala @@ -25,7 +25,7 @@ object datatypes { } object typeclasses { - // A typeclass + // A type class trait Eq[T] { def eql(x: T, y: T): Boolean } @@ -79,7 +79,7 @@ object typeclasses { } } - // Another typeclass + // Another type class trait Pickler[T] { def pickle(buf: mutable.ListBuffer[Int], x: T): Unit def unpickle(buf: mutable.ListBuffer[Int]): T @@ -177,7 +177,7 @@ object typeclasses { } } - // A third typeclass, making use of labels + // A third type class, making use of labels trait Show[T] { def show(x: T): String }