Default method survey results
yshavit at akiban.com
Fri Aug 17 12:19:24 PDT 2012
On Fri, Aug 17, 2012 at 3:07 PM, Zhong Yu <zhong.j.yu at gmail.com> wrote:
> On Fri, Aug 17, 2012 at 1:36 PM, Yuval Shavit <yshavit at akiban.com> wrote:
> > On Fri, Aug 17, 2012 at 1:27 PM, Zhong Yu <zhong.j.yu at gmail.com> wrote:
> >> On Thu, Aug 16, 2012 at 12:32 PM, Brian Goetz <brian.goetz at oracle.com>
> >> wrote:
> >> >> The oddity of "default" implementation is that it puts the programmer
> >> >> in a box. He has to provide some sort of implementation that does not
> >> >> rely on state. That's an odd place to be in -- especially if no
> >> >> suitable implementation can be given without state.
> >> >
> >> > No, there are plenty of default methods that can be implemented
> >> > access to state. For example, there are optional methods. For
> >> > Iterator.remove() can have a default to throw UOE, so that the 99% of
> >> > Iterator implementations that don't want to implement remove() don't
> >> > have to implement a version that throws.
> >> That means it was a mistake to include remove() in Iterator. And now
> >> we use a tool to mask that mistake, ending up with 2 mistakes. There
> >> should not be a default impl of Iterator.remove() - a default impl
> >> must work in all cases, not just in common cases.
> > Well, throwing UOE from Iterator.remove() *does* work in all cases, in
> > it always conforms to the Iterator contract (which states that you may
> > UOE from remove()). If you want more interesting behavior, you are free
> > provide it.
> What I meant is, the default impl should correct, even if subclass
> forgets to override it. While in the Iterator.remove() case, the
> default impl is correct, only if subclass deliberately does not
> override it. To compiler there's no difference: the method is not
> overridden. To human there's a difference.
How do you define "correct"? My point was that if you define it as
"conforming to the specified contract," then throwing UOE is *always*
correct from the Iterator's perspective -- though it may not be correct and
maximally useful. If you have a class whose iterator() method returns an
Iterator with a more specific contract, then you as the implementer
presumably know about that stronger contract and its implications on
overriding your Iterator's remove().
I happen to agree with you that it would have been nice to have something
like Iterator <- ModifiableIterator, but that ship has sailed, and there's
no point in re-opening the debate now. Given the current state of affairs,
I think it's reasonable to provide Iterator.remove with a default
implementation which is always correct, though not necessary desirable --
and then to let implementers override it if they want to add additional,
More information about the lambda-dev