Say we have this code:
a = 1
def func1():
if a == 1:
func2()
def func2():
if a == 1:
func3()
def func3():
func1()
Is there a way we could make func3 call func1 stepping out of the 'parent functions' it already incurred in? Meaning, going back to 'recursion depth 0', as if it was starting fresh?
Thank you!
Some languages offer tail-call optimization, which amounts to throwing away the previous stack frame before creating the new one. It's only possible when the recursive call is the last operation that happens (otherwise you need the stack frame because it points to the rest of the operations). Python doesn't, however.
You have two options:
Note that both of these things are trickier to do when you have, say, three functions which call each other recursively. But the overall idea is to come up with new code that preserves the behavior of the old code without using recursion, and obviously how you do that is going to differ depending on the starting code, although the general patterns (linked above) remain the same.
In your case, the code either goes into an infinite loop or doesn't, depending on a
, so
a = 1
def func3():
while a == 1:
pass
func3()
would suffice.
As a side note: for some algorithms, memoization can reduce the number of calls. If the results for large inputs to a function are always composed out of the results of smaller inputs, which are repeatedly calculated ("overlapping subproblems"), then you can keep a global cache of returned values and check the cache before making new calls. Generic memoization code can be written in Python using decorators.