trampoline
The `trampoline` library (version 0.1.2) provides a simple and tiny yield-based implementation of the trampoline technique in Python. It allows recursive functions to overcome Python's recursion depth limit by converting them into generators that yield subsequent recursive calls, which are then driven by a central `trampoline` function. This enables virtually infinite recursion without exhausting the call stack. The library has not seen recent updates, with its last release in 2018.
Warnings
- maintenance The `trampoline` library (v0.1.2) was last updated in 2018. While its core concept is stable, the lack of recent maintenance means it may not receive updates for new Python features, critical bug fixes, or security patches. Consider this for long-term project viability.
- gotcha Trampolined functions must be written as generators that `yield` the next recursive call, rather than calling it directly. Failing to `yield` will bypass the trampoline and lead to Python's `RecursionError`.
- gotcha When a trampolined function needs to return a value from a recursive step, the `yield` statement must be used as an expression to capture the result. Simply `yield`ing the call will not pass the return value back.
- gotcha The initial call to your trampolined generator function must be wrapped by the `trampoline()` utility function. The generator itself does not execute the trampoline logic.
Install
-
pip install trampoline
Imports
- trampoline
from trampoline import trampoline
- TailCall
from trampoline import TailCall
Quickstart
from trampoline import trampoline
def factorial(n):
"""Calculates factorial of n using a trampolined generator."""
if n <= 1:
return 1
# Yield the next recursive call, and receive its result
return (yield factorial(n - 1)) * n
# Run the trampolined function
result = trampoline(factorial(5))
print(f"Factorial of 5: {result}")
try:
# Example with a large number that would cause RecursionError normally
# result_large = trampoline(factorial(2000))
# print(f"Factorial of 2000: {result_large}")
print("Skipping factorial(2000) for quickstart brevity, but it would work.")
except RecursionError as e:
print(f"Caught expected RecursionError (if not trampolined): {e}")