继前面理解了CPS后,尾递归的概念深化了我对函数式编程的理解。那Python作为一个不那么正宗的函数式语言。
自己能对尾递归优化么?我们来看个例子。
def fib(count, cur=0, next_=1):
if count <= 1:
return cur
else:
# Notice that this is the tail-recursive version
# of fib.
return fib(count-1, next_, cur + next_)
print fib(996)
#执行结果
RuntimeError: maximum recursion depth exceeded
>>>
看来就算我们的函数已经是尾递归形式了,堆栈还是会层层累计,996次就崩溃了。
再来看这个版本
def fib(count, cur=0, next_=1):
if count <= 1:
yield cur
else:
# Notice that this is the tail-recursive version
# of fib.
yield fib(count-1, next_, cur + next_)
print fib(996)
这样我们用关键字Yield代替Return把原来的函数变成了生成器。这样如果你只传入参数解释器是不会真正运行的!!!
#执行结果
<generator object fib at 0x02B00D00>
那我们怎么办呢,这里我们使用的技术称为Trampline,我们用一个方法让它不断执行生成器的next(),达到我们的目的。
import types
def tramp(gen, *args, **kwargs):
g = gen(*args, **kwargs)
while isinstance(g, types.GeneratorType):
g=g.next()
return g
print tramp(fib, 996)
#执行结果
3919377061614427623668052985592742430389065042819420493170692719480242247392252775480208752179017313071371501566248877239254299341332131655760767122899079117071192049598939666199865808814650408864891823186505
成功了,堆栈不会溢出了,尾递归被真的优化了!