Formal model for defender method resolution

Brian Goetz brian.goetz at oracle.com
Tue Feb 1 13:16:43 PST 2011


> <mailto:brian.goetz at oracle.com>> wrote:
>
>     While we're having a nice syntax bike-shed paint, I'll just point out
>     that it would be nice if the syntax in the default were the same as the
>     syntax in a clarifying override, which is currently:
>
>        intf A { void m() default X.a }
>        intf B { void m() default X.b }
>        class C implements A, B {
>          void m() { A.super.m(); }
>        }
>
> Yes, many of us have pointed out the benefits of writing the body inline.

Nice try :)  Whether the body goes inline is a largely separate issue to 
the point that was being discussed here.

>     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.  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 think that's getting awfully complicated -- while you are 
treating "none" as a default with an identity, people are likely to be 
confused at the difference between "no default" and "default of none". 
(Shades of Scala's None/Nothing/Nil/Null/Unit.)

In any case I'm working on a new design draft that I believe is a 
worthwhile simplification of defender resolution, which I'm hoping to 
have in a few days.



More information about the lambda-dev mailing list