#species vs OrderedColleciton

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

#species vs OrderedColleciton

Levente Uzonyi
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?


Levente

[1] http://lists.squeakfoundation.org/pipermail/squeak-dev/2014-November/180766.html
[2] http://lists.squeakfoundation.org/pipermail/squeak-dev/2014-November/180809.html

Reply | Threaded
Open this post in threaded view
|

Re: #species vs OrderedColleciton

Bert Freudenberg
On Sun, Dec 25, 2016 at 5:09 PM, Levente Uzonyi <[hidden email]> wrote:
So, I suggest we should change OrderedCollection >> #collect: to always return an OrderedCollection.

Sounds reasonable.

- Bert -


Reply | Threaded
Open this post in threaded view
|

Re: #species vs OrderedColleciton

Tobias Pape
In reply to this post by Levente Uzonyi

On 25.12.2016, at 17:09, Levente Uzonyi <[hidden email]> 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?

Best regards
        -Tobias

>
>
> Levente
>
> [1] http://lists.squeakfoundation.org/pipermail/squeak-dev/2014-November/180766.html
> [2] http://lists.squeakfoundation.org/pipermail/squeak-dev/2014-November/180809.html
>


Reply | Threaded
Open this post in threaded view
|

Re: #species vs OrderedColleciton

Levente Uzonyi
On Tue, 27 Dec 2016, Tobias Pape wrote:

>
> On 25.12.2016, at 17:09, Levente Uzonyi <[hidden email]> 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.

Levente

Reply | Threaded
Open this post in threaded view
|

Re: #species vs OrderedColleciton

Tobias Pape

On 27.12.2016, at 17:45, Levente Uzonyi <[hidden email]> wrote:

> On Tue, 27 Dec 2016, Tobias Pape wrote:
>
>>
>> On 25.12.2016, at 17:09, Levente Uzonyi <[hidden email]> 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
as much as possible with the closure property for large parts of the collection API.

Whats wrong with species -> class, and collect: staying within the class?
We got several specialized collections, I don't want a buch of collectFloat: collectInteger: collectShortPoint:
for each and every class.


Best regards
        -Tobas




Reply | Threaded
Open this post in threaded view
|

Re: #species vs OrderedColleciton

Levente Uzonyi
On Tue, 27 Dec 2016, Tobias Pape wrote:

>
> On 27.12.2016, at 17:45, Levente Uzonyi <[hidden email]> wrote:
>
>> On Tue, 27 Dec 2016, Tobias Pape wrote:
>>
>>>
>>> On 25.12.2016, at 17:09, Levente Uzonyi <[hidden email]> 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?

> as much as possible with the closure property for large parts of the collection API.

What's the "closure property"?

>
> 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.

> 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?

Levente

>
>
> Best regards
> -Tobas
>
>
>
>>
>> Levente
>>
>>>
>>> Best regards
>>> -Tobias
>>>
>>>> Levente
>>>> [1] http://lists.squeakfoundation.org/pipermail/squeak-dev/2014-November/180766.html
>>>> [2] http://lists.squeakfoundation.org/pipermail/squeak-dev/2014-November/180809.html

Reply | Threaded
Open this post in threaded view
|

Re: #species vs OrderedColleciton

Tobias Pape

On 27.12.2016, at 18:01, Levente Uzonyi <[hidden email]> wrote:

> On Tue, 27 Dec 2016, Tobias Pape wrote:
>
>>
>> On 27.12.2016, at 17:45, Levente Uzonyi <[hidden email]> wrote:
>>
>>> On Tue, 27 Dec 2016, Tobias Pape wrote:
>>>> On 25.12.2016, at 17:09, Levente Uzonyi <[hidden email]> 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 ?

Reply | Threaded
Open this post in threaded view
|

Re: #species vs OrderedColleciton

Levente Uzonyi
On Tue, 27 Dec 2016, Tobias Pape wrote:

>
> On 27.12.2016, at 18:01, Levente Uzonyi <[hidden email]> wrote:
>
>> On Tue, 27 Dec 2016, Tobias Pape wrote:
>>
>>>
>>> On 27.12.2016, at 17:45, Levente Uzonyi <[hidden email]> wrote:
>>>
>>>> On Tue, 27 Dec 2016, Tobias Pape wrote:
>>>>> On 25.12.2016, at 17:09, Levente Uzonyi <[hidden email]> 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:.

(Have you read the thread about IdentitySet >> #collect: I linked in my
original post?)
#select: and #reject: are very different from #collect:. Ignoring this
fact was one of the sources of the current problems with #species.
When you #select: or #reject: from a collection, you can't transform the
objects, only filter them.
When you #collect: from a collection, you can't filter the objects, but
you can transform them to anything.

So, what makes you think the result of #collect:'s argument should be the
same kind as its argument?

>
>>
>>>
>>> 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.

Oh. It's wrong, because, as my example showed, it doesn't work. Here's
another one in case you think it's only about #asString:

  (#(1 2 3) as: FloatCollection) collect: #asPoint

>
>>
>>> 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.

Uh. The way GraphicSymbol is implemented is a plain mistake. Subclassing
any Collection for no reason is a big no-no. Also, it's a variable
subclass for absolutely no reason; the slots are never used.
Fortunately that class is not used at all. To be removed.

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

The answer is the same as to the same question about WeakSet: the
collected objects may get GC'd before #collect: returns.

>
> 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)"

Another thing to fix. ;)

Levente

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