[Pharo-project] Dictionary as a Set
Sorry to repost, seems that gmane did not like my first attempt... Stéphane Ducasse <stephane.ducasse@...> writes:
On Dec 29, 2008, at 12:23 PM, Alexandre Bergel wrote:
Dear List,
I was wondering whether I am the only one shocked when I see this:
(Set new add: #b -> 'B'; yourself) includes: #b -> 'B' ====> true (Set new add: #b -> 'B'; yourself) includes: 'B' ====> false
this is correct
(Dictionary new add: #b -> 'B'; yourself) includes: #b -> 'B' ====> false (Dictionary new add: #b -> 'B'; yourself) includes: 'B' ====> true
we should check the semantics of includes:
Dictionary inherits from Set. This means that if Set would have a contract, it would break in Dictionary. IMO, we should have (Dictionary new add: #b -> 'B'; yourself) includes: #b -> 'B' ====> true (Dictionary new add: #b -> 'B'; yourself) includes: 'B' ====>
false
No?
Dictionary and Set relationship is subclassing so a lot can be strange. We should fix that in Bloc.
From the st80 origin, Dictionary is a Bag of values. Each value of this Bag is indexed with a unique key. It is a Bag because: a) multiple values can be in the dictionary: (Dictionary new) at: 'one' put: 1; at: 'first' put: 1; yourself. b) values are unordered: | d1 d2 | (d1 := Dictionary new: 3) at: 'one' put: 1; at: 'two' put: 2. (d2 := Dictionary new: 4) at: 'one' put: 1; at: 'two' put: 2. stream := (String new: 64) writeStream. d1 do: [:v | stream print: v; cr]. d2 do: [:v | stream print: v; cr]. stream contents. And as you can see, #do: does apply on values, as would #collect: #select: #reject: #includes: etc... The fact that Dictionary is implemented with Associations could be seen as a private implementation-defined feature. Though, by tradition, associationsDo: has been made a public interface, so as the possibility to directly add an Association. But semantically, Dictionary is not a Set of Associations. Example: (Set new) add: $a->65; add: $a->1; yourself. (Dictionary new) add: $a->65; add: $a->1; yourself. Dictionary could be viewed as a Set of keys. From that POV, it shared enough property with Set to be implemented as a subclass. That's all. I proposed once to detach Set and Dictionary and derive them from a common ancestor just for clarity... Nicolas
There was a discussion about Dicts/Sets on squeak dev more than year ago http://lists.squeakfoundation.org/pipermail/squeak-dev/2007-June/117840.html IMO making Dictionary a subclass of Set was mistake. But there's little what can be done without risk of breaking many code. Some related problem - about letting Sets include nils and 'self' as elements, also was discussed on squeak-dev. It can be done w/o breaking much compatibility. 2008/12/30 nicolas cellier <ncellier@ifrance.com>:
Sorry to repost, seems that gmane did not like my first attempt...
Stéphane Ducasse <stephane.ducasse@...> writes:
On Dec 29, 2008, at 12:23 PM, Alexandre Bergel wrote:
Dear List,
I was wondering whether I am the only one shocked when I see this:
(Set new add: #b -> 'B'; yourself) includes: #b -> 'B' ====> true (Set new add: #b -> 'B'; yourself) includes: 'B' ====> false
this is correct
(Dictionary new add: #b -> 'B'; yourself) includes: #b -> 'B' ====> false (Dictionary new add: #b -> 'B'; yourself) includes: 'B' ====> true
we should check the semantics of includes:
Dictionary inherits from Set. This means that if Set would have a contract, it would break in Dictionary. IMO, we should have (Dictionary new add: #b -> 'B'; yourself) includes: #b -> 'B' ====> true (Dictionary new add: #b -> 'B'; yourself) includes: 'B' ====>
false
No?
Dictionary and Set relationship is subclassing so a lot can be strange. We should fix that in Bloc.
From the st80 origin, Dictionary is a Bag of values. Each value of this Bag is indexed with a unique key.
It is a Bag because: a) multiple values can be in the dictionary: (Dictionary new) at: 'one' put: 1; at: 'first' put: 1; yourself. b) values are unordered: | d1 d2 | (d1 := Dictionary new: 3) at: 'one' put: 1; at: 'two' put: 2. (d2 := Dictionary new: 4) at: 'one' put: 1; at: 'two' put: 2. stream := (String new: 64) writeStream. d1 do: [:v | stream print: v; cr]. d2 do: [:v | stream print: v; cr]. stream contents. And as you can see, #do: does apply on values, as would #collect: #select: #reject: #includes: etc...
The fact that Dictionary is implemented with Associations could be seen as a private implementation-defined feature. Though, by tradition, associationsDo: has been made a public interface, so as the possibility to directly add an Association.
But semantically, Dictionary is not a Set of Associations. Example: (Set new) add: $a->65; add: $a->1; yourself. (Dictionary new) add: $a->65; add: $a->1; yourself.
Dictionary could be viewed as a Set of keys. From that POV, it shared enough property with Set to be implemented as a subclass. That's all. I proposed once to detach Set and Dictionary and derive them from a common ancestor just for clarity...
Nicolas
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
-- Best regards, Igor Stasenko AKA sig.
There was a discussion about Dicts/Sets on squeak dev more than year ago http://lists.squeakfoundation.org/pipermail/squeak-dev/2007-June/117840.html
IMO making Dictionary a subclass of Set was mistake.
subclassing indeed is not really a good choice.
But there's little what can be done without risk of breaking many code.
Yes this is not the point. What we want to do is to build another library for Smalltalk 3000 :)
Some related problem - about letting Sets include nils and 'self' as elements, also was discussed on squeak-dev. It can be done w/o breaking much compatibility.
I would love that this issue gets solved. As eliot pointed it out this could be done with one primitive been able to preallocate with a default value. Now I may be wrong.
2008/12/30 nicolas cellier <ncellier@ifrance.com>:
Sorry to repost, seems that gmane did not like my first attempt...
Stéphane Ducasse <stephane.ducasse@...> writes:
On Dec 29, 2008, at 12:23 PM, Alexandre Bergel wrote:
Dear List,
I was wondering whether I am the only one shocked when I see this:
(Set new add: #b -> 'B'; yourself) includes: #b -> 'B' ====> true (Set new add: #b -> 'B'; yourself) includes: 'B' ====> false
this is correct
(Dictionary new add: #b -> 'B'; yourself) includes: #b -> 'B' ====> false (Dictionary new add: #b -> 'B'; yourself) includes: 'B' ====> true
we should check the semantics of includes:
Dictionary inherits from Set. This means that if Set would have a contract, it would break in Dictionary. IMO, we should have (Dictionary new add: #b -> 'B'; yourself) includes: #b -> 'B' ====> true (Dictionary new add: #b -> 'B'; yourself) includes: 'B' ====>
false
No?
Dictionary and Set relationship is subclassing so a lot can be strange. We should fix that in Bloc.
From the st80 origin, Dictionary is a Bag of values. Each value of this Bag is indexed with a unique key.
It is a Bag because: a) multiple values can be in the dictionary: (Dictionary new) at: 'one' put: 1; at: 'first' put: 1; yourself. b) values are unordered: | d1 d2 | (d1 := Dictionary new: 3) at: 'one' put: 1; at: 'two' put: 2. (d2 := Dictionary new: 4) at: 'one' put: 1; at: 'two' put: 2. stream := (String new: 64) writeStream. d1 do: [:v | stream print: v; cr]. d2 do: [:v | stream print: v; cr]. stream contents. And as you can see, #do: does apply on values, as would #collect: #select: #reject: #includes: etc...
The fact that Dictionary is implemented with Associations could be seen as a private implementation-defined feature. Though, by tradition, associationsDo: has been made a public interface, so as the possibility to directly add an Association.
But semantically, Dictionary is not a Set of Associations. Example: (Set new) add: $a->65; add: $a->1; yourself. (Dictionary new) add: $a->65; add: $a->1; yourself.
Dictionary could be viewed as a Set of keys. From that POV, it shared enough property with Set to be implemented as a subclass. That's all. I proposed once to detach Set and Dictionary and derive them from a common ancestor just for clarity...
Nicolas
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
-- Best regards, Igor Stasenko AKA sig. _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
participants (3)
-
Igor Stasenko -
nicolas cellier -
Stéphane Ducasse