[squeak-dev] The Inbox: Collections-mt.938.mcz

Levente Uzonyi leves at caesar.elte.hu
Wed Apr 14 17:17:42 UTC 2021


Hi Marcel,

Due to the flaw of OrderedCollection >> #new:, the code won't work with 
OrderedCollections (and its subclasses).
This is the same issue Tim found with OrderedCollection and 
#streamContents: the other day.
The current workaround is to use #ofSize: instead of #new: to create a 
non-empty instance with the given capacity.
It would be great to change OrderedCollection class >> #new: to return a 
non-empty collection, and create a new method, e.g. #newWithCapacity: to 
create an empty collection with the given capacity, but I don't think it's 
possible to do that without breaking almost all existing programs out 
there.

The code won't work with LinkedList either because of the same reason. So, 
that class will need its own implementation.

The code also suffers from #collect:'s problem, which is its reliance on 
#species. #species is used for way too many things, and a single method 
cannot fit all those roles.
The fix for that is #collect:as:, which lets the user decide what the 
class of the result should be.
So, the question is: should there be #collect:as:separatedBy: too?


Levente

On Wed, 14 Apr 2021, commits at source.squeak.org wrote:

> A new version of Collections was added to project The Inbox:
> http://source.squeak.org/inbox/Collections-mt.938.mcz
>
> ==================== Summary ====================
>
> Name: Collections-mt.938
> Author: mt
> Time: 14 April 2021, 2:38:21.265628 pm
> UUID: d109bde4-42a6-e840-803c-e4e80b98a74d
> Ancestors: Collections-mt.937
>
> Proposal. Add a #joinSeparatedBy: that does not end up as a string.
>
> The current alternative would be #gather
> (#(1 2 3 4 5) gather: [:each | {each . $x}]) allButLast.
>
> Not sure whether a non-sequenceable version in Collection makes sense. We have had that discussion about #join etc. being not useful for uncertain output order.
>
> Some benchmarks:
>
> [ ((1 to: 1000) gather: [:num | {num . $x}]) allButLast ] bench.
> '22,000 per second. 45.5 microseconds per run. 13.09738 % GC time.'
>
> [ (1 to: 1000) collect: [:num | num] separatedBy: [$x] ] bench.
> '26,000 per second. 38.5 microseconds per run. 1.73965 % GC time.'
>
> =============== Diff against Collections-mt.937 ===============
>
> Item was added:
> + ----- Method: Collection>>collect:separatedBy: (in category 'enumerating') -----
> + collect: elementBlock separatedBy: separatorBlock
> + 	"Evaluate the elementBlock for all elements in the receiver, and evaluate the separatorBlock between. Collect the resulting values of both blocks into a collection like the receiver. Answer the new collection."
> + 
> + 	| newCollection |
> + 	newCollection := self species new.
> + 	self
> + 		do: [:each | newCollection add: (elementBlock value: each)]
> + 		separatedBy: [:each | newCollection add: separatorBlock value].
> + 	^ newCollection!
>
> Item was added:
> + ----- Method: SequenceableCollection>>collect:separatedBy: (in category 'enumerating') -----
> + collect: elementBlock separatedBy: separatorBlock
> + 	"Evaluate the elementBlock for all elements in the receiver, and evaluate the separatorBlock between. Collect the resulting values of both blocks into a collection like the receiver. Answer the new collection."
> + 
> + 	| newCollection |
> + 	newCollection := self species new: self size *2 -1.
> + 	1 to: self size do: [:index |
> + 		index = 1 ifFalse: [newCollection at: (index-1 *2) put: separatorBlock value].
> + 		newCollection at: (index-1 *2)+1 put: (elementBlock value: (self at: index))].
> + 	^ newCollection!


More information about the Squeak-dev mailing list