- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
implicit parameter lookup precedence
Fri, 2011-12-23, 02:43
Hi,
I have a question about the implicit parameter lookup precedence,specifically with regards to SLS and Josh's [Implicits without import tax][1] talk from earlier this year.
SLS page 106 states that there are two major categories for looking an implicit parameter of type T.Category 1: local scopeCategory 2: implicit scope (implicit members of the companion objects of the associated types)
We can ignore Category 2 for now.The local scope lookup is described as follows:
> First, eligible are all identifier *x* that can be accessed at the point of the method call without a prefix > and that denote an implicit definition (§7.1) or an implicit parameter. An eligible identifier may thus be > a local name, or a member of an enclosing template, or it may be have been made accessible without > a prefix through an import clause (§4.7).
My question is, if there are several eligible arguments which match the implicit parameter's type in the local scope,
which one is picked?
Josh's talk tells us how it's works in reality:> Implicits defined in current scope (1)> Explicit imports (2)> Wildcard imports (3)> Same scope in other files (4)
This precedence looks identical to binding ordering described in SLS p. 15.Since binding precedence is about binding a known identifier "x", to a variable "P.A.B.x",I can't see how it could be implied just by the passage I quoted.
Further down the page 106, after defining implicit scope, it says:
> If there are several eligible arguments which match the implicit parameter’s type,> a most specific one will be chosen using the rules of static overloading resolution (§6.26.3).
Does this clause apply both to Category 1 (local scope) and Category 2 (implicit scope)?I admit I don't fully understand 6.26.3, but it seems to be sayingthat specific types and subtypes wins. Nothing about explicit imports etc..
Here's an example:
As Josh's list says, LocalIntFoo wins over ImportedIntFoo.
Thanks,-eugene
[1]: https://docs.google.com/present/view?id=dfqn4jb_106hq4mvbd8
I have a question about the implicit parameter lookup precedence,specifically with regards to SLS and Josh's [Implicits without import tax][1] talk from earlier this year.
SLS page 106 states that there are two major categories for looking an implicit parameter of type T.Category 1: local scopeCategory 2: implicit scope (implicit members of the companion objects of the associated types)
We can ignore Category 2 for now.The local scope lookup is described as follows:
> First, eligible are all identifier *x* that can be accessed at the point of the method call without a prefix > and that denote an implicit definition (§7.1) or an implicit parameter. An eligible identifier may thus be > a local name, or a member of an enclosing template, or it may be have been made accessible without > a prefix through an import clause (§4.7).
My question is, if there are several eligible arguments which match the implicit parameter's type in the local scope,
which one is picked?
Josh's talk tells us how it's works in reality:> Implicits defined in current scope (1)> Explicit imports (2)> Wildcard imports (3)> Same scope in other files (4)
This precedence looks identical to binding ordering described in SLS p. 15.Since binding precedence is about binding a known identifier "x", to a variable "P.A.B.x",I can't see how it could be implied just by the passage I quoted.
Further down the page 106, after defining implicit scope, it says:
> If there are several eligible arguments which match the implicit parameter’s type,> a most specific one will be chosen using the rules of static overloading resolution (§6.26.3).
Does this clause apply both to Category 1 (local scope) and Category 2 (implicit scope)?I admit I don't fully understand 6.26.3, but it seems to be sayingthat specific types and subtypes wins. Nothing about explicit imports etc..
Here's an example:
trait CanFoo[A] { def foos(x: A): String}
object Def { implicit object ImportIntFoo extends CanFoo[Int] { def foos(x: Int) = "ImportIntFoo:" + x.toString }}
object Main { def test(): String = { implicit object LocalIntFoo extends CanFoo[Int] { def foos(x: Int) = "LocalIntFoo:" + x.toString } import Def._ foo(1) } def foo[A:CanFoo](x: A): String = implicitly[CanFoo[A]].foos(x)}
println(Main.test)
As Josh's list says, LocalIntFoo wins over ImportedIntFoo.
Thanks,-eugene
[1]: https://docs.google.com/present/view?id=dfqn4jb_106hq4mvbd8
Fri, 2011-12-30, 18:01
#2
Re: implicit parameter lookup precedence
On Thu, Dec 22, 2011 at 8:43 PM, Eugene Yokota <eed3si9n@gmail.com> wrote:
Hi,You get an "ambiguous call" error, IIRC.
I have a question about the implicit parameter lookup precedence,specifically with regards to SLS and Josh's [Implicits without import tax][1] talk from earlier this year.
SLS page 106 states that there are two major categories for looking an implicit parameter of type T.Category 1: local scopeCategory 2: implicit scope (implicit members of the companion objects of the associated types)
We can ignore Category 2 for now.The local scope lookup is described as follows:
> First, eligible are all identifier *x* that can be accessed at the point of the method call without a prefix > and that denote an implicit definition (§7.1) or an implicit parameter. An eligible identifier may thus be > a local name, or a member of an enclosing template, or it may be have been made accessible without > a prefix through an import clause (§4.7).
My question is, if there are several eligible arguments which match the implicit parameter's type in the local scope,
which one is picked?
Josh's talk tells us how it's works in reality: > Implicits defined in current scope (1)> Explicit imports (2)> Wildcard imports (3)> Same scope in other files (4)I believe this is only for the second type of import, and a 'recent' change (2.8.x)
This precedence looks identical to binding ordering described in SLS p. 15. Since binding precedence is about binding a known identifier "x", to a variable "P.A.B.x",I can't see how it could be implied just by the passage I quoted.
Further down the page 106, after defining implicit scope, it says:
> If there are several eligible arguments which match the implicit parameter’s type,> a most specific one will be chosen using the rules of static overloading resolution (§6.26.3).
Does this clause apply both to Category 1 (local scope) and Category 2 (implicit scope)?I admit I don't fully understand 6.26.3, but it seems to be sayingthat specific types and subtypes wins. Nothing about explicit imports etc..
Here's an example:trait CanFoo[A] { def foos(x: A): String}
object Def { implicit object ImportIntFoo extends CanFoo[Int] { def foos(x: Int) = "ImportIntFoo:" + x.toString } }
object Main { def test(): String = { implicit object LocalIntFoo extends CanFoo[Int] { def foos(x: Int) = "LocalIntFoo:" + x.toString } import Def._ foo(1) } def foo[A:CanFoo](x: A): String = implicitly[CanFoo[A]].foos(x) }
println(Main.test)
As Josh's list says, LocalIntFoo wins over ImportedIntFoo.
Thanks,-eugene
[1]: https://docs.google.com/present/view?id=dfqn4jb_106hq4mvbd8
-eugene
[1]: http://eed3si9n.com/revisiting-implicits-without-import-tax