Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re: Continuations in Perl - Returning to an arbitrary level up the call stack

by BrowserUk (Patriarch)
on May 18, 2013 at 23:09 UTC ( [id://1034164]=note: print w/replies, xml ) Need Help??


in reply to Continuations in Perl - Returning to an arbitrary level up the call stack

I have a need to return from a deeply nested function, not to the caller, but to a higher point up the call stack.

Every time I've found my code needing something as crazy as that, I've thrown the code away, got drunk/sober/laid/slept, whatever it took me to forget the idea and then come back and started over.

What you are suggesting sound likes bypassing the stairs by jumping from one landing to the next; and whilst Parkour makes for some great movie chases and youtube clips; designing a building that relied on it for emergency exits just isn't on.

But that exactly what you are doing by designing your code to rely upon such shortcuts.

I bet if you were to describe your application in sufficient detail that you'd get a raft of better solutions that don't require the equivalent of leaping from one tall building to the next as part of your daily commute.


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.
  • Comment on Re: Continuations in Perl - Returning to an arbitrary level up the call stack

Replies are listed 'Best First'.
Re^2: Continuations in Perl - Returning to an arbitrary level up the call stack
by LanX (Saint) on May 19, 2013 at 00:00 UTC
    I agree in general, but there are some good use cases.

    For instance, when designing a recursion to search a graph it's sometimes desirable to stop immediately after the goal is reached.

    No need to backtrack and branch thru the whole labyrinth after the exit is already found!

    And the recursion is much simpler w/o special case handling for chained returns.

    Perl internally cares about cleaning up all intermediate frames.

    Cheers Rolf

    ( addicted to the Perl Programming Language)

      For instance, when design a recursion to search a graph it's sometimes desirable to stop immediately after the goal is reached.

      I'm having trouble imagining a routine designed to search a graph, where finding the target is a special case?

      No need to backtrack and branch thru the whole labyrinth after the exit is already found!

      The emotive language makes it sound like returning from (several nested) subroutines is a difficult thing to do; but that is what subroutines do. Via a return or falling off the end. it is neither hard to program nor costly in executions time.

      Indeed, whatever alternative mechanism is used, in whatever language, it will always be more costly than the natural return chain. The stack still has to be unwound

      Just as the exception mechanism in C++ (or structured exceptions in MSC), are a magnitude or more expensive because they have to search back up the stack looking for stack frames interpreting them as they go; so the goto that underlies such mechanisms in Perl has to go through an equally convoluted process to find a label at the appropriate scope.

      Such costs and overheads -- not to mention the difficulties they create when they fail to work as expected and need to be traced and debugged -- are just about acceptable for the exceptional (rare, non-normal) cases they are designed for; but wrapping them over in a cute sounding abstraction and subverting them for use in the general case -- such as a search routine finding what it is looking for -- seems like abuse of the very worse kind to me.

      Whilst I'm sure it is possible to contrive a theoretical use case that might stand up to cursory inspection; but unless I saw a real-world use case that I couldn't find a less obscure alternative, any use of the mechanism would garner a big red flag in any code review I was involved in.

      Luckily, neither the OP nor you have to subject your code to my review :)


      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.
        > Luckily, neither the OP nor you have to subject your code to my review :)

        and vice versa!

        Cheers Rolf

        ( addicted to the Perl Programming Language)

        Your inerrant holiness who represents all of us!

        > Indeed, whatever alternative mechanism is used, in whatever language, it will always be more costly than the natural return chain. The stack still has to be unwound

        > Just as the exception mechanism in C++ (or structured exceptions in MSC), are a magnitude or more expensive because they have to search back up the stack looking for stack frames interpreting them as they go; so the goto that underlies such mechanisms in Perl has to go through an equally convoluted process to find a label at the appropriate scope.

        Some heretics didn't fully trust you and tried to measure a time penalty for die or goto.

        Look what they have done!

        Timing for 1000000 recursions: Mode: return takes sec: 5.55880403518677 Mode: goto takes sec: 4.51015114784241 Mode: die takes sec: 1.70386385917664

        use Time::HiRes qw/time/; no warnings 'recursion'; our $mode; sub rec { my $i=shift; $i--; if ($i<0) { return if $mode eq "return"; goto OUT if $mode eq "goto"; die "finished" if $mode eq "die"; } rec($i) } $|=1; my $recs=1000000; print "Timing for $recs recursions:\n" ; for $mode (qw/return goto die/) { print "\tMode: $mode takes sec: "; my $start=time; eval { rec($recs); }; OUT: # print $@ if $@; print time-$start,"\n"; }

        Please prove them wrong!

        May those heathens all burn in hell (...or emacs)!

        Cheers Rolf

        ( addicted to the Perl Programming Language)

      You are reinventing exception handling.

      While a daily routine for a Python programmer most Perl hackers won't understand it.

      Don't bother preaching, switch to Python! :-D

        While a daily routine for a Python programmer most Perl hackers won't understand it.

        Hackers not understand something "python programmers do routinely?"

        LOL!

        > You are reinventing exception handling.

        probably ...

        ...most likely

        ... but I never liked fiddling with die to throw.

        > While a daily routine for a Python programmer most Perl hackers won't understand it.

        Single popes don't represent our whole monastery!

        > Don't bother preaching, switch to Python! :-D

        It's far easier to reimplement exception handling in Perl than getting along with crippled lamdas in Python.

        The problem with Python are not the features but the restrictions!

        Cheers Rolf

        ( addicted to the Perl Programming Language)

        update

        Found good discussions of the matter on SO whats-broken-about-exceptions-in-perl and in the appendix to Try::Tiny.

        Try::Tiny looks reasonable to me! =)

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (4)
As of 2024-04-19 23:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found