Skip to content

Commit 000dce1

Browse files
oderskyfelixmulder
authored andcommitted
Implicit By Name Parameters section
1 parent 825f6cf commit 000dce1

File tree

1 file changed

+42
-0
lines changed

1 file changed

+42
-0
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Implicit By-Name Parameters
2+
3+
Call-by-name implicit parameters can be used to avoid a divergent implicit expansion.
4+
5+
```scala
6+
implicit def serializeOption[T](implicit ev: => Serializable[T]): Serializable[Option[T]] =
7+
new Serializable[Option[T]] {
8+
def write(x: Option[T], out: DataOutputStream) = t match {
9+
case Some(x) => ev.write(x)
10+
case None =>
11+
}
12+
}
13+
14+
val s = serializeOption[Option[Int]]
15+
s.write(Some(33))
16+
s.write(None)
17+
```
18+
As is the case for a normal by-name parameter, the argument for the implicit parameter `ev`
19+
is evaluated on demand. In the example above, if the option value `x` is `None`, it is
20+
not evaluated at all.
21+
22+
The synthesized argument for an implicit parameter is backed by a lazy
23+
val, which means that the parameter is evaluated at most once. The
24+
lazy val is also available as a value for implicit search, which can
25+
be useful to avoid an otherwise diverging expansion.
26+
27+
The precise steps for constructing an implicit argument for a by-name parameter of type `=> T` are:
28+
29+
1. Create a new implicit value with a fresh name _lv_, which has the signature of the following definition:
30+
31+
implicit lazy val lv: T
32+
33+
The current implementation uses the prefix `$lazy_implicit$` followed by a unique integer for _lv_.
34+
35+
1. This lazy val is not immediately available as candidate for implicit search (making it immediately available would result in a looping implicit computation). But it becomes available in all nested contexts that look again for an implicit argument to a by-name parameter.
36+
37+
1. If this implicit search succeeds with expression `E`, and `E` contains references to the lazy implicit value _lv_, replace `E` by
38+
39+
{ implicit lazy val lv: T = E; lv }
40+
41+
Otherwise, return `E` unchanged.
42+

0 commit comments

Comments
 (0)