implicit def mkNumericOps(lhs: T): IntegralOps = new IntegralOps(lhs)
there is a one design question: should the extension methods be on the top-level or in the type class?
I’ve chosen the second one, but I don’t have a strong opinion.
Current draft doesn’t break binary compatibility, but it does break the source one (only if someone extends the TC and it’s not a problem in minor release, isn’t it?).
Inner extension methods in several instances bring the method name clash (they have to be marked with @targetName) but they allow to omit all the redundant bridges like this:
extension [T: Ops as ops](t: T)
def meth = ops.meth(t)
However, with top-level extensions, there is a problem with overloading (e.g. math.max vs math.max for Ordering)
Can you give an example — the most plausible-to-actually-occur possible example — of the source incompatibility, to help us judge whether it’s acceptable breakage?
If someone extends the TC, that’s why community build fails
//before
trait X:
def meth(a: A): Unit
class XImpl extends X:
def meth(a: A): Unit = ???
//after
trait X:
extension(a: A) def meth: Unit
class XImpl extends X:
def meth(a: A): Unit = ???
fails with method meth of type (a: A): Unit is a normal method, cannot override an extension method, but is still binary compatible
I wonder how much breakage would occur in the open community build. (The closed community build, the one that runs during PR validation, is small, so it doesn’t give us much data.)
We discussed this again on the core meeting and we are still unsure about the impact and whether this can always be worked around.
@sjrd mentioned that there might be cases where we can’t even change the code to compile it still.
On the other hand if we plan on evolving the standard library we will need changes like this. Maybe adding a way to override extension methods with a real method would help with that (discussed on core as well)
@sjrd could you provide an example of such a case? (no offense, I’m just curious)
@sjrd is right. If someone extends our trait (normal → extension methods) and another trait with a normal method, they won’t be able to fix it easily, because they would have to override both the normal method and the extension method at once, which is impossible
Thanks for coming up with this, but overall we need to think about what approach we would take. Community build should help us find how much impact it has, but it will not show all the impact from private codebases unfortunately.