Is there any difference with #do: ?
If not, I suggest deprecating #valuesDo: More other, browsing #values senders, this pattern: aDictionary values do: [:aValue | self doSomethingWith: aValue]. can often be replaced with: aDictionary do: [:aValue | self doSomethingWith: aValue]. except of course when aDictionary is modified inside the loop. Nicolas |
Traditionally in st80, #keys returns a Set of keys, and #values a Bag
of values... Rationale: none of them is ordered. Now I noticed squeak #values returns an Array, and wondered why by analyzing senders. Most of them are superfluous, and maybe this will explain latest wave of commits in the trunk. Now I find the idea of answering an Array a good one, - because it is faster than a Bag (no lookup) - for historical reasons, some senders expect a SequenceableCollection, - while no senders seems to rely on a Bag protocol Others think the same should apply to keys, because of speed too, and because of rare expectation of Set specific protocol. This is #fasterKeys. What do squeakers think ? Shouldn't we do to the #keys what we did to the #values ? Nicolas 2009/10/19 Nicolas Cellier <[hidden email]>: > Is there any difference with #do: ? > If not, I suggest deprecating #valuesDo: > > More other, browsing #values senders, this pattern: > aDictionary values do: [:aValue | self doSomethingWith: aValue]. > can often be replaced with: > aDictionary do: [:aValue | self doSomethingWith: aValue]. > except of course when aDictionary is modified inside the loop. > > Nicolas > |
So I gave it a try with a bunch of commits
(ouch, commiting is longer than editing!) I used #fasterKeys because the message already exist. I cannot change keys directly, a few senders really expect a Set (plus external packages...) Reverting is easy, just change senders of fasterKeys -> keys, or force load of packages from update-nice.40.mcm. Nicolas 2009/10/19 Nicolas Cellier <[hidden email]>: > Traditionally in st80, #keys returns a Set of keys, and #values a Bag > of values... > Rationale: none of them is ordered. > Now I noticed squeak #values returns an Array, and wondered why by > analyzing senders. > Most of them are superfluous, and maybe this will explain latest wave > of commits in the trunk. > > Now I find the idea of answering an Array a good one, > - because it is faster than a Bag (no lookup) > - for historical reasons, some senders expect a SequenceableCollection, > - while no senders seems to rely on a Bag protocol > > Others think the same should apply to keys, because of speed too, and > because of rare expectation of Set specific protocol. > This is #fasterKeys. > What do squeakers think ? Shouldn't we do to the #keys what we did to > the #values ? > > Nicolas > > 2009/10/19 Nicolas Cellier <[hidden email]>: >> Is there any difference with #do: ? >> If not, I suggest deprecating #valuesDo: >> >> More other, browsing #values senders, this pattern: >> aDictionary values do: [:aValue | self doSomethingWith: aValue]. >> can often be replaced with: >> aDictionary do: [:aValue | self doSomethingWith: aValue]. >> except of course when aDictionary is modified inside the loop. >> >> Nicolas >> > |
Hi Nicolas -
I agree with your (original) reasoning that keys should return an array just like values. Not only because of performance, but also because it preserves ordering between keys and values making "aDict keys with: aDict values do:" nicely symmetrical to "aDict keysAndValuesDo:". Nicolas Cellier wrote: > So I gave it a try with a bunch of commits > (ouch, commiting is longer than editing!) > > I used #fasterKeys because the message already exist. > I cannot change keys directly, a few senders really expect a Set (plus > external packages...) Which ones are those? I do dislike the idea of using fasterKeys. It's a bad name (like using #valuesWithOrder instead of #values) and unless the difficulties with the change are systematic (i.e., usage patterns that are not easily detected and lead to hidden and hard to find issues) I would much rather see this fixed than worked around. Can you provide some examples of places that break? Cheers, - Andreas |
2009/10/20 Andreas Raab <[hidden email]>:
> Hi Nicolas - > > I agree with your (original) reasoning that keys should return an array just > like values. Not only because of performance, but also because it preserves > ordering between keys and values making "aDict keys with: aDict values do:" > nicely symmetrical to "aDict keysAndValuesDo:". > > Nicolas Cellier wrote: >> >> So I gave it a try with a bunch of commits >> (ouch, commiting is longer than editing!) >> >> I used #fasterKeys because the message already exist. >> I cannot change keys directly, a few senders really expect a Set (plus >> external packages...) > > Which ones are those? I do dislike the idea of using fasterKeys. It's a bad > name (like using #valuesWithOrder instead of #values) and unless the > difficulties with the change are systematic (i.e., usage patterns that are > not easily detected and lead to hidden and hard to find issues) I would much > rather see this fixed than worked around. > Totally agree about the bad name ! My plan was to use this name in an interim period, gradually handle special cases of methods expecting a Set, change keys to behave as fasterKeys, then deprecate message fasterKeys. > Can you provide some examples of places that break? > Look among 49 remaining senders of keys, a few use usage like #selectors do. Nicolas > Cheers, > - Andreas > > |
In reply to this post by Andreas.Raab
On 20.10.2009, at 06:54, Andreas Raab wrote: > Hi Nicolas - > > I agree with your (original) reasoning that keys should return an > array just like values. Not only because of performance, but also > because it preserves ordering between keys and values making "aDict > keys with: aDict values do:" nicely symmetrical to "aDict > keysAndValuesDo:". > > Nicolas Cellier wrote: >> So I gave it a try with a bunch of commits >> (ouch, commiting is longer than editing!) >> I used #fasterKeys because the message already exist. >> I cannot change keys directly, a few senders really expect a Set >> (plus >> external packages...) > > Which ones are those? I do dislike the idea of using fasterKeys. > It's a bad name (like using #valuesWithOrder instead of #values) and > unless the difficulties with the change are systematic (i.e., usage > patterns that are not easily detected and lead to hidden and hard to > find issues) I would much rather see this fixed than worked around. > > Can you provide some examples of places that break? > > Cheers, > - Andreas Yes, #fasterKeys is ugly. I'd rather replace the places that need a Set with "keys asSet". Unless ANSI says differently - could someone check? - Bert - |
2009/10/20 Bert Freudenberg <[hidden email]>:
> > On 20.10.2009, at 06:54, Andreas Raab wrote: > >> Hi Nicolas - >> >> I agree with your (original) reasoning that keys should return an array >> just like values. Not only because of performance, but also because it >> preserves ordering between keys and values making "aDict keys with: aDict >> values do:" nicely symmetrical to "aDict keysAndValuesDo:". >> >> Nicolas Cellier wrote: >>> >>> So I gave it a try with a bunch of commits >>> (ouch, commiting is longer than editing!) >>> I used #fasterKeys because the message already exist. >>> I cannot change keys directly, a few senders really expect a Set (plus >>> external packages...) >> >> Which ones are those? I do dislike the idea of using fasterKeys. It's a >> bad name (like using #valuesWithOrder instead of #values) and unless the >> difficulties with the change are systematic (i.e., usage patterns that are >> not easily detected and lead to hidden and hard to find issues) I would much >> rather see this fixed than worked around. >> >> Can you provide some examples of places that break? >> >> Cheers, >> - Andreas > > Yes, #fasterKeys is ugly. I'd rather replace the places that need a Set with > "keys asSet". Unless ANSI says differently - could someone check? > > - Bert - > That's what it will turn into... OK, I realize we should better attack the problem under this angle: 1) modify senders expecting a Set keys -> keys asSet 2) change keys implentation -> faster keys implementation I can do this this evening, unless there is another taker Nicolas |
In reply to this post by Nicolas Cellier
Nicolas Cellier wrote:
>> Can you provide some examples of places that break? > > Look among 49 remaining senders of keys, a few use usage like #selectors do. Looking through this, nothing springs to mind that would break. Even places like, e.g., aClass selectors includes: aSelector should continue to work with the one possible exception that in cases where IdentityDictionary keys are used the resulting collection should compare identity not equality, which would be a problem if there were code that expects e.g., Object selectors includes: 'yourself' => false. (that seems rare) But other than that I don't really see anything that would break with the change. Have you tried making the change and just run all the tests to see which ones break and why? Cheers, - Andreas |
In reply to this post by Bert Freudenberg
On Tue, Oct 20, 2009 at 1:49 AM, Bert Freudenberg <[hidden email]> wrote:
You're in the clear. Here's the relevant screed from my draft standard:
Protocol: <abstractDictionary XE "abstractDictionary" > Conforms To <collection> Description Provides protocol for accessing, adding, removing, and iterating over the elements of an unordered collection whose elements are accessed using an explicitly assigned external key. Glossary Entries Messages addAll: at: at:ifAbsent: at:ifAbsentPut: at:put: collect: includesKey: keyAtValue: keyAtValue:ifAbsent: keys keysAndValuesDo: keysDo: reject: removeAllKeys: removeAllKeys:ifAbsent: removeKey: removeKey:ifAbsent: select: values ... Message: keys Synopsis Answer a collection of keys at which there is an element stored in the receiver. Definition: <abstractDictionary> Answer a collection of all the keys in the receiver. The size of the result is equal to the size of the receiver. Return Values <collection> unspecified Errors none There are also places where the standard explicitly denotes something as unspecified. Most notably, the protocol section allows an unspecified return value. The specifics of such features are not defined by the standard although some reasonable behavior is required. Conforming implementation must support the feature but need not documented the details of the implementation. A Smalltalk program conforms to the standard if it only makes use of features defined in the standard. It may use implementation-defined features or unspecified features and still be considered a conforming program, though doing so may limit the program's portability.
|
In reply to this post by Andreas.Raab
well, among 49 senders of keys, I see very few problem:
Bag>>#asSet obviously Behavior>>#selector the comment tells Set, but is it necessary ? among 92 usages of selectors basicLocalSelectors: aSetOrNil localSelectors := aSetOrNil traits ? didn't try to follow further some will use remove which is not an Array protocol (removeAllFoundIn: from #replaceSilently:to:) some usages like class selectors includes: will be a bit less efficient #classVarNames comment tells a Set, though code would behave as well with a sorted collection... some = test might not work if collection is arbitrarily ordered (tempRefs keys = method startpcsToBlockExtents values asSet) ImageSegment findRogueRootsRefStrm: will use remove: A few asSet should be necessary. Nicolas 2009/10/20 Andreas Raab <[hidden email]>: > Nicolas Cellier wrote: >>> >>> Can you provide some examples of places that break? >> >> Look among 49 remaining senders of keys, a few use usage like #selectors >> do. > > Looking through this, nothing springs to mind that would break. Even places > like, e.g., aClass selectors includes: aSelector should continue to work > with the one possible exception that in cases where IdentityDictionary keys > are used the resulting collection should compare identity not equality, > which would be a problem if there were code that expects e.g., Object > selectors includes: 'yourself' => false. (that seems rare) > > But other than that I don't really see anything that would break with the > change. Have you tried making the change and just run all the tests to see > which ones break and why? > > Cheers, > - Andreas > > |
So my plan is currently:
- track #keys usage, and use #asSet where due to be future proof - this involves inquiring some keys senders like selectors and classVarNames - publish a mcm - change keys to behave like fasterKeys - publish a mcm - revert fasterKeys senders to just send keys (except the bug I found, and a few #sort shortcuts) Don't know if feasible in one evening... 2009/10/20 Nicolas Cellier <[hidden email]>: > well, among 49 senders of keys, I see very few problem: > > Bag>>#asSet obviously > Behavior>>#selector the comment tells Set, but is it necessary ? > > among 92 usages of selectors > > basicLocalSelectors: aSetOrNil > localSelectors := aSetOrNil > traits ? didn't try to follow further > > some will use remove which is not an Array protocol (removeAllFoundIn: > from #replaceSilently:to:) > > some usages like class selectors includes: will be a bit less efficient > > #classVarNames comment tells a Set, though code would behave as well > with a sorted collection... > > some = test might not work if collection is arbitrarily ordered > (tempRefs keys = method startpcsToBlockExtents values asSet) > > ImageSegment findRogueRootsRefStrm: will use remove: > > A few asSet should be necessary. > > Nicolas > > > 2009/10/20 Andreas Raab <[hidden email]>: >> Nicolas Cellier wrote: >>>> >>>> Can you provide some examples of places that break? >>> >>> Look among 49 remaining senders of keys, a few use usage like #selectors >>> do. >> >> Looking through this, nothing springs to mind that would break. Even places >> like, e.g., aClass selectors includes: aSelector should continue to work >> with the one possible exception that in cases where IdentityDictionary keys >> are used the resulting collection should compare identity not equality, >> which would be a problem if there were code that expects e.g., Object >> selectors includes: 'yourself' => false. (that seems rare) >> >> But other than that I don't really see anything that would break with the >> change. Have you tried making the change and just run all the tests to see >> which ones break and why? >> >> Cheers, >> - Andreas >> >> > |
2009/10/20 Nicolas Cellier <[hidden email]>:
> So my plan is currently: > > - track #keys usage, and use #asSet where due to be future proof > - this involves inquiring some keys senders like selectors and classVarNames done, I added very few asSet and I changed classVarNames messages to return a sorted Array. Hope it works OK (no add: no remove: ). Note that sorted Array do compare well with equality = > - publish a mcm update-nice.40.mcm > - change keys to behave like fasterKeys > - publish a mcm Done, but the server just lost update-nice.41.mcm ... > - revert fasterKeys senders to just send keys (except the bug I found, > and a few #sort shortcuts) Note: I kept (x keys asArray sort) rather than just (x keys sort) just for compatibility issues. - publish a mcm update-nice.42.mcm but now that update-nice.41.mcm disappeared, I don't know if it will work OK - deprecate #fasterKeys Done with my contract Now we just have to chase the eventual bugs... Nicolas > > Don't know if feasible in one evening... > > 2009/10/20 Nicolas Cellier <[hidden email]>: >> well, among 49 senders of keys, I see very few problem: >> >> Bag>>#asSet obviously >> Behavior>>#selector the comment tells Set, but is it necessary ? >> >> among 92 usages of selectors >> >> basicLocalSelectors: aSetOrNil >> localSelectors := aSetOrNil >> traits ? didn't try to follow further >> >> some will use remove which is not an Array protocol (removeAllFoundIn: >> from #replaceSilently:to:) >> >> some usages like class selectors includes: will be a bit less efficient >> >> #classVarNames comment tells a Set, though code would behave as well >> with a sorted collection... >> >> some = test might not work if collection is arbitrarily ordered >> (tempRefs keys = method startpcsToBlockExtents values asSet) >> >> ImageSegment findRogueRootsRefStrm: will use remove: >> >> A few asSet should be necessary. >> >> Nicolas >> >> >> 2009/10/20 Andreas Raab <[hidden email]>: >>> Nicolas Cellier wrote: >>>>> >>>>> Can you provide some examples of places that break? >>>> >>>> Look among 49 remaining senders of keys, a few use usage like #selectors >>>> do. >>> >>> Looking through this, nothing springs to mind that would break. Even places >>> like, e.g., aClass selectors includes: aSelector should continue to work >>> with the one possible exception that in cases where IdentityDictionary keys >>> are used the resulting collection should compare identity not equality, >>> which would be a problem if there were code that expects e.g., Object >>> selectors includes: 'yourself' => false. (that seems rare) >>> >>> But other than that I don't really see anything that would break with the >>> change. Have you tried making the change and just run all the tests to see >>> which ones break and why? >>> >>> Cheers, >>> - Andreas >>> >>> >> > |
I wonder, if its a feasible to make a proxies which instead of
creating a separate collection will direct the requests to dictionary, i.e.: Set subclass: #DictionaryKeys instanceVariableNames: 'dict' ... then: Dictionary>>keys ^ DictionaryKeys on: self same for values. Any #asXXX methods should instantiate new collection. But any iterations, like #do: etc.. should use dictionary. 2009/10/21 Nicolas Cellier <[hidden email]>: > 2009/10/20 Nicolas Cellier <[hidden email]>: >> So my plan is currently: >> >> - track #keys usage, and use #asSet where due to be future proof >> - this involves inquiring some keys senders like selectors and classVarNames > > done, I added very few asSet > and I changed classVarNames messages to return a sorted Array. Hope it > works OK (no add: no remove: ). > Note that sorted Array do compare well with equality = > >> - publish a mcm > > update-nice.40.mcm > >> - change keys to behave like fasterKeys >> - publish a mcm > > Done, but the server just lost update-nice.41.mcm ... > >> - revert fasterKeys senders to just send keys (except the bug I found, >> and a few #sort shortcuts) > Note: I kept (x keys asArray sort) rather than just (x keys sort) just > for compatibility issues. > > - publish a mcm > > update-nice.42.mcm but now that update-nice.41.mcm disappeared, I > don't know if it will work OK > > - deprecate #fasterKeys > > Done with my contract > > Now we just have to chase the eventual bugs... > > Nicolas > > >> >> Don't know if feasible in one evening... >> >> 2009/10/20 Nicolas Cellier <[hidden email]>: >>> well, among 49 senders of keys, I see very few problem: >>> >>> Bag>>#asSet obviously >>> Behavior>>#selector the comment tells Set, but is it necessary ? >>> >>> among 92 usages of selectors >>> >>> basicLocalSelectors: aSetOrNil >>> localSelectors := aSetOrNil >>> traits ? didn't try to follow further >>> >>> some will use remove which is not an Array protocol (removeAllFoundIn: >>> from #replaceSilently:to:) >>> >>> some usages like class selectors includes: will be a bit less efficient >>> >>> #classVarNames comment tells a Set, though code would behave as well >>> with a sorted collection... >>> >>> some = test might not work if collection is arbitrarily ordered >>> (tempRefs keys = method startpcsToBlockExtents values asSet) >>> >>> ImageSegment findRogueRootsRefStrm: will use remove: >>> >>> A few asSet should be necessary. >>> >>> Nicolas >>> >>> >>> 2009/10/20 Andreas Raab <[hidden email]>: >>>> Nicolas Cellier wrote: >>>>>> >>>>>> Can you provide some examples of places that break? >>>>> >>>>> Look among 49 remaining senders of keys, a few use usage like #selectors >>>>> do. >>>> >>>> Looking through this, nothing springs to mind that would break. Even places >>>> like, e.g., aClass selectors includes: aSelector should continue to work >>>> with the one possible exception that in cases where IdentityDictionary keys >>>> are used the resulting collection should compare identity not equality, >>>> which would be a problem if there were code that expects e.g., Object >>>> selectors includes: 'yourself' => false. (that seems rare) >>>> >>>> But other than that I don't really see anything that would break with the >>>> change. Have you tried making the change and just run all the tests to see >>>> which ones break and why? >>>> >>>> Cheers, >>>> - Andreas >>>> >>>> >>> >> > > -- Best regards, Igor Stasenko AKA sig. |
Free forum by Nabble | Edit this page |