On Thu, 2004-02-12 at 18:50, Uri Guttman wrote:

> there are only a short list of key comparisons possible, int, string,
> float and maybe unicode. i separate int from float since they do have
> different internals in the GRT. it is one area where you do expose
> stuff. otherwise you could just use number. 

And comparing in a particular language (as Dan pointed out in his Parrot
talk); comparing sets (e.g. numeric comparison, but odds and evens are
separate); ordering by string length; ordering by string-to-numeric
value with esoteric exceptions (software versions); etc.

Comparison is essentially always numeric, but only if you reduce your
inputs to numbers, and that's often not terribly efficent (e.g. you can
reduce any ascii string to:

        chr(substr($s,0,1))+chr(substr($s,1,1))*128+...

and then comparing. The only limitation is that you'll have to use
Math::BigInt to do the comparison.

> simple. pick almost any language char set other than US ascii. many have
> special collating sequences. i am not anything close to a unicode expert
> but i have seen this issue. in fact setting the LANG (or some other)
> environment variable will affect many programs by changing the collating
> order.

Ok, yes. This was Dan's example, and is EXACTLY why I think you want to
use map once for key extraction and then sort's expression for
comparison.

> that is scary. do you realize that the sort block will be called for
> each comparison?

Yes.... why would it not be? How do you compare, say, IPv6 addresses if
not by performing a logically-ored comparison between each octet? I
certainly don't want to instantiate a Math::BigInt just to compare two
128-bit values.

>   AS>         @new1 = sortpairs {$_[0] <=> $_[1]} map {[$_,$_]} @old1;
> 
>   AS>         @new2 = sortpairs {$_[0] <=> $_[1] || $_[4] cmp $_[3]} map
>   AS>         {[getkeys($_),$_]} @old2;
> 
> where is getkeys defined?

It was an example. It's whatever you like. In some cases, that might
just be:

  sub getkeys {
    my $object = shift;
    return @{$object->keys};
  }

or perhaps:

  sub getkeys {
    my $string = shift;
    return(length($string),$string); # Order by length and then ascii order
  }

It was just an example. sortpairs was the interesting part.

> how do you know what indexes to use for each
> comparison? what happened to $_[2]? your call to $comp is passed 2
> arguments but the second example accesses 4 arguments.

You missed a layer of extraction there. $comp is passed each parameter
PAIR.

So if your input is [1,2,3,4,"moo"], then you are comparing the keys 1,
2, 3 and 4 and your value is "moo".

>   AS> The second example really illustrates the point that you can swap the
>   AS> direction of key order and mechanism to compare them at your whim.
> 
>   AS> Now, you just need to call sortpairs with any array of arrays of keys
>   AS> (with trailing value).
> 
> add a third key to that. quickly!

ok, easy:

  @new2 = sortpairs {$_[0] <=> $_[1] || $_[4] cmp $_[3] || 
ACME::Compare::Thingulas->compare($_[5],$_[6])} map {[getkeys($_),$_]} @old2;

Please notice that the ONLY change is in the way I call it, not in
sortpairs. sortpairs still works just fine.

> a more straightforward api (which is close to what i will do in
> Sort::GRT) is (p5 code)
> 
>       my $sort = Sort::GRT->new(
> 
>               keys    => [
>                       { descending => 1,
>                         type => float,
>                         extract => '$_->{amount},
>                       },
>                       { extract => 'substr( $_->{date}, 0, 4)' },
>               ]
>       ) ;

The value of extract should be a subref, not a string (thus having
closure status, and therefore access to context).

I think you and I are in violent agreement. I just look at this as a
problem that doesn't need solving because Schwartzian Transforms do all
the work for me. You look at it as something needing encapsulation.
That's cool, but sematically, we're doing the same work.

-- 
Aaron Sherman <[EMAIL PROTECTED]>
Senior Systems Engineer and Toolsmith
"It's the sound of a satellite saying, 'get me down!'" -Shriekback


Reply via email to