Open In App

Tail Recursion in Python Without Introspection

These are the special type of recursive functions, where the last statement executed inside the function is the call to the function itself.

Advantages of implementing Tail Recursive function

Note: In Python, the interpreter doesn’t perform any special optimization even if the function is a tail-recursive function.



Example of Python Tail Recursive function Structure

In this example, we are just trying to emulate the structure of a tail-recursive function in Python. But in reality, this structure is the same as any other recursive function in Python.




def count(n):
    if n < 0:
        return
    print("Counting", n)
    count(n-1)
 
count(3)

Output

Counting 3
Counting 2
Counting 1
Counting 0

Time Complexity: O(n)
Auxiliary Space: O(n)

But, the above example, similar to any recursive function in Python, also has the disadvantage of limited recursive calls. To overcome this, we can convert the recursive structure of the function into an iterative structure using Python decorators.

Difference between Tail Recursive function and Recursion in Python

Tail recursive function




def count(n):
    if n < 0:
        return
    print("Counting", n)
    count(n - 1)
     
count(3)

Output
Counting 3
Counting 2
Counting 1
Counting 0

Time Complexity: O(n)
Auxiliary Space: O(n)

Simple Recursive Function




def count(n):
    if n < 0:
        return 0
    print("Counting", n)
    n -= count(n-1)
    return n
 
count(3)

Output
Counting 3
Counting 2
Counting 1
Counting 0

Time Complexity: O(n)
Auxiliary Space: O(n)

Converting Tail Recursive function into Iterative function using Python decorator.




# class to define our own exception
class Recurse(Exception):
    def __init__(self, *args: object) -> None:
        super(Recurse, self).__init__()
        self.args = args
 
 
# function to simulate the
# tail-recursive call
def recurse_sim(*args):
    raise Recurse(*args)
 
 
# decorator function to convert
# recursive -> iterative
def iterative_recursion(fn):
    def wrapper(*args):
        while 1:
            try:
                return fn(*args)
            except Recurse as exc:
                args = exc.args
 
    return wrapper
 
 
# tail recursive function
# implementation
@iterative_recursion
def count_pseudo_recursive(n):
    if n < 0:
        return
 
    print("Counting", n)
    return recurse_sim(n - 1)
 
 
# function call to start the
# tail recursion
count_pseudo_recursive(3)

Output
Counting 3
Counting 2
Counting 1
Counting 0

The above Python code gives output exactly the same as the normal Python code, with the tail-recursive structure. The only difference is, that this function can run for greater numbers without raising RecursionError in Python.

Explanation:

Advantages of this process:

Disadvantages of this process:


Article Tags :