The standard does *not* support - a removeAll: a - [was: Re: [BUG] Collection>>removeAll:]

Lex Spoon squeak-dev at lists.squeakfoundation.org
Sun Sep 15 19:16:22 UTC 2002


"Richard A. O'Keefe" <ok at cs.otago.ac.nz> wrote:
> 	This is actually the point of view I'm coming from.  If you follow this
> 	style guideline fervently, then you never have to worry about "a
> 	removeAll: b" with a==b.
> 
> Then you don't care what #removeAll: does in that case, and should not be
> unhappy if it has an assertion to cover it.

The qualification is important.  I don't think most Smalltalkers would
be so fervent, especially in the case they return the entire underlying
collection.  So, they wait until there is a problem before they add the
#copy's.  This is specifically the reason I suggested flagging an error:
people who follow this guideline lazily, will want to be informed when
they violate the presumption.

It's possible that, indeed, Smalltalkers should just copy like crazy. 
But I don't think so, and at the very least it will take a lot of time
to convince the current programmers.

> 
> 	If you like the guideline but would are lazy
> 	in its implementation, then you'd like to get warnings whenever you
> 	violate it in an erroneous or even borderline situation.  When,
> 	precisely, would a programmer want to do "a removeAll: b" where a==b ? 
> 
> This was explained in some detail some time ago.
> 
> First, it actually _happened_ in someone else's code.  I don't know _why_
> it happened, but it happened.

Granted, but they could easily change this code once the situation is
uncovered.  Simple solutions have been posted and no one has argued with
them.

> 
> Second, in the absence of a #removeAll method (note the absence of a colon)
> then if you want to make a collection empty,
>     myownprivatecollection removeAll: myownprivatecollection
> is an obvious thing to try.

Everyone agrees that #removeAll is an omission.  Let's suppose that the
method indeed gets added to Squeak.  Now what should #removeAll: do ?


> 
> Third, the programmer who wrote the method that does a removeAll: b
> might not *KNOW* whether a is b or not; they might be passed as parameters.

This certainly happens, but I question that this it is good practice to
blissfully allow it.  Here's an even better example of the situation
than the unrolling example I gave in a previous post:

	b := self chooseSomeElements.
	a removeAll: b.
	b do: [ :each | "act on the elements of b" ]


If a==b here then you have some very difficult code to debug!   It's
much easier to debug if an error gets flagged in removeAll:.



> In the second case, you might be trying to operate on your own innards.
> 
> The third case also can arise from one method passing private unshared
> objects to another method in the same class, where the author of the
> second method didn't know the two objects might be the same and never
> thought to document the restriction s/he didn't know about anyway.

I don't think these are good excuses for allowing a==b.  In both cases,
you know enough of what is going on to avoid the case, and you are just
as likely as elsewhere to get bitten if you overlook the aliasing. 
Especially in the second case, you'd like to get notification if you
have an alias but have forgotten it.


This debate doesn't seem as complicated as the length of the thread
suggests.  It comes down to comparing usefulness to danger.  To me, the
extension seems excessively dangerous without being very useful.


-Lex



More information about the Squeak-dev mailing list