Skip to content

Updated pages to be “Scala 3 Only” #2689

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
Feb 6, 2023
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
4 changes: 2 additions & 2 deletions _overviews/FAQ/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,9 @@ See [this]({{ site.baseurl }}/tutorials/FAQ/initialization-order.html).

See the [Scala 2.13 Collections Guide](https://docs.scala-lang.org/overviews/collections-2.13/introduction.html).

### What are context bounds (`[T : Foo]`)?
### What are context bounds?

It's syntactic sugar for an `implicit` parameter of type `Foo[T]`.
It's syntactic sugar for a context parameter (an `implicit` parameter in Scala 2, or a `using` parameter in Scala 3).

More details in this [Stack Overflow answer](https://stackoverflow.com/a/4467012).

Expand Down
44 changes: 27 additions & 17 deletions _overviews/scala3-book/ca-context-bounds.md
Original file line number Diff line number Diff line change
@@ -1,50 +1,60 @@
---
title: Context Bounds
type: section
description: This page demonstrates Context Bounds in Scala 3.
description: This page demonstrates Context Bounds in Scala.
languages: [zh-cn]
num: 61
previous-page: ca-given-using-clauses
next-page: ca-given-imports
---


{% comment %}
- TODO: define "context parameter"
- TODO: define "synthesized" and "synthesized arguments"
{% endcomment %}

In many situations the name of a _context parameter_ doesn’t have to be mentioned explicitly, since it’s only used by the compiler in synthesized arguments for other context parameters.
In many situations the name of a [context parameter]({% link _overviews/scala3-book/ca-given-using-clauses.md %}#using-clauses) doesn’t have to be mentioned explicitly, since it’s only used by the compiler in synthesized arguments for other context parameters.
In that case you don’t have to define a parameter name, and can just provide the parameter type.


## Background

For example, this `maximum` method takes a _context parameter_ of type `Ord`, only to pass it on as an argument to `max`:

{% tabs context-bounds-max-named-param class=tabs-scala-version %}

{% tab 'Scala 2' %}
```scala
def maximum[A](xs: List[A])(using ord: Ord[A]): A =
def maximum[A](xs: List[A])(implicit ord: Ord[A]): A =
xs.reduceLeft(max(ord))
```
{% endtab %}

In that code the parameter name `ord` isn’t actually required; it can be passed on as an inferred argument to `max`, so you just state that `maximum` uses the type `Ord[A]` without giving it a name:

{% tab 'Scala 3' %}
```scala
def maximum[A](xs: List[A])(using Ord[A]): A =
xs.reduceLeft(max)
def maximum[A](xs: List[A])(using ord: Ord[A]): A =
xs.reduceLeft(max(using ord))
```
{% endtab %}

{% endtabs %}

## Context bounds

Given that background, a _context bound_ is a shorthand syntax for expressing the pattern of, “a context parameter that depends on a type parameter.”
Given that background, a _context bound_ is a shorthand syntax for expressing the pattern of, “a context parameter applied to a type parameter.”

Using a context bound, the `maximum` method can be written like this:

{% tabs context-bounds-max-rewritten %}

{% tab 'Scala 2 and 3' %}

```scala
def maximum[A: Ord](xs: List[A]): A = xs.reduceLeft(max)
def maximum[A: Ord](xs: List[A]): A =
xs.reduceLeft(max)
```

A bound like `: Ord` on a type parameter `A` of a method or class indicates a context parameter with `Ord[A]`.
{% endtab %}

{% endtabs %}


A bound like `: Ord` on a type parameter `A` of a method or class indicates a context parameter with type `Ord[A]`.
Under the hood, the compiler transforms this syntax into the one shown in the Background section.

For more information about context bounds, see the [“What are context bounds?”](https://docs.scala-lang.org/tutorials/FAQ/context-bounds.html) section of the Scala FAQ.
For more information about context bounds, see the [“What are context bounds?”]({% link _overviews/FAQ/index.md %}#what-are-context-bounds) section of the Scala FAQ.
17 changes: 17 additions & 0 deletions _overviews/scala3-book/ca-given-imports.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@ num: 62
previous-page: ca-context-bounds
next-page: ca-type-classes
---
<span class="tag tag-inline">Scala 3 only</span>


To make it more clear where givens in the current scope are coming from, a special form of the `import` statement is used to import `given` instances.
The basic form is shown in this example:

{% tabs given-imports-basic-form %}

{% tab 'Scala 3 Only' %}

```scala
object A:
class TC
Expand All @@ -23,15 +28,27 @@ object B:
import A.given // import the given instance
```

{% endtab %}

{% endtabs %}

In this code the `import A.*` clause of object `B` imports all members of `A` *except* the `given` instance, `tc`.
Conversely, the second import, `import A.given`, imports *only* that `given` instance.
The two `import` clauses can also be merged into one:

{% tabs given-imports-merged %}

{% tab 'Scala 3 Only' %}

```scala
object B:
import A.{given, *}
```

{% endtab %}

{% endtabs %}


## Discussion

Expand Down
2 changes: 1 addition & 1 deletion _overviews/scala3-book/ca-given-using-clauses.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def renderWidget(items: List[String])(using c: Config): String = ???
{% endtab %}
{% endtabs %}

By starting a parameter section with the keyword `using`, we tell the Scala compiler that at the callsite it should automatically find an argument with the correct type.
By starting a parameter section with the keyword `using`, we tell the Scala compiler that at the call-site it should automatically find an argument with the correct type.
The Scala compiler thus performs **term inference**.

In our call to `renderWidget(List("cart"))` the Scala compiler will see that there is a term of type `Config` in scope (the `c`) and automatically provide it to `renderWidget`.
Expand Down
4 changes: 4 additions & 0 deletions _overviews/scala3-book/ca-multiversal-equality.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ num: 64
previous-page: ca-type-classes
next-page: ca-implicit-conversions
---
<span class="tag tag-inline">New In Scala 3</span>

> Multiversal Equality is a new language feature that was introduced in Scala 3.
> Because it has no equivalent in Scala 2, all code examples
> in this lesson assume you are using Scala 3.

Previously, Scala had *universal equality*: Two values of any types could be compared with each other using `==` and `!=`.
This came from the fact that `==` and `!=` are implemented in terms of Java’s `equals` method, which can also compare values of any two reference types.
Expand Down