collect: vs. to:do:
Bijan Parsia
bparsia at email.unc.edu
Fri Oct 20 18:44:08 UTC 2000
On Fri, 20 Oct 2000, Dan Winkler wrote:
> Thank you.
>
> That's interesting that collect: returns different classes of
> collections based on the class of the source collection. When would
> you want that behavior?
Er..all the time? #collect, #select, etc. return collection that is
"like" the receiver. Think of them as being like filter and map in Scheme.
> I see in this particular method, the next line allocates and Array
> explicitly. Is there a reason we want to let collect: decide the
> class of collection in the first line but use an Array in particular
> in the second line?
Dunno, what method are you looking at? Offhand, it's a little hard to
tell. I don't see any *harm* in using #collect: to initialize the Array in
the first case. As I wrote, maybe you'll want to modify it in the future.
You can't use Array class>>#new:withAll: because you'd end up with only
one OrderedCollectoin, which is clearly not what you want. You could have
a #new:withAllValuesFrom: or something, that took a block as it's second
arg, but I'm not seeing a huge gain here.
> allText _ pages collect: [:pg | OrderedCollection new].
> allTextUrls _ Array new: pages size.
>
> Would you say we should change the second line to:
>
> allTextUrls _ pages collect: [:pg | nil].
No that's silly, since all slots are niled by default. I *might* say
allTextUrls _ pages species new: pages size
*if* I thought that keeping all the colletions the same type were
important. For all I know, there's a reason to have allTextUrls be an
Array.
> As an old C programmer I'd be tempted to go the other way and force them both
> to be Arrays for compactness since I know they're not going to grow.
Do you? Is the compactness worth it?
Even if so, I'm still inclined to prefer the #collect: to any more verbose
version. I mean, what's the *clarity* gain?
allText _ pages species new: pages size.
"or, allText _ Array new: pages size."
"Gah! I imediately want to do a collect :))"
1 to: pages size do: [:i | allText at: i do: OrderedCollection new].
I *never* see this. So, I would *definitely say it's a Smalltalk
idiom. Frankly, I don't see a bit of clarity gained, and much lost.
After all, it's not like one is *confused* by the collect into thinking
it's somehow attending to the pages. It's perfectly *clear* what it's
doing and why (to initialize allText).
In the end, when it gets down to it, my rewrite is basically the
implementation of #collect:!
| newCollection |
newCollection _ self species new: self size.
1 to: self size do:
[:index |
newCollection at: index put: (aBlock value: (self
at: index))].
^ newCollection
Why not reuse it? (Follow the once and only once rule ;))
Cheers,
Bijan Parsia.
More information about the Squeak-dev
mailing list
|