This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Implicit resolution spec (wording may not be strong enough)

2 replies
Joshua.Suereth
Joined: 2008-09-02,
User offline. Last seen 32 weeks 5 days ago.
So there's a fun part of the spec that talks about implicit resolution.

That's where the spec states that it uses the parts of type T to look for implicits, and that it uses the rules of static resolution in the event of failure.  Well, I have the following:

trait TypeClass[T] {  def one(t : T) : Unit  def two(t : T) : Unit}trait LowPriorityMagic {   implicit def troublemaker[T <: { def one() : Unit }] = new TypeClass[T] {    def one(t : T) = t.one()    def two(t : T) = println("No two on this T")  }} object TypeClass extends LowPriorityMagicclass OneTwoPunch {  def one() = println("ONE")  def two() = println("TWO")}object OneTwoPunch {   implicit object MyTypeClass extends TypeClass[OneTwoPunch] {    def one(t : OneTwoPunch) = t.one()    def two(t : OneTwoPunch) = t.two()  }}def foo[T](t : T)(implicit tc : TypeClass[T]) = {   tc.one(t); tc.two(t);}
foo(new OneTwoPunch)  // ONE! TWO!

Which is working right now, however I'm afraid that the wording is not strong enough to prevent a breaking change, such that the troublemaker implicit in LowPriorityMagic gets called.
Is there anyway we can guarantee that given a lookup of:

T[A,B]
U <: TV <: AX <: B

T, A and B companions will be searched first before U, V and X?  Is the spec actually stating that it performs a lookup on (T with A with B) and checks for conflicts and then (U with V with X)?

Sorry for the random spec questions, but I'm very curious.   I don't want my current design to be implementation dependent.
dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Implicit resolution spec (wording may not be strong enough)
I think you inverted the relationship of U, V and X to T, A and B. Shouldn't it be U >: T?

On Fri, Apr 8, 2011 at 00:22, Josh Suereth <joshua.suereth@gmail.com> wrote:
So there's a fun part of the spec that talks about implicit resolution.

That's where the spec states that it uses the parts of type T to look for implicits, and that it uses the rules of static resolution in the event of failure.  Well, I have the following:

trait TypeClass[T] {  def one(t : T) : Unit  def two(t : T) : Unit}trait LowPriorityMagic {   implicit def troublemaker[T <: { def one() : Unit }] = new TypeClass[T] {    def one(t : T) = t.one()    def two(t : T) = println("No two on this T")  }} object TypeClass extends LowPriorityMagicclass OneTwoPunch {  def one() = println("ONE")  def two() = println("TWO")}object OneTwoPunch {   implicit object MyTypeClass extends TypeClass[OneTwoPunch] {    def one(t : OneTwoPunch) = t.one()    def two(t : OneTwoPunch) = t.two()  }}def foo[T](t : T)(implicit tc : TypeClass[T]) = {   tc.one(t); tc.two(t);}
foo(new OneTwoPunch)  // ONE! TWO!

Which is working right now, however I'm afraid that the wording is not strong enough to prevent a breaking change, such that the troublemaker implicit in LowPriorityMagic gets called.
Is there anyway we can guarantee that given a lookup of:

T[A,B]
U <: TV <: AX <: B

T, A and B companions will be searched first before U, V and X?  Is the spec actually stating that it performs a lookup on (T with A with B) and checks for conflicts and then (U with V with X)?

Sorry for the random spec questions, but I'm very curious.   I don't want my current design to be implementation dependent.



--
Daniel C. Sobral

I travel to the future all the time.
Joshua.Suereth
Joined: 2008-09-02,
User offline. Last seen 32 weeks 5 days ago.
Re: Implicit resolution spec (wording may not be strong enough)
Yes, I apologize.
U V and X are supertypes of T, A and B respectively.
On Thu, Apr 7, 2011 at 11:51 PM, Daniel Sobral <dcsobral@gmail.com> wrote:
I think you inverted the relationship of U, V and X to T, A and B. Shouldn't it be U >: T?

On Fri, Apr 8, 2011 at 00:22, Josh Suereth <joshua.suereth@gmail.com> wrote:
So there's a fun part of the spec that talks about implicit resolution.

That's where the spec states that it uses the parts of type T to look for implicits, and that it uses the rules of static resolution in the event of failure.  Well, I have the following:

trait TypeClass[T] {  def one(t : T) : Unit  def two(t : T) : Unit}trait LowPriorityMagic {   implicit def troublemaker[T <: { def one() : Unit }] = new TypeClass[T] {    def one(t : T) = t.one()    def two(t : T) = println("No two on this T")  }} object TypeClass extends LowPriorityMagicclass OneTwoPunch {  def one() = println("ONE")  def two() = println("TWO")}object OneTwoPunch {   implicit object MyTypeClass extends TypeClass[OneTwoPunch] {    def one(t : OneTwoPunch) = t.one()    def two(t : OneTwoPunch) = t.two()  }}def foo[T](t : T)(implicit tc : TypeClass[T]) = {   tc.one(t); tc.two(t);}
foo(new OneTwoPunch)  // ONE! TWO!

Which is working right now, however I'm afraid that the wording is not strong enough to prevent a breaking change, such that the troublemaker implicit in LowPriorityMagic gets called.
Is there anyway we can guarantee that given a lookup of:

T[A,B]
U <: TV <: AX <: B

T, A and B companions will be searched first before U, V and X?  Is the spec actually stating that it performs a lookup on (T with A with B) and checks for conflicts and then (U with V with X)?

Sorry for the random spec questions, but I'm very curious.   I don't want my current design to be implementation dependent.



--
Daniel C. Sobral

I travel to the future all the time.

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland