Species and replaceFrom:to:with:startingAt:

Stephen Pair spair at acm.org
Mon Aug 12 13:38:49 UTC 2002


In implementing a LargeArray class (for LargeWeakIdentityKeyDictionary),
I've encountered two weaknesses of the current factoring of the
collections classes.

- #species

When we need to grow a collection, current we use code like "array
species new: size"...but, this doesn't work for my LargeArray class
because I need the new instance to adopt some of the properties of the
old instance (like the chunksize and the base array class).  

My proposal is that we change the current factoring to instead send
#speciesNew and/or #speciesNew: to the old instance.  This will offer
the receiver the chance to do such initialization based on its state.

- #replaceFrom:to:with:startingAt:

The primitive version of this method accesses the state of one of it's
arguments (thus breaking encapsulation).  When this method is called,
the argument (the replacement array) has no opportunity to hook in and
override the way in which its contents are being accessed.  This is a
problem for my LargeArray because if the LargeArray is passed as the
replacement, the primtive might fail and fall through to the slower
Smalltalk code that copies each element one by one.  If the primitive
doesn't happen to fail, it's only because the LargeArray had enough
chunks, and what we get are the chunks being copies, not the actual
elements.

My proposal is that we solve this issue using double dispatch.  Rather
than send #replaceFrom:to:with:startingAt: directly, current senders
should be changed to send #startingAt:replace:from:to:.  The code for
this method would looke like:

SequenceableCollection
startingAt: index replace: target from: start to: stop  
	"This destructively replaces elements from start to stop in
target 
	starting at index in the receiver. Answer the receiver. No range

	checks are performed."

	^target replaceFrom: start to stop with: self startingAt: index

This will offer my LargeArray class the opportunity to override this
method such that it can take maximum advantage of the primitive behavior
to copy itself (it would override startingAt:replace:from:to: and
replaceFrom:to:with:startingAt: such that it is actually re-sending
these methods to its constituent chunks).

- Stephen






More information about the Squeak-dev mailing list