Skip to content

Allow implicit conversions to have a parameter of singleton type? #876

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
smarter opened this issue Oct 27, 2015 · 7 comments
Closed

Allow implicit conversions to have a parameter of singleton type? #876

smarter opened this issue Oct 27, 2015 · 7 comments

Comments

@smarter
Copy link
Member

smarter commented Oct 27, 2015

This is explicitly disallowed since f0d3487 the commit message says:

Reason for 2) is that we can do a much better caching for eligible implicits if we can widen singleton arguments in ViewProto. This leads to consicderable speedups in implicit search which seem to be hard to get without the restriction.

But implicit conversions on singletons seem to be a common pattern, see for example:

We should either allow them or find a good replacement for them that can be automatized.

@odersky
Copy link
Contributor

odersky commented Oct 28, 2015

I have never seen that pattern before. Given that implicit conversions are anyway under a language flag, I don't think supporting this functionality is high priority.

@odersky
Copy link
Contributor

odersky commented Jan 26, 2018

The argument that this slows down implicit search has not been refuted. Closing for now, with scope to revisit if somebody can come up with a search algorithm that does not introduce slowdowns.

@odersky odersky closed this as completed Jan 26, 2018
@allanrenucci
Copy link
Contributor

Reopening as implicit conversion on singleton types is used a lot in the standard library. E.g.

implicit def toFactory[K <: AnyRef, V](dummy: AnyRefMap.type): Factory[(K, V), AnyRefMap[K, V]]
implicit def toBuildFrom[K <: AnyRef, V](factory: AnyRefMap.type): BuildFrom[Any, (K, V), AnyRefMap[K, V]]

cc/ @julienrf

@odersky
Copy link
Contributor

odersky commented Jun 28, 2018

For the new collections, it's easy to work around the restriction:

Make AnyRefMap extend a class AnyRefMapCompanion and use that class instead of AnyRefMap.type in the implicits.

@sjrd
Copy link
Member

sjrd commented Jun 28, 2018

It is also a very common pattern in Scala.js facade libraries. You declare an @js.native object Foo with the JS API, then you pimp Scala-esque APIs on top of it using an implicit class for Foo.type.

In that case you cannot define the methods inside the object, because there can be only native methods in there. And you also do not want to alter the hierarchy because the facade types hierarchy should follow the JS hierarchy that it models. It's technically possible to extend from a dummy trait, but that's awkward.

@odersky
Copy link
Contributor

odersky commented Jun 28, 2018

OK, I am giving this another try.

@odersky odersky self-assigned this Jun 28, 2018
@julienrf
Copy link
Contributor

I guess we can systematically replace implicit conversions applied to singleton types with the “magnet pattern”:

trait Iterable[+A] {
  def to[P, C](parameter: P)(implicit factory: IsFactory[P, A, C]): C
}

As a reminder, the current version is:

trait Iterable[+A] {
  def to[C](factory: Factory[A, C]): C
}

And it relies on an implicit conversion to allow the syntax .to(List).

That being said I’m not sure this solution would not have the same drawback as implicit conversions applied to singleton types.

odersky added a commit that referenced this issue Jun 29, 2018
Fix #876: Allow implicit conversions from singleton types
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants