天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

你的編程語言能這樣做嗎?

  本文是從 Can Your Programming Language Do This? 這篇文章翻譯而來。

  一日,你查看你的程序代碼,你有兩大塊代碼看起來幾乎完全的一樣。事實上它們就是完全一樣,除了一個代碼里說的是“Spaghetti(意大利面條)”,另一個代碼里說的是“Chocolate Moose(巧克力慕絲)”。

//一個小例子:
alert("I'd like some Spaghetti!");
alert("I'd like some Chocolate Moose!");

  這個例子恰好是用Javascript寫的,但即使是你不懂Javascript,你也應該能看懂我說的。

  當然,重復的代碼看起來不太好。所以你決定寫一個函數:

function SwedishChef( food ) { alert("I'd like some "+ food +"!"); } SwedishChef("Spaghetti");
SwedishChef("Chocolate Moose");

  沒錯,這個例子很簡單,但你可以想出一些更有實際價值的例子。這樣做是更好一些,有很多理由,這些理由估計你都聽說過一萬遍了。可維護性,可讀性,抽象 = 好!

  現在,你又發現兩塊代碼幾乎完全一樣,除了一塊是不停的調用一個叫BoomBoom的函數,而一塊是不停的調用一個叫PutInPot的函數。除此之外,這兩塊代碼完全一樣。

alert("get the lobster");
PutInPot("lobster");
PutInPot("water");
alert("get the chicken");
BoomBoom("chicken");
BoomBoom("coconut");

  現在,你需要一個途徑,把一個參數傳遞到一個函數里,而這個參數本身是個函數。這是一個很重要的功能,它是一個好的方法,能讓你發現函數中存在的重復的代碼,減少這樣的重復。

function Cook( i1, i2, f ) { alert("get the "+ i1); f(i1); f(i2); } Cook("lobster","water", PutInPot );
Cook("chicken","coconut", BoomBoom );

  看見了沒!我們把一個函數當做了參數。

  你的語言能這樣做嗎?

  且慢…如果你還沒有寫出PutInPot 或 BoomBoom 函數呢。如果你能把他們寫成內聯函數,而不是要在其它地方先聲明,這樣是不是更好?

Cook("lobster", "water", function(x){ alert("pot "+x); } );
Cook("chicken", "coconut", function(x){ alert("boom "+x); });

  老天,這太方便了。注意到了沒有,我即時創建了一個方法,甚至都不用麻煩給它起名,只需掂著它的耳朵把它丟進函數里。

  當你開始思考把匿名函數當作參數時,你也許會注意到有一種代碼到處都是,就是,遍歷數組里的所有元素進行操作。

var a = [1,2,3];
for (i=0; i<a.length; i++) { a[i] = a[i] * 2; }
for (i=0; i<a.length; i++) { alert(a[i]); }

  對數組里的每個元素進行操作是一種很常見的動作,你可以寫出一個函數,讓它為你做這些:

function map(fn, a) {
for (i = 0; i < a.length; i++) {
a[i] = fn(a[i]); }
}

  現在,你可以把上面的代碼重寫成這樣:

map( function(x){return x*2;}, a );
map( alert, a );

  另一個常見的跟數組相關的操作是,通過某種方式把數組里的所有值組合到一起。

function sum(a) { var s = 0; for (i = 0; i < a.length; i++) s += a[i]; return s; } function join(a) { var s = ""; for (i = 0; i < a.length; i++) s += a[i]; return s; } alert(sum([1,2,3]));
alert(join(["a","b","c"]));

  sumjoin 看起來非常的相似,你也許會想把它們的通用之處提取出來做成一個能把數組里的元素合并成一個值的通用函數:

function reduce(fn, a, init) {
var s = init;
for (i = 0; i < a.length; i++) s = fn( s, a[i] );
return s;
}
function sum(a) { return reduce( function(a, b){ return a + b; }, a, 0 ); } function join(a) { return reduce( function(a, b){ return a + b; }, a,""); }

  很多老式的語言根本沒有方法做出這種事情。另外一些語言允許你做這些,但不容易(例如,C語言里有函數指針,但你必須進行聲明,并要在什么地方定義它)。面向對象的語言并沒有被證實可以允許你對函數做所有的操作。

  如果你想在Java里把函數作為一個一等(First Class)對象,你需要建一個只包含一個用來調用功能點的方法的整個對象。把這種現象跟實際情況聯系起來,很多的面向對象語言都會要求你為每個class創建一個完整的文件,非常的沒效率。如果你的編程語言里要求你去這樣的調用功能點,那你根本沒有享受到現代語言環境給你帶來的所有好處。看看能否退貨吧,挽回一點損失。

  寫這樣的小函數,只是做一些遍歷數組,處理其中的每個元素的操作,這樣做究竟能得到多少好處?

  那好,我們來回頭看一看map這個函數。當你需要對數組里的每個元素依次做一些操作時,實際情況是,你并不在乎處理這些元素的順序。你可以向前或向后遍歷整個數組,得到的結果是一樣的,不是嗎?事實上,如果你的機器是2cpu的,你可以寫出一些程序讓每個cpu個處理一半的元素,你的map一下子就變快了2倍。

  或者,只是個假設,在你遍布全球的數個數據中心里,你有成千上萬的服務器,你有一個非常非常大的數組,我說過,只是假設,它們裝載著整個互聯網的內容信息。那現在,你就可以在你的成千上萬的計算機上運行map函數,每個機器都能分攤掉計算中的一小部分任務。

  所以,如今,舉個例子,要想寫出一個十分高效的能搜索整個互聯網內容信息的代碼,你只需要簡單的用基本搜索字符串當作參數來調用map函數就行了。

  這里,我想請你們要真正注意的有趣的事情是,你會發現像mapreduce這樣的函數每個人都可以使用,當人們使用它時,你只需要找到一個編程能手寫出最困難的調用mapreduce函數的代碼,讓它們能夠運行在全球大量的并行執行的計算機上,而以前舊的運行的很好的代碼只需要調用這個循環操作,唯一不同的是,它們獲得了比以前千萬倍快的速度,這意味著你能做瞬間處理完巨大的計算工作。

  讓我再復述一遍。通過把通用的循環操作提取出來,你可以實現你想要的任何循環操作,包括實現出一種能隨硬件設備的增加而性能升級的效果。

  我想現在你就該明白為什么我在前段時間寫的一篇文章里抱怨學校只教授計算機科學專業的學生Java知識而忽略其它:

缺乏對函數式編程的理解,你不可能發明出MapReduce——這個能夠讓Google實現大規模按需擴展和升級的算法。Map和Reduce這兩個詞來自于Lisp語言和函數式編程。回首看來,MapReduce對于任何還存有記憶的人來說都意味著一種純函數式的編程,沒有副作用,易于并行計算。事實恰巧是Google發明了MapReduce,而微軟沒有,這就說明了為什么微軟仍然努力做那些基本的搜索功能研究的原因了,而Google已經開始了它的下一個目標:開發它的SkyNET^H^H^H^H^H^H——這世界上最大規模的并行超級計算機。我并不覺得微軟已經認識到在如今的潮流中它已經落后的多遠。

  那么,我希望現在你已經能理解了以函數為一等(First class)特征編程語言能使你更容易的對代碼進行提煉抽象,這意味著你的代碼更短小,緊湊,可復用性強,更容易擴展升級。大量的Google應用程序都使用了MapReduce,在他們優化程序或修改Bug時,都能從中得到益處。

  現在我要說一點怨言牢騷,最高效的語言開發環境應該是一種能讓你在不同層次上進行抽象歸納的語言環境。笨拙陳舊的FORTRAN語言甚至不允許你寫函數。C語言里有函數指針,但實現的很丑陋,不能匿名,使用之前必須先進行聲明實現。Java允許你使用功能點調用(functor),但更加丑陋。就像Steve Yegge指出的,Java就是一個名詞的王國

it知識庫你的編程語言能這樣做嗎?,轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

主站蜘蛛池模板: 含羞草在线 | 欧美日韩一区不卡在线观看 | 乱码AV午夜噜噜噜噜 | 国产69精品久久久久人妻刘玥 | 亚洲无遮挡无码A片在线 | 四虎精品久久久久影院 | 蜜桃TV成人网站免费打开 | 狠日狠干日曰射 | 亚洲一区在线观看无码欧美 | 亚洲AV无码A片在线观看蜜桃 | 国产日韩高清一区二区三区 | 女子扒开腿让男生桶爽 | 日本十八禁无遮拦啪啪漫画 | 在线播放午夜理论片 | 忘忧草研究院一二三 | 99精品视频在线观看免费播放 | 欧美乱码伦视频免费66网 | 伊人伊人影院 | 伊人精品视频直播 | 日本福利片午夜免费观着 | 把腿张开再深点好爽宝贝动态图 | 一级做a爰片久久免费 | 少妇两个奶头喷出奶水了怎么办 | 亚洲国产精品一区二区三区在线观看 | 国产午夜精品理论片久久影视 | 在线观看中文字幕国产 | 久久精品国产只有精品 | 午夜不卡av免费 | 果冻传媒在线播放 免费观看 | 亚洲精品偷拍影视在线观看 | 尹人久久大香找蕉综合影院 | 大学生第一次破苞疼哭了 | 欧美大香线蕉线伊人久久 | 抽插性奴中出乳精内射 | 达达兔欧美午夜国产亚洲 | 久久免费资源福利资源站 | 广西美女色炮150p图 | 日本浴室日产在线系列 | 久久热这里只有 精品 | 国产亚洲精品首页在线播放 | 蜜芽tv在线观看免费网站 |