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

Andrew C. Greenberg werdna at mucow.com
Sat Aug 31 16:33:11 UTC 2002


I frankly find all the spec-lawyering quite disheartening.  (This 
coming from a patent lawyer.)  But as long as folks seem to be 
overwhelming compelled to viewing this as a black-or-white 
answer-or-no-answer issue,  let me add, at least, a few more shades of 
gray to these discussions.

Much lip-service has been given to "accepting" my prior proposition 
that an iterand Collection should never be modified without expecting 
poor results.  "Yes, yes of course," others would say.  And then go on 
to argue, "but the parameter to removeAll: is not an iterand -- indeed, 
there is not even an implied enumeration -- the #removeAll is in the 
'remove' protocol, not the 'enumeration' protocol.  There is no 
iteration in #removeAll:, express or implied, except perhaps because of 
a few naive implementations."  (Paraphrases of course, but I think a 
fair summary of this sub-line of argument)

But the ANSI standard does not, in fact, admit such a dodge.  Indeed, 
it DEFINES removeAll: as "the equivalent" to an iteration over the 
elements of the parameter, as a call of #remove for each such element.  
Specifically, it says that, "[t]he operation is defined to be 
equivalent to removing each element of oldElements from the receiver."  
In this sense, I stand by my construction of the standard, to wit:

	1) An enumeration over an iterand that changes during the enumeration 
is undefined.
	2) If element each is in a receiver, r, then "r remove: x" changes r.
	3) The ANSI standard section 5.7.5.5 explicitly defines "removeAll: 
oldElements" as an iteration over the elements of oldElements, sending 
for each such element, say 'each', the message #remove: each.
	4) At least for non-empty collections, "x removeAll: x" is undefined.

While one can quibble over the truth of proposition 3, one must accept, 
at least, that it is a fair argument, at least in the gray region.  (I, 
for one, find it compelling, but reasonable people, apparently, may 
differ.)  Accordingly, it seems to me that the argument that "failure" 
of "x removeAll: x" is clearly and in black-and-white a bug is, at 
best, overstated.

While I am sensible to some of the discussion on both sides of this 
argument, I find it simply indefensible to suggest that it is in any 
sense clear and black-and-white how, if at all, the ANSI standard 
actually defines the result in the class of cases where such an 
iteration results in changes to oldCollection, and particularly the 
special case where the reciver and parameter are identical.

On Friday, August 30, 2002, at 10:46 AM, Stephan Rudlof wrote:

> <standard>
>
> 5.7.5.5 Message: removeAll: oldElements
>
> Synopsis
>   For each element in oldElements, remove the first element from the
> receiver which is equivalent to this element.
> Definition: <extensibleCollection>
>   This message is used to remove each element of a given collection 
> from the
> receiver's elements. The operation is defined to be equivalent to 
> removing
> each element of oldElements from the receiver using the #remove: 
> message
> with the element as the parameter. The behavior is undefined if any 
> element
> of oldElements is not found.
> Parameters
>   oldElements <collection> uncaptured
> Return Values
>   UNSPECIFIED
> Errors:
>   none
>
> </standard>




More information about the Squeak-dev mailing list