Skip to content

Add more guidelines for labelling code examples for Scala 2/3 #2768

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 9 commits into from
Apr 13, 2023
Prev Previous commit
Next Next commit
Use the new way of labelling pages in Given Instances and Using Claus…
…es, and adjust the “version-specific-notice”.
  • Loading branch information
julienrf committed Apr 12, 2023
commit 4455cd2da32d14128ea35ce8e5905d7f0c1366e4
9 changes: 5 additions & 4 deletions _includes/version-specific-notice.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
<i class="fa fa-info"></i><span style="margin-left: 0.5rem">
{% if include.language == 'scala3' %}
This doc page is specific to Scala 3,
and may cover new concepts not available in Scala 2. All the code
examples in this page assume you are using Scala 3.
and may cover new concepts not available in Scala 2. Unless
otherwise stated, all the code examples in this page assume
you are using Scala 3.
{% else if include.language == 'scala2' %}
This doc page is specific to features shipped in Scala 2,
which have either been removed in Scala 3 or replaced by an
alternative. All the code examples in this page assume you are
using Scala 2.
alternative. Unless otherwise stated, all the code examples
in this page assume you are using Scala 2.
{% endif %}
</span>
</blockquote>
Expand Down
35 changes: 2 additions & 33 deletions _overviews/scala3-book/ca-given-using-clauses.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ languages: [zh-cn]
num: 60
previous-page: ca-extension-methods
next-page: ca-context-bounds
scala3: true
versionSpecific: true
---


<h5>Use contextual abstraction <span class="tag tag-inline">Scala 3 Only</span></h5>

Scala 3 offers two important feature for contextual abstraction:

- **Using Clauses** allow you to specify parameters that, at the call site, can be omitted by the programmer and should be automatically provided by the context.
Expand Down Expand Up @@ -48,9 +47,6 @@ Passing `c` to each and every method call (like `renderWidget`) becomes very ted

In Scala 3, we can mark some parameters of our methods as _contextual_.

{% tabs using1 %}
{% tab 'Scala 3 Only' %}

```scala
def renderWebsite(path: String)(using c: Config): String =
"<html>" + renderWidget(List("cart")) + "</html>"
Expand All @@ -60,9 +56,6 @@ def renderWebsite(path: String)(using c: Config): String =
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 call-site it should automatically find an argument with the correct type.
The Scala compiler thus performs **term inference**.

Expand All @@ -71,36 +64,24 @@ So the program is equivalent to the one above.

In fact, since we do not need to refer to `c` in our implementation of `renderWebsite` anymore, we can even omit its name in the signature:

{% tabs using2 %}
{% tab 'Scala 3 Only' %}

```scala
// no need to come up with a parameter name
// vvvvvvvvvvvvv
def renderWebsite(path: String)(using Config): String =
"<html>" + renderWidget(List("cart")) + "</html>"
```

{% endtab %}
{% endtabs %}

#### Explicitly providing contextual arguments

We have seen how to _abstract_ over contextual parameters and that the Scala compiler can provide arguments automatically for us.
But how can we specify which configuration to use for our call to `renderWebsite`?

Like we specified our parameter section with `using`, we can also explicitly provide contextual arguments with `using:`

{% tabs using3 %}
{% tab 'Scala 3 Only' %}

```scala
renderWebsite("/home")(using config)
```

{% endtab %}
{% endtabs %}

Explicitly providing contextual parameters can be useful if we have multiple different values in scope that would make sense, and we want to make sure that the correct one is passed to the function.

For all other cases, as we will see in the next Section, there is also another way to bring contextual values into scope.
Expand All @@ -110,9 +91,6 @@ For all other cases, as we will see in the next Section, there is also another w
We have seen that we can explicitly pass arguments as contextual parameters by marking the argument section of the _call_ with `using`.
However, if there is _a single canonical value_ for a particular type, there is another preferred way to make it available to the Scala compiler: by marking it as `given`.

{% tabs given1 %}
{% tab 'Scala 3 Only' %}

```scala
val config = Config(8080, "docs.scala-lang.org")
// this is the type that we want to provide the
Expand All @@ -124,24 +102,15 @@ given Config = config
// as argument to contextual parameters of type Config
```

{% endtab %}
{% endtabs %}

In the above example we specify that whenever a contextual parameter of type `Config` is omitted in the current scope, the compiler should infer `config` as an argument.

Having defined a given for `Config`, we can simply call `renderWebsite`:

{% tabs given2 %}
{% tab 'Scala 3 Only' %}

```scala
renderWebsite("/home")
// ^^^^^
// again no argument
```

{% endtab %}
{% endtabs %}

[reference]: {{ site.scala3ref }}/overview.html
[blog-post]: /2020/11/06/explicit-term-inference-in-scala-3.html