Re-specification and re-abstraction

David Holmes david.holmes at oracle.com
Thu Dec 22 16:10:10 PST 2011


On 23/12/2011 8:14 AM, Brian Goetz wrote:
>> 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...

Aside: do we have any real world example where "just some javadoc" does 
not affect the actual semantic specification of the method? I guess the 
addition of doc tags would be one case.

>> */
>> @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.
>
> That is right.

 From where does user Y derive their "expectations"? Have they read the 
documentation for how default methods work? If not they have no 
expectations beyond "something may happen". If they have read the 
documentation then they understand what they need to do to use or not 
use the default in A.

<snip>

>> In that case maybe one would want those defaults to be inherited by pre-
>> existing extensions of List that "just redeclare" those methods.
>
> Yes, this is one case where the pass-through behavior is desirable.
>
> As I said, both directions are somewhat unfortunate.

There is a big difference between convenience and correctness. The two 
directions are by no means equivalent in their "badness".

David
-----


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