Re-specification and re-abstraction

Howard Lovatt howard.lovatt at gmail.com
Thu Dec 22 14:31:38 PST 2011


David H and Peter L make a good point about potentially surprising
behaviour and introducing difficult to find bugs with inherited defender
methods and on balance I favour their suggested semantics over the current
semantics. It is also a pleasingly simple solution with five easy to follow
forms:

interface M0 { void m() { ... } } // m has a default body and Javadoc
interface M1 extends M0 { void m(); } // m is re-abstracted & Javadoc
interface M2 extends M0 { void m() { M0.super.m(); } } // Re-use M0's
definition & Javadoc
interface M3 extends M0 {} // Re-use M0's definition, no Javadoc
interface M4 extends M0 { void m() { ... } } // Re-define m & Javadoc

I do accept that the current semantics have some advantage and also that
either set of semantics are workable, however I slightly prefer the above
semantics. Partially that preference is because I find "default" and
"default none" ugly, but the biggest point is that I think it will least
likely to cause difficult to find bugs.

 -- Howard.

On 23 December 2011 01:14, Brian Goetz <brian.goetz at oracle.com> wrote:

> The tension here is between respecting the existing language behavior,
> intended or not -- where exact redeclarations of interface methods is a
> no-op -- and how we want this "new" feature to work, and who loses when
> existing usage patterns conflict with the desired usage patterns for the
> new feature.
>
> The existing semantics were designed to respect the no-op-ness of these
> redeclarations, effectively making them "invisible" to the default
> calculation, rather than give a potentially surprising new meaning to a
> hitherto meaningless (but used in practice) construct.
>
> Neither answer is obviously right, or even good (and anyone claiming
> otherwise has not thought through it enough.)  Its only a matter of
> which alternative is less bad, and there's arguments on both sides.  We
> went back and forth on this one a few times already, and may well go
> back and forth on it a few times more before we're done.
>
>
> On 12/22/2011 2:25 AM, Peter Levart wrote:
> > On 12/22/11, David Holmes wrote:
> >> One of the things that concerns me in the current State of the Lambda is
> >> the fact that re-specification of method on a sub-interface does not
> >> re-abstract the method, but continues to allow any default from a super
> >> interface to be applied to that method. This is inherently wrong in my
> >> opinion.
> >>
> >> Consider this fictitious but plausible example.
> >>
> >> We have the present Map interface. We also have a ConcurrentMap
> >> interface that adds some additional methods that provide atomicity for
> >> compound actions on maps that support concurrent access.
> >>
> >> Suppose that ConcurrentMap actually re-specified each of the Map methods
> >> to add various thread-safety and atomicity guarantees.
> >>
> >> Now suppose that the maintainer of Map decides to take advantage of
> >> default methods and adds default implementations to some of those Map
> >> methods. This is not done with ConcurrentMap in mind and those
> >> implementations offer no specific thread-safety or atomicity guarantees.
> >> It should be obvious that those implementations are not likely to be
> >> valid for any class that implements ConcurrentMap.
> >>
> >> Given the current semantics however, if I were to write a class that
> >> implements ConcurrentMap and accidentally forgot to implement those
> >> methods for which a default exists in Map, then my class will in fact
> >> "inherit" those implementations. And in doing so my class would be
> >> completely broken, but I would be unaware of it.
> >>
> >> To me this is completely wrong - we should never sacrifice correctness.
> >> A supertype does not in general know about any subtypes and so a
> >> supertype's default implementation should not apply if the subtype has
> >> redefined that method. Any change to the "documentation" of a method is
> >> a change to its specification. Only the author of that change is in a
> >> position to say whether a default implementation in a supertype is still
> >> applicable - so to assume that it is by default (no pun intended) is
> >> just wrong in my view.
> >>
> >> If redefinition of a method always re-abstracted it then, I think, no
> >> explicit syntax for re-abstraction would be needed.
> >>
> >> David Holmes
> >>
> >
> > I aggree. Only the author of the interface should say when an if the
> "new" default on a superinterface is adequate. I don't see any drawback
> when re-specification of a method in a subinterface has the semantics of
> re-abstraction compared to current state where the default is inherited. It
> certainly doesn't break any code.
> >
> > Looking from the perspective of code evolution: if an interface method
> was abstract (non-default) at the start than any non-abstract
> implementations of this interface or subinterface already specifies a
> concrete implementation for that method. Changing this abstract method to a
> default method on a superinterface does not break anything even if this
> method is re-abstracted on any subinterface (because class allways wins).
> >
> >   Regards, Peter
> >
> >>
> >
>
>


-- 
  -- Howard.


More information about the lambda-dev mailing list