Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
lua中的尾部调用优化_Lua_Tail Recursion_Tail Call Optimization - Fatal编程技术网

lua中的尾部调用优化

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

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 = 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)”,因此显然不是没有返回的尾部调用。