perl python ruby_perl,lua,python,ruby的对比(3) -- lambda,closure,proper tail function call
今天的題目是函數,先看一下匿名函數。
Perl里是這樣的
$f = sub{ return $_[0]+$_[1]+$_[2];
};
print &$f(1,2,3)."\n";
lua里是這樣的
f = function(x,y,z) return x+y+z end
print (f(1,2,3))
python里使用了lambda概念,實現是這樣的,也可以通過全局函數apply調用任意的函數
f = lambda x,y,z : x+y+z
print f(1,2,3)
#or print apply(f, 1, 2, 3)
ruby沒有仔細看過,似乎必須這樣。可能由于ruby中所有的東西都是對象,所以一定要一個顯式的call來調用函數,也可以使用send方式
f = proc { |x,y,z| print x+y+z
}
f.call(1,2,3)
#or the small talk way
#f.send "call", 1, 2, 3
#k.send :call, 1, 2, 3
再看Closure,Closure這個概念很難解釋,但是在腳本語言里的作用非常大,現在的腳本語言無一例外的支持它。主要的用途在于Callback函數和iterator中,也就是需要在一個函數需要保留一些外界的value時,提供一個輕量級的方案。對象方法也能提供類似的功能,像C++中STL的iterator就是用inner
class實現的,C中的回調函數通常需要傳遞一個對象指針,在腳本語言中完全沒有必要這么復雜。各種語言實現基本一致,詳細的例子可以看看類似iterator的實現代碼或者Qt\GTK\wxWindows之類的腳本類庫,看一個簡單的例子。
Perl的實現
sub CreateObj
{
# parameter
my ($str) = @_;
# This is the closure function that saves external str
value
$callback = sub {
print "$str called\n";
};
return $callback;
}
$call = CreateObj("CB1");?&$call();
python里的實現
def CreateObj(str):
def callback(): print str," called"
return callback
call = CreateObj("CB1")
call()
lua里的實現
function CreateObj(str)
function callback()
print (str.." called")
end
return callback
end
call = CreateObj("CB1")
call
ruby里的實現
def CreateObj(str)
# use proc object instead of anonymous function
return proc { || print str, " called"
}
end
p1 = CreateObj("CB1")
p1.call()
最后看一個有趣的特性,叫做Proper tail call。看下面的偽代碼
function test()
begin
return test()
end
這是一個典型的死循環遞歸調用,在絕大多數語言中類似的調用很快就會導致Stack
Overflow。但是在Perl和Lua中就不會發生,原因就在于當解析器發現函數調用的最后一行是return一個函數調用時,它就會很“智能地”把這個調用延后到函數返回之后再調用,這樣就避免了堆棧溢出的問題。所以下面兩段代碼也不會出問題。
Perl的代碼
sub cycle{
print "s\n";
return cycle();
};
cycle();
lua的代碼
function cycle()
local dir = io.read()
print (dir)
return cycle()
end
cycle()
上面的例子也許沒有什么實際用處,仔細想想這個特性在構造狀態機之類的功能是非常有用的,比如一個狀態機有三個狀態,lua里可以這樣寫
function state1()
input = getinput()
if (input == 2) then
return state2()
end?if (input == 3) then
return state3()
end?end
function state2()
input = getinput()
if (input == 1) then
return state1()
end?if (input == 3) then
return state3()
end?end
function state3()
input = getinput()
if (input == 1) then
return state1()
end?if (input == 2) then
return state2()
end?end
給定一個初始狀態
init = state1()
然后整個狀態機就自動地運行下去了,節省了大量通常的狀態機編程需要考慮的狀態存儲、對象設計問題。
總結
以上是生活随笔為你收集整理的perl python ruby_perl,lua,python,ruby的对比(3) -- lambda,closure,proper tail function call的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 网络编程 异步io_异步I
- 下一篇: python3数据科学入门与实战_Pyt