Default method survey results

"Zdeněk Troníček" tronicek at
Sat Aug 18 02:45:02 PDT 2012

Yuval Shavit napsal(a):
> On Sat, Aug 18, 2012 at 3:35 AM, "Zdeněk Troníček"
> <tronicek at>wrote:
>> 2) Iterator with remove() that throws UOE breaks the Liskov substitution
>> principle. Mutable iterator is not a special case of immutable iterator.
> Sorry for beating this horse, but I fail to see why this is the case.
> Invoking remove() on an Iterator is obligated to do one of two things:
> remove the last element that next() returned, or throw UOE. An iterator
> with remove() that throws UOE conforms to this contract, and can be
> replaced with any other iterator *about which nothing is known other than
> it's an Iterator*.
> Taking wikipedia at face value, the LSP states:
>     Let be q(x) a property provable about objects x of type T. Then q(y)
> should be provable for objects y of type S where is S a subtype of T.
> Let q(n) be "remove() throws UOE or removes the last element returned by
> next()." I can prove q(x) for objects x of type Iterator, since that is
> the
> contract of Iterator.remove(). If some type S has a method remove() that
> always throw UOE, then I can by definition prove the property "remove()
> throws UOE" for objects y of S. In that case, I can also trivially prove
> that "remove() always throws UOE or removes the last element returned by
> next()" for objects y of S. So the LSP holds.

Although this reasoning is right, it is not about immutable iterator. q(x)
for immutable iterator is "remove() throws UOE" which apparently does not
hold true for mutable iterator.
The property you state ("remove() throws UOE or removes the last
element...") holds true for general iterator.
And when you add "remove() { throw new UOE(); }" to Iterator, it becomes
immutable iterator, regardless of whether the name remains Iterator or
changes to ImmutableIterator.

More information about the lambda-dev mailing list