Defender methods and compatibility

Reinier Zwitserloot reinier at zwitserloot.com
Tue Nov 30 02:48:41 PST 2010


On Mon, Nov 29, 2010 at 11:28 PM, Neal Gafter <neal at gafter.com> wrote:

To be (hopefully) more clear, here are the costs of the current approach:
> o New syntax for extension methods (as opposed to using the existing method
> body syntax)
>

Not related. If at some point the ability to specify the default directly as
a method body in the interface is added, there's still a default of some
sort. Possibly this will point at itself
(InterfaceName.methodWithInlineDefault), possibly the method body is
desugared into some form of method, and the 'default method' becomes this
generated construct. Either way, there's still the concept of realizing 2
different defaults happen to point at the same method. In other words, this
is NOT a cost of the "current approach" (being: default method is relevant
for Source Compatibility). If the "default MethodRef" syntax goes away
entirely, this point becomes moot, as all defaults will always point at
incompatible things.


> o Changing the default of an extension method is not source compatible (in
> the sense that it can cause some existing clients to no longer compile)
>

This is a trivial detail that's not worth holding back progress for, for two
reasons. (1) Such a change leading to an actual compile error for existing
code is exceedingly rare. The same level of rare as adding new methods to
existing classes in rt.jar, which could cause problems in code extending the
class and also having added this method. This is in fact _why_ I asked you
for realistic use cases. If I wanted some arrogant guy insulting me, I'd
have asked for that instead. (2) In the few cases where the maintainer of
the interface realizes this could become a problem, he can change the
default implementation instead. That would be an entirely source (and
binary) compatible change. This is not of course possible if this maintainer
does not control the default method, but I again ask for practical
situations where that would be the case. For example, List will possibly get
a sort() method, defaulted to Collections.sort. Both List and Collections
are in the same "module" - whomever has the ability to change the one has
the ability to change the other.

If, on the other hand, you could make a case that regardless of these 2
reasons, there's still a decent chance that Source Incompatible changes are
going to be likely, I'm all ears. But, to channel Brian for a moment, please
show some examples instead of hammering on about "should", "broken", and
other meaningless fearmongering.

o Under the current draft spec, not binary compatible either, but there have
> been promised (as yet unexplained) complexities to be added to method
> resolution (and therefore the JVM) that may be introduced to reduce this
> effect.
>
>
Not relevant either:

Reason 1: It's easy to imagine a fix. There's a mechanism for the
classloader or VM to fix a class implementing interface X and missing the
default method to link it to the default. There's also the option for the
compiler to do so at compile time. If the runtime mechanism exists anyway,
we have a path of fixing a change in default method.

Reason 2: See previous section's Reason 2.

Reason 3: Unless you're talking about doing away with the "default X"
mechanism entirely and going with "supply body inline", how do you propose
to fix this? You're doing the same thing: You insinuate a way to get rid of
the complexities without explaining how.

Here are the benefits:
> o Certain compile-time ambiguities might be avoided when extension methods
> in unrelated classes have the same signature and implementation.
>

Surely you mean unrelated /interfaces/, not classes. That's a rather
creative definition of "unrelated". If the default implementation is the
same, odds are the 2 interfaces are related (such as: are from the same
"module", i.e. List and Map).

The default of an extension method is not a part of the programmer-visible
> API in any useful, observable sense *except to the extent that it can
> introduce this incompatibility.*
>
>
Vs. not introducing it, in which case the potential incompatibility is
turned into a sure thing. How is that practical? Or are you suggesting that
there's an arbitrary but deterministic algorithm for picking the winner,
such as "whichever interface is listed first"?


More information about the lambda-dev mailing list