Skip to content

Commit

Permalink
Merge pull request #9059 from asakaev/type-class
Browse files Browse the repository at this point in the history
Make the spelling of "type class" consistent
  • Loading branch information
liufengyun authored May 28, 2020
2 parents 5e9d927 + 6db3a6c commit 3c28893
Show file tree
Hide file tree
Showing 32 changed files with 92 additions and 92 deletions.
12 changes: 6 additions & 6 deletions compiler/src/dotty/tools/dotc/typer/Deriving.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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 =>

Expand Down Expand Up @@ -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
Expand All @@ -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.
Expand Down Expand Up @@ -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
Expand Down
12 changes: 6 additions & 6 deletions docs/blog/_posts/2019-03-05-13th-dotty-milestone-release.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand All @@ -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
Expand All @@ -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
Expand Down
6 changes: 3 additions & 3 deletions docs/blog/_posts/2019-06-11-16th-dotty-milestone-release.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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).

Expand Down
2 changes: 1 addition & 1 deletion docs/docs/reference/changed-features/main-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/reference/changed-features/numeric-literals.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ gives a type error, since without an expected type `-10_000_000_000` is treated
### The FromDigits Trait

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] {
Expand Down
12 changes: 6 additions & 6 deletions docs/docs/reference/contextual/motivation.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand All @@ -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
Expand Down Expand Up @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/reference/contextual/multiversal-equality.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/reference/contextual/relationship-implicits.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Loading

0 comments on commit 3c28893

Please sign in to comment.