Skip to content

Instantly share code, notes, and snippets.

@hltbra
Created November 22, 2012 20:01
Show Gist options
  • Save hltbra/4132721 to your computer and use it in GitHub Desktop.
Save hltbra/4132721 to your computer and use it in GitHub Desktop.
tail call optimization decorator
import sys
def tail_recursion_with_stack_inspection(g):
'''
Version of tail_recursion decorator using stack-frame inspection.
'''
loc_vars ={"in_loop":False,"cnt":0}
def result(*args, **kwd):
if not loc_vars["in_loop"]:
loc_vars["in_loop"] = True
while 1:
tc = g(*args,**kwd)
try:
qual, args, kwd = tc
if qual == 'continue':
continue
except TypeError:
loc_vars["in_loop"] = False
return tc
else:
f = sys._getframe()
if f.f_back and f.f_back.f_back and \
f.f_back.f_back.f_code == f.f_code:
return ('continue',args, kwd)
return g(*args,**kwd)
return result
def tail_recursion(g):
'''
Version of tail_recursion decorator using no stack-frame inspection.
'''
loc_vars ={"in_loop":False,"cnt":0}
def result(*args, **kwd):
loc_vars["cnt"]+=1
if not loc_vars["in_loop"]:
loc_vars["in_loop"] = True
while 1:
tc = g(*args,**kwd)
try:
qual, args, kwd = tc
if qual == 'continue':
continue
except (TypeError, ValueError):
loc_vars["in_loop"] = False
return tc
else:
if loc_vars["cnt"]%2==0:
return ('continue',args, kwd)
else:
return g(*args,**kwd)
return result
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment