[GOODIE] invarAssn-raok
Richard A. O'Keefe
ok at cs.otago.ac.nz
Thu Aug 29 05:20:02 UTC 2002
I posted InvariantKeyAssocation,
"a subclass of Association which can be safely used when the key
must not be replaced."
Tommy Thorn <thorn at meko.dk> wrote:
1) What exactly does it mean to replace the key?
Suppose you do
x := Association key: #foo value: 27.
The basic operations now available are
x value => 27
x value: 99 changes x, returns x. x value will now be 27
x key => #foo
x key: #bar changes x, returns x. x key will now by bar.
Basically all that InvariantKeyAssocation does is block this last message.
I assume that it assumes the association itself as a mutable object
Yes, they are. Always have been.
where the key can be updated (which is not ok), whereas deleting
a pair (k,v) and inserting a new (k',v) is ok?
Right. This is a building block for a new version of Dictionary (NOT
a change to Dictionary, a whole new class). However, I'm _really_ supposed
to be writing exam questions, so it may be some time before I get to finish
the rest of it, and I thought this chunk might be useful as it stands.
2) What is the advantage of InvariantKeyAssociation / when
should it be preferred?
Consider
aDictionary associationsDo:
[:eachAssociation | eachAssociation key: nil].
This doesn't actually make sense, but Squeak won't stop you doing it.
InvariantKeyAssociations are associations with a key you can't change,
so my new Dictionary-like class will be able to hand its associations
out safe in the knowledge that which object the key _is_ can't be changed.
The values can be changed, indeed that's one reason why #assocationsDo:
is useful. But the values aren't used to structure the dictionary.
The key objects may be mutated, but the ANSI Smalltalk standard says
over and over again "don't do that", so I think we can expect people to
know not to change the keys themselves.
Note that it is possible to imagine an implementation of
#associationsDo: in which changes to the keys were allowed and worked.
Here's one:
associationsDo: aBlock
|deltas old|
deltas := OrderedCollection new.
super do: [:eachAssociation |
old := eachAssociation key.
aBlock value: eachAssocation.
eachAssociation key ~= old
ifTrue: [deltas addLast:
{old. eachAssocation key. eachAssociation value}.
eachAssociation key: old]].
deltas do: [:eachTriple |
self remove: (eachTriple at: 1).
(eachTriple at: 2) ifNotNil: [
self at: (eachTriple at: 2)
put: (eachTriple at: 3)].
This lets aBlock change a key; it notes the change and puts the old key
back so that the structural properties of the Dictionary are preserved
while the #do: is happening. (No, I am NOT proposing that #associationsDo:
be changed. Nor am I suggesting that it _should_ have been like this.
I'm only trying to stave off the inevitable comments that any Smalltalk
programmer should just _know_ as a universal constraint across all
programming languages that it isn't going to work. Well, it could have.)
We REALLY need better comments in Squeak.
Dictionary>>associationsDo: just says
"Evaluate aBlock for each of the receiver's elements
(key/value associations)."
It should say something like
"Pass each of the receivers (key->value) Associations to
aBlock in an unspecified order. aBlock may change the
value of an Association, but should not change any key."
More information about the Squeak-dev
mailing list
|