2012-11-09 77 views
12

lua聲稱它正確執行尾部呼叫,因此不需要爲每個呼叫維護堆棧因此允許無限遞歸,我試圖編寫一個總和函數,一個不是尾部呼叫,一個是尾部調用:lua的尾部呼叫優化

非尾調用版本

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) 

我想會有在這種情況下,沒有計算器,因爲它是一個尾調用,但它仍然失敗,原因是計算器:

/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真的支持尾部呼叫優化,或者我的功能其實不是尾巴呼叫嗎?

我使用紅帽LUA 5.1.4 5

回答

20

尾調用在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 
+0

哦,是的 - 這正是原因!只是一個額外的「回報」,感謝prapin! –

+0

但lua怎麼可能不知道這實際上是一個尾巴呼叫:) –

+1

「*盧阿怎麼可能不知道這實際上是一個尾巴呼叫*」我不明白你剛纔問。 –