If we could just have tail call optimization, I think we could make the rest work (well, maybe better lambdas, too).
Manually thunk/trampoline it?
class trampoline(object): def __init__(self, fn): self.fn = fn def __call__(self, *args, **kwargs): ret = self.fn(*args, **kwargs) while isinstance(ret, thunk): ret = ret() return ret class thunk(object): def __init__(self, fn, *args, **kwargs): self.__dict__.update(fn=fn, args=args, kwargs=kwargs) def __call__(self): if isinstance(self.fn, trampoline): return self.fn.fn(*self.args, **self.kwargs) else: return self.fn(*self.args, **self.kwargs) @trampoline def fact(n, accum=1): if n <= 1: return accum else: return thunk(fact, n-1, n*accum) print fact(1000) @trampoline def is_even(n): if n == 0: return True else: return thunk(is_odd, n - 1) @trampoline def is_odd(n): if n == 0: return False else: return thunk(is_even, n - 1) print is_even(1000001)
Manually thunk/trampoline it?
You only have to write thunk/trampoline utility once, and it is similar to how we do it in clojure.