lua中的尾部调用优化
Lua声称它正确地实现了tail调用,因此每个调用都不需要维护堆栈,因此允许无限递归,我尝试编写一个sum函数,一个不是tail调用,一个是tail调用: 非尾呼版本lua中的尾部调用优化,lua,tail-recursion,tail-call-optimization,Lua,Tail Recursion,Tail Call Optimization,Lua声称它正确地实现了tail调用,因此每个调用都不需要维护堆栈,因此允许无限递归,我尝试编写一个sum函数,一个不是tail调用,一个是tail调用: 非尾呼版本 function sum(n) if n > 0 then return n + sum(n-1) end end print(sum(1000000)) function sum2(accu, n) if n > 0 then accu.value = ac
function sum(n)
if n > 0 then
return n + sum(n-1)
end
end
print(sum(1000000))
function sum2(accu, n)
if n > 0 then
accu.value = accu.value + n
sum2(accu, n-1)
end
end
local accu = {value = 0}
sum2(accu, 1000000)
print(accu.value)
stackoverflow如预期的那样
tailcall版本
function sum(n)
if n > 0 then
return n + sum(n-1)
end
end
print(sum(1000000))
function sum2(accu, n)
if n > 0 then
accu.value = accu.value + n
sum2(accu, n-1)
end
end
local accu = {value = 0}
sum2(accu, 1000000)
print(accu.value)
我认为在这种情况下不会出现stackoverflow,因为它是一个tailcall,但由于stackoverflow,它仍然失败:
/bin/lua/5.1.4/bin/lua: tailcall.lua:13: stack overflow
stack traceback:
tailcall.lua:13: in function 'sum2'
tailcall.lua:13: in function 'sum2'
tailcall.lua:13: in function 'sum2'
tailcall.lua:13: in function 'sum2'
tailcall.lua:13: in function 'sum2'
tailcall.lua:13: in function 'sum2'
tailcall.lua:13: in function 'sum2'
tailcall.lua:13: in function 'sum2'
tailcall.lua:13: in function 'sum2'
tailcall.lua:13: in function 'sum2'
...
tailcall.lua:13: in function 'sum2'
tailcall.lua:13: in function 'sum2'
tailcall.lua:13: in function 'sum2'
tailcall.lua:13: in function 'sum2'
tailcall.lua:13: in function 'sum2'
tailcall.lua:13: in function 'sum2'
tailcall.lua:13: in function 'sum2'
tailcall.lua:13: in function 'sum2'
tailcall.lua:17: in main chunk
[C]: ?
那么lua真的支持尾部调用优化,还是我的函数实际上不是尾部调用呢
我在Redhat5上使用Lua5.1.4,lua中的Tail调用必须具有以下形式
return fct(args)
因此,您的尾部呼叫版本必须重写为:
function sum2(accu, n)
if n > 0 then
accu.value = accu.value + n
return sum2(accu, n-1) --< note the return here
end
end
功能sum2(累计,n)
如果n>0,则
累计值=累计值+n
返回sum2(accu,n-1)--<注意此处的返回
结束
结束
哦,是的-这正是原因!只是额外的“回报”,谢谢普拉平!但是lua怎么可能不知道这实际上是一个尾部呼叫:)“lua怎么可能不知道这实际上是一个尾部呼叫”我不明白你刚才问了什么。@NicolBolas我想我知道原因,对于lua来说,“sum2(acu,n-1)”和“sum2(acu,n-1)”是一样的;return',而不是“return sum2(accu,n-1)”,因此显然不是没有返回的尾部调用。