perl python ruby_perl,lua,python,ruby的对比(3) -- lambda,closure,proper tail function call
今天的題目是函數(shù),先看一下匿名函數(shù)。
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概念,實(shí)現(xiàn)是這樣的,也可以通過全局函數(shù)apply調(diào)用任意的函數(shù)
f = lambda x,y,z : x+y+z
print f(1,2,3)
#or print apply(f, 1, 2, 3)
ruby沒有仔細(xì)看過,似乎必須這樣。可能由于ruby中所有的東西都是對(duì)象,所以一定要一個(gè)顯式的call來(lái)調(diào)用函數(shù),也可以使用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這個(gè)概念很難解釋,但是在腳本語(yǔ)言里的作用非常大,現(xiàn)在的腳本語(yǔ)言無(wú)一例外的支持它。主要的用途在于Callback函數(shù)和iterator中,也就是需要在一個(gè)函數(shù)需要保留一些外界的value時(shí),提供一個(gè)輕量級(jí)的方案。對(duì)象方法也能提供類似的功能,像C++中STL的iterator就是用inner
class實(shí)現(xiàn)的,C中的回調(diào)函數(shù)通常需要傳遞一個(gè)對(duì)象指針,在腳本語(yǔ)言中完全沒有必要這么復(fù)雜。各種語(yǔ)言實(shí)現(xiàn)基本一致,詳細(xì)的例子可以看看類似iterator的實(shí)現(xiàn)代碼或者Qt\GTK\wxWindows之類的腳本類庫(kù),看一個(gè)簡(jiǎn)單的例子。
Perl的實(shí)現(xiàn)
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里的實(shí)現(xiàn)
def CreateObj(str):
def callback(): print str," called"
return callback
call = CreateObj("CB1")
call()
lua里的實(shí)現(xiàn)
function CreateObj(str)
function callback()
print (str.." called")
end
return callback
end
call = CreateObj("CB1")
call
ruby里的實(shí)現(xiàn)
def CreateObj(str)
# use proc object instead of anonymous function
return proc { || print str, " called"
}
end
p1 = CreateObj("CB1")
p1.call()
最后看一個(gè)有趣的特性,叫做Proper tail call??聪旅娴膫未a
function test()
begin
return test()
end
這是一個(gè)典型的死循環(huán)遞歸調(diào)用,在絕大多數(shù)語(yǔ)言中類似的調(diào)用很快就會(huì)導(dǎo)致Stack
Overflow。但是在Perl和Lua中就不會(huì)發(fā)生,原因就在于當(dāng)解析器發(fā)現(xiàn)函數(shù)調(diào)用的最后一行是return一個(gè)函數(shù)調(diào)用時(shí),它就會(huì)很“智能地”把這個(gè)調(diào)用延后到函數(shù)返回之后再調(diào)用,這樣就避免了堆棧溢出的問題。所以下面兩段代碼也不會(huì)出問題。
Perl的代碼
sub cycle{
print "s\n";
return cycle();
};
cycle();
lua的代碼
function cycle()
local dir = io.read()
print (dir)
return cycle()
end
cycle()
上面的例子也許沒有什么實(shí)際用處,仔細(xì)想想這個(gè)特性在構(gòu)造狀態(tài)機(jī)之類的功能是非常有用的,比如一個(gè)狀態(tài)機(jī)有三個(gè)狀態(tài),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
給定一個(gè)初始狀態(tài)
init = state1()
然后整個(gè)狀態(tài)機(jī)就自動(dòng)地運(yùn)行下去了,節(jié)省了大量通常的狀態(tài)機(jī)編程需要考慮的狀態(tài)存儲(chǔ)、對(duì)象設(shè)計(jì)問題。
總結(jié)
以上是生活随笔為你收集整理的perl python ruby_perl,lua,python,ruby的对比(3) -- lambda,closure,proper tail function call的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 网络编程 异步io_异步I
- 下一篇: java file 字符串_Java读取