Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does python implement mutual recursion?

Moving to python with C/Java background, I recently had to implement a mutual recursion, but something in python is bothering me:

since a python program is interpreted line by line, if I have two functions one after another in the same python file:

def A(n):
    B(n-1)
# if I add A(1) here, it gives me an error
def B(n):
    if n <= 0:
        return
    else:
        A(n-1)

When the interpreter is reading A, B is not yet defined, however this code does not give me an error

My understanding is that, when def is interpreted, python adds an entry to some local name space locals() with {"function name": function address}, but as for the function body, it only do a syntax check:

def A():
    blabla # this will give an error

def B():
    print x # even though x is not defined, this does not give an error
    A()     # same as above, NameError is only detected during runtime
like image 220
watashiSHUN Avatar asked Oct 08 '15 21:10

watashiSHUN


People also ask

How does recursion work in Python?

Recursion in Python When you call a function in Python, the interpreter creates a new local namespace so that names defined within that function don’t collide with identical names defined elsewhere.

What is the difference between recursion and mutual recursion?

Recursion is, to quote Wikipedia, "a method of defining functions in which the function being defined is applied within its own definition". Similarly mutual recursion applies another function which, directly or indirectly, applies the function we are defining.

How do you write a tail recursive function in Python?

We can write the given function Recur_facto as a tail-recursive function. The idea is to use one more argument and in the second argument, we accommodate the value of the factorial. When n reaches 0, return the final value of the factorial of the desired number.

Is it possible to make recursion limit infinite in Python?

Technical note: You can find out what Python’s recursion limit is with a function from the sys module called getrecursionlimit (): You can set it to be pretty large, but you can’t make it infinite. There isn’t much use for a function to indiscriminately call itself recursively without end.


Video Answer


2 Answers

The line B(n-1) says "when this statement is executed, lookup some function B in the module scope, then call it with parameters n-1". Since the lookup happens when the function is executed, B can be defined later.

(Additionally, you can completely overwrite B with a different function, and A will call the new B afterwards. But that can lead to some confusing code.)

If you're worried about not catching calls to nonexistent functions, you can try using static analysis tools. Other than that, be sure you're testing your code.

like image 148
Colonel Thirty Two Avatar answered Sep 18 '22 16:09

Colonel Thirty Two


A SyntaxError will be caught at compile time, but most other errors (NameError, ValueError, etc.) will be caught only at runtime, and then only if that function is called.

"if I have written a function, if its not called in my test.." - and that is why you should test everything.

Some IDEs will raise warnings in various situations, but the best option is still to conduct thorough testing yourself. This way, you can also check for errors that arise through factors like user input, which an IDE's automated checks won't cover.

like image 44
TigerhawkT3 Avatar answered Sep 19 '22 16:09

TigerhawkT3