Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Re^2: sort +*, @array

by raiph (Friar)
on Dec 09, 2013 at 12:16 UTC ( #1066276=note: print w/ replies, xml ) Need Help??


in reply to Re: sort +*, @array
in thread sort +*, @array

I think "akin to ST" is reasonable.

It's not the decorate-sort-undecorate of a by-the-book ST, but it's a direct equivalent which retains the ST's generality and efficiency and substantially improves on its elegance.

To understand how the P6 design retains full ST capability, follow my attempt to P6ify your example thru two versions, the first not ST equivalent, the second equivalent:

enum days <mo tu we th fr sa su>; enum months <jan feb mar apr may jun jul aug sep oct nov dec>; my $noon = DateTime.new(now) .truncated-to(day) .delta(12, hours); my @dates = $noon, *.delta(1, day), ... *; my @ordered = sort { ~days($^a.day-of-week - 1) cmp ~days($^b.day-of-week - 1) || ~months($^b.month - 1) cmp ~months($^a.month - 1) } ], @dates[^365];

Some may quibble with the jump from the +* construct to a { ... } closure. But +* in term position is just sugar for a (one arg) closure (which as an arg to sort is assumed to be a "key extractor" closure).

Some may quibble with the jump from a one arg "key extractor" closure to a two arg P5 style "comparator" closure. But P6 uses the one arg closure to do the same thing for both args ($a and $b in P5) in an automatically constructed comparator closure, and assumes use of cmp for comparison. So, no need for an explicit two arg "comparator" closure unless you really want one.

Update I had intended that folk would read this comment as a whole, including what comes next, but I think some stopped at the above. The above works in current Rakudo, reads pretty cleanly, and is fully general functionally, but is not ST equivalent in at least the sense that it doesn't cache the keys. The following reads cleanly, does cache the keys, and is fully general -- but does not work in current Rakudo.

enum days <<:mo(1) tu we th fr sa su>>; enum months <<:jan(1) feb mar apr may jun jul aug sep oct nov dec>>; my $noon = DateTime.new(now).truncated-to(day).delta(12, hours); my @dates = $noon, *.delta(1, day), ... *; my @ordered = sort [ { ~days(.day-of-week) }, { ~months(.month) } is descending ], @dates[^365];

Update Let's add some commentary to try make the ST equivalency pop...

Those two closures ({ ~days(.day-of-week) }, { ~months(.month) }) are key extractor closures. They correspond to the two calls in the P5 original:

substr(scalar localtime($_),0,3), substr(scalar localtime($_),+5,3)

Just as one can have arbitrary before maps with P5 ST, the P6 sort builtin design supports any number of arbitrary key extractor closures. P6 then automatically generates two comparator closures, and runs the first comparison to see if it sorts between a given pair of items, and if it doesn't, runs the next comparison. This corresponds to the P5:

$a->[1] cmp $b->[1] || $b->[2] cmp $a->[2]

(The descending aspect of the second cmp expression in the P5 comparator closure is covered by the is descending trait on the second closure in the P6 code.)


Comment on Re^2: sort +*, @array
Select or Download Code
Re^3: sort +*, @array (misinformation)
by BrowserUk (Pope) on Dec 09, 2013 at 15:54 UTC

    That's not an ST, it's at best an Orcish Maneuver. (Or simply shorthand for {$a<=>$b}.)

    Some may quibble ...

    And some may simply stop reading misinformation...


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      It's not an Orcish Maneuver.

      The original example +* (reads "numeric context Whatever") is syntactic sugar for the one arg closure {+*} which is in turn treated by the P6 sort builtin as a key extractor and results in use of the comparator closure {$a<=>$b}.

      I've realized I didn't make it clear that my response to your challenge contained two parts and you needed to read both to see the ST equivalence. I suspect you didn't read both. I've updated it to try make things clearer.

Re^3: sort +*, @array
by jdporter (Canon) on Dec 09, 2013 at 18:36 UTC
    but it's a direct equivalent

    By that logic, every sort could be called a ST. That just doesn't make sense. Use the term as it is defined and well known: decorate-sort-undecorate!

    retains the ST's generality

    I don't see how it does that at all. Unless it can do decorate-sort-undecorate, it falls very far short of the ST's generality.

    And it's not just about the "decorate" step, which your "key extractor" closure is roughly equivalent of. Because the ST has an explicit sort block (normally, unless it's the GRT variant :-)), it allows to execute arbitrarily complex Perl code in the comparison. Where does one do that in this Perl 6 "equivalent"?

    I reckon we are the only monastery ever to have a dungeon stuffed with 16,000 zombies.
      I'm not saying that the design of the P6 builtin is ST, just that it is functionally equivalent, and even more concise.

      And it's not just about the "decorate" step, which your "key extractor" closure is roughly equivalent of.

      One critical point: while a "key extractor" closure is indeed roughly equivalent to the decorate step in terms of the role it's playing, it's multiple key extractor closures that is basically fully equivalent to the before map.

      Because the ST has an explicit sort block (normally, unless it's the GRT variant :-)), it allows to execute arbitrarily complex Perl code in the comparison. Where does one do that in this Perl 6 "equivalent"?

      You just specify a comparator closure (or multiple, if you want).

      (P6 can tell the difference due to a closure's number of args. If it has one, it's a key extractor closure, if it has two it's a comparator closure.)

      For lots more examples which are still correct modulo a few minor syntax shifts, see "The Sort Problem: a definitive ruling" from 2004.

      Which got me to focus on the Pair variant which maybe helps clarify the connection for you:

      sort { #`( key extractor closure) } => { #`( comparator closure) }, { #`( key extractor closure) } => { #`( comparator closure) }, ... @array

        I'm not saying your posts are full of blowhard marketing nonsense, but they're functionally equivalent. Do you even program, bro?

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1066276]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (11)
As of 2014-08-22 20:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (164 votes), past polls