lua中的尾调用优化

Bai*_*ang 12 lua tail-recursion tail-call-optimization

Lua声称它正确实现尾调用,因此不需要为每个调用维护堆栈,因此允许无限递归,我试图写一个求和函数,一个不是尾调用,一个是尾调用:

非tailcall版本

function sum(n)
    if n > 0 then
        return n + sum(n-1)
    end
end

print(sum(1000000))
Run Code Online (Sandbox Code Playgroud)

stackoverflow正如预期的那样.

tailcall版本

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)
Run Code Online (Sandbox Code Playgroud)

我想在这种情况下不存在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]: ?
Run Code Online (Sandbox Code Playgroud)

那么lua真的支持尾调用优化,或者我的函数实际上不是尾调用吗?

我在redhat 5上使用lua 5.1.4

pra*_*pin 21

Lua的尾巴呼叫必须具有以下形式

return fct(args)
Run Code Online (Sandbox Code Playgroud)

因此,您的尾部调用版本必须重写为:

function sum2(accu, n)
  if n > 0 then
    accu.value = accu.value + n
    return sum2(accu, n-1) --< note the return here
  end
end
Run Code Online (Sandbox Code Playgroud)

  • @NicolBolas我想我知道原因,对于lua,'sum2(accu,n-1)'与'sum2(accu,n-1)相同; return',not'返回sum2(accu,n-1)',所以很明显不是没有返回的尾调用. (4认同)