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 C<sort> 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 C<for> 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.