Skip to content

Instantly share code, notes, and snippets.

@zyguan
Created June 20, 2016 14:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zyguan/e63fe64649ceb6cbdff14343c82bb24c to your computer and use it in GitHub Desktop.
Save zyguan/e63fe64649ceb6cbdff14343c82bb24c to your computer and use it in GitHub Desktop.
from inspect import isgenerator
def fact(n):
if n <= 1:
return n
else:
f = yield fact(n-1)
return f * n
def fib(n):
if n <= 1:
return n
else:
f_1 = yield fib(n-1)
f_2 = yield fib(n-2)
return f_1 + f_2
def xfib(n):
if n <= 1:
return n
else:
f_1 = yield from xfib(n-1)
f_2 = yield from xfib(n-2)
return f_1 + f_2
def fn(gen):
return cons(None, cons(gen, none()))
def none():
return ()
def cons(x, xs):
return (x, xs)
def head(xs):
return xs[0]
def rest(xs):
return xs[1]
def empty(xs):
return xs == none()
def run(xs):
if empty(xs): return xs
val, gens = xs
if empty(gens): return xs
ret = go(head(gens), val)
if isgenerator(ret):
return cons(None, cons(ret, gens))
else:
return cons(ret, rest(gens))
def go(gen, val):
try:
return gen.send(val)
except StopIteration as e:
return e.value
def inspect_run(gen):
f = fn(gen)
while not empty(rest(f)):
print("run {} <- {}".format(head(rest(f)), head(f)))
f = run(f)
print("return {} by {}".format(head(f), gen))
if __name__ == "__main__":
inspect_run(fact(4))
inspect_run(fib(4))
inspect_run(xfib(4))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment