[comp.lang.perl] inlining your sort subroutine

tchrist@convex.com (Tom Christiansen) (11/23/90)

Instead of having to doing this:

    sub numerically { $a <=> $b; }
    @out = sort numerically @in;

wouldn't this be nice:

    @out = sort { $a <=> $b; } @in;

You can *almost* do it right now.

    $func = 'func0001';
    sub makefun { eval "sub $func { $_[0]; }"; $func++; } 

    $f1 = &makefun('print "hello $a\n"');
    $f2 = &makefun('$a++');

    for (1..3) {
	do $f1(); do $f2(); 
    }

That works just fine.  So then I did this:

    @a = (3, 5, 12, 3,  9, 23, 93, 1, 445, 33, 12);

    $sortsub = &makefun('$a <=> $b');
    @a = sort $sortsub @a;
    print join(", ", @a), "\n";

And again it worked just fine.  However, I could NOT do this:

    @a = sort &makefun('$a <=> $b') @a;

Which is too bad.  Of course, I would still like things like

    @a = sort { $a <=> $b; } @a;
    @a = sort { $x{$a} cmp $x{$b}; } keys %x;

to work.  You run the risk -- if you want to call it that -- that people 
would start writing stuff like this:

    @a = sort {
		# lots of code
		# might intervene here, taking
		# a long time to find the list
	  } @b;

But I still like the idea.  I don't see how it could break any scripts.

--tom

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (11/25/90)

In article <109155@convex.convex.com> tchrist@convex.com (Tom Christiansen) writes:
: Instead of having to doing this:
: 
:     sub numerically { $a <=> $b; }
:     @out = sort numerically @in;
: 
: wouldn't this be nice:
: 
:     @out = sort { $a <=> $b; } @in;

It would be possible, but apart from the problem you mentioned of making it
hard to find the list, I also think people should occasionally be encouraged
to name their abstractions.

Of course, the fact that it would be hard to implement has nothing to
do with it...  :-)

Larry

tchrist@convex.COM (Tom Christiansen) (11/28/90)

In article <10521@jpl-devvax.JPL.NASA.GOV> lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) writes:
>In article <109155@convex.convex.com> I wrote:
>: wouldn't this be nice:
>: 
>:     @out = sort { $a <=> $b; } @in;

>It would be possible, but apart from the problem you mentioned of making it
>hard to find the list, I also think people should occasionally be encouraged
>to name their abstractions.

By all means.  It's just that the quoted line above seems to be more
readable than naming a subroutine for the sort; it would seem easier
on both the writer and the reader of the code.  I know in teaching 
perl, students have more than once asked me whether this was possible
as soon as I show them how sort takes an optional subroutine.  My 
response generally begins with "Alas, no; ...". 

>Of course, the fact that it would be hard to implement has nothing to
>do with it...  :-)

I see we come at last to the meat of the matter. :-)

In the meantime (and perhaps forever), you can always write
a sort() function like this if you really want to:

    @out = &sort('$a <=> $b', @in);

and a byreference version like this:

    @out = &sortr('$a <=> $b', *in);

so that you don't try this:

    @out = &sortr('$a <=> $b', 3, 4, 2, 1, 4, 98);

Naw, that's too complex.  I'll go back to naming subroutines
for a while.

--tom