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)) 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))