Skip to content

Commit f23fa7d

Browse files
committed
Add code tabs to page 'Context Parameters'
1 parent 836e98b commit f23fa7d

23 files changed

+180
-136
lines changed

_overviews/scala3-book/ca-context-bounds.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ type: section
44
description: This page demonstrates Context Bounds in Scala.
55
languages: [zh-cn]
66
num: 61
7-
previous-page: ca-given-using-clauses
7+
previous-page: ca-context-parameters
88
next-page: ca-given-imports
99
---
1010

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

1414

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
---
2+
title: Context Parameters
3+
type: section
4+
description: This page demonstrates how to declare context parameters, and how the compiler infers them at call-site.
5+
languages: [zh-cn]
6+
num: 60
7+
previous-page: ca-extension-methods
8+
next-page: ca-context-bounds
9+
redirect_from: /scala3/book/ca-given-using-clauses.html
10+
---
11+
12+
Scala offers two important features for contextual abstraction:
13+
14+
- **Context Parameters** allow you to specify parameters that, at the call-site, can be omitted by the programmer and should be automatically provided by the context.
15+
- **Given Instances** (in Scala 3) or **Implicit Definitions** (in Scala 2) are terms that can be used by the Scala compiler to fill in the missing arguments.
16+
17+
## Context Parameters
18+
19+
When designing a system, often context information like _configuration_ or settings need to be provided to the different components of your system.
20+
One common way to achieve this is by passing the configuration as additional argument to your methods.
21+
22+
In the following example, we define a case class `Config` to model some website configuration and pass it around in the different methods.
23+
24+
{% tabs example %}
25+
{% tab 'Scala 2 and 3' %}
26+
```scala
27+
case class Config(port: Int, baseUrl: String)
28+
29+
def renderWebsite(path: String, config: Config): String =
30+
"<html>" + renderWidget(List("cart"), config) + "</html>"
31+
32+
def renderWidget(items: List[String], config: Config): String = ???
33+
34+
val config = Config(8080, "docs.scala-lang.org")
35+
renderWebsite("/home", config)
36+
```
37+
{% endtab %}
38+
{% endtabs %}
39+
40+
Let us assume that the configuration does not change throughout most of our code base.
41+
Passing `config` to each and every method call (like `renderWidget`) becomes very tedious and makes our program more difficult to read, since we need to ignore the `config` argument.
42+
43+
### Marking parameters as contextual
44+
45+
We can mark some parameters of our methods as _contextual_.
46+
47+
{% tabs 'contextual-parameters' class=tabs-scala-version %}
48+
{% tab 'Scala 2' %}
49+
```scala
50+
def renderWebsite(path: String)(implicit config: Config): String =
51+
"<html>" + renderWidget(List("cart")) + "</html>"
52+
// ^
53+
// no argument config required anymore
54+
55+
def renderWidget(items: List[String])(implicit config: Config): String = ???
56+
```
57+
{% endtab %}
58+
{% tab 'Scala 3' %}
59+
```scala
60+
def renderWebsite(path: String)(using config: Config): String =
61+
"<html>" + renderWidget(List("cart")) + "</html>"
62+
// ^
63+
// no argument config required anymore
64+
65+
def renderWidget(items: List[String])(using config: Config): String = ???
66+
```
67+
{% endtab %}
68+
{% endtabs %}
69+
70+
By starting a parameter section with the keyword `using` in Scala 3 or `implicit` in Scala 2, we tell the compiler that at the call-site it should automatically find an argument with the correct type.
71+
The Scala compiler thus performs **term inference**.
72+
73+
In our call to `renderWidget(List("cart"))` the Scala compiler will see that there is a term of type `Config` in scope (the `config`) and automatically provide it to `renderWidget`.
74+
So the program is equivalent to the one above.
75+
76+
In fact, since we do not need to refer to `config` in our implementation of `renderWebsite` anymore, we can even omit its name in the signature in Scala 3:
77+
78+
{% tabs 'anonymous' %}
79+
{% tab 'Scala 3 Only' %}
80+
```scala
81+
// no need to come up with a parameter name
82+
// vvvvvvvvvvvvv
83+
def renderWebsite(path: String)(using Config): String =
84+
"<html>" + renderWidget(List("cart")) + "</html>"
85+
```
86+
{% endtab %}
87+
{% endtabs %}
88+
89+
In Scala 2, the name of implicit parameters is still mandatory.
90+
91+
### Explicitly providing contextual arguments
92+
93+
We have seen how to _abstract_ over contextual parameters and that the Scala compiler can provide arguments automatically for us.
94+
But how can we specify which configuration to use for our call to `renderWebsite`?
95+
96+
{% tabs 'explicit' class=tabs-scala-version %}
97+
{% tab 'Scala 2' %}
98+
We explicitly supply the argument value as if it was a regular argument:
99+
```scala
100+
renderWebsite("/home")(config)
101+
```
102+
{% endtab %}
103+
{% tab 'Scala 3' %}
104+
Like we specified our parameter section with `using`, we can also explicitly provide contextual arguments with `using`:
105+
```scala
106+
renderWebsite("/home")(using config)
107+
```
108+
{% endtab %}
109+
{% endtabs %}
110+
111+
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.
112+
113+
For all other cases, as we will see in the next section, there is also another way to bring contextual values into scope.
114+
115+
## Given Instances (Implicit Definitions in Scala 2)
116+
117+
We have seen that we can explicitly pass arguments as contextual parameters.
118+
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` in Scala 3 or `implicit` in Scala 2.
119+
120+
{% tabs 'instances' class=tabs-scala-version %}
121+
{% tab 'Scala 2' %}
122+
```scala
123+
implicit val config: Config = Config(8080, "docs.scala-lang.org")
124+
// ^^^^^^
125+
// this is the value the Scala compiler will infer
126+
// as argument to contextual parameters of type Config
127+
```
128+
{% endtab %}
129+
{% tab 'Scala 3' %}
130+
```scala
131+
val config = Config(8080, "docs.scala-lang.org")
132+
// this is the type that we want to provide the
133+
// canonical value for
134+
// vvvvvv
135+
given Config = config
136+
// ^^^^^^
137+
// this is the value the Scala compiler will infer
138+
// as argument to contextual parameters of type Config
139+
```
140+
{% endtab %}
141+
{% endtabs %}
142+
143+
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.
144+
145+
Having defined a canonical value for the type `Config`, we can call `renderWebsite` as follows:
146+
147+
```scala
148+
renderWebsite("/home")
149+
// ^
150+
// again no argument
151+
```
152+
153+
[reference]: {{ site.scala3ref }}/overview.html
154+
[blog-post]: /2020/11/06/explicit-term-inference-in-scala-3.html

_overviews/scala3-book/ca-contextual-abstractions-intro.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ Benefits of these changes include:
7878

7979
This chapter introduces many of these new features in the following sections.
8080

81-
[givens]: {% link _overviews/scala3-book/ca-given-using-clauses.md %}
81+
[givens]: {% link _overviews/scala3-book/ca-context-parameters.md %}
8282
[given-imports]: {% link _overviews/scala3-book/ca-given-imports.md %}
8383
[implicit-conversions]: {% link _overviews/scala3-book/ca-implicit-conversions.md %}
8484
[extension-methods]: {% link _overviews/scala3-book/ca-extension-methods.md %}

_overviews/scala3-book/ca-extension-methods.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description: This page demonstrates how Extension Methods work in Scala 3.
55
languages: [zh-cn]
66
num: 59
77
previous-page: ca-contextual-abstractions-intro
8-
next-page: ca-given-using-clauses
8+
next-page: ca-context-parameters
99
scala3: true
1010
versionSpecific: true
1111
---

_overviews/scala3-book/ca-given-using-clauses.md

Lines changed: 0 additions & 110 deletions
This file was deleted.

_overviews/scala3-book/ca-implicit-conversions.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ This section describes how to define and use implicit conversions.
6161
In Scala 2, an implicit conversion from type `S` to type `T` is defined by an
6262
[implicit class]({% link _overviews/core/implicit-classes.md %}) `T` that takes
6363
a single constructor parameter of type `S`, an
64-
[implicit value]({% link _overviews/scala3-book/ca-given-using-clauses.md %}) of
64+
[implicit value]({% link _overviews/scala3-book/ca-context-parameters.md %}) of
6565
function type `S => T`, or by an implicit method convertible to a value of that type.
6666

6767
For example, the following code defines an implicit conversion from `Int` to `Long`:
@@ -81,7 +81,7 @@ at the beginning.
8181

8282
{% tab 'Scala 3' %}
8383
In Scala 3, an implicit conversion from type `S` to type `T` is defined by a
84-
[`given` instance]({% link _overviews/scala3-book/ca-given-using-clauses.md %})
84+
[`given` instance]({% link _overviews/scala3-book/ca-context-parameters.md %})
8585
of type `scala.Conversion[S, T]`. For compatibility with Scala 2, it can also
8686
be defined by an implicit method (read more in the Scala 2 tab).
8787

_overviews/scala3-book/methods-main-methods.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ Happy 23rd Birthday, Lisa and Peter!
7272
```
7373

7474
As shown, the `@main` method can have an arbitrary number of parameters.
75-
For each parameter type there must be a [given instance](./ca-given-using-clauses.html) of the `scala.util.CommandLineParser.FromString` type class that converts an argument `String` to the required parameter type.
75+
For each parameter type there must be a [given instance]({% link _overviews/scala3-book/ca-context-parameters.md %}) of the `scala.util.CommandLineParser.FromString` type class that converts an argument `String` to the required parameter type.
7676
Also as shown, a main method’s parameter list can end in a repeated parameter like `String*` that takes all remaining arguments given on the command line.
7777

7878
The program implemented from an `@main` method checks that there are enough arguments on the command line to fill in all parameters, and that the argument strings can be converted to the required types.

_overviews/scala3-book/scala-features.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ In particular, the type system supports:
244244
- [Intersection types]({% link _overviews/scala3-book/types-intersection.md %})
245245
- [Union types]({% link _overviews/scala3-book/types-union.md %})
246246
- [Type lambdas]({{ site.scala3ref }}/new-types/type-lambdas.html)
247-
- [`given` instances and `using` clauses]({% link _overviews/scala3-book/ca-given-using-clauses.md %})
247+
- [`given` instances and `using` clauses]({% link _overviews/scala3-book/ca-context-parameters.md %})
248248
- [Extension methods]({% link _overviews/scala3-book/ca-extension-methods.md %})
249249
- [Type classes]({% link _overviews/scala3-book/ca-type-classes.md %})
250250
- [Multiversal equality]({% link _overviews/scala3-book/ca-multiversal-equality.md %})
@@ -572,7 +572,7 @@ As this page shows, Scala has many terrific programming language features at a h
572572
[reference]: {{ site.scala3ref }}/overview.html
573573
[multiversal]: {% link _overviews/scala3-book/ca-multiversal-equality.md %}
574574
[extension]: {% link _overviews/scala3-book/ca-extension-methods.md %}
575-
[givens]: {% link _overviews/scala3-book/ca-given-using-clauses.md %}
575+
[givens]: {% link _overviews/scala3-book/ca-context-parameters.md %}
576576
[opaque_types]: {% link _overviews/scala3-book/types-opaque-types.md %}
577577

578578

_overviews/scala3-book/scala-for-java-devs.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1306,7 +1306,7 @@ This includes:
13061306
[equality]: {% link _overviews/scala3-book/ca-multiversal-equality.md %}
13071307
[error-handling]: {% link _overviews/scala3-book/fp-functional-error-handling.md %}
13081308
[extension-methods]: {% link _overviews/scala3-book/ca-extension-methods.md %}
1309-
[givens]: {% link _overviews/scala3-book/ca-given-using-clauses.md %}
1309+
[givens]: {% link _overviews/scala3-book/ca-context-parameters.md %}
13101310
[hofs]: {% link _overviews/scala3-book/fun-hofs.md %}
13111311
[imports]: {% link _overviews/scala3-book/packaging-imports.md %}
13121312
[modeling-intro]: {% link _overviews/scala3-book/domain-modeling-intro.md %}

_overviews/scala3-book/scala-for-javascript-devs.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1366,7 +1366,7 @@ There are other concepts in Scala which currently have no equivalent in JavaScri
13661366
[control]: {% link _overviews/scala3-book/control-structures.md %}
13671367
[extension-methods]: {% link _overviews/scala3-book/ca-extension-methods.md %}
13681368
[fp-intro]: {% link _overviews/scala3-book/fp-intro.md %}
1369-
[givens]: {% link _overviews/scala3-book/ca-given-using-clauses.md %}
1369+
[givens]: {% link _overviews/scala3-book/ca-context-parameters.md %}
13701370
[hofs]: {% link _overviews/scala3-book/fun-hofs.md %}
13711371
[intersection-types]: {% link _overviews/scala3-book/types-intersection.md %}
13721372
[modeling-fp]: {% link _overviews/scala3-book/domain-modeling-fp.md %}

_overviews/scala3-book/why-scala-3.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ Several surveys have shown that different groups of developers love different fe
490490
Hopefully you’ll discover more great Scala features as you use the language.
491491

492492
[java]: {% link _overviews/scala3-book/interacting-with-java.md %}
493-
[given]: {% link _overviews/scala3-book/ca-given-using-clauses.md %}
493+
[given]: {% link _overviews/scala3-book/ca-context-parameters.md %}
494494
[contextual]: {% link _overviews/scala3-book/ca-contextual-abstractions-intro.md %}
495495
[reference]: {{ site.scala3ref }}
496496
[dropped]: {{ site.scala3ref }}/dropped-features

_ru/scala3/book/methods-main-methods.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,4 +175,4 @@ $ scala happyBirthday 23 Lisa Peter
175175
Happy 23rd Birthday, Lisa and Peter!
176176
```
177177

178-
[given]: {% link _overviews/scala3-book/ca-given-using-clauses.md %}
178+
[given]: {% link _overviews/scala3-book/ca-context-parameters.md %}

_ru/scala3/book/scala-features.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ val z = nums
230230
- [Типы пересечения]({% link _overviews/scala3-book/types-intersection.md %})
231231
- [Типы объединения]({% link _overviews/scala3-book/types-union.md %})
232232
- [Лямбда-типы]({{ site.scala3ref }}/new-types/type-lambdas.html)
233-
- [Экземпляры `given` и предложения `using`]({% link _overviews/scala3-book/ca-given-using-clauses.md %})
233+
- [Экземпляры `given` и предложения `using`]({% link _overviews/scala3-book/ca-context-parameters.md %})
234234
- [Методы расширения]({% link _overviews/scala3-book/ca-extension-methods.md %})
235235
- [Типовые классы]({% link _overviews/scala3-book/ca-type-classes.md %})
236236
- [Многостороннее равенство]({% link _overviews/scala3-book/ca-multiversal-equality.md %})
@@ -482,6 +482,6 @@ JSON библиотеки:
482482
[reference]: {{ site.scala3ref }}/overview.html
483483
[multiversal]: {% link _overviews/scala3-book/ca-multiversal-equality.md %}
484484
[extension]: {% link _overviews/scala3-book/ca-extension-methods.md %}
485-
[givens]: {% link _overviews/scala3-book/ca-given-using-clauses.md %}
485+
[givens]: {% link _overviews/scala3-book/ca-context-parameters.md %}
486486
[opaque_types]: {% link _overviews/scala3-book/types-opaque-types.md %}
487487

0 commit comments

Comments
 (0)