Luke --

Hmmm... I haven't been practicing my Perl 6, and its been a while
since the last Apocalyptic refresher, but here goes (I'll don a paper
bag preemptively)...

Thinking of that as the equivalent to:

  sort {
    my ($ta, $tb) = map { $_.foo('bar').compute } ($^a, $^b);
    $ta <=> $tb
  } @unsorted;

so if you had a unary <=> that took a two element array (old style
syntax here, sorry):

  sub cmp_num { my ($a, $b) = @_; $a <=> $b; }

you could write that as:

  sort {
    cmp_num map { $_.foo('bar').compute } ($^a, $^b);
  } @unsorted;

I'd be a bit afraid of allowing <=> itself to be prefix, although I
admit it would be handy not to need the separate sub definition:

  sort {
    <=> map { $_.foo('bar').compute } ($^a, $^b);
  } @unsorted;

The Schwartzian is the usual way, of course:

  map { $_->[1] }
  sort { $^a[0] <=> $^b[0] }
  map { [ $_.foo('bar').compute, $_ ] }
  @unsorted;

But we really aren't being concise here.

(Aside) I wonder if there will be a new Perl 6 idiom to replace this
using properties, something like this:

  map { $_.really }
  sort : numerically
  map { $_.foo('bar').compute but really($_) }
  @unsorted;

or:

  @unsorted
    ==> map { $_.foo('bar').compute but really($_) }
    ==> sort : numerically
    ==> map { $_.really };

But we *still* aren't concise.

Maybe we should have a two-block sort? The second block gives the
transform to apply to the elements before applying the comparison
block:

  sort { $^a <=> $^b } { $_.foo('bar').compute } @unsorted;

Or maybe even something like this:

  sort :numerically :as { $^a.foo('bar').compute } @unsorted;


Regards,

-- Gregor

On Wed, 2004-02-11 at 19:11, Luke Palmer wrote:
> I've been thinking about this problem which comes up in my code a lot:
> 
>     @sorted = sort { $^a.foo('bar').compute <=> $^b.foo('bar').compute }
>                 @unsorted;
> 
> Often the expressions on each side are even longer than that.  But one
> thing remains:  both sides are exactly the same, substitute a $^b for a
> $^a.
> 
> I can see a couple less-than-desirable ways around this redundancy:
> 
>     @sorted = sort { infix:<=>( *($^a, $^b)».foo('bar').compute ) }
>                 @unsorted;
> 
> Which doesn't work if .compute returns a list... not to mention its
> horrible ugliness.  Another is to define a variant of sort (haven't had
> much practice with A6 material recently; here we go!):
> 
>     multi sub sort (&block($) = { $_ } : [EMAIL PROTECTED]) {
>         sort { block($^a) cmp block($^b) } @data;
>     }
> 
>     @sorted = sort { .foo('bar').compute } @unsorted;
> 
> Which has the disadvantage of forcing you to use C<cmp> and forcing an
> ascending sort.
> 
> Any other ideas?  Is a more general solution necessary?
> 
> Luke
-- 
Gregor Purdy                            [EMAIL PROTECTED]
Focus Research, Inc.               http://www.focusresearch.com/

Reply via email to