Re: The Sort Problem (was: well, The Sort Problem)

2004-02-13 Thread Rod Adams
Here's my stab at a sort syntax, pulling syntax over from REs:

@out
 == sort key:ri($_-[2]), key:s($_-[4])
 == @in;
Basicly, you have a list of RE syntax like Ckey values, whilch take 
various modifiers to say how to play with that key, and then an expr on 
how to generate the key given element $_.

Possible modifiers: (verbose versions welcome)
:rreverse/descending
:n   force numeric comparisons
:s  force string comparisons (default)
:u  unicode (implies :s)
:i   case insensitive (implies :s)
:l   localized collation order
:x  call custom compare sub (a la P5)
This allows:

@out = sort keys %hash; # everything gets defaulted
@out = sort key:x{myfunc($a) cmp myfunc($b)}(), @in; # handy for P5 
migration, but not much else
@out = sort key(myfunc($_)), @in; # same as above, but much better.
@out = sort key(%lookup{$_-{remotekey}}), key:ir($_-{priority}), @in; 
# complex in P5, easy here.

Advantages:
- Uses syntax idioms used elsewhere in P6.
- Common cases are easy
- Decent huffman coding.
Disadvantages:
- Do we really want things that look like REs that are not REs?
- If we do this, are we setting ourselves up to create other RE-like 
creatures for grep, for, etc,  to the point
 where people will start wanting to roll their own in modules?

Thoughts?
-- Rod


Re: The Sort Problem (was: well, The Sort Problem)

2004-02-13 Thread Dan Sugalski
At 11:52 PM -0700 2/12/04, Luke Palmer wrote:
But it needs some major syntax work so it can feel more like it's a part
of the language instead of a library function.  Not, mind, that I think
Perl's syntax needs to be changed at all to accommodate.
Since everyone's well past mad here and deep into drug-induced brain 
damage territory...

If you're *really* looking to get fancy, why not just allow the sort 
specification to be done with SQL? Comfortable, well-understood, 
already has a decade or so of stupid things welded into it (so 
everyone can stop trying to think up new stupid things to weld in), 
and there are several grammars for it so it'd be no work to speak of 
for me.

Heck, you could even unify map, grep, and sort and, if you fed in a 
list of pair lists or hashes, return parts of each record^Wlist 
element rather than the whole thing.
--
Dan

--it's like this---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
  teddy bears get drunk


Re: The Sort Problem (was: well, The Sort Problem)

2004-02-13 Thread Angel Faus

Friday 13 February 2004 15:02, Dan Sugalski wrote:

 If you're *really* looking to get fancy, why not just allow the
 sort specification to be done with SQL? Comfortable,
 well-understood, already has a decade or so of stupid things welded
 into it [...]

 Heck, you could even unify map, grep, and sort [...]


That would be postmodern indeed.

-angel


Re: The Sort Problem (was: well, The Sort Problem)

2004-02-12 Thread Luke Palmer
Jonathan Lang writes:
  We already have that.  It's spelled:
  
  routine [EMAIL PROTECTED];
  
  Or
  
  routine * == @x;
 
 Then you've got your solution:
 
   @sorted = sort {infix:= * map {$_.foo('bar').compute}, $^a, $^b }
 @unsorted; 
 
 or
 
   @sorted = sort {($^a, $^b) ==
   map {$_.foo('bar').compute} ==
   infix:= * } @unsorted; 

No, I don't think we do.  Uri's given some good points in this thread
about specifying what you want out of the sort, instead of some
arbitrary callback interface.

But it needs some major syntax work so it can feel more like it's a part
of the language instead of a library function.  Not, mind, that I think
Perl's syntax needs to be changed at all to accommodate.

I'm thinking that Csort might take a list of closures or pairs (with
the value being a closure).  I'm still not sure how that separates from
the data to be sorted, but it's probably related to the problem of how
Cfor works in declaration.

The return value of each closure is dispatched into some sort of generic
=, hopefully one that blows up if its arguments are of different
types[1]. That way if you have a method that always returns a number,
you can just leave it alone.  Otherwise you're expected to prefix with
the approprate contextifier.

For example:

sort { .foo('bar').compute }, desc = { ~.baz }, @data;
# ascending by default  string compares

Pairs don't exactly seem fit here.  Maybe we're supposed to think of
these these closures as higher-level 'extractors', and therefore attach
properties to them:

sort { .foo('bar').compute }, { ~.baz } but descending, @data;

Or even something on the value that tells = to negate whatever it
returns:

sort { .foo('bar').compute }, { ~.baz but swap }, @data;

That's starting to expose implementation again, though.

Moving a different direction now.  Instead of being honest and saying
that sort does each of these comparisons until one of them is nonzero,
let's pretend that it sorts with respect to the first comparison and
feeds the lists of equal elements into the second comparison, etc.

Sort might then look like:

sub sort (?extract, ?next, [EMAIL PROTECTED])

And our example turns into:

sort { .foo('bar').compute } 
 { reverse sort { ~.baz } [EMAIL PROTECTED] } 
 [EMAIL PROTECTED];

That hurts, especially when there are more than two keys.  I'd really
like to do that with the piping operators instead of nested closures,
but that screws with the simple case.

There might be even more ways of looking at this that would result in
more novel syntaxes.  Brainstorming required.

Luke

[1] There's something to be said for a generic comparison, but not one
that blows up.  Mostly because certain containers want their elements to
be well ordered.  But we could just as easily say that elements that
aren't intercompatible with the short-tempered = aren't allowed in
said containers.