Search code examples
recursiontclstack-overflow

Can I recursively source a TCL script indefinitely?


I have a TCL script running inside a TCL shell (synopsys primetime if it's of any difference). The script is initiated by source <script> from the shell. The script calls itself recursively after a specific time interval has passed by calling source <script> at the end of the script. My question is a bit academic: Could there be a stack-overflow issue if the script keeps calling itself in this method?

If I expand the question: What happens when a TCL script sources another script? Does it fork to a child process? if so, then every call forks to another child, which will eventually stack up to a pile of processes - but since the source command itself is not parallel - there is no fork (from my understanding).

Hope the question is clear. Thanks.


Solution

  • Short answer: yes.

    If you're using Tcl 8.5 or before, you'll run out of C stack. There's code to try to detect it and throw a soft (catchable) error if you do. There's also a (lower) limit on the number of recursions that can be done, controllable via interp recursionlimit. Note that this is counting recursive entries to the core Tcl script interpreter engine; it's not exactly recursion levels in your script, though it is very close.

    # Set the recursion limit for the current interpreter to 2000
    interp recursionlimit {} 2000
    

    The default is 1000, which is enough for nearly any non-recursive algorithm.

    In Tcl 8.6, a non-recursive execution engine is used for most commands (including source). This lets your code use much greater recursion depths, limited mainly by how much general memory you have. I've successfully run code with recursion depths of over a million on conventional hardware.

    You'll still need to raise the interp recursionlimit though; the default 1000 limit remains because it catches more bugs (i.e., unintentional recursions) than not. It's just that you can meaningfully raise it much more.