Formal model for defender method resolution

Neal Gafter neal at gafter.com
Tue Feb 1 19:26:56 PST 2011


On Tuesday, February 1, 2011, Brian Goetz <brian.goetz at oracle.com> wrote:
> Nice try :)

Every chance I get. ;)

>     I am much more interested in getting a clean semantics of what it
>     *means* to remove a default, and how it might play into default
>     resolution in cases like:
>
>     intf A { String m() default X.a }
>     intf B { String m() default X.b }
>     intf C extends A { String m() default none }
>     intf D extends A, B, C { }
>
>     What now?  Do we barf because A and B are contributing conflicting
>     defaults?  If we prune A from consideration (as I believe we should), do
>     we barf because the "none" in C conflicts with the default in B?
>
> Yes.  To see why this is the only reasonable resolution, make every
> override in your example covariant.
>
>
> We've already posited that in the presence of a covariant override, the overrider must provide a new defender (see rule T-IntDefOvr in the latest draft.)  Whether that new defender could be "none" or not is a separate issue.
>
> It sounds like you are saying that "none" should be considered to be a defender with an identity, and therefore can only be replaced through an override rather than through mixing.

Not at all.  In fact, I'd prefer to do away with the concept of a
default's identity.

> Which makes this a different category of abstract method; ordinary abstract methods can be given a defender through mixing:
>
>   intf A { String m(); }
>   intf B { String m() default k; }
>   intf C extends A, B { }
>
> whereas you are suggesting that if A had "default none", then C would fail?

I see your point: there is a unique, non-overridden concrete
implementation here, as in the previous example.

In both this and the previous example, any problem arises only in the
context of a particular concrete class.  Either the class has a unique
overrider for each abstract method it inherits, or it does not (and is
rejected).  Why should we should reject interfaces, which can't
generally be instantiated in isolation anyway?  I think the primary
reason (if there is one) is that there are defaults in the hierarchy
that can't be "used" by a class because of ambiguity, so the defaults
dont do the clients any good.  I think you're thinking that ought to
be an error we want to diagnose when the interface is compiled.  Is
that right?


More information about the lambda-dev mailing list