Skip to content

[docs/reference] more fixes in Markdown files #10826

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions docs/docs/reference/changed-features/eta-expansion-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ layout: doc-page
title: "Automatic Eta Expansion - More Details"
---

### Motivation
## Motivation

Scala maintains a convenient distinction between _methods_ and _functions_.
Methods are part of the definition of a class that can be invoked in objects while functions are complete objects themselves, making them first-class entities. For example, they can be assigned to variables.
These two mechanisms are bridged in Scala by a mechanism called _eta-expansion_ (also called eta-abstraction), which converts a reference to a method into a function. Intuitively, a method `m` can be passed around by turning it into an object: the function `x => m(x)`.
These two mechanisms are bridged in Scala by a mechanism called
[_eta-expansion_](https://www.scala-lang.org/files/archive/spec/2.13/06-expressions.html#eta-expansion-section)
(also called eta-abstraction), which converts a reference to a method into a function. Intuitively, a method `m` can be passed around by turning it into an object: the function `x => m(x)`.

In this snippet which assigns a method to a `val`, the compiler will perform _automatic eta-expansion_, as shown in the comment:

Expand Down Expand Up @@ -69,6 +71,6 @@ Thus, an unapplied method with an empty argument list is only converted to a fun

The method value syntax `m _` is deprecated.

### Reference
## Reference

For more info, see [PR #2701](https://github.com/lampepfl/dotty/pull/2701).
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ The standard library defines an abstract class `Conversion`:
```scala
package scala
@java.lang.FunctionalInterface
abstract class Conversion[-T, +U] extends Function1[T, U]
abstract class Conversion[-T, +U] extends Function1[T, U]:
def apply(x: T): U
```

Function literals are automatically converted to `Conversion` values.
Expand Down Expand Up @@ -80,8 +81,8 @@ implicit val myConverter: Int => String = _.toString
implicit val myConverter: Conversion[Int, String] = _.toString
```

Note that implicit conversions are also affected by the [changes to
implicit resolution](implicit-resolution.md) between Scala 2 and
Note that implicit conversions are also affected by the
[changes to implicit resolution](implicit-resolution.md) between Scala 2 and
Scala 3.

## Motivation for the changes
Expand Down
8 changes: 4 additions & 4 deletions docs/docs/reference/changed-features/implicit-resolution.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
layout: doc-page
title: "Changes in Implicit Resolution"
---
This page describes changes to the implicit resolution that apply both to the new `given`s and to the old-style `implicit`s in Scala 3.
This section describes changes to the implicit resolution that apply both to the new `given`s and to the old-style `implicit`s in Scala 3.
Implicit resolution uses a new algorithm which caches implicit results
more aggressively for performance. There are also some changes that
affect implicits on the language level.
Expand All @@ -20,8 +20,8 @@ where the type may still be inferred:
/*!*/ implicit def y = ... // error: type must be given explicitly

val y = {
implicit val ctx = this.ctx // ok
...
implicit val ctx = this.ctx // ok
...
}
```
**2.** Nesting is now taken into account for selecting an implicit. Consider for instance the following scenario:
Expand Down Expand Up @@ -114,7 +114,7 @@ the implicit search for `Q` fails.
**5.** The treatment of divergence errors has also changed. A divergent implicit is treated as a normal failure, after which alternatives are still tried. This also makes sense: Encountering a divergent implicit means that we assume that no finite solution can be found on the corresponding path, but another path can still be tried. By contrast,
most (but not all) divergence errors in Scala 2 would terminate the implicit search as a whole.

**6.** Scala-2 gives a lower level of priority to implicit conversions with call-by-name parameters relative to implicit conversions with call-by-value parameters. Scala 3 drops this distinction. So the following code snippet would be ambiguous in Scala 3:
**6.** Scala 2 gives a lower level of priority to implicit conversions with call-by-name parameters relative to implicit conversions with call-by-value parameters. Scala 3 drops this distinction. So the following code snippet would be ambiguous in Scala 3:

```scala
implicit def conv1(x: Int): A = new A(x)
Expand Down
8 changes: 4 additions & 4 deletions docs/docs/reference/changed-features/pattern-matching.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ def unapply[A](x: T)(implicit x: B): U
def unapplySeq[A](x: T)(implicit x: B): U
```

Extractors expose the method `unapply` are called fixed-arity extractors, which
work with patterns of fixed arity. Extractors expose the method `unapplySeq` are
Extractors that expose the method `unapply` are called fixed-arity extractors, which
work with patterns of fixed arity. Extractors that expose the method `unapplySeq` are
called variadic extractors, which enables variadic patterns.

### Fixed-Arity Extractors
Expand Down Expand Up @@ -93,7 +93,7 @@ A usage of a variadic extractor is irrefutable if one of the following condition
## Boolean Match

- `U =:= Boolean`
- Pattern-matching on exactly `0` patterns
- Pattern-matching on exactly `0` pattern

For example:

Expand Down Expand Up @@ -250,4 +250,4 @@ Abstract type testing with `ClassTag` is replaced with `TypeTest` or the alias `
- pattern `_: X` for an abstract type requires a `TypeTest` in scope
- pattern `x @ X()` for an unapply that takes an abstract type requires a `TypeTest` in scope

[More details on TypeTest](../other-new-features/type-test.md)
[More details on `TypeTest`](../other-new-features/type-test.md)
2 changes: 1 addition & 1 deletion docs/docs/reference/contextual/context-bounds.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ A context bound is a shorthand for expressing the common pattern of a context pa
def maximum[T: Ord](xs: List[T]): T = xs.reduceLeft(max)
```

A bound like `: Ord` on a type parameter `T` of a method or class indicates a context parameter `with Ord[T]`. The context parameter(s) generated from context bounds come last in the definition of the containing method or class. E.g.,
A bound like `: Ord` on a type parameter `T` of a method or class indicates a context parameter `with Ord[T]`. The context parameter(s) generated from context bounds come last in the definition of the containing method or class. For instance,

```scala
def f[T: C1 : C2, U: C3](x: T)(using y: U, z: V): R
Expand Down
9 changes: 5 additions & 4 deletions docs/docs/reference/contextual/context-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,11 @@ object PostConditions {

def result[T](using r: WrappedResult[T]): T = r

extension [T](x: T) def ensuring(condition: WrappedResult[T] ?=> Boolean): T = {
assert(condition(using x))
x
}
extension [T](x: T)
def ensuring(condition: WrappedResult[T] ?=> Boolean): T = {
assert(condition(using x))
x
}
}
import PostConditions.{ensuring, result}

Expand Down
5 changes: 3 additions & 2 deletions docs/docs/reference/contextual/conversions.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ title: "Implicit Conversions"
Implicit conversions are defined by given instances of the `scala.Conversion` class.
This class is defined in package `scala` as follows:
```scala
abstract class Conversion[-T, +U] extends (T => U)
abstract class Conversion[-T, +U] extends (T => U):
def apply (x: T): U
```
For example, here is an implicit conversion from `String` to `Token`:
```scala
Expand Down Expand Up @@ -41,7 +42,7 @@ given int2Integer: Conversion[Int, java.lang.Integer] =
java.lang.Integer.valueOf(_)
```

2. The "magnet" pattern is sometimes used to express many variants of a method. Instead of defining overloaded versions of the method, one can also let the method take one or more arguments of specially defined "magnet" types, into which various argument types can be converted. E.g.
2. The "magnet" pattern is sometimes used to express many variants of a method. Instead of defining overloaded versions of the method, one can also let the method take one or more arguments of specially defined "magnet" types, into which various argument types can be converted. Example:
```scala
object Completions {

Expand Down
26 changes: 14 additions & 12 deletions docs/docs/reference/contextual/derivation-macro.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,13 @@ The implementation of `summonAll` as a macro can be show below assuming that we
have the given instances for our primitive types:

```scala
def summonAll[T: Type](using Quotes): List[Expr[Eq[_]]] = Type.of[T] match {
case '[String *: tpes] => '{ summon[Eq[String]] } :: summonAll[tpes]
case '[Int *: tpes] => '{ summon[Eq[Int]] } :: summonAll[tpes]
case '[tpe *: tpes] => derived[tpe] :: summonAll[tpes]
case '[EmptyTuple] => Nil
}
def summonAll[T: Type](using Quotes): List[Expr[Eq[_]]] =
Type.of[T] match {
case '[String *: tpes] => '{ summon[Eq[String]] } :: summonAll[tpes]
case '[Int *: tpes] => '{ summon[Eq[Int]] } :: summonAll[tpes]
case '[tpe *: tpes] => derived[tpe] :: summonAll[tpes]
case '[EmptyTuple] => Nil
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nicolasstucki : Do we still support this use case? It seems to be a valid use case.

```

One additional difference with the body of `derived` here as opposed to the one
Expand Down Expand Up @@ -169,12 +170,13 @@ object Eq {
def eqv(x: T, y: T): Boolean = body(x, y)
}

def summonAll[T: Type](using Quotes): List[Expr[Eq[_]]] = Type.of[T] match {
case '[String *: tpes] => '{ summon[Eq[String]] } :: summonAll[tpes]
case '[Int *: tpes] => '{ summon[Eq[Int]] } :: summonAll[tpes]
case '[tpe *: tpes] => derived[tpe] :: summonAll[tpes]
case '[EmptyTuple] => Nil
}
def summonAll[T: Type](using Quotes): List[Expr[Eq[_]]] =
Type.of[T] match {
case '[String *: tpes] => '{ summon[Eq[String]] } :: summonAll[tpes]
case '[Int *: tpes] => '{ summon[Eq[Int]] } :: summonAll[tpes]
case '[tpe *: tpes] => derived[tpe] :: summonAll[tpes]
case '[EmptyTuple] => Nil
}

given derived[T: Type](using q: Quotes): Expr[Eq[T]] = {
import quotes.reflect._
Expand Down
26 changes: 16 additions & 10 deletions docs/docs/reference/contextual/derivation.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,16 @@ object Mirror {
/** The Mirror for a product type */
trait Product extends Mirror {

/** Create a new instance of type `T` with elements taken from product `p`. */
/** Create a new instance of type `T` with elements
* taken from product `p`.
*/
def fromProduct(p: scala.Product): MirroredMonoType
}

trait Sum extends Mirror { self =>
/** The ordinal number of the case class of `x`. For enums, `ordinal(x) == x.ordinal` */
/** The ordinal number of the case class of `x`.
* For enums, `ordinal(x) == x.ordinal`
*/
def ordinal(x: MirroredMonoType): Int
}
}
Expand Down Expand Up @@ -199,10 +203,11 @@ implementation of `summonAll` is `inline` and uses Scala 3's `summonInline` cons

```scala

inline def summonAll[T <: Tuple]: List[Eq[_]] = inline erasedValue[T] match {
case _: EmptyTuple => Nil
case _: (t *: ts) => summonInline[Eq[t]] :: summonAll[ts]
}
inline def summonAll[T <: Tuple]: List[Eq[_]] =
inline erasedValue[T] match {
case _: EmptyTuple => Nil
case _: (t *: ts) => summonInline[Eq[t]] :: summonAll[ts]
}
```

with the instances for children in hand the `derived` method uses an `inline match` to dispatch to methods which can
Expand Down Expand Up @@ -243,10 +248,11 @@ Pulling this all together we have the following complete implementation,
import scala.deriving._
import scala.compiletime.{erasedValue, summonInline}

inline def summonAll[T <: Tuple]: List[Eq[_]] = inline erasedValue[T] match {
case _: EmptyTuple => Nil
case _: (t *: ts) => summonInline[Eq[t]] :: summonAll[ts]
}
inline def summonAll[T <: Tuple]: List[Eq[_]] =
inline erasedValue[T] match {
case _: EmptyTuple => Nil
case _: (t *: ts) => summonInline[Eq[t]] :: summonAll[ts]
}

trait Eq[T] {
def eqv(x: T, y: T): Boolean
Expand Down
3 changes: 2 additions & 1 deletion docs/docs/reference/contextual/extension-methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,8 @@ object List:
def < (ys: List[T]): Boolean = ...
end List

// extension method available since it is in the implicit scope of List[List[Int]]
// extension method available since it is in the implicit scope
// of List[List[Int]]
List(List(1, 2), List(3, 4)).flatten

// extension method available since it is in the given Ordering[List[T]],
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/reference/contextual/motivation.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ title: "Overview"

Scala's implicits are its most distinguished feature. They are _the_ fundamental way to abstract over context. They represent a unified paradigm with a great variety of use cases, among them: implementing type classes, establishing context, dependency injection, expressing capabilities, computing new types and proving relationships between them.

Following Haskell, Scala was the second popular language to have some form of implicits. Other languages have followed suit. E.g Rust's traits or Swift's protocol extensions. Design proposals are also on the table for Kotlin as [compile time dependency resolution](https://github.com/Kotlin/KEEP/blob/e863b25f8b3f2e9b9aaac361c6ee52be31453ee0/proposals/compile-time-dependency-resolution.md), for C# as [Shapes and Extensions](https://github.com/dotnet/csharplang/issues/164)
Following Haskell, Scala was the second popular language to have some form of implicits. Other languages have followed suit. E.g [Rust's traits](https://doc.rust-lang.org/rust-by-example/trait.html) or [Swift's protocol extensions](https://docs.swift.org/swift-book/LanguageGuide/Protocols.html#ID521). Design proposals are also on the table for Kotlin as [compile time dependency resolution](https://github.com/Kotlin/KEEP/blob/e863b25f8b3f2e9b9aaac361c6ee52be31453ee0/proposals/compile-time-dependency-resolution.md), for C# as [Shapes and Extensions](https://github.com/dotnet/csharplang/issues/164)
or for F# as [Traits](https://github.com/MattWindsor91/visualfsharp/blob/hackathon-vs/examples/fsconcepts.md). Implicits are also a common feature of theorem provers such as Coq or [Agda](https://agda.readthedocs.io/en/latest/language/implicit-arguments.html).

Even though these designs use widely different terminology, they are all variants of the core idea of _term inference_. Given a type, the compiler synthesizes a "canonical" term that has that type. Scala embodies the idea in a purer form than most other languages: An implicit parameter directly leads to an inferred argument term that could also be written down explicitly. By contrast, type class based designs are less direct since they hide term inference behind some form of type classification and do not offer the option of writing the inferred quantities (typically, dictionaries) explicitly.
Expand Down
12 changes: 7 additions & 5 deletions docs/docs/reference/contextual/relationship-implicits.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ Given instances can be mapped to combinations of implicit objects, classes and i

```scala
class listOrd[T](implicit ord: Ord[T]) extends Ord[List[T]] { ... }
final implicit def listOrd[T](implicit ord: Ord[T]): listOrd[T] = new listOrd[T]
final implicit def listOrd[T](implicit ord: Ord[T]): listOrd[T] =
new listOrd[T]
```

3. Alias givens map to implicit methods or implicit lazy vals. If an alias has neither type nor context parameters,
Expand Down Expand Up @@ -76,7 +77,7 @@ Tuples are treated as transparent, i.e. a type `F[(X, Y)]` would get the synthes

### Using Clauses

Using clauses correspond largely to Scala-2's implicit parameter clauses. E.g.
Using clauses correspond largely to Scala 2's implicit parameter clauses. E.g.

```scala
def max[T](x: T, y: T)(using ord: Ord[T]): T
Expand Down Expand Up @@ -112,7 +113,8 @@ will map to using clauses instead.
Extension methods have no direct counterpart in Scala 2, but they can be simulated with implicit classes. For instance, the extension method

```scala
extension (c: Circle) def circumference: Double = c.radius * math.Pi * 2
extension (c: Circle)
def circumference: Double = c.radius * math.Pi * 2
```

could be simulated to some degree by
Expand All @@ -123,7 +125,7 @@ implicit class CircleDecorator(c: Circle) extends AnyVal {
}
```

Abstract extension methods in traits that are implemented in given instances have no direct counterpart in Scala-2. The only way to simulate these is to make implicit classes available through imports. The Simulacrum macro library can automate this process in some cases.
Abstract extension methods in traits that are implemented in given instances have no direct counterpart in Scala 2. The only way to simulate these is to make implicit classes available through imports. The Simulacrum macro library can automate this process in some cases.

### Type Class Derivation

Expand Down Expand Up @@ -197,7 +199,7 @@ given SymDecorator = symDecorator

## Implementation Status and Timeline

The Scala 3 implementation implements both Scala-2's implicits and the new abstractions. In fact, support for Scala-2's implicits is an essential part of the common language subset between 2.13/2.14 and Scala 3.
The Scala 3 implementation implements both Scala 2's implicits and the new abstractions. In fact, support for Scala 2's implicits is an essential part of the common language subset between 2.13/2.14 and Scala 3.
Migration to the new abstractions will be supported by making automatic rewritings available.

Depending on adoption patterns, old style implicits might start to be deprecated in a version following Scala 3.0.
4 changes: 2 additions & 2 deletions docs/docs/reference/dropped-features/auto-apply.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: "Dropped: Auto-Application"
---

Previously an empty argument list `()` was implicitly inserted when
calling a nullary method without arguments. E.g.
calling a nullary method without arguments. Example:
```scala
def next(): T = ...
next // is expanded to next()
Expand Down Expand Up @@ -69,7 +69,7 @@ class B extends A {
def next: Int // overriding error: incompatible type
}
```
Methods overriding Java or Scala-2 methods are again exempted from this
Methods overriding Java or Scala 2 methods are again exempted from this
requirement.

### Migrating code
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/reference/dropped-features/class-shadowing-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ layout: doc-page
title: "Dropped: Class Shadowing - More Details"
---

Spec diff: in section [5.1.4 Overriding](https://www.scala-lang.org/files/archive/spec/2.12/05-classes-and-objects.html), add *M' must not be a class*.
Spec diff: in section [5.1.4 Overriding](https://www.scala-lang.org/files/archive/spec/2.13/05-classes-and-objects.html#Overriding), add *M' must not be a class*.

> Why do we want to make this change to the language?

Expand All @@ -12,7 +12,7 @@ Class shadowing is irregular compared to other types of overrides. Indeed, inner

> How much existing code is going to be affected?

From all the code compiled so far with Dotty the only instance of this I could find is in the stdlib. Looking at [this commit](https://github.com/lampepfl/scala/commit/68f13bf39979b631ed211ec1751934306ceb5d6c#diff-7aa508b70e055b47c823764e3e5646b8) it seems like the usage of class shadowing was accidental.
From all the code compiled so far with Scala 3 the only instance of this I could find is in the stdlib. Looking at [this commit](https://github.com/lampepfl/scala/commit/68f13bf39979b631ed211ec1751934306ceb5d6c#diff-7aa508b70e055b47c823764e3e5646b8) it seems like the usage of class shadowing was accidental.


> How exactly is existing code going to be affected?
Expand Down
6 changes: 4 additions & 2 deletions docs/docs/reference/dropped-features/existential-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ layout: doc-page
title: "Dropped: Existential Types"
---

Existential types using `forSome` have been dropped. The reasons for dropping them are:
Existential types using `forSome` (as in
[SLS §3.2.12](https://www.scala-lang.org/files/archive/spec/2.13/03-types.html#existential-types))
have been dropped. The reasons for dropping them are:

- Existential types violate a type soundness principle on which DOT
and Scala 3 are constructed. That principle says that every
Expand All @@ -27,6 +29,6 @@ is treated as the type `Map`, where the first type parameter
is upper-bounded by `AnyRef` and the second type parameter is an alias
of `Int`.

When reading classfiles compiled with _scalac_, Scala 3 will do a best
When reading class files compiled with Scala 2, Scala 3 will do a best
effort to approximate existential types with its own types. It will
issue a warning that a precise emulation is not possible.
2 changes: 1 addition & 1 deletion docs/docs/reference/dropped-features/package-objects.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ package object p {
```
will be dropped. They are still available in Scala 3.0, but will be deprecated and removed afterwards.

Package objects are no longer needed since all kinds of definitions can now be written at the top-level. E.g.
Package objects are no longer needed since all kinds of definitions can now be written at the top-level. Example:
```scala
package p
type Labelled[T] = (String, T)
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/reference/dropped-features/procedure-syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ has been dropped. You need to write one of the following instead:
def f() = { ... }
def f(): Unit = { ... }
```
Scala 3 will accept the old syntax under the `-source:3.0-migration` option.
Scala 3 accepts the old syntax under the `-source:3.0-migration` option.
If the `-migration` option is set, it can even rewrite old syntax to new.
The [ScalaFix](https://scalacenter.github.io/scalafix/) tool also
can rewrite procedure syntax to make it Scala-3-compatible.
can rewrite procedure syntax to make it Scala 3 compatible.
Loading