defender method syntax considered harmful
Per Bothner
per at bothner.com
Wed Sep 29 11:10:27 PDT 2010
[Sorry for arriving late to the party. I've bitched about this
privately, but I belatedly joined this list so I can bitch in public.]
I still haven't seen a satisfying justification for the new
"defender method" syntax. (I know people say "syntax is
not important" but they're wrong: one could argue a major reason
for Java's success was the familiar-looking syntax. They also say
we can always fix the syntax later, but "later" becomes "never".)
Worse, defender methods add a new *concept* (both syntax and semantics),
when we have a perfectly usable and familiar one available:
overridable method bodies.
Specifically:
"It is a deliberate choice to not simply allow the programmer to include
the code of the
default inline within the interface. Not only would this violate the
long-held rule that
“interfaces don’t have code”, but by specifying the default by name
rather than by value,
it is easier for the runtime to identify whether two defaults are in
fact the same method,
which is important for conflict resolution."
I don't think this deliberate choice is sufficiently motivated. Obviously,
letting the programmer "include the code of the default inline within
the interface"
would be much more natural and intuitive, and does not require new syntax.
(Technically that would also be change in the syntax, but it's a modest
simplification/regularization, as opposed to real new syntax with two
new context-dependen keywords, if you count "default" as new *in this
usage*.)
So the syntax needs a lot stronger justification. That this would
"violate the long-held rule that "interfaces don’t have code"" doesn't
mean anything - the whole point of this change is to *change* this
rule so that interface *can* have code.
So that leaves "by specifying the default by name rather than by value,
it is easier for the runtime to identify whether two defaults are in
fact the same method,
which is important for conflict resolution." I'm missing something there:
The runtime determined whether two defaults are the same method - by
seeing if they're the same method: Defined in the same interface, with the
same name and parameter list. Is it because you might have two interfaces
that might want to have the same default method? That would seem a
fairly rare use case, and can be easily solved by adding a new
super-interface.
I.e. I'm gathering the issue is because of:
"Method resolution for extension methods is as follows:
...
4. Construct the set of distinct default methods corresponding to the
list of interfaces
arrived at in step (2). If the result has a single item (either
because there was only
one default or multiple interfaces provided the same default), the
search is
resolved successfully."
I.e. "multiple interfaces provided the same default". I don't think this is
useful enough to motivate the new syntax. Is there a motivating example for
where a class implements two or more unrelated interfaces that happen to
have the "same method" (in the sense of the same name and types)? Wouldn't
this be a conflict that would need to be resolved explicitly by the class?
When would you ever design an API this way, unless you change both
interfaces
to have a common ancestor? Note that if can change two interfaces to be
implemented by the same static method, then you can change them to implement
the same super-interface. I guess in theory team 1 could add a default
for method m in interface A, and then later team 2 could the "same" default
for method m to an unrelated interface B, without having to modify A.
However, I can't think of a motivating example.
--
--Per Bothner
per at bothner.com http://per.bothner.com/
More information about the lambda-dev
mailing list