Hi -
Just got bitten by the fact that Dictionary>>collect: returns an OrderedCollection instead of a Dictionary. What I had expected was e.g., dict := Dictionary newFromPairs:{ #first. 1. #second. 2. #third. 3. }. dict collect:[:item| item asWords]. => a Dictionary(#first->'one' #second->'two' #third->'three' ) but instead the result is an OrderedCollection('one' 'two' 'three'). Does anyone besides me consider this a bug? What does ANSI say about this issue? Cheers, - Andreas |
On 12.06.2008, at 23:21, Andreas Raab wrote: > Hi - > > Just got bitten by the fact that Dictionary>>collect: returns an > OrderedCollection instead of a Dictionary. What I had expected was > e.g., > > dict := Dictionary newFromPairs:{ > #first. 1. > #second. 2. > #third. 3. > }. > dict collect:[:item| item asWords]. > > => a Dictionary(#first->'one' #second->'two' #third->'three' ) > > but instead the result is an OrderedCollection('one' 'two' 'three'). > Does anyone besides me consider this a bug? What does ANSI say about > this issue? Don't know about ANSI, but I'd have expected a Dictionary, too. - Bert - |
In reply to this post by Andreas.Raab
Andreas Raab schrieb:
> Does anyone besides me consider this a bug? What does ANSI say about > this issue? I think that #collect: should be in line with #select: and #reject: which both return Dictionaries. One possible reason why #collect returns a different kind of collection is that for some base collections, the results of the block might not fit (for example, "aByteArray collect: [:x | x odd]" would raise an exception). Incidentally, VisualWorks behaves as you and I expect. Cheers, Hans-Martin |
Hans-Martin Mosner a écrit :
> Andreas Raab schrieb: >> Does anyone besides me consider this a bug? What does ANSI say about >> this issue? > I think that #collect: should be in line with #select: and #reject: > which both return Dictionaries. Agree, I fully support Andreas request as a very logical one. Beside, it is very easy to get an OrederedCollection if that is really wanted in Squeak: (dict collect:[:item| item asWords]) asOrderedCollection. or: dict values collect:[:item| item asWords] > One possible reason why #collect returns a different kind of collection > is that for some base collections, the results of the block might not > fit (for example, "aByteArray collect: [:x | x odd]" would raise an > exception). True, but since Dictionary can hold any arbitrary value... I think that historical reason is that #do: only iterates on values, and that super #collect: was implemented with a #do: loop... And long ago, values would answer a Bag because Dictionary keys are unordered (I guess Dictionary species would ^Bag, but no old image here to check...) > Incidentally, VisualWorks behaves as you and I expect. > Only recently, because 7.2 did still return an OrderedCollection... > Cheers, > Hans-Martin > > Nicolas |
In reply to this post by Andreas.Raab
Hi,
VA Smalltalk returns a Dictionary. Returning a Dictionary makes sense, as you can always get an OrderedCollection with: dict values collect: [:item| item asWords]. forcing a Dictionary from what Squeak does for #collect:, is probably not so easy. Lou >Just got bitten by the fact that Dictionary>>collect: returns an >OrderedCollection instead of a Dictionary. What I had expected was e.g., > > dict := Dictionary newFromPairs:{ > #first. 1. > #second. 2. > #third. 3. > }. > dict collect:[:item| item asWords]. > >=> a Dictionary(#first->'one' #second->'two' #third->'three' ) > >but instead the result is an OrderedCollection('one' 'two' 'three'). >Does anyone besides me consider this a bug? What does ANSI say about >this issue? > >Cheers, > - Andreas > Louis LaBrunda Keystone Software Corp. SkypeMe callto://PhotonDemon mailto:[hidden email] http://www.Keystone-Software.com |
In reply to this post by Hans-Martin Mosner
Thanks everyone. I filed a bug and a fix at
http://bugs.squeak.org/view.php?id=7095 BTW, Josh pointed out that ANSI agrees with that definition too: 5.7.2.6 Message Refinement: 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 order specified by the #do: message for the receiver. Unless specifically refined, this message is defined to answer an object conforming to the same protocol as the receiver. Refinement: <abstractDictionary> Answer a new instance of the receiver's type with the 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. Cheers, - Andreas Hans-Martin Mosner wrote: > Andreas Raab schrieb: >> Does anyone besides me consider this a bug? What does ANSI say about >> this issue? > I think that #collect: should be in line with #select: and #reject: > which both return Dictionaries. > One possible reason why #collect returns a different kind of collection > is that for some base collections, the results of the block might not > fit (for example, "aByteArray collect: [:x | x odd]" would raise an > exception). > Incidentally, VisualWorks behaves as you and I expect. > > Cheers, > Hans-Martin > > |
In reply to this post by Hans-Martin Mosner
On Friday 13 Jun 2008 3:02:34 am Hans-Martin Mosner wrote:
> Andreas Raab schrieb: > > Does anyone besides me consider this a bug? What does ANSI say about > > this issue? > > I think that #collect: should be in line with #select: and #reject: > which both return Dictionaries. Why so? #collect; is a closed operation on Collection, not on Dictionary. Unlike #select: or #reject:, it aggregates new objects (String in the example) generated from the values (Integer). Key associated with the value will not carry over to the new object automatically. Bluebook describes collect: aBlock as: <quote> Evaluate the argument, aBlock, for each of the receiver's elements. Answer a new collection like that of the receiver containing the value returned by the block on each evaluation. .... Messages inherited from the class Collection -- includes:, do: and other enumeration messages -- are applied to the *values* of the Dictionary. That is, these messages refer to the values of each association in the Dictionary, rather than to the keys or to the associations themselves. </quote> Subbu |
K. K. Subramaniam a écrit :
> On Friday 13 Jun 2008 3:02:34 am Hans-Martin Mosner wrote: >> Andreas Raab schrieb: >>> Does anyone besides me consider this a bug? What does ANSI say about >>> this issue? >> I think that #collect: should be in line with #select: and #reject: >> which both return Dictionaries. > Why so? #collect; is a closed operation on Collection, not on Dictionary. > Unlike #select: or #reject:, it aggregates new objects (String in the > example) generated from the values (Integer). Key associated with the value > will not carry over to the new object automatically. > > Bluebook describes collect: aBlock as: > <quote> > Evaluate the argument, aBlock, for each of the receiver's elements. Answer a > new collection like that of the receiver containing the value returned by the > block on each evaluation. > .... > Messages inherited from the class Collection -- includes:, do: and other > enumeration messages -- are applied to the *values* of the Dictionary. That > is, these messages refer to the values of each association in the Dictionary, > rather than to the keys or to the associations themselves. > </quote> > > Subbu > > From historical POV, you are right, but... With all the respect due to the holly blue book and its authors, it is not the bible. Viewing a Dictionary as a Bag of values certainly was a simple way to define a compatible Behavior with other collections. However, it's a much too reductive view that is loosing the Dictionary spirit. The spirit is associated to the keys undoubtedly. Let's adopt a more useful behaviour preserving the keys. And good news, if a Dictionary can be viewed as a Bag of Values, then collected key/value associations can still be viewed as a Bag of values... So you don't loose anything, you can still ask for includes: do: and other Bag-compatible protocol... you only win some associated keys! Cheers Nicolas |
On Friday 13 Jun 2008 5:38:37 pm nicolas cellier wrote:
> With all the respect due to the holly blue book and its authors, it is > not the bible. Sorry, I didn't mean to throw the book at you. I only quoted the passage to point out that collect: is WAD. That doesn't stop us from adding a new method to create a new dictionary by mapping values from an existing dict without affecting its keys. E.g. numberDictionary associationsCollect: [ :v | v asWords ]. Here is my first cut at it: associationsCollect: aBlock | d | d = WriteStream on: (Array new: self size). self associationsDo: [ :assoc | d nextPut: assoc key -> (aBlock value: assoc value) ]. ^Dictionary newFrom: d contents Subbu |
In reply to this post by Andreas.Raab
I believe ANSI says it should be a dictionary. VW has just changed their
implementation in version 7.6 to return a Dictionary. -----Original Message----- From: [hidden email] [mailto:[hidden email]] On Behalf Of Andreas Raab Sent: Thursday, June 12, 2008 2:22 PM To: The general-purpose Squeak developers list Subject: [squeak-dev] Dictionary>>collect: returning OrderedCollection? Hi - Just got bitten by the fact that Dictionary>>collect: returns an OrderedCollection instead of a Dictionary. What I had expected was e.g., dict := Dictionary newFromPairs:{ #first. 1. #second. 2. #third. 3. }. dict collect:[:item| item asWords]. => a Dictionary(#first->'one' #second->'two' #third->'three' ) but instead the result is an OrderedCollection('one' 'two' 'three'). Does anyone besides me consider this a bug? What does ANSI say about this issue? Cheers, - Andreas |
Dictionary>do: etc work on the values of the associations. #collect:
should continue the pattern. #associationsDo: etc exist if you need to work with the associations. tim -- tim Rowledge; [hidden email]; http://www.rowledge.org/tim Artificial Intelligence: Making computers behave like they do in the movies. |
tim Rowledge a écrit :
> Dictionary>do: etc work on the values of the associations. #collect: > should continue the pattern. #associationsDo: etc exist if you need to > work with the associations. > > tim > -- > tim Rowledge; [hidden email]; http://www.rowledge.org/tim > Artificial Intelligence: Making computers behave like they do in the > movies. > Hi tim and Subbu, you follow a certain historical logic. But behaviour could be much simpler and homogeneous with ANSI POV. Consider current state of Squeak: 1) select: and reject: already return a Dictionary 2) collect: current implementation would answer an OrderedCollection which is a nonsense for these reasons: - there is no reason that values be Ordered since keys are not - depending on Dictionary allocated size, the order will just change - answering an OrderedCollection is equivalent to associating integer keys to values in an arbitrary random order... Original st-80 logic would have been to answer a Bag, nothing else. 3) Since Dictionary can answer most of Bag protocol transparently, you won't even notice the change if collect: answers a Dictionary. This is a transparent operation Changing collect: does absolutely not change the fact that Dictionary can be viewed as a Collection of values... I vote against this un-necessary associationsCollect: Nicolas |
In reply to this post by Nicolas Cellier-3
>> Messages inherited from the class Collection -- includes:, do: and >> other enumeration messages -- are applied to the *values* of the >> Dictionary. That is, these messages refer to the values of each >> association in the Dictionary, rather than to the keys or to the >> associations themselves. > > With all the respect due to the holly blue book and its authors, > it is not the bible. Actually, the "modern" view of Dictionary as a "keyed collection with external keys" (external = given by the user) does not conflict at all with the blue book definition. Like #do:, #collect: only works on the values -- but like on the other keyed collections, i.e. SequenceableCollections, the keys are preserved. From here, one can define by extension the obvious meaning of #select: and #reject: for a dictionary. Note that this meaning is different between sequenceable collections and dictionaries, because answering false (resp. true) will change the keys of all subsequent values in a sequenceable collection! Note that this: > associationsCollect: aBlock > ... > self associationsDo: [ :assoc | d nextPut: assoc key -> (aBlock value: assoc value) ]. would be very wrong, because associationsSomething: messages work on associations, while your message passes only the value to the block. An hypothetical associationsCollect: would do associationsCollect: aBlock | d | d := Dictionary new. self associationsDo: [ :assoc | d add: (aBlock value: assoc) ] and I have nothing against it. :-) Paolo |
In reply to this post by Nicolas Cellier-3
On Saturday 14 Jun 2008 12:36:54 am nicolas cellier wrote:
> tim Rowledge a écrit : > > Dictionary>do: etc work on the values of the associations. #collect: > > should continue the pattern. #associationsDo: etc exist if you need to > > work with the associations. > > > > tim > > -- > > tim Rowledge; [hidden email]; http://www.rowledge.org/tim > > Artificial Intelligence: Making computers behave like they do in the > > movies. > > Hi tim and Subbu, > you follow a certain historical logic. > But behaviour could be much simpler and homogeneous with ANSI POV. a collection. Returning a dictionary is a permitted 'refinement'. > Consider current state of Squeak: > > 1) select: and reject: already return a Dictionary This is a non-sequitur. select:/reject: are discriminators while collect: is a transformer. > Original st-80 logic would have been to answer a Bag, nothing else. :-/. In ST-80, Dictionary isa Set isa Collection while Bag isa Collection. You meant a Set, perhaps? [1] http://wiki.squeak.org/squeak/uploads/172/standard_v1_9-indexed.pdf Subbu |
In reply to this post by Paolo Bonzini-2
On Saturday 14 Jun 2008 6:03:34 am Paolo Bonzini wrote:
> > associationsCollect: aBlock > > ... > > self associationsDo: [ :assoc | d nextPut: assoc key -> (aBlock > > value: assoc > > value) ]. > > would be very wrong, because associationsSomething: messages work on > associations, while your message passes only the value to the block. An > hypothetical associationsCollect: would do > > associationsCollect: aBlock > | d | > d := Dictionary new. > self associationsDo: [ :assoc | d add: (aBlock value: assoc) ] as we are not changing the keys, only replacing the values associated with the keys. Now we have three ways of defining collect: on a dictionary - values alone, on the value part of associations, and on associations. Subbu |
On 14.06.2008, at 08:26, K. K. Subramaniam wrote: > On Saturday 14 Jun 2008 6:03:34 am Paolo Bonzini wrote: >>> associationsCollect: aBlock >>> ... >>> self associationsDo: [ :assoc | d nextPut: assoc key -> >>> (aBlock >>> value: assoc >> >> value) ]. >> >> would be very wrong, because associationsSomething: messages work on >> associations, while your message passes only the value to the >> block. An >> hypothetical associationsCollect: would do >> >> associationsCollect: aBlock >> | d | >> d := Dictionary new. >> self associationsDo: [ :assoc | d add: (aBlock value: >> assoc) ] > I did write it this way initially but then it appeared like an > overkill to me > as we are not changing the keys, only replacing the values > associated with > the keys. > > Now we have three ways of defining collect: on a dictionary - values > alone, > on the value part of associations, and on associations. Shouldn't "associationsCollect:" be equivalent to "associations collect:"? - Bert - |
In reply to this post by K. K. Subramaniam
K. K. Subramaniam a écrit :
> On Saturday 14 Jun 2008 12:36:54 am nicolas cellier wrote: >> tim Rowledge a écrit : >>> Dictionary>do: etc work on the values of the associations. #collect: >>> should continue the pattern. #associationsDo: etc exist if you need to >>> work with the associations. >>> >>> tim >>> -- >>> tim Rowledge; [hidden email]; http://www.rowledge.org/tim >>> Artificial Intelligence: Making computers behave like they do in the >>> movies. >> Hi tim and Subbu, >> you follow a certain historical logic. >> But behaviour could be much simpler and homogeneous with ANSI POV. > ANSI v1.9 [1] treats collect: as a transformer and only requires it to return > a collection. Returning a dictionary is a permitted 'refinement'. > >> Consider current state of Squeak: >> >> 1) select: and reject: already return a Dictionary > This is a non-sequitur. select:/reject: are discriminators while collect: is a > transformer. > >> Original st-80 logic would have been to answer a Bag, nothing else. > :-/. In ST-80, Dictionary isa Set isa Collection while Bag isa Collection. You > meant a Set, perhaps? > > [1] http://wiki.squeak.org/squeak/uploads/172/standard_v1_9-indexed.pdf > No, I mean Bag. Dictionary keys are a Set, but values don't have to be unique. If you have the blue book or a st80 available, check what values was originally returning. > Subbu > > |
In reply to this post by K. K. Subramaniam
> Now we have three ways of defining collect: on a dictionary - values alone, > on the value part of associations, and on associations. Associations are just an implementation detail. Dictionaries are just collections of values with an externally-defined keys. Paolo |
In reply to this post by Bert Freudenberg
On Saturday 14 Jun 2008 3:02:03 pm Bert Freudenberg wrote:
> Shouldn't "associationsCollect:" be equivalent to "associations > collect:"? If both key and its value are being transformed by aBlock, yes. If only the values are being changed with the keys remaining same (e.g. translating english words to french) then we could avoid key lookups for every add. Subbu |
In reply to this post by Nicolas Cellier-3
On Saturday 14 Jun 2008 11:50:27 pm nicolas cellier wrote:
> No, I mean Bag. > Dictionary keys are a Set, but values don't have to be unique. > If you have the blue book or a st80 available, check what values was > originally returning. Ha, I see what you mean. The values of a Dictionary are indeed a Bag. I got confused because the original poster was expecting to retain the keys in the result. Perhaps, I should cut down on my late night sessions :-). Thank you for your patience, Subbu |
Free forum by Nabble | Edit this page |