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

Richard A. O'Keefe squeak-dev at lists.squeakfoundation.org
Mon Sep 2 05:42:23 UTC 2002


Stephan Rudlof <sr at evolgo.de> wrote:
	I've just read parts of the ANSI Smalltalk Standard,

	<standard>
	
	Essential aliasing of parameters is described using a parameter aliasing
	attribute:
	
	*captured*     The receiver always retains a reference to the parameter,
	directly or indirectly, as a result of this message.
	*uncaptured*   The receiver never retains a reference to the parameter,
	directly or indirectly, as a result of this message.
	*unspecified*  It is unspecified as to whether or not a reference is
	retained as a result of this message i.e. either case may occur.
	
I quoted the relevant part of this before.

Note the key phrase:  **AS A RESULT OF THIS MESSAGE**.
	Since we have an 'uncaptured' parameter, the receiver *has* *to* never
	retain a reference to the parameter, directly or indirectly, as a result of
	this message.
	
This does not mean: "As a result of this message, the receiver must not
retain a reference to the parameter" but "The receiver must not retain a
reference to the parameter AS A RESULT OF THE MESSAGE".

	Further: The parameter *is* the receiver in the case of
	    a removeAll: a
	. Has this receiver a direct reference to itself?  I don't think
	so.  But the *coupling* between receiver and parameter here is
	much stronger - identity!  - than a mere reference.  And the
	intent of the requirement here - as *I* read the standard - has
	been to have *no* coupling between parameter and receiver here.
	
No, that's not what it says.  It says that any coupling that exists
must not be AS A RESULT OF THE MESSAGE.

Let's take another case concerning which I hope there is no dispute.

    a := #(1 2 3 4).
    b := a asSet.
    b add: a.

With me so far?  'b' is the set {1 2 3 4 #(1 2 3 4)}.

    b removeAll: a.

I hope we are agreed that this clearly and unambiguously leaves
'b' as the set {#(1 2 3 4)}; the elements of 'a' have gone but
the reference to 'a' itself has not.  According to Squeak the
final value of b is 'a Set(#(1 2 3 4))' and 'b anyOne == a' is true.

So after this call to #removeAll:, the receiver *does* retain a reference
to the argument, but that is OK because that isn't AS A RESULT OF THE
MESSAGE.  The reference exists because of an _earlier_ message.

	My conclusions:
	- I think this supports Allen Wirfs-Brock's view, that this
	special case has been overlooked.

There was never any reason to doubt his word on the matter.

	- The intent of the standard seems to be to *forbid*
	    a removeAll: a
	
You may be able to justify that conclusion on other grounds, but not on
this one.  It is quite clear that the "Rudlof reading" of uncaptured is
untenable in this case and elsewhere.  For another example, consider
    x = x
where x is any object supporting an #= method.  After the message,
x retains something stronger than a reference to x, x retains identity
with x.  But section 5.3.1.1 says firmly that the argument is 'uncaptured'.
On the Rudlof reading, x would not be allowed to be identical to itself
afterward.  On the "Richard reading", x knowing itself after x = x is
perfectly fine because it doesn't do so AS A RESULT OF the #= message.
In the same way, x knowing itself after x removeAll: x is perfectly fine
because it doesn't do so AS A RESULT OF the #removeAll: method.

Whatever _else_ we can say about x removeAll: x is entirely outside the
scope of this message, which is concerned _solely_ with the question
"how do we interpret 'uncaptured' when reading the ANSI Smalltalk standard."




More information about the Squeak-dev mailing list