【问题标题】:tail call optimization in lualua中的尾调用优化
【发布时间】:2012-11-09 06:44:13
【问题描述】:

Lua 声称它正确实现了尾调用,因此每次调用都不需要维护堆栈,因此允许无限递归,我尝试编写一个 sum 函数,一个不是尾调用,一个是尾声:

非尾随版本

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

print(sum(1000000))

stackoverflow 符合预期。

尾随版本

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,因为它是一个尾调用,但由于 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真的支持尾调用优化,还是我这里的函数其实没有尾调用?

我在 redhat 5 上使用 lua 5.1.4

【问题讨论】:

    标签: lua tail-recursion tail-call-optimization


    【解决方案1】:

    Lua 中的尾调用必须具有以下形式

    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
    

    【讨论】:

    • 哦,是的 - 这正是原因!只是一个额外的“回报”,谢谢 prapin!
    • 但是 lua 怎么可能想不通这实际上是一个尾调用:)
    • "lua 怎么会不知道这实际上是一个尾调用"我不明白你刚才问了什么。
    • @NicolBolas 我想我知道原因,对于 lua,'sum2(accu, n-1)' 与 'sum2(accu, n-1); return',而不是'return sum2(accu, n-1)',所以很明显不是没有返回的尾调用。
    猜你喜欢
    • 2015-04-23
    • 2012-08-19
    • 2011-05-27
    • 2019-04-20
    • 1970-01-01
    • 1970-01-01
    • 2011-03-31
    • 2014-04-06
    • 1970-01-01
    相关资源
    最近更新 更多