Syntax for calling super
David Holmes
david.holmes at oracle.com
Sun Aug 26 23:05:29 PDT 2012
On 27/08/2012 3:25 PM, Howard Lovatt wrote:
> To me the super syntax is what you would expect consider:
>
> public class OuterOuter {
> String level() { return "Outer Outer"; }
> class Outer {
> String level() { return "Outer"; }
> class Inner {
> String level() { return "Inner"; }
> void print() {
> out.println(level());
> out.println(Outer.this.level());
> out.println(OuterOuter.this.level());
> }
> }
> }
> }
>
> Just substitute super for this, to indicate that the method in question
> does come from this class but from the inherited interface.
^not
I don't follow your reasoning. Outer.this is a specific enclosing
instance. Outer.super is not a legal expression. Outer.super.level()
means "invoke Outer.this's super.level() method" (a syntactic shorthand
if you will for Outer.this.super.level()). So with inner classes Outer
is used to find the receiver NOT the method, and super only indicates
the immediate superclass. (Yes the receiver indirectly determines the
method but that is not directly related to the Outer name or even the
direct superclass of Outer - the method could actually exist in Object
for example.)
With the default method situation you want Outer.super to be the exact
interface in which the method is found (an immediate superinterface of
Outer), and the receiver is always this.
That would be fine and dandy if the syntax did not already exist today,
but it does. I simply don't like overloading the syntax to mean two
completely different things. And I am arguing against claims that
somehow these are the same, or very similar, things.
There is no perfect syntax here, all of the options have problems. I
think super.K.m() is the most natural form, but has an ambiguity problem
that is not readily solved. K.m() is even more nature in a sense but
gives the appearance of being a general method invoker when its actually
constrained to K being a direct superinterface (and would be ambiguous
if static methods were ever introduced into interfaces).
Note: depending on which syntax is being discussed K is either the
current class (K.super suggestion) or the superinterface (super.K.m(),
K.M()).
I really don't think I can say any more on the matter. :)
Cheers,
David
> -- Howard.
>
> On 27 August 2012 11:12, David Holmes <david.holmes at oracle.com
> <mailto:david.holmes at oracle.com>> wrote:
>
> Gregg,
>
> The distinction is not OuterName.this versus OuterName.super. Both of
> these exist today in the context of inner-classes - specifically
> accessing members of an enclosing class instance.
>
> The proposal to use K.super.m() for default method access is completely
> different to that usage - there is no other instance involved.
>
> We already have "super" to indicate that we want to look-to/access
> something in a supertype, but super.m() is not expressive enough to
> solve the default method problem, and super.K.m() can be ambiguous (if K
> is also the name of a member of your supertype). So K.super.m() has been
> proposed to address that. As a standalone suggestion it would be quite
> reasonable, but given there is an existing syntactic construct with
> quite different semantics today I find it objectionable.
>
> YMMV.
>
> David
>
> On 27/08/2012 10:29 AM, Gregg Wonderly wrote:
> >
> > On Aug 24, 2012, at 7:27 PM, David Holmes<david.holmes at oracle.com
> <mailto:david.holmes at oracle.com>> wrote:
> >
> >> On 25/08/2012 3:03 AM, GREGG WONDERLY wrote:
> >>>
> >>> On Aug 23, 2012, at 8:00 PM, David
> Holmes<david.holmes at oracle.com <mailto:david.holmes at oracle.com>>
> wrote:
> >>>
> >>>> On 24/08/2012 12:56 AM, Peter Levart wrote:
> >>>>> On Thursday, August 23, 2012 11:01:46 AM David Holmes wrote:
> >>>>>> On 23/08/2012 8:13 AM, Brian Goetz wrote:
> >>>>>>> The syntax was designed to be analogous to the "K.this.m()"
> syntax that
> >>>>>>> is used in inner classes.
> >>>>>>
> >>>>>> But the semantics are quite different. K.this is a reference
> to a
> >>>>>> completely different object (the enclosing instance from
> class K).
> >>>>>> Whereas as K.super is meant to infer something about 'this'.
> >>>>>
> >>>>> Intuitively I don't have problems with K.super. I see
> K.something as something
> >>>>> qualified with type K.
> >>>>>
> >>>>> In case of "this" it selects the innermost instance of type
> K, whereas in case
> >>>>> of "super" it selects the most specific visible member from the
> >>>>> superclass/superinterface K's hierarchy.
> >>>>>
> >>>>> In both cases K is an addidional restriction to the "search
> strategy".
> >>>>
> >>>> K.super.m() already has an existing meaning with inner
> classes, just as
> >>>> K.this.m() does. There's a difference between searching for a
> type alone
> >>>> and searching for an object and then a type. Using the same
> notation is
> >>>> confusing in my view.
> >>>
> >>> This view is troubling to me. If we are in an inner class, and
> code
> >>>
> >>> OuterName.this.m();
> >>>
> >>> The compiler knows to look for the type OuterName in the
> hierarchy of class definitions visible to the inner class, and then
> invoke m().
> >>
> >> I don't see OuterName as telling the compiler where to look for
> something, it is simply naming something. The current object is
> "this", the enclosing instance is OuterName.this. It is not a search
> path it is a direct name for an object.
> >
> > The location of the statement tells the compiler what name space
> is visible to it. I.e. it knows it is in an inner class, and thus
> it will look outward till it reaches the "outer" class, looking for
> the "OuterName" class.
> >
> >>> For default methods, if a we write
> >>>
> >>> OuterName.this.m();
> >>>
> >>> It seems to me that even though the compiler has to look in a
> slightly different way, the fully qualified name of OuterName is
> visible to it, so that it can ask "Is this a class" or "Is this an
> interface", and the take the appropriate steps to resolve what to
> invoke.
> >>
> >> Here OuterName.this does not name an enclosing instance. You are
> using the same syntax for two completely different things in my view.
> >
> > The context that this statement is in, specifies the "class" and
> interfaces which are visible in that context. Thus, the "this"
> refers to the "context" which is the current "class", and thus it's
> implemented interfaces and thus the visible interfaces which can be
> reached. If OuterName is not reachable in that namespace, the
> compiler can provide the appropriate error message.
> >
> >> No doubt compiler writers and parser writes think about this
> differently, but from my perspective as an end-programmer, these are
> quite different things. If I was explaining what this statement
> meant to someone the explanation in the two cases would be
> completely different - hence in my opinion the same syntax should
> not be used for both.
> >
> > The current details of "inner class" references to outer classes,
> in my view, is just one example of a context qualified reference to
> some more narrow scope, relative to the current class.
> >
> > I am, at this point, calling an interface, a special type of
> "class" definition, and thus I am thinking of interfaces and classes
> as having a common base, because we've now made abstract classes
> even more like interfaces.
> >
> > When I think about code wanting to access a specific "class"
> detail, we have several things that the language uses to control
> access. We have very tedious things like introspection. We have
> less tedious things like "public", "private" and package access.
> The string, "OuterName.this", for me, is another one of these
> "control points".
> >
> > Maybe if you could provide a sentence or description that you'd
> say in a code review, or other moment that you'd talk about a code
> fragment for each of
> >
> > OuterName.this
> >
> > and
> >
> > OuterName.super
> >
> > that might help me really "get" how you are thinking about these
> two types of references, and why they seem so different in nature,
> that you'd prefer to add another keyword that is context sensitive
> into the mix.
> >
> > Gregg
> >
> >
> >>
> >>> Having the compiler do this small amount of introspection of
> the class/interface name space, seems like a lot better choice, then
> asking the developer to remember to type this vs super.
> >>>
> >>> What will be the compiler error message, if I type this instead
> of super or vice versa? What will that do to help the developer
> really code effectively?
> >>>
> >>> Gregg
> >
>
>
>
>
> --
> -- Howard.
>
More information about the lambda-dev
mailing list