I agree with Igor, best implementation of remove: is self error: 'Dictionary cannot #remove:, please use #removeKey:' Dictionary have two faces: - a bag of values indexed thru a set of keys - a set of associations (at least in st80 when association = was only testing the key) The second form is historical and IMO kind of private implementation details. Moreover, now that Association = is also based on values, the second form is not even more true. The strange thing is to define #add: in Dictionary. Normally we cannot add a value without a key index. Thus the right protocol for dictionary is #at:put: IMO, #add: intention was private, as Association should have been. But for conveniency we decided to let this #add: protocol survive. For remove:, you have two options: - provide any Object (Dictionary is a Bag of values) Then, remove is self associationsDo: [:e | e value = anObject ifTrue: [self removeKey: e key. ^anObject]]. ^absentBlock value. But then, you don't have symmetry with add: and remove:, so is it of any use ? - provide an association... But, then, what do you expect: Dictionary new add: #a -> 1; remove: #a -> 2 Nicolas 2010/12/7 Igor Stasenko <siguctua@gmail.com>:
On 7 December 2010 12:49, Stéphane Ducasse <stephane.ducasse@inria.fr> wrote:
Hello, jaayer.
The point about Dictionary inconsistency was raised multiple times before. I was among ones of those who did that couple of years ago. What can i say? While it is much better to have consistency, in fact it doesn't really changes much. I don't think that #remove: in a form you proposed will be any userful. I would really keep it simply #shouldNotImplement , because it is unclear what is a least surprising behavior of this method for Dictionary.
Igor why?
why remove: does not take the same argument than add: and does what it should?
because with collection you can do:
collection copy do: [:xx  | collection remove: xx ]. or collection removeAll: (collection select: [:each | each isOdd ] )
but not with dictionary. So i don't see much reason fixing #remove: because we never going to fix #do: anyways, which makes all beautiful manipulations with collections useless for dictionary.
One might argue, that its more userful to make it same as #removeKey:, other one could point that its should be symmetrical to #add: ,
#add: is not part of the ANSI <abstractDictionary> protocol. It is, however, part of the ANSI <extensibleCollection> protocol: add: addAll: remove: remove:ifAbsent: removeAll:
One could make the argument that if Dictionary elects to implement part of it, it might as well implement the rest too.
but hey, then #do: should be also symmetrical to #add: , isnt? And so it should iterate over associations , not just values. So, it is a can of worms, once you open it , you can never finish the endless discussions :) It is just works in a way how we like (defined). It is like an imaginary numbers in math where sqrt(-1) == i and basta :)
Right... I wasn't planning on going there, but are we basically stuck with #do:, #select: #collect:, #includes: and other such messages operating on the Dictionary's values rather than its associations, forever?
I hope not.
-- Best regards, Igor Stasenko AKA sig.