Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

No recursion depth limit?

by Yary (Pilgrim)
on Sep 02, 2015 at 01:28 UTC ( [id://1140739]=perlquestion: print w/replies, xml ) Need Help??

Yary has asked for the wisdom of the Perl Monks concerning the following question:

I have this memory of Perl limiting how deep subroutine recursion could go, but the following test suggests not:
perl -E 'sub f{say $_[0] unless $_[0] % 10000;exit if $_[0] > 30000;f( +$_[0]+1)};f(1)'

on perl 5.12 and 5.20, on windows and NetBSD, they both run (and without apparent limit, if you remove the "exit")

I got bit when debugging a recursive sub, and my perl process hard-froze my Windows 7 machine. The mouse moved but nothing else worked, not ctrl-alt-del, not "Fn-Sleep". I waited about 10 minutes, thinking it would run out of memory and exit, but the machine just stayed frozen :-(

Just curious if there was a recursion limit, and if so, when was it lifted?

Next day addendum - Thanks for all the replies! I've encountered the runtime warning, and the regexp recursion limit, and the debugger warnings all in the past, and I must have confabulated them. You all got ++ votes from me for your reminders.

Replies are listed 'Best First'.
Re: No recursion depth limit?
by Athanasius (Archbishop) on Sep 02, 2015 at 03:29 UTC

    Hello Yary,

    It depends what you mean by “limit.” AFAICT, Perl has never prevented subroutine recursion to arbitrary depth; but if warnings are in use, it has always warned about Deep recursion when the recursion depth reaches a certain pre-set limit. From perl5101delta#New-or-Changed-Diagnostics:

    Deep recursion on subroutine "%s"
    • It is now possible to change the depth threshold for this warning from the default of 100, by recompiling the perl binary, setting the C pre-processor macro PERL_SUB_DEPTH_WARN to the desired value.

    On my Strawberry Perl, this limit is still set to the default:

    13:24 >perl -wE "$|++; say ''; sub f { print qq($_[0] ); if ($_[0] >= +99) { say 'Bye!'; } else { f($_[0] + 1); } } f(1);" 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 2 +7 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 5 +0 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 7 +3 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 9 +6 97 98 99 Bye! 13:24 >perl -wE "$|++; say ''; sub f { print qq($_[0] ); if ($_[0] >= +100) { say 'Bye!'; } else { f($_[0] + 1); } } f(1);" 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 2 +7 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 5 +0 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 7 +3 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 9 +6 97 98 99 Deep recursion on subroutine "main::f" at -e line 1. 100 Bye! 13:24 >perl -v This is perl 5, version 22, subversion 0 (v5.22.0) built for MSWin32-x +64-multi-thread

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Re: No recursion depth limit?
by kcott (Archbishop) on Sep 02, 2015 at 03:31 UTC

    G'day Yary,

    "I have this memory of Perl limiting how deep subroutine recursion could go, ..."

    Perl only warns when a certain recursion depth is reached; it doesn't prevent you from recursing deeper.

    "... but the following test suggests not:"

    If you ask for warnings, you get them:

    $ perl -E 'sub f{say $_[0] unless $_[0] % 10000;exit if $_[0] > 30000; +f($_[0]+1)};f(1)' 10000 20000 30000 $ perl -wE 'sub f{say $_[0] unless $_[0] % 10000;exit if $_[0] > 30000 +;f($_[0]+1)};f(1)' Deep recursion on subroutine "main::f" at -e line 1. 10000 20000 30000
    "Just curious if there was a recursion limit, ..."

    The limit is 100, i.e. on the 100th recursion, a warning is emitted.

    $ perl -wE 'sub f{say $_[0] unless $_[0] % 33;exit if $_[0] >= 99;f($_ +[0]+1)};f(1)' 33 66 99 ken@ganymede: ~/tmp $ perl -wE 'sub f{say $_[0] unless $_[0] % 33;exit if $_[0] >= 100;f($ +_[0]+1)};f(1)' 33 66 99 Deep recursion on subroutine "main::f" at -e line 1.

    Search for "Deep recursion on subroutine" in perldiag for more details and additional information.

    Also, if you're using the warnings pragma, which I strongly recommend, you can selectively turn off warning messages.

    — Ken

Re: No recursion depth limit?
by Anonymous Monk on Sep 02, 2015 at 03:02 UTC
Re: No recursion depth limit?
by stevieb (Canon) on Sep 02, 2015 at 13:45 UTC

    I didn't see anyone post about this warning while using the debugger (sorry if I missed it). You can change the default of 100 in the debugger very easily for testing/troubleshooting by setting $DB::deep...

    Default:

    $ perl -d rec.pl main::(rec.pl:10): f(1); DB<1> c main::f(rec.pl:6): $_[0] unless $_[0] % 10000; 100 levels deep in subroutine calls!

    Set to 500:

    $ perl -d rec.pl main::(rec.pl:10): f(1); DB<1> $DB::deep = 500 DB<2> c main::f(rec.pl:6): $_[0] unless $_[0] % 10000; 500 levels deep in subroutine calls!
Re: No recursion depth limit?
by jf1 (Beadle) on Sep 10, 2015 at 15:06 UTC

    You can get a hard recursion limit and thus similar behaviour as e.g. in python with:

     use warnings FATAL => 'recursion';

    Just wondering: Do people here actually use this statement?

      I almost always use strictures; which makes warnings fatal. So, the answer is "yes" in a slightly roundabout way; see strictures. Oh, say… I just "saw" the documentation and while recursion is a fatal in strictures v1, which I'm still using in production, it is a plain warning in v2. Hmmmm, not sure how I feel about that. I see the rationale is that it will cause an error if it's going to so why stop it at some early, semi-arbitrary point. Well, alllllllrighty then.

A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1140739]
Approved by GrandFather
Front-paged by kcott
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (2)
As of 2024-04-20 10:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found