寫這樣的小函數,只是做一些遍歷數組,處理其中的每個元素的操作,這樣做究竟能得到多少好處?
那好,我們來回頭看一看map這個函數。當你需要對數組里的每個元素依次做一些操作時,實際情況是,你并不在乎處理這些元素的順序。你可以向前或向后遍歷整個數組,得到的結果是一樣的,不是嗎? 事實上,如果你的機器是2cpu的,你可以寫出一些程序讓每個cpu個處理一半的元素,你的map一下子就變快了2倍。
或者,只是個假設,在你遍布全球的數個數據中心里,你有成千上萬的服務器,你有一個非常非常大的數組,我說過,只是假設,它們裝載著整個互聯網的內容信息。那現在,你就可以在你的成千上萬的計算機上運行map函數,每個機器都能分攤掉計算中的一小部分任務。
所以,如今,舉個例子,要想寫出一個十分高效的能搜索整個互聯網內容信息的代碼,你只需要簡單的用基本搜索字符串當作參數來調用map函數就行了。
這里,我想請你們要真正注意的有趣的事情是,你會發現像map 和 reduce這樣的函數每個人都可以使用,當人們使用它時,你只需要找到一個編程能手寫出最困難的調用map 和 reduce 函數的代碼,讓它們能夠運行在全球大量的并行執行的計算機上,而以前舊的運行的很好的代碼只需要調用這個循環操作,唯一不同的是,它們獲得了比以前千萬倍快的速度,這意味著你能做瞬間處理完巨大的計算工作。
讓我再復述一遍。通過把通用的循環操作提取出來,你可以實現你想要的任何循環操作,包括實現出一種能隨硬件設備的增加而性能升級的效果。
我想現在你就該明白為什么我在前段時間寫的一篇文章里抱怨學校只教授計算機科學專業的學生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就是一個名詞的王國。