Re-specification and re-abstraction

Peter Levart peter.levart at gmail.com
Thu Dec 22 13:54:45 PST 2011


On Thursday, December 22, 2011 09:14:40 AM Brian Goetz 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 no-op-ness of "exact redeclaration of interface method" is respected 
either way if the definition of "exact" is adequate.

Or:

If all we have is abstract methods, then re-abstraction can be viewed as no-
op.

> 
> 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.

So the scenario that current semantics is trying to serve best is the 
following:

// author X creates:

interface A {
  void m() defaut { ... }
}

// then comes user Y and extends A:

interface AExt extends A {
  /**
   * Just Some JavaDoc...
   */
  @Override void m();

   ...
}


Now, you are saying that user Y might expect that method redeclaration is a 
no-op and would be surprised if it was in fact re-abstraction. Maybe so, but 
he would certainly be the 1st to implement the AExt interface and find that 
out. There is practicaly no chance that he would not notice that and would 
therefore deprive other implementors of AExt from the chance of utilizing the 
A's default.


Or are you planning to replace existing methods in existing interfaces with 
default methods as an alternative to extending abstract base classes. For 
example:

Instead of extending from AbstractList, one could just implement List and get 
implementations of methods that are now part of AbstractList via default 
methods in List interface.

In that case maybe one would want those defaults to be inherited by pre-
existing extensions of List that "just redeclare" those methods.

Peter

> 
> 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


More information about the lambda-dev mailing list