Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Re: (almost) foldl

by Fox (Pilgrim)
on Jun 08, 2011 at 14:25 UTC ( #908716=note: print w/replies, xml ) Need Help??


in reply to (almost) foldl

No recursion ?

sub sum { (shift()//0) + (@_ ? sum(@_) : 0) };

Replies are listed 'Best First'.
Re^2: (almost) foldl
by BrowserUk (Patriarch) on Jun 08, 2011 at 19:25 UTC

    I came up with a similar, and arguably neater implementation:

    sub sum{ ( shift()//return 0 ) + &sum } print sum( 1,2,3);; 6 print sum( 1 .. 100 );; Deep recursion on subroutine "main::sum" at 5050

    but rejected it because 'sum' is a (glob) variable.

    In theory, it is possible to avoid the naming of the sub, thereby achieving "anonymous recursion", by using the Y-combinator. And the Y-combinator has been achieved in Perl by a former regular here.

    Putting it together you get:

    print Y( sub{my$rec=shift; sub{(shift()//return 0) + &$rec }})->(1 .. +100);; 5050

    But whilst that achieves the Y-combinators goal of recursion without adding the sub to the permanent namespace, it still requires the naming of the pesky closure $rec.

    And of course, requires you to add the Y-combinator to the permanent namespace first:

    sub Y { my ( $curried_rec ) = @_; sub { my ( $f1 ) = @_; $curried_rec->( sub { $f1->( $f1 )->( @_ ) } ) }->( sub { my ( $f2 ) = @_; $curried_rec->( sub { $f2->( $f2 )->( @_ ) } ) } ) }

    And that's already more obfuscation as I want to wrap my brain around, even in an obfuscation section post!

    My final thought is that the simplest mechanism that fits the OPs breif is just:

    C:\test>perl -Mstrict -wE"say eval join'+',()" C:\test>perl -Mstrict -wE"say eval join'+',0" 0 C:\test>perl -Mstrict -wE"say eval join'+',-1" -1 C:\test>perl -Mstrict -wE"say eval join'+',-1..+3" 5

    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.
      Nice! But print eval join "+", ("1e", 6) yields 1000000, whereas my aforementioned solution: print sub {eval 'pop(@_)+' x ($#_ + 1) . '0';}->("1e", 6); prints the expected result, 7. Ok, ok, I'm quibbling.
        Ok, ok, I'm quibbling.

        Then add a couple of extra spaces :)

        say eval join' + ','1e',6;

        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.
      Great! There was once a YAPC auction selling off a built-in name in a future perl, at the buyer's choice. IIRC it has never actualized, but now I wish it was Y )

        Whilst Aristotle's Y() combinator is very clever, the requirement to assign the coderef to a local variable complicates the using code.

        If something along these lines were to be built-in, I'd like to simplify it so that you could write:

        print sub{ ( shift() // return ) + &$^SUB }->( 1 .. 10 );

        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.
Re^2: (almost) foldl
by Grimy (Pilgrim) on Jun 08, 2011 at 17:05 UTC
    This method is extremely elegant, and therefore doubleplus unsuitable for the "Obfuscated code" section. Just kidding, sorry if it sounds harsh :-)
Re^2: (almost) foldl
by dk (Chaplain) on Jun 08, 2011 at 15:52 UTC
    cool! ++

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (4)
As of 2022-09-29 11:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    I prefer my indexes to start at:




    Results (125 votes). Check out past polls.

    Notices?