[squeak-dev] #species vs OrderedColleciton

Tobias Pape Das.Linux at gmx.de
Tue Dec 27 18:37:06 UTC 2016


On 27.12.2016, at 18:01, Levente Uzonyi <leves at caesar.elte.hu> wrote:

> On Tue, 27 Dec 2016, Tobias Pape wrote:
> 
>> 
>> On 27.12.2016, at 17:45, Levente Uzonyi <leves at caesar.elte.hu> wrote:
>> 
>>> On Tue, 27 Dec 2016, Tobias Pape wrote:
>>>> On 25.12.2016, at 17:09, Levente Uzonyi <leves at caesar.elte.hu> wrote:
>>>>> Hi All,
>>>>> We had a discussion[1] about #species, in the context of Sets and IdentitySets, and its multiple roles which it cannot fulfill[2].
>>>>> A similar issue arises in case of OrderedCollection and its subclasses, but with a smoother resolution, because an OrderedCollection is always an acceptable result (for #collect:).
>>>>> So, I suggest we should change OrderedCollection >> #collect: to always return an OrderedCollection. This change obviously would not affect OrderedCollection, but we already have the same override in SortedCollection.
>>>>> Example:
>>>>> Currently the following raises and error:
>>>>> 
>>>>> 	(FloatCollection withAll: #(1 2 3)) collect: #asString
>>>>> Of course, #collect:as: works as expected:
>>>>> 
>>>>> 	(FloatCollection withAll: #(1 2 3)) collect: #asString as: OrderedCollection
>>>>> 	"==> an OrderedCollection('1.0' '2.0' '3.0')"
>>>>> So, why not make #collect: behave the same way?
>>>>> This change would make #species not being used in #collect:, which is similar to the solution we have in Set and subclasses.
>>>>> Currently #select: and #copyEmpty also use #species, but no class implements #species in the hierarchy. So, changing #species to return OrderedCollection would have unwanted side effects. (This also shows that #species doesn't solve anything here.)
>>>>> Any objections?
>>>> Just a question for clarification, would
>>>> 
>>>> 	(FloatCollection withAll: #(1.0 2.0 3.0)) collect: [:ea | ea sqrt]
>>>> result in a FloatCollection or in an OrderedCollection?
>>> An OrderedCollection of course. #collect: would always return an OrderedCollection.
>> 
>> Ok, so to make good use of FloatCollections in the first place i would have to always use collect:as: to _stay within_ the class? I somehow do not like that :(. I'd rather have to stay
> 
> So you'd rather have the errors?

Yes, sure. FloatCollection withAll: #('1.0' '2.0' '3.0') raises an error too. The result is just not fitted for the storage.

> 
>> as much as possible with the closure property for large parts of the collection API.
> 
> What's the "closure property"?

Roughly, "If you apply Operation x to a thing y, and the result always stays within the domain of y, then (the domain of) y is closed under x".

Examples: The real numbers are closed under addition, as are the integers. 
But while the real numbers are closed under division, integers are not.

In scheme, 'cons' is closed under 'map'.

Most of our collections are closed under #collect:, #select:, #reject:.

> 
>> 
>> Whats wrong with species -> class, and collect: staying within the class?
> 
> Did you try the example in my first post?
> 
> species -> class would do nothing, because, as I mentioned in my original post, species is not overridden anywhere in the class hierarchy.

I meant retaining  the species -> class that is inherited from object.

> 
>> We got several specialized collections, I don't want a buch of collectFloat: collectInteger: collectShortPoint: for each and every class.
> 
> Why would such methods ever appear? Have you seen anything like that anywere?

Because I assume that 'closed' usage of collect is the more common usage[1], and sooner or later,
we would have FloatCollection>>collectFloat: next to collect:, and SortedCollection>>collectSorted: next to collect:, and 
GraphicSymbol probably would break with just few people noticeing.

And why should a WeakOrderedCollection return something 'strong' after a collect?

Also, the symmetry between FloatArray and FloatCollection would break:

(FloatCollection withAll: #(1.0 2.0 3.0)) collect: [:ea | ea sqrt]  "a FloatCollection(1.0 1.4142135381698608 1.7320507764816284)"
(FloatArray withAll: #(1.0 2.0 3.0)) collect: [:ea | ea sqrt] "a FloatArray(1.0 1.4142135381698608 1.7320507764816284)"

Best regards
	-Tobias


[1]: maybe except for #asString, but that's debugging. Maybe we should introduce Collection>>#allAsString ?


More information about the Squeak-dev mailing list