Skip to content

Change docs as suggested in SIP meeting #8527

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 1 commit into from
Mar 12, 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
20 changes: 18 additions & 2 deletions docs/docs/reference/contextual/extension-methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,7 @@ only be used for its extension methods.
### Collective Extensions

Sometimes, one wants to define several extension methods that share the same
left-hand parameter type. In this case one can "pull out" the common parameters
into the extension instance itself. Examples:
left-hand parameter type. In this case one can "pull out" the common parameters into the extension instance itself. Examples:
```scala
extension stringOps on (ss: Seq[String]) {
def longestStrings: Seq[String] = {
Expand All @@ -186,6 +185,11 @@ extension on [T](xs: List[T])(using Ordering[T]) {
def largest(n: Int) = xs.sorted.takeRight(n)
}
```
**Note**: If a collective extension defines type parameters in its prefix
(as the `listOps` extension above does), the extension methods themselves are not
allowed to have additional type parameters. This restriction might be lifted in the
future once we support multiple type parameter clauses in a method.

Collective extensions like these are a shorthand for extension instances where
the parameters following the `on` are repeated for each implemented method.
For instance, the collective extensions above expand to the following extension instances:
Expand Down Expand Up @@ -217,6 +221,18 @@ parameter `ss`. The usage is made explicit when translating the method:
def (ss: Seq[String]).longestString: String =
ss.longestStrings.head
```
By contrast, the meaning of `this` in a collective extension is as usual
a reference to the enclosing object (i.e. the one implementing the extension methods).
It's not a reference to the shared parameter. So this means that the following
implementation of `longestString` would be illegal:
```scala
def longestString: String = this.longestStrings.head // error: missing parameter
```
But the following version would again be correct, since it calls the `longestString`
method as a regular non-extension method, passing the prefix parameter `ss` as a regular parameter:
```scala
def longestString: String = this.longestStrings(ss).head
```

### Syntax

Expand Down
2 changes: 1 addition & 1 deletion docs/docs/reference/contextual/given-imports.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ The following modifications avoid this hurdle to migration.

These rules mean that library users can use `given _` selectors 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
representation clauses once their user base has migrated.
given instances once their user base has migrated.

### Syntax

Expand Down
11 changes: 11 additions & 0 deletions docs/docs/reference/contextual/givens.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,17 @@ given [T](using Ord[T]) as Ord[List[T]] { ... }
If the name of a given is missing, the compiler will synthesize a name from
the implemented type(s).

**Note** The name synthesized by the compiler is chosen to be readable and reasonably concise. For instance, the two instances above would get the names:
```scala
given_Ord_Int
given_Ord_List_T
```
The precise rules for synthesizing names are found in [./relationship-implicit.html]. These rules do not guarantee absence of name conflicts between
given instances of types that are "too similar". To avoid conflicts one can
use named instances.

**Note** To ensure robust binary compatibility, publicly available libraries should prefer named instances.

## Alias Givens

An alias can be used to define a given instance that is equal to some expression. E.g.:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ xs map {
case (x, y) => x + y
}
```
While correct, this is also inconvenient. Dotty now also allows:
While correct, this is also inconvenient and confusing, since the `case`
suggests that the pattern match could fail. As a shorter and clearer alternative Dotty now allows
```scala
xs.map {
(x, y) => x + y
Expand Down