Skip to content

Commit 773c2fc

Browse files
committed
Make Finding Implicits easier to read
- Drop first person voice - Dial down humour setting to 20% by removing distracting Other Dimensions - Add link to issues - Update links to language specification - Remove comment about revision of StackOverflow answer because the reader won't have seen the previous slightly incorrect version
1 parent 4515e01 commit 773c2fc

File tree

1 file changed

+33
-36
lines changed

1 file changed

+33
-36
lines changed

tutorials/FAQ/finding-implicits.md

Lines changed: 33 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@ partof: FAQ
88
num: 7
99
---
1010

11-
An _implicit_ question to newcomers to Scala seems to be: where does the
12-
compiler look for implicits? I mean implicit because the question never seems
13-
to get fully formed, as if there weren't words for it. :-) For example, where
14-
do the values for `integral` below come from?
11+
Newcomers to Scala often ask: Where does the compiler look for implicits?
12+
13+
For example, where do the values for `integral` below come from?
1514

1615
scala> import scala.math._
1716
import scala.math._
@@ -27,17 +26,17 @@ do the values for `integral` below come from?
2726
scala> foo(0L)
2827
scala.math.Numeric$LongIsIntegral$@48c610af
2928

30-
Another question that does follow up to those who decide to learn the answer to
31-
the first question is how does the compiler choose which implicit to use, in
32-
certain situations of apparent ambiguity (but that compile anyway)?
29+
The natural continuation of this line of inquiry leads to a second question: How
30+
does the compiler choose which implicit to use, in certain situations of apparent
31+
ambiguity (but that compile anyway)?
3332

3433
For instance, `scala.Predef` defines two conversions from `String`: one to
3534
`WrappedString` and another to `StringOps`. Both classes, however, share a lot
3635
of methods, so why doesn't Scala complain about ambiguity when, say, calling
3736
`map`?
3837

3938
**Note:** this question was inspired by [this other question on Stack
40-
Overflow][4], but stating the problem in more general terms. The example was
39+
Overflow][4], but states the problem in more general terms. The example was
4140
copied from there, because it is referred to in the answer.
4241

4342
## Types of Implicits
@@ -84,10 +83,10 @@ implicit parameter. For example:
8483
getIndex("abc", 'a')
8584

8685
The method `getIndex` can receive any object, as long as there is an implicit
87-
conversion available from its class to `Seq[T]`. Because of that, I can pass a
88-
`String` to `getIndex`, and it will work.
86+
conversion available from its class to `Seq[T]`. Because of that, a `String` can be
87+
passed to `getIndex`, and it will work.
8988

90-
Behind the scenes, the compile changes `seq.IndexOf(value)` to
89+
Behind the scenes, the compiler changes `seq.IndexOf(value)` to
9190
`conv(seq).indexOf(value)`.
9291

9392
### Context Bounds
@@ -97,9 +96,9 @@ pattern enables the provision of common interfaces to classes which did not
9796
declare them. It can both serve as a bridge pattern -- gaining separation of
9897
concerns -- and as an adapter pattern.
9998

100-
The `Integral` class you mentioned is a classic example of type class pattern.
101-
Another example on Scala's standard library is `Ordering`. There's a library
102-
that makes heavy use of this pattern, called Scalaz.
99+
The `Integral` class mentioned above is a classic example of type class pattern.
100+
Another example on Scala's standard library is `Ordering`. Scalaz is a library
101+
that makes heavy use of this pattern.
103102

104103
This is an example of its use:
105104

@@ -134,16 +133,16 @@ a method which does not exist on the object's class, or because you are calling
134133
a method that requires an implicit parameter, it will search for an implicit
135134
that will fit the need.
136135

137-
This search obey certain rules that define which implicits are visible and
136+
This search obeys certain rules that define which implicits are visible and
138137
which are not. The following table showing where the compiler will search for
139138
implicits was taken from an excellent [presentation][1] about implicits by Josh
140-
Suereth, which I heartily recommend to anyone wanting to improve their Scala
139+
Suereth, which is heartily recommend to anyone wanting to improve their Scala
141140
knowledge. It has been complemented since then with feedback and updates.
142141

143-
The implicits available under number 1 below has precedence over the ones under
142+
The implicits available under number 1 below have precedence over the ones under
144143
number 2. Other than that, if there are several eligible arguments which match
145144
the implicit parameter’s type, a most specific one will be chosen using the rules
146-
of static overloading resolution (see [Scala Specification][5] §6.26.3).
145+
of static overloading resolution (see [Scala Specification][5] §6.26.4).
147146

148147
1. First look in current scope
149148
* Implicits defined in current scope
@@ -155,7 +154,6 @@ of static overloading resolution (see [Scala Specification][5] §6.26.3).
155154
* Implicit scope of an argument's type **(2.9.1)**
156155
* Implicit scope of type arguments **(2.8.0)**
157156
* Outer objects for nested types
158-
* Other dimensions
159157

160158
Let's give examples for them.
161159

@@ -202,7 +200,7 @@ example:
202200
y <- Some('x')
203201
} yield (x, y)
204202

205-
That expression is translated by the compile into
203+
That expression is translated by the compiler into
206204

207205
List(1, 2, 3).flatMap(x => Some('x').map(y => (x, y)))
208206

@@ -228,18 +226,18 @@ Note that companion objects of super classes are also looked into. For example:
228226
val b = new B(5, 2)
229227
val s: String = b // s == "A: 2"
230228

231-
This is how Scala found the implicit `Numeric[Int]` and `Numeric[Long]` in your
232-
question, by the way, as they are found inside `Numeric`, not `Integral`.
229+
This is how Scala found the implicit `Numeric[Int]` and `Numeric[Long]` in the
230+
opening example, by the way, as they are found inside `Numeric`, not `Integral`.
233231

234232
### Implicit scope of an argument's type
235233

236234
If you have a method with an argument type `A`, then the implicit scope of type
237-
`A` will also be considered. By "implicit scope" I mean that all these rules
235+
`A` will also be considered. Here "implicit scope" means all these rules
238236
will be applied recursively -- for example, the companion object of `A` will be
239237
searched for implicits, as per the rule above.
240238

241239
Note that this does not mean the implicit scope of `A` will be searched for
242-
conversions of that parameter, but of the whole expression. For example:
240+
conversions of that parameter alone, but of the whole expression. For example:
243241

244242
class A(val n: Int) {
245243
def +(other: A) = new A(n + other.n)
@@ -285,17 +283,15 @@ implicits are found inside companion objects to the type parameters of
285283
`CanBuildFrom`.
286284

287285
**Note**: `Ordering` is defined as `trait Ordering[T]`, where `T` is a type
288-
parameter. Previously, I said that Scala looked inside type parameters, which
289-
doesn't make much sense. The implicit looked for above is `Ordering[A]`, where
286+
parameter. The implicit looked for above is `Ordering[A]`, where
290287
`A` is an actual type, not type parameter: it is a _type argument_ to
291-
`Ordering`. See section 7.2 of the [Scala Specification][5].
288+
`Ordering`. See section 7.2 of the [Scala Specification][6].
292289

293290
**This available only since Scala 2.8.0.**
294291

295292
### Outer Objects for Nested Types
296293

297-
I haven't actually seen examples of this. I'd be grateful if someone could
298-
share one. The principle is simple:
294+
The principle is simple:
299295

300296
class A(val n: Int) {
301297
class B(val m: Int) { require(m < n) }
@@ -307,14 +303,13 @@ share one. The principle is simple:
307303
val b = new a.B(3)
308304
val s: String = b // s == "B: 3"
309305

310-
### Other Dimensions
306+
A real world example of this would be welcome. Please share your example!
311307

312-
I'm pretty sure this was a joke, but this answer might not be up-to-date. So
313-
don't take this question as being the final arbiter of what is happening, and
314-
if you do noticed it has gotten out-of-date, do open a ticket about it, or, if
315-
you know how to correct it, please fix it. It's a wiki after all.
308+
### Call To Action
316309

317-
**EDIT**
310+
Avoid taking this question as being the final arbiter of what is happening.
311+
If you do notice it has become out-of-date, do [open a ticket about it][7], or, if
312+
you know how to correct it, please fix it.
318313

319314
Related questions of interest:
320315

@@ -327,5 +322,7 @@ This question and answer were originally submitted on [Stack Overflow][3].
327322
[2]: https://issues.scala-lang.org/browse/SI-4427
328323
[3]: http://stackoverflow.com/q/5598085/53013
329324
[4]: http://stackoverflow.com/questions/5512397/passing-scala-math-integral-as-implicit-parameter
330-
[5]: http://scala-lang.org/files/archive/spec/2.11/
325+
[5]: http://scala-lang.org/files/archive/spec/2.11/06-expressions.html
326+
[6]: http://scala-lang.org/files/archive/spec/2.11/07-implicits.html
327+
[7]: https://github.com/scala/scala.github.com/issues
331328

0 commit comments

Comments
 (0)