On Tue, Oct 25, 2016 at 6:33 AM, monty <monty2@programmer.net> wrote:
Except #do: isn't the only method required to be overridden. #add: and #remove:ifAbsent: are also abstract.

Only for extensible subclasses. These *can not* be implemented in terms of #do: so they have to be implemented in a subclass.

Collection provides a maximum of protocol with a minimum of methods required to be overridden.

This discussion is besides the point though. I was just pointing out that requiring #size or #isEmpty to be a subclass responsibility is not a good idea, because they can and should be implemented in terms of #do:. Whether #isEmpty should be implemented in terms of #size is a wholly different issue. 

Chris has some valid points about historical performance trade-offs which are worth discussing.

My take is that if we don't know *anything* about the subclass, we have to assume that #size can be way more expensive than a single iteration of #do: (e.g. a linked list). So using #do: is the sensible default implementation for #isEmpty. If OTOH a subclass has a very expensive #do:, then it's reasonable to assume that it would avoid doing much work if it is in fact empty.

If a Collection subclass did rely on an implementation detail of its superclass performance-wise then this is unfortunate, but easy to fix by implementing #isEmpty in terms of #size. We shouldn't let that get in the way of making our base libraries more elegant.

- Bert -