develooper Front page | perl.perl5.porters | Postings from July 2021

Re: Elevator pitch, deprecating $a/$b sort globals by using sub{}

Thread Previous | Thread Next
July 6, 2021 10:27
Re: Elevator pitch, deprecating $a/$b sort globals by using sub{}
Message ID:
On 6/7/21 11:48, Smylers wrote:
> Nicholas Clark writes:
>> On Sun, Jul 04, 2021 at 05:40:09PM +0200, Martijn Lievaart wrote:
>>>      sort sub($a,$b){ $a->{x} <=> $b->{x} } @list
>> The first thing that thought was that this makes sort special,
>> compared with the other builtins that take blocks (map, grep)
>> But those take one implicit argument, for which $_ works just fine.
>> Our problem here is that sort needs two implicit arguments.
> Does it?
> I mean, yes, obviously at the moment a sort routine requires two
> arguments. But how common is it for those not to be duplicates of each
> other? That is, in:
>      sort { f($a) <=> g($b) } @list
> f() and g() are overwhelmingly identical operations. And if either of
> them are involved, it's irksome to have to duplicate the operation on
> both sides:
>      sort { lc "$a->{somefield}->@*" cmp lc "$b->{somefeild}->@*" } @list
> [Ooops — typo in the second hash key!]
> If we're looking at re-doing sort, it might be worth considering whether
> this repetition can be avoided, rather than just at different ways of
> specifying it.
> Sort needs to know:
> 1.  How to transform an item into a key to use for comparison.
> 2.  Whether to compare with <=> or cmp.
> 3.  Whether the output should be ascending or descending.
> So instead of $a and $b, a sort routine could be specified with $_ and
> an indication of whether to use <=> or cmp.
> One possible design (to show the concept; I'm not suggesting
> specifically this):
>      asort { lc "$_->{somefield}->@*" } @list
>      reverse nsort { $_->{age} } @list
> That is:
> 1.  A single (optional) block takes $_ and returns the sort key.
> 2.  Comparison operator specified with the function name — cos this
>      seems less messy than trying to force it into an argument somewhere.
> 3.  Ascending by default; reverse is available for occasions where
>      descending is required.
> And it gets rid of $a and $b.

In general, when sorting, you have two customizable steps:

1) key extraction
2) key comparison

Reducing key comparison to just numeric or string comparison is not 
flexible enough (or at least not user-friendly enough). For a start you 
want to support having multiple keys, every one with its own comparison 
operation and direction.

BTW, regarding direction, sorting and reversing is not equivalent to 
sorting in the opposite direction. So if you provide "numsort" you also 
need "descnumsort".

Finally, check Sort::Key family of modules. They support almost 
everything related to key based sorting but at the expense of providing 
a myriad of functions in order to cover all the different key type and 
direction combinations.

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About