Virtual extension methods -- a strawman design
Nathan Bryant
nathan.bryant at linkshare.com
Mon May 24 09:37:41 PDT 2010
Yes, and Java up to Java 6 also brushes the problem under the covers...
by not even attempting to solve it at all.
Fundamentally, this proposal is neither multiple inheritance nor traits.
It just is what it is: extension methods.
Some of the more important differences:
* If this were multiple inheritance, extension methods could themselves
reference "super". In this proposal, they can't, because they're just
ordinary static methods. (MethodHandles from a lookupSpecial would be a
way to fake that, but I digress.)
* The order of implemented interfaces does not affect method resolution,
as it does for both multiple inheritance and traits.
* As in multiple inheritance, but unlike with traits, "super" is always
resolved statically.
* In some implementations of traits, when a trait gains or loses a
member, classes that inherit from it must be recompiled without
exception; it's clear that any implementation with such limitations
would not meet the requirements for this project. That limitation is not
the case here; the brittleness limitations being proposed here are more
limited.
So from the perspective of the principle of least surprise, this
implementation should be easier to understand for novice programmers
compared to either multiple inheritance or traits.
The proposal is useful for what it's designed for: widening primitive
interfaces. It doesn't seem particularly useful for stacking
modifications.
-----Original Message-----
From: lambda-dev-bounces at openjdk.java.net
[mailto:lambda-dev-bounces at openjdk.java.net] On Behalf Of Howard Lovatt
Sent: Sunday, May 23, 2010 8:52 PM
To: lambda-dev at openjdk.java.net
Subject: RE: Virtual extension methods -- a strawman design
Alex Blewitt said:
> This is the classic 'diamond problem' that is experienced with
multiple implementation inheritance.
> Unfortunately, the proposal document
(http://cr.openjdk.java.net/~darcy/DefenderMethods.pdf)
> brushes this under the covers (5.1) with a 'should throw an exception'
at this point. This is
> pretty silent, outside of any compiler warnings, and is definitely a
change of behaviour.
Section 4.2 seems to cover what happens.
"4.2. Resolving ambiguity
If the class implements multiple extended interfaces, both of which
provide a default
implementation for the same method name and signature, the
implementing class MUST
provide an implementation. (This is expected to be a quite unusual
case.) The existence
of the InterfaceName.super.methodName() syntax makes it easy for the
class to choose
one of the defaults. (We might choose to relax this restriction if
both interfaces provide the same default.)"
This solution is the normal solution for traits, i.e. programmer has
to resolve the issues.
Alex Blewitt said:
> public class A implements DataStructure {
> public boolean filter(FilterSam filter) {...}
> }
> // Later, someone makes the change:
> public interface DataStructure {
> extension DataStructure filter(FilterSam filter) default
Default.filter;
> }
When A is net recompiled there is a compiler error. If A is not
recompiled there is a link error. See section:
"5.1. Resolving ambiguity
In the unlikely case that the VM attempts to load a class that
implements multiple
extended interfaces that have a common defender method but with
different defaults, the
VM should not attempt to resolve the ambiguity automatically.
Instead, it should
generate a bridge method that throws UOE or similar exception. We
expect this situation
to be rare."
I would agree with the assessment that this will be rare and therefore
catching the error is sufficient.
-- Howard.
More information about the lambda-dev
mailing list