SortedCollection based on SortFunction [Re: SortedCollection>>reverse answers an inconsistent object]

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

SortedCollection based on SortFunction [Re: SortedCollection>>reverse answers an inconsistent object]

Denis Kudriashov
Hi.

Now we have really nice SortFunction's machinery. We can simply write:

Object allSubclasses sorted: #name ascending

instead of: 

Object allSubclasses sorted: [:a :b | a name <= b name ].

And there is special kind of SortFunction which represent such block itself: 

[:a :b | a name <= b name ] asSortFunction "==>  a CollatorBlockFunction".
 
The power of first class functions is that they provide reusable composition features like:

contacts sorted: #name ascending, #surname descending.
contacts sorted: (#name ascending, #surname descending) reversed.

(look at class comments for more examples).

It is all very cool and powerful but in the core Pharo still work with primitive blocks. 
All sorting methods and SortedCollection are implemented in terms of sortBlock.
So SortFunction's are adopted to block interface #value:value:.

And my proposal: 
Let's replace sortBlock by sortFunction everywhere. Block will still work but it will be converted to function.
It will open new possibilities to implement more features. 
For example SortedCollection>>reversed would be trivial with sortFunction (see previous thread).

Drawback is extra dependency in collections. But we can extract SortedCollection and related functions into separate package which probably will allow reduce bootstrapped codebase.

I am not going to implement it right now. Just want to share this idea to see what's wrong with it.

Best regards,
Denis
Reply | Threaded
Open this post in threaded view
|

Re: SortedCollection based on SortFunction [Re: SortedCollection>>reverse answers an inconsistent object]

Esteban A. Maringolo
I think sortfunctions are a great tool, with particular benefits if you
use it in the context of metamodels, like with Magritte descriptions.

Also I think it is more readable to use symbols/sortfunctions than blocks.

The only thing that should be guarded in the use of SortFunctions is the
handling of nil, a comparison with a nil object should fail noisily,
which currently doesn't by default AFAIR (I added the option to put nils
first or last in the resulting collection).

Note: Being myself an stubborn early optimizer I would make that
`SortedCollection new` returns a sorted collection with itself as the
default sortblock implementing #value:value: in SortedCollection. This
saves you from instantiating new objects other than the collection
itself for instances where sortblock is based on #<= as it currently is.

Regards,


On 25/04/2018 09:08, Denis Kudriashov wrote:

> Hi.
>
> Now we have really nice SortFunction's machinery. We can simply write:
>
>     Object allSubclasses sorted: #name ascending
>
> instead of: 
>
>     Object allSubclasses sorted: [:a :b | a name <= b name ].
>
> And there is special kind of SortFunction which represent such block
> itself: 
>
>
>     [:a :b | a name <= b name ] asSortFunction "==>  a
>     CollatorBlockFunction".
>
>  
> The power of first class functions is that they provide reusable
> composition features like:
>
>
>     contacts sorted: #name ascending, #surname descending.
>     contacts sorted: (#name ascending, #surname descending) reversed.
>
>
> (look at class comments for more examples).
>
> It is all very cool and powerful but in the core Pharo still work with
> primitive blocks. 
> All sorting methods and SortedCollection are implemented in terms of
> sortBlock.
> So SortFunction's are adopted to block interface #value:value:.
>
> And my proposal: 
> Let's replace sortBlock by sortFunction everywhere. Block will still
> work but it will be converted to function.
> It will open new possibilities to implement more features. 
> For example SortedCollection>>reversed would be trivial with
> sortFunction (see previous thread).
>
> Drawback is extra dependency in collections. But we can extract
> SortedCollection and related functions into separate package which
> probably will allow reduce bootstrapped codebase.
>
> I am not going to implement it right now. Just want to share this idea
> to see what's wrong with it.
>
> Best regards,
> Denis

--
Esteban A. Maringolo

Reply | Threaded
Open this post in threaded view
|

Re: SortedCollection based on SortFunction [Re: SortedCollection>>reverse answers an inconsistent object]

Denis Kudriashov
2018-04-25 14:57 GMT+02:00 Esteban A. Maringolo <[hidden email]>:
I think sortfunctions are a great tool, with particular benefits if you
use it in the context of metamodels, like with Magritte descriptions.

Also I think it is more readable to use symbols/sortfunctions than blocks.

The only thing that should be guarded in the use of SortFunctions is the
handling of nil, a comparison with a nil object should fail noisily,
which currently doesn't by default AFAIR (I added the option to put nils
first or last in the resulting collection).

Note: Being myself an stubborn early optimizer I would make that
`SortedCollection new` returns a sorted collection with itself as the
default sortblock implementing #value:value: in SortedCollection. This
saves you from instantiating new objects other than the collection
itself for instances where sortblock is based on #<= as it currently is.

+1 for default function in collection.

But I don't like solution. 
We have DefaultSortFunction for this. Only missing part is singleton instance:

SortedCollection>>new
^self sortBlock: DefaultSortFunction instance
 

Regards,


On 25/04/2018 09:08, Denis Kudriashov wrote:
> Hi.
>
> Now we have really nice SortFunction's machinery. We can simply write:
>
>     Object allSubclasses sorted: #name ascending
>
> instead of: 
>
>     Object allSubclasses sorted: [:a :b | a name <= b name ].
>
> And there is special kind of SortFunction which represent such block
> itself: 
>
>
>     [:a :b | a name <= b name ] asSortFunction "==>  a
>     CollatorBlockFunction".
>
>  
> The power of first class functions is that they provide reusable
> composition features like:
>
>
>     contacts sorted: #name ascending, #surname descending.
>     contacts sorted: (#name ascending, #surname descending) reversed.
>
>
> (look at class comments for more examples).
>
> It is all very cool and powerful but in the core Pharo still work with
> primitive blocks. 
> All sorting methods and SortedCollection are implemented in terms of
> sortBlock.
> So SortFunction's are adopted to block interface #value:value:.
>
> And my proposal: 
> Let's replace sortBlock by sortFunction everywhere. Block will still
> work but it will be converted to function.
> It will open new possibilities to implement more features. 
> For example SortedCollection>>reversed would be trivial with
> sortFunction (see previous thread).
>
> Drawback is extra dependency in collections. But we can extract
> SortedCollection and related functions into separate package which
> probably will allow reduce bootstrapped codebase.
>
> I am not going to implement it right now. Just want to share this idea
> to see what's wrong with it.
>
> Best regards,
> Denis

--
Esteban A. Maringolo