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
From:
Nicholas Clark
Date:
July 4, 2021 17:02
Subject:
Re: Elevator pitch, deprecating $a/$b sort globals by using sub{}
Message ID:
20210704170200.GR11066@etla.org
On Sun, Jul 04, 2021 at 05:40:09PM +0200, Martijn Lievaart wrote:
> Hi list
> 
> 
> Karl Wiliamson's remarks about $a/$b as a quirk got me thinking. With
> signatures as a language feature it's feasable to make sort not only take a
> blok or a subroutine name, but also a sub. That means $a and $b for sort can
> be deprecated in the long run, and eventually turned off with a feature flag
> if we so choose.
> 
> 
> So basically,
> 
>     sort { $a->{x} <=> $b->{x} } @list
> 
> could be written as:
> 
>     sort sub($a,$b){ $a->{x} <=> $b->{x} } @list
> 
> which is currently a syntax error.

That's always a good start when proposing new syntax :-)

> Yes, it is longer, but less of a wart. It lessens the cognitive load, avoids
> the $a/b global variables and makes the language more consistent.

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.

(And I think that most others that might get proposed, such as first and any
would also use $_)

Our problem here is that sort needs two implicit arguments. *Is* it the only
operator that wants >1 implicit argument?

Because to me it feels like we're now creating a *different* set of special
case syntax for sort, to eliminate the current special-case syntax ($a, $b).

What else might re-use this syntax?


The second thing that I thought was that as sort can currently take a
subroutine with a *prototype* of $$ to eliminate $a, $b:

$ perl -lwe 'sub foo($$) { 1/$_[0] <=> 1/$_[1] }; print for sort foo (.5, .25, 3, 42, 1, -1, -.1)'
-0.1
-1
42
3
1
0.5
0.25

then really to be consistent we should then say that also a signature of
arity exactly 2 should behave the same.

We currently we can't do.

$ ./perl -Ilib -lwe 'use feature "signatures"; sub foo ($q, $r) { 1/$q <=> 1/$r }; print for sort foo (.5, .25, 3, 42, 1, -1, -.1)'
The signatures feature is experimental at -e line 1.
Too few arguments for subroutine 'main::foo' (got 0; expected 2) at -e line 1.


and signatures are compiled to regular perl OPs at the start of the
subroutine body, so we don't (currently) have a way to introspect the
signature of a subroutine to reason about its arity.


> An argument against it, is that it adds yet another way to use sort, which
> already has three modes of operation. I think it is worth it, but that is
> certainly something to be considered, it lessens the cognitive load on one
> side and adds to it on another.

That sums up what I'm currently thinking. "Swings and roundabouts"

To me it seems more that it adds another way of doing something, making it
differently easy, rather than making something previously hard easy.

But that's as much about the syntax you're suggesting as the problem you're
trying to solve. It doesn't seem that the proposed syntax can be re-used for
any other task.

> P.S. That means 'sort \&x, @list;' probably should be valid too, which
> points to a syntax problem, why does the this one have a comma, but the
> 'sub($a,$b){}' version does not? There is some room for bikeshedding here.
> However, allowing this does not really add anything, as 'sort x @list;'
> already achieves the same thing, and easier at that. So allowing it would
> either be for consistency, or an artifact of implementation.


I am not an expert on the corners of the parser, but given that I can write:

perl -lwe 'sub foo($$) { 1/$_[0] <=> 1/$_[1] }; my $bar = \&foo; print for sort $bar (.5, .25, 3, 42, 1, -1, -.1)'
-0.1
-1
42
3
1
0.5
0.25


my impression was that the syntax that follows sort is already complex and
hides various special cases and heuristics.


I *think* that your new suggestion is only "not currently valid syntax"
because you omit the comma. If I write:

$ ./perl -Ilib -lwe 'use feature "signatures"; print for sort sub ($q, $r) { 1/$q <=> 1/$r }, (.5, .25, 3, 42, 1, -1, -.1)'

The signatures feature is experimental at -e line 1.
-0.1
-1
0.25
0.5
1
3
42
CODE(0x55c991505c68)


at which point, it looks like this plan only works because a comma isn't
there.

Put a comma in, and the code means something else.

That feels like a risky design.


Nicholas Clark

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About