Check even if an existing method on an object is implicitly available

Let’s say I had the following implicit class

    implicit class PimpList[A](l: List[A]) {
          def head: Option[A] = l.headOption
    }
    val l = List(1,2,3)
    l.head should call the implicit definition of head

Well we can always achieve a similar thing by extending List and overriding the appropriate methods but that would require the developer to instantiate newer class objects

With this they get the new definition of head for free

Any thoughts?

You might be interested in Travis Brown’s abstracted library.

2 Likes

It seems that in your example overriding cannot be done because you want to change head’s method signature incompatibly.

In your example, you are also introducing an implicit conversion to a class which interface (as a set of methods) is not compatible with original class. Saying

do you think that implicit conversions should have precedence over class’es own methods? Do you think (or suggest) that in your example having such an implicit conversion must break existing code that expects head returning A, not Option[A]?

oh yes, extending won’t work. my bad :slight_smile:

yes having implicit conversion taking precedence was my thinking. I just felt this would be more flexible. and i dont think it would break anything right? if a developer did decide to override the methods of a class, then it would be a conscious decision and the rest of the code would have to adhere to the new method signature [where the implicit is imported ofcourse]

@buzden

1 Like

Having to check for possible implicit conversions on every method invocation would make compilation times unbearable IMO. Currently compiler checks for implicit conversions only if it doesn’t find the method directly in class members.

1 Like

Lots of existing implicits that exist and are in scope (possibly the implicit scope) would start getting preferred to existing methods. They were written assuming this wouldn’t happen. So “nothing would break” is a pretty bold claim.

There’s a small example. Implicit classes have their own toString. Which is usually the Scala default, and currently there’s little point in overriding it. With this change, any implicit class in scope wrapping type Baz would change (and break) Baz.toString. Blacklisting toString would just move the problem.

scala> implicit class Foo(a: Int)
defined class Foo

scala> Foo(1).toString
res0: String = Foo@25d0cb3a

scala> implicit class Bar(val a: Int) extends AnyVal
defined class Bar

scala> Bar(1).toString
res1: String = Bar@1
2 Likes