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
|