A new version of Collections was added to project The Inbox:
http://source.squeak.org/inbox/Collections-mt.852.mcz ==================== Summary ==================== Name: Collections-mt.852 Author: mt Time: 6 September 2019, 4:57:45.245608 pm UUID: 3582be1c-a006-ed46-a517-3d2d570db6cc Ancestors: Collections-mt.851 Proposal: Initialize a new collection with a computation block without needing an existing collection to #collect: from. OrderedCollection new: 20 filledWith: [100 atRandom]. Thanks to Christoph (ct) for the idea. If we want this in Trunk, there will be tests. :-) =============== Diff against Collections-mt.851 =============== Item was added: + ----- Method: ArrayedCollection class>>new:filledWith: (in category 'instance creation') ----- + new: size filledWith: aBlock + "Similar to #collect:as: and #fillFrom:with: but uses only the interval (1 to: size) to fill the collection. Different compared to #new:withAll: because aBlock can return different values for each index." + + | result | + result := self new: size. + 1 to: size do: [:each | result at: each put: (aBlock cull: each)]. + ^ result! Item was added: + ----- Method: Collection class>>new:filledWith: (in category 'instance creation') ----- + new: size filledWith: aBlock + "Similar to #collect:as: and #fillFrom:with: but uses only the interval (1 to: size) to fill the collection. Different compared to #new:withAll: because aBlock can return different values for each index." + + | result | + result := self new: size. + 1 to: size do: [:each | result add: (aBlock cull: each)]. + ^ result! |
Hi, all. Any thoughts on this matter? Here are more examples: OrderedCollection new: 20 filledWith: [100 atRandom]. Set new: 20 filledWith: [:ea | (ea + 32) asCharacter]. Dictionary new: 20 filledWith: [:ea | ea -> (ea + 32) asCharacter]. Further reading (for related naming and concepts): (all implementors of ...) #collect:as: #fillFrom:with: #newFrom: #new:withAll: Best, Marcel
|
> On 18.11.2019, at 15:00, Marcel Taeumel <[hidden email]> wrote: > > Hi, all. > > Any thoughts on this matter? Here are more examples: > > OrderedCollection new: 20 filledWith: [100 atRandom]. > Set new: 20 filledWith: [:ea | (ea + 32) asCharacter]. > Dictionary new: 20 filledWith: [:ea | ea -> (ea + 32) asCharacter]. > > Further reading (for related naming and concepts): > > (all implementors of ...) > #collect:as: > #fillFrom:with: > #newFrom: > #new:withAll: > Here's an example from the scheme/lisp world how they're using that: https://docs.racket-lang.org/reference/pairs.html?q=make-list#%28def._%28%28lib._racket%2Fprivate%2Flist..rkt%29._build-list%29%29 > Best, > Marcel >> Am 06.09.2019 16:57:53 schrieb [hidden email] <[hidden email]>: >> >> A new version of Collections was added to project The Inbox: >> http://source.squeak.org/inbox/Collections-mt.852.mcz >> >> ==================== Summary ==================== >> >> Name: Collections-mt.852 >> Author: mt >> Time: 6 September 2019, 4:57:45.245608 pm >> UUID: 3582be1c-a006-ed46-a517-3d2d570db6cc >> Ancestors: Collections-mt.851 >> >> Proposal: Initialize a new collection with a computation block without needing an existing collection to #collect: from. >> >> OrderedCollection new: 20 filledWith: [100 atRandom]. >> >> Thanks to Christoph (ct) for the idea. >> >> If we want this in Trunk, there will be tests. :-) >> >> =============== Diff against Collections-mt.851 =============== >> >> Item was added: >> + ----- Method: ArrayedCollection class>>new:filledWith: (in category 'instance creation') ----- >> + new: size filledWith: aBlock >> + "Similar to #collect:as: and #fillFrom:with: but uses only the interval (1 to: size) to fill the collection. Different compared to #new:withAll: because aBlock can return different values for each index." >> + >> + | result | >> + result := self new: size. >> + 1 to: size do: [:each | result at: each put: (aBlock cull: each)]. >> + ^ result! >> >> Item was added: >> + ----- Method: Collection class>>new:filledWith: (in category 'instance creation') ----- >> + new: size filledWith: aBlock >> + "Similar to #collect:as: and #fillFrom:with: but uses only the interval (1 to: size) to fill the collection. Different compared to #new:withAll: because aBlock can return different values for each index." >> + >> + | result | >> + result := self new: size. >> + 1 to: size do: [:each | result add: (aBlock cull: each)]. >> + ^ result! >> >> > |
In reply to this post by marcel.taeumel
+1
I don't know if there is a practical use case for new:filledWith: but I think that the examples you give are instructive. Suggestion - for the method comments, consider this: "Evaluate aBlock with integers from 1 to: size as the block argument. Collect the resulting values into a new collection." Dave On Mon, Nov 18, 2019 at 03:00:34PM +0100, Marcel Taeumel wrote: > Hi, all. > > Any thoughts on this matter? Here are more examples: > > OrderedCollection new: 20 filledWith: [100 atRandom]. > Set new: 20 filledWith: [:ea | (ea + 32) asCharacter]. > Dictionary new: 20 filledWith: [:ea | ea -> (ea + 32) asCharacter]. > > Further reading (for related naming and concepts): > > (all implementors of ...) > #collect:as: > #fillFrom:with: > #newFrom: > #new:withAll: > > Best, > Marcel > Am 06.09.2019 16:57:53 schrieb [hidden email] <[hidden email]>: > A new version of Collections was added to project The Inbox: > http://source.squeak.org/inbox/Collections-mt.852.mcz > > ==================== Summary ==================== > > Name: Collections-mt.852 > Author: mt > Time: 6 September 2019, 4:57:45.245608 pm > UUID: 3582be1c-a006-ed46-a517-3d2d570db6cc > Ancestors: Collections-mt.851 > > Proposal: Initialize a new collection with a computation block without needing an existing collection to #collect: from. > > OrderedCollection new: 20 filledWith: [100 atRandom]. > > Thanks to Christoph (ct) for the idea. > > If we want this in Trunk, there will be tests. :-) > > =============== Diff against Collections-mt.851 =============== > > Item was added: > + ----- Method: ArrayedCollection class>>new:filledWith: (in category 'instance creation') ----- > + new: size filledWith: aBlock > + "Similar to #collect:as: and #fillFrom:with: but uses only the interval (1 to: size) to fill the collection. Different compared to #new:withAll: because aBlock can return different values for each index." > + > + | result | > + result := self new: size. > + 1 to: size do: [:each | result at: each put: (aBlock cull: each)]. > + ^ result! > > Item was added: > + ----- Method: Collection class>>new:filledWith: (in category 'instance creation') ----- > + new: size filledWith: aBlock > + "Similar to #collect:as: and #fillFrom:with: but uses only the interval (1 to: size) to fill the collection. Different compared to #new:withAll: because aBlock can return different values for each index." > + > + | result | > + result := self new: size. > + 1 to: size do: [:each | result add: (aBlock cull: each)]. > + ^ result! > > > |
In reply to this post by marcel.taeumel
On Mon, 18 Nov 2019, Marcel Taeumel wrote:
> Hi, all. > Any thoughts on this matter? Here are more examples: > > OrderedCollection new: 20 filledWith: [100 atRandom]. > Set new: 20 filledWith: [:ea | (ea + 32) asCharacter]. > Dictionary new: 20 filledWith: [:ea | ea -> (ea + 32) asCharacter]. > > Further reading (for related naming and concepts): > > (all implementors of ...) > #collect:as: > #fillFrom:with: > #newFrom: > #new:withAll: #fillFrom:with: is a private method which exists to support #collect:as: and #collect:into:. I just noticed that there's a third user: #any:as:. Levente > > Best, > Marcel > > Am 06.09.2019 16:57:53 schrieb [hidden email] <[hidden email]>: > > A new version of Collections was added to project The Inbox: > http://source.squeak.org/inbox/Collections-mt.852.mcz > > ==================== Summary ==================== > > Name: Collections-mt.852 > Author: mt > Time: 6 September 2019, 4:57:45.245608 pm > UUID: 3582be1c-a006-ed46-a517-3d2d570db6cc > Ancestors: Collections-mt.851 > > Proposal: Initialize a new collection with a computation block without needing an existing collection to #collect: from. > > OrderedCollection new: 20 filledWith: [100 atRandom]. > > Thanks to Christoph (ct) for the idea. > > If we want this in Trunk, there will be tests. :-) > > =============== Diff against Collections-mt.851 =============== > > Item was added: > + ----- Method: ArrayedCollection class>>new:filledWith: (in category 'instance creation') ----- > + new: size filledWith: aBlock > + "Similar to #collect:as: and #fillFrom:with: but uses only the interval (1 to: size) to fill the collection. Different compared to #new:withAll: because aBlock can return different values for each index." > + > + | result | > + result := self new: size. > + 1 to: size do: [:each | result at: each put: (aBlock cull: each)]. > + ^ result! > > Item was added: > + ----- Method: Collection class>>new:filledWith: (in category 'instance creation') ----- > + new: size filledWith: aBlock > + "Similar to #collect:as: and #fillFrom:with: but uses only the interval (1 to: size) to fill the collection. Different compared to #new:withAll: because aBlock can return different values for each index." > + > + | result | > + result := self new: size. > + 1 to: size do: [:each | result add: (aBlock cull: each)]. > + ^ result! > > > > |
In reply to this post by commits-2
They share the same selector API, but for ArrayedCollection's, it culls integers 1 to: n, while for non-Arrayed, it culls nil over and over. This means the sender will have to know whether it's Arrayed or not anyway (otherwise you'd need a nil check inside the loop). And so, if you have to know that, one could just write classic Smalltalk. (1 to: 20) collect: [ :i | ... ] (with or without an "as:" converter on the end). OTOH, if you were expecting a non-arrayed collection, then simply: Array streamContents: [ : stream | ... ] I do appreciate the readability for people less experienced with Smalltalk, but for the long run, classic, readable, portable Smalltalk may actually be the better way for them to read it. Collecting nil over and over could be a sign of something not fully optimized here. -1 on this one, even though I'm really enjoying many of your other contributions, Christoph. Best, Chris On Fri, Sep 6, 2019 at 9:57 AM <[hidden email]> wrote: A new version of Collections was added to project The Inbox: |
On Tue, Nov 19, 2019 at 10:58 PM Chris Muller <[hidden email]> wrote:
Woops, I got that wrong, sorry. It is the index in both cases, not nil. That's better but, still, I'm sure I would just write collect:as: without remembering this. - Chris
|
Hi, all. What's the "most idiomatic" way to create an array with 100 random numbers > 0 < 100? (1 to: 100) collect: [:ea | 100 atRandom] Array streamContents: [:s | 100 timesRepeat: [s nextPut: 100 atRandom]]. ... Best, Marcel
|
Random new next: 100 Le mer. 20 nov. 2019 à 08:49, Marcel Taeumel <[hidden email]> a écrit :
|
Oups, that's not the same, but it was just to underline that Random generators already behaves like streams... With Xstreams, there is a very simple way to express such infinite stream generators [100 atRandom] reading read: 10 Otherwise, our own Generator is too complex. Le mer. 20 nov. 2019 à 08:57, Nicolas Cellier <[hidden email]> a écrit :
|
In reply to this post by Nicolas Cellier
Thanks! Still, I have to compute the numbers: (Random new next: 100) collect: [:ea | (ea * 100) truncated] Best, Marcel
|
In reply to this post by marcel.taeumel
What about? 20 timesCollect: [ 100 atRandom ] as: OrderedCollection It could use cull: to accept the :index argument, or not. It does seem that this (1 to: n) collect: [ :n| ...] has come up several times over the years, but not always in the context of instantiating a collection. Let's take a side-by-side look:
20 timesCollect: [ 100 atRandom ] as: OrderedCollection Hmm. Although the number of words and elements seems about the same, the order is different because the receiver is different. Even though I like the flexibility of #timesCollect:as: over #new:filledWith:, and also how it echoes #collect:as:, object construction is typically the responsibility of Classes, so, idiomatically, I think #new:filledWith: probably WOULD be found afterall (even if not by me because of my habits). I retract my -1. I do still like #timesCollect: for those other cases though, since it saves from needing to allocate the (1 to: n) Interval. Hm. Best, Chris On Wed, Nov 20, 2019 at 1:48 AM Marcel Taeumel <[hidden email]> wrote:
|
In reply to this post by marcel.taeumel
On Wed, Nov 20, 2019 at 08:48:50AM +0100, Marcel Taeumel wrote:
> Hi, all. > > What's the "most idiomatic" way to create an array with 100 random numbers > 0 < 100? > > (1 to: 100) collect: [:ea | 100 atRandom] > Array streamContents: [:s | 100 timesRepeat: [s nextPut: 100 atRandom]]. > ... > If "most idiomatic" means "functionally correct, easy to read, and easy to understand" then I prefer the first: (1 to: 100) collect: [:ea | 100 atRandom] I can read it from left to right, and it tells me that I am collecting 100 elements and putting 100 atRandom into each of the 100 elements. It's also simple, just a collect: and nothing more. Dave |
In reply to this post by marcel.taeumel
Yes, i push send button too fast. The Xstreams way translated in more familiar API would be: [100 atRandom] readStream next: 100. You could not choose the recipient class though... Le mer. 20 nov. 2019 à 09:13, Marcel Taeumel <[hidden email]> a écrit :
|
Free forum by Nabble | Edit this page |