Commit 09a6d962 authored by Jindřich Sedláček's avatar Jindřich Sedláček
Browse files

Added the tail recursion utility.

parent 8fa0cf1e
Loading
Loading
Loading
Loading

tailrecursion.py

0 → 100644
+51 −0
Original line number Diff line number Diff line
"""
This utility makes it easy to write recursion with tail call
optimization. To make a function utilize tail call optimization,
decorate a function with a "tail_call" decorator, and wrap the
return value with "Res", recursive descent with "Recursive".

TODO: support for tail call optimization when a different
function is called in return
"""

from __future__ import annotations


class Res:
    __slots__='res'

    def __init__(self, res):
        self.res = res


class Recursive:
    __slots__='args', 'kwargs'

    def __init__(self, *args, **kwargs):
        self.args = args
        self.kwargs = kwargs


def tail_recursion(f):
    def _wrap(*args, **kwargs):
        res: Res | Recursive = Recursive(*args, **kwargs)

        while isinstance(res, Recursive):
            res = f(*res.args, **res.kwargs)

        return res.res

    return _wrap


@tail_recursion
def factorial(x: int, accum=1):
    if x == 0:
        return Res(accum)
    return Recursive(x-1, accum*x)


print(factorial(10))
print(factorial(100))
print(factorial(10000))