Dictionary>>collect: vs. Dictionary>>select: : why are theydifferent?

Richard A. O'Keefe ok at cs.otago.ac.nz
Mon Nov 17 00:03:42 UTC 2003


What should (aDictionary collect: aBlock) return?
What does the ANSI Smalltalk standard say?

<collection>
5.7.1.10 Message: collect: transformer
  Synopsis
    Answer a new collection constructed by gathering the results of
    evaluating transformer with each element of the receiver.
  Definition: <collection>
    For each element of the receiver, transformer is evaluated with the
    element as the parameter.  The results of these evaluations are
    collected into a new collection.
    The elements are traversed in the same order as they would be if the
    message #do: had been sent to the receiver.
>>  Unless specifically refined, the message is defined to answer an object
    conforming to the same protocol as the receiver.
  Parameters
    transformer <monadicValuable> upcatured
  Return Values
    <RECEIVER> new
  Errors
    If any element of the receiver is inappropriate for use as an
    arguments (sic!) to transformer.
    If the result of evaluating the transformer does not conform to
    any element type restrictions of the collection to be returned.

<abstractDictionary>
5.7.2.6 Message Refinedment: collect: transformer
  Synopsis (unchanged)
  Definition: <collection> (unchanged)
  Refinement: <abstractDictionary>
>>  Answer a new instance of the receiver's type witht he same keys.
    For each key of the answer, a new element is obtained by evaluating
    transformer with the corresponding element of the receiver as the
    parameter.
  Parameters (unchanged)
  Return Values (unchanged)
  Errors (unchanged)

It says just exactly what you would expect:  #collect: returns the same
kind of thing as the receiver (IF it can, which it can't always; the Set
and Bag familes are good examples of where it can't).  Not only is this
expectation not cancelled for Dictionaries, it is explicitly affirmed.
A {,Identity,Pluggable}Dictionary _can_ answer exactly the same kind of
object because the answer has exactly the same keys as the receiver.

The really interesting thing is what the comment says.  In Squeak 3.5,
Dictionary>>collect: starts with this comment:
    "Evaluate aBlock with each of my values as the argument.
     Collection the resulting values into
>>   a collection that is like me.
     Answer with the new collection."

One way to make this comment true (and to make the code compatible
with the ANSI standard) would be

    Dictionary>>
    collect: aBlock
	|r|

	r := self copy.
	r associationsDo: [:each | each value: (aBlock value: each value)].
	^r

One thing I like about this way of defining it is that any changes made
to the original receiver while the method is running will have no effect
at all.




More information about the Squeak-dev mailing list