Last active
November 10, 2018 04:31
-
-
Save sagnibak/c6d1c20373909b22bca8032525250c72 to your computer and use it in GitHub Desktop.
An example of tail-call elimination in Python using trampolining and thunkification. This shows how to implement tail-call optimization in a language that does not support it by default. Note that we don't really need the Thunk class in this example, but having an explicit Thunk class demonstrates the concept of thunkification.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Thunk: | |
def __init__(self, *args, **kwargs): | |
self.args = args | |
self.kwargs = kwargs | |
def trampoline(func): | |
def jumper(*args, **kwargs): | |
result = func(*args, **kwargs) | |
while isinstance(result, Thunk): | |
result = func(*result.args, **result.kwargs) | |
return result | |
return jumper | |
# tail recursive, but not optimized | |
def fact(n, k=1): | |
if n == 0: | |
return k | |
return fact(n - 1, n * k) | |
# tail recursive and optimized | |
@trampoline | |
def fact_optimized(n, k=1): | |
if n == 0: | |
return k | |
return Thunk(n - 1, n * k) # return a Thunk on the recursive call | |
if __name__ == '__main__': | |
try: | |
result = fact(1000) | |
except RecursionError as e: | |
print('We just blew up the stack!') | |
result = fact_optimized(1000) | |
print('1000! is', result) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment