Default methods syntax/semantics [Re: Updated State of the Lambda]

Stephen Colebourne scolebourne at joda.org
Mon Dec 12 15:21:08 PST 2011


On 12 December 2011 17:14, Rémi Forax <forax at univ-mlv.fr> wrote:
> On 12/12/2011 04:25 PM, Brian Goetz wrote:
>>> Another solution would be to use the abstract keyword, perhaps at the
>>> end in place of "default none".
>> No, that already means something (actually, it is defined to mean
>> nothing in that context.)
>>
>> I think you should make sure you understand the feature as designed
>> better before declaring that getting rid of it would "make perfect sense."
>>
>> If you don't understand the feature as designed, you can ask.  Or you
>> can wait for the more detailed explanation that is surely forthcoming,
>> but just hasn't arrived yet.
>>
> Don't be so harsh with Stephen,
> I've followed exactly the same path, 'default' is ugly the first
> time you see it and 'default none' is uglier, but after writing
> some use cases it's obvious that this is the right choice.
>
> You need default because you need to express the fact that
> a method defined in a super-class will always win to one
> defined in an interface.

There are two distinct issues here - whether the default keyword is
needed for a method body, and whether default none is the best
solution in its design space. In each case, it would not be disastrous
for Java if the current spec goes final, I'm just providing feedback
that it "feels wrong".

On the first point - the need for default with a method body, Remi
makes the case for using it to imply that the superclass version takes
precedence over the interface one - "You need default because you need
to express the fact that a method defined in a super-class will always
win to one defined in an interface."

I'm afraid I simply don't think thats necessary. Bear in mind that in
the past I've suggested adding syntax to clarify meaning (like the #
in lambdas to indicate capture of the return keyword), so its
interesting in its own right that I think less is more here.

Put simply, I see it as a simple enough rule that classes are more
important than interfaces when inheriting, that I think the default
keyword is superfluous. Beyond that, I think it actually becomes
distracting. Right now, it looks like a holdover from when there were
no method bodies, and you had to declare a static method - in the
static method case, the default keyword made a lot of sense, but in
the method body case it seems superfluous (but see below...)

While this is primarily a syntax issue, it does clearly impact on how
the feature is sold/perceived, and obviously affects the "none" case
which is a bit more of a semantic discussion.

The "default none" case is more subtle. The main thrust of my point is
that it looks and feels wrong (note that I'm not complaining about the
new keyword "none" per se, more the thrust of the feature point). Now
it may be that it is the best option available - if so, then let it
be. But I tend to find that things that look and feel wrong are signs
that something should be closely examined.

The reabstraction case seems rare, so anything added here will be
rarely seen, making it seem even more out of place. I also suggested a
new "documentation override" feature, which appears to tackle the core
part of the problem rather than the effect.

Having said all that, perhaps examining the "default none" case in
isolation may miss something. For example, here is an interesting
alternative approach to the whole area - requiring defaulting
interfaces to declare themselves as such, similar to the way abstract
classes have to:

interface A {
  void a();  // normal interface, no defaulting allowed
}
default interface B {
  void a();  // normal interface method
  void b() { ... }  // interface method with default body
}
default interface C extends B {
  void a();  // reabstraction
  void b() { B.super.b() }  // override for documentation, as per classes
  void c();  // normal interface method (same syntax as reabstraction)
}

With the scheme above, "default" is a bit like the mirror opposite of
"abstract". Adding "abstract" to a class makes it more like an
interface, whereas adding "default" to an interface makes it more like
a class.

More interestingly, taking the mirror opposite approach to its logical
conclusion yields the following:

interface A {
  void a();  // normal interface, no defaulting allowed
}
default interface B {
  void a();  // normal interface method
  default void b() { ... }  // interface method with default body
}
default interface C extends B {
  default void a();  // reabstraction
  default void b() { B.super.b() }  // override for documentation, as
per classes
  void c();  // normal interface method
}

Now the "default" keyword is a modifier, used exactly as "abstract"
would be, but in reverse. More verbose yes, but perhaps more Java-like
too.

Summary:  I've outlined two directions here - dropping "default" from
method bodies based on the current spec, and using "default" as the
mirror opposite of "abstract" (or a simplified version where the
default is only on the interface declaration).

Stephen


More information about the lambda-dev mailing list