defender method syntax considered harmful
alex.buckley at oracle.com
Wed Sep 29 15:55:57 PDT 2010
On 9/29/2010 11:10 AM, Per Bothner wrote:
> So the syntax needs a lot stronger justification. That this would
> "violate the long-held rule that "interfaces don’t have code"" doesn't
> mean anything - the whole point of this change is to *change* this
> rule so that interface *can* have code.
The goal is source-compatible interface evolution, not "method bodies in
interfaces" per se. Now, a good way to get source-compatible interface
evolution is via defaults for abstract methods. Specifying defaults by
value (i.e. method bodies) is plausible, but with the introduction of
method references in the language, it is also reasonable to think of
specifying defaults by reference.
> So that leaves "by specifying the default by name rather than by
> value, it is easier for the runtime to identify whether two defaults
> are in fact the same method, which is important for conflict
> resolution." I'm missing something there:
> The runtime determined whether two defaults are the same method - by
> seeing if they're the same method: Defined in the same interface, with the
> same name and parameter list. Is it because you might have two interfaces
> that might want to have the same default method? That would seem a
> fairly rare use case, and can be easily solved by adding a new
Fairly rare? Maybe, or maybe not.
In general, the interfaces implemented by a class do not all define the
same abstract method. If they do, then the interfaces are likely to have
a common superinterface - what I might call a "hyperinterface". A
hyperinterface is an important high-level interface with not only many
possible implementations but also many possible subinterfaces. A good
example in the Java SE API is java.util.Collection.
So, incompatible defaults are only going to be a problem where a class
implements interfaces commonly under a hyperinterface. Because
hyperinterfaces are few in number but rich in scope, it's certainly a
problem to worry about. Yet, it's quite conceivable that subinterfaces
of a hyperinterface will independently choose the same default for a
given abstract method, especially high up in the interface hierarchy. We
want to exploit that possibility. In finance terms, we get a good
increase in alpha with minimal increase in beta.
You mention adding a common superinterface where interfaces wish to
choose the same default for an abstract method. That more or less
assumes global recompilation. But the challenge is precisely to preserve
type soundness _under separate compilation_. That is, if a consumer
(caller or implementer) can be compiled and run against a library, and
then you add a default to a method in an interface in the library and
recompile only that interface, does the consumer still compile and run?
You don't get to recompile every class that implements the interface or
(It goes without saying that a consumer that compiles against the
library, should run against the library.)
Thank you for raising your concern on the list, BTW.
More information about the lambda-dev