disambiguate implicits

View: New views
6 Messages — Rating Filter:   Alert me  

disambiguate implicits

by Normen Mueller :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

He,

I have a disambiguation problem regarding implicits.

Let us assume in a library ``libA'' there is an implicit like:

package A
object Views { implicit def view(string: String) = new Ex(string) }
private class Ex(string: String) { lazy val toA = ... }

Moreover, let us assume in a library ``libB'' there is an implicit like:

package B
object Views { implicit def view(string: String) = new Ex(string) }
private class Ex(string: String) { lazy val toB = ... }

Now, there is a project X using libA and libB, like;

import A.Views._
import B.Views._

println("foo".toA)
println("foo".toB)

With respect to the order of the imports, one of the implicits (toA or  
toB) is not recognized.

So my question is: Why is that?

Cheers,
--
Normen Müller


Re: disambiguate implicits

by Adriaan Moors-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message



On Tue, Nov 3, 2009 at 2:47 PM, Normen Müller <normen.mueller@...> wrote:
He,

I have a disambiguation problem regarding implicits.

Let us assume in a library ``libA'' there is an implicit like:

package A
object Views { implicit def view(string: String) = new Ex(string) }
private class Ex(string: String) { lazy val toA = ... }

Moreover, let us assume in a library ``libB'' there is an implicit like:

package B
object Views { implicit def view(string: String) = new Ex(string) }
private class Ex(string: String) { lazy val toB = ... }

Now, there is a project X using libA and libB, like;

import A.Views._
import B.Views._

println("foo".toA)
println("foo".toB)

With respect to the order of the imports, one of the implicits (toA or toB) is not recognized.
This sounds like a bug -- I would expect an "ambiguous implicit" compiler error.
(Try making the implicit explicit, and you'll get a similar error.)

in principle, I think you should be forced to select which implicit you want, by hiding the other one:
import A.Views.{View => _, _} // hide view in A.Views

when they aren't ambiguous, you could simply rename one of them

cheers
adriaan

Re: disambiguate implicits

by Normen Mueller :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Nov 3, 2009, at 5:13 PM, Adriaan Moors wrote:

>
> I have a disambiguation problem regarding implicits.
>
> Let us assume in a library ``libA'' there is an implicit like:
>
> package A
> object Views { implicit def view(string: String) = new Ex(string) }
> private class Ex(string: String) { lazy val toA = ... }
>
> Moreover, let us assume in a library ``libB'' there is an implicit  
> like:
>
> package B
> object Views { implicit def view(string: String) = new Ex(string) }
> private class Ex(string: String) { lazy val toB = ... }
>
> Now, there is a project X using libA and libB, like;
>
> import A.Views._
> import B.Views._
>
> println("foo".toA)
> println("foo".toB)
>
> With respect to the order of the imports, one of the implicits (toA  
> or toB) is not recognized.
> This sounds like a bug -- I would expect an "ambiguous implicit"  
> compiler error.
> (Try making the implicit explicit, and you'll get a similar error.)
>
> in principle, I think you should be forced to select which implicit  
> you want, by hiding the other one:
> import A.Views.{View => _, _} // hide view in A.Views

Do you mean:

import A.Views.{view => _, _ }

But, anyways, I don't quite understand this import statement.  We map  
the function view of A.Views to ``_'' but what does the second ``_''  
mean?

> when they aren't ambiguous, you could simply rename one of them

Renaming would be a solution, but why doesn't it disambiguate at all?  
Aren't the two view functions unique in sense of fully qualified  
names?  I just want to understand what's going here ;)

Cheers,
--
Normen Müller


Re: disambiguate implicits

by Adriaan Moors-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Do you mean:

import A.Views.{view => _, _ }

But, anyways, I don't quite understand this import statement.  We map the function view of A.Views to ``_'' but what does the second ``_'' mean?
yes, sorry. "_" is the wildcard name, its first occurrence effectively hides view because you don't care what its name becomes, the second instance imports all the members of A.Views that weren't named explicitly
 


when they aren't ambiguous, you could simply rename one of them

Renaming would be a solution, but why doesn't it disambiguate at all?  Aren't the two view functions unique in sense of fully qualified names?  I just want to understand what's going here ;)
import disambiguation is based solely on the name of the members (for an example, see http://lampsvn.epfl.ch/trac/scala/ticket/2551)

hth
adriaan


Re: disambiguate implicits

by Normen Mueller :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Nov 3, 2009, at 5:26 PM, Adriaan Moors wrote:

>
> Do you mean:
>
> import A.Views.{view => _, _ }
>
> But, anyways, I don't quite understand this import statement.  We  
> map the function view of A.Views to ``_'' but what does the second  
> ``_'' mean?
> yes, sorry. "_" is the wildcard name, its first occurrence  
> effectively hides view because you don't care what its name becomes,  
> the second instance imports all the members of A.Views that weren't  
> named explicitly

Understand, thanks!

> when they aren't ambiguous, you could simply rename one of them
>
> Renaming would be a solution, but why doesn't it disambiguate at  
> all?  Aren't the two view functions unique in sense of fully  
> qualified names?  I just want to understand what's going here ;)
> import disambiguation is based solely on the name of the members  
> (for an example, see http://lampsvn.epfl.ch/trac/scala/ticket/2551)

Does that mean that this /might/ be solved in future such that then my  
two imports would disambiguate?

Cheers,
--
Normen Müller


Re: disambiguate implicits

by Naftoli Gugenheim :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

What's happening is import shadowing. Only one implicit is in scope. It's not directly related to implicits; the issue applies if you want to invoke view(...) explicitly. Importing "overwrites" previously imported names.
Implicits have to resolve to a named implicit def that is in scope.

On Tue, Nov 3, 2009 at 11:32 AM, Normen Müller <normen.mueller@...> wrote:
On Nov 3, 2009, at 5:26 PM, Adriaan Moors wrote:

Do you mean:

import A.Views.{view => _, _ }

But, anyways, I don't quite understand this import statement.  We map the function view of A.Views to ``_'' but what does the second ``_'' mean?
yes, sorry. "_" is the wildcard name, its first occurrence effectively hides view because you don't care what its name becomes, the second instance imports all the members of A.Views that weren't named explicitly

Understand, thanks!


when they aren't ambiguous, you could simply rename one of them

Renaming would be a solution, but why doesn't it disambiguate at all?  Aren't the two view functions unique in sense of fully qualified names?  I just want to understand what's going here ;)
import disambiguation is based solely on the name of the members (for an example, see http://lampsvn.epfl.ch/trac/scala/ticket/2551)

Does that mean that this /might/ be solved in future such that then my two imports would disambiguate?

Cheers,
--
Normen Müller