青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

coreBugZJ

此 blog 已棄。

你的編程語言能這樣做嗎 (轉)

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

    // 一個小例子:

    alert("I'd like some Spaghetti!");
    alert("I'd like some Chocolate Moose!");

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

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

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

    SwedishChef("Spaghetti");
    SwedishChef("Chocolate Moose");


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

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

 

    alert("get the lobster");
    PutInPot("lobster");
    PutInPot("water");

    alert("get the chicken");
    BoomBoom("chicken");
    BoomBoom("coconut");

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

    function Cook( i1, i2, f )
    {
        alert("get the " + i1);
        f(i1);
        f(i2);
    }

    Cook( "lobster", "water", PutInPot );
    Cook( "chicken", "coconut", BoomBoom );

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

你的語言能這樣做嗎?

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

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

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

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

    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]);
    }

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

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

現(xiàn)在,你可以把上面的代碼重寫成這樣:

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

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

    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 看起來非常的相似,你也許會想把它們的通用之處提取出來做成一個能把數(shù)組里的元素合并成一個值的通用函數(shù):

    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語言里有函數(shù)指針,但你必須進行聲明,并要在什么地方定義它)。面向對象的語言并沒有被證實可以允許你對函數(shù)做所有的操作。


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


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


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


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


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


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

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


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

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


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


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


糾正:我最后一次使用FORTRAN大概是27年前,很顯然它現(xiàn)在有了函數(shù)了。我還當是GW-BASIC呢。

posted on 2012-04-12 16:30 coreBugZJ 閱讀(2226) 評論(5)  編輯 收藏 引用 所屬分類: 技術視野SoftwareProgrammingLanguageLisp

Feedback

# re: 你的編程語言能這樣做嗎 (轉)[未登錄] 2012-04-12 19:19 cc

就知道你要說的是Lisp  回復  更多評論   

# re: 你的編程語言能這樣做嗎 (轉) 2012-04-12 20:25 lltg

C語言雖然有函數(shù),但是C語言不支持閉包。
雖然你可以再在函數(shù)外面套個結構體
struct cl {
void* func;
void* paramters[0];
}
但是這樣的封裝不僅是很丑,而且簡直能令人抓狂……  回復  更多評論   

# re: 你的編程語言能這樣做嗎 (轉)[未登錄] 2012-04-12 21:54 jk

匿名函數(shù)  回復  更多評論   


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            男同欧美伦乱| 欧美一区二区成人| 六月婷婷久久| 亚洲国产精品一区在线观看不卡| 久久久人成影片一区二区三区观看| 午夜久久久久久| 激情综合电影网| 欧美大胆a视频| 欧美绝品在线观看成人午夜影视| 国产精品99久久久久久白浆小说| 亚洲乱码日产精品bd| 欧美视频精品在线| 久久精品一区二区三区中文字幕 | 久久精品日产第一区二区| 欧美一区二区视频观看视频| 怡红院av一区二区三区| 亚洲国产精品一区二区三区| 欧美黄色网络| 午夜精品久久久久久久久久久久| 欧美在线黄色| 99视频日韩| 欧美在线|欧美| 一本色道久久综合亚洲精品不卡| 亚洲一区二区在线免费观看| 在线看视频不卡| 在线中文字幕不卡| 樱花yy私人影院亚洲| 99国内精品久久| 在线成人小视频| 亚洲午夜一区二区三区| 亚洲国产91| 亚洲免费中文| a4yy欧美一区二区三区| 小黄鸭精品密入口导航| 一区二区三区高清在线观看| 欧美一区=区| 亚洲天堂黄色| 免费久久99精品国产自在现线| 午夜视频在线观看一区| 欧美成人影音| 玖玖综合伊人| 国产精品性做久久久久久| 亚洲国产精品高清久久久| 国产区亚洲区欧美区| 亚洲毛片在线免费观看| 亚洲第一精品久久忘忧草社区| 亚洲图片欧美一区| 亚洲免费电影在线观看| 久久免费99精品久久久久久| 欧美一级片在线播放| 欧美天堂亚洲电影院在线观看| 欧美大片免费久久精品三p| 国产一区二区欧美| 亚洲一区三区电影在线观看| aa日韩免费精品视频一| 欧美暴力喷水在线| 欧美激情第8页| 影音先锋久久精品| 欧美中文字幕在线| 欧美一区日本一区韩国一区| 国产精品jizz在线观看美国| 亚洲精品一区中文| 亚洲精品偷拍| 欧美国产日韩二区| 亚洲国产电影| 日韩视频在线观看一区二区| 欧美成人免费在线视频| 亚洲丰满在线| 日韩一级不卡| 欧美日韩精品伦理作品在线免费观看 | 欧美粗暴jizz性欧美20| 亚洲第一搞黄网站| 亚洲人成欧美中文字幕| 欧美freesex8一10精品| 亚洲欧洲一级| 一区二区三区精品视频在线观看| 欧美精品久久久久久久久老牛影院| 欧美成人一区在线| 亚洲精品人人| 欧美三级欧美一级| 亚洲视频一区二区| 久久疯狂做爰流白浆xx| 国外成人在线视频| 久久久青草青青国产亚洲免观| 免费高清在线一区| 亚洲精品人人| 国产精品久99| 久久久一区二区三区| 欧美国产日本| 亚洲婷婷综合色高清在线| 国产精品私房写真福利视频| 欧美一区二区免费观在线| 欧美va亚洲va香蕉在线| 一区二区精品在线观看| 国产女主播在线一区二区| 久久亚洲私人国产精品va| 日韩一区二区精品| 久久九九免费视频| 91久久精品视频| 国产精品久久网| 久久久久久91香蕉国产| 亚洲黄色av| 久久不射2019中文字幕| 亚洲国产精品123| 国产精品爱啪在线线免费观看| 性色一区二区| 亚洲卡通欧美制服中文| 久久国产精品99久久久久久老狼| 亚洲国产精品福利| 国产精品视频在线观看| 巨乳诱惑日韩免费av| 亚洲性av在线| 亚洲成人资源| 欧美国产第一页| 亚洲天堂第二页| 亚洲国产导航| 久久婷婷一区| 欧美一区二区黄色| 一区二区欧美在线观看| 欲色影视综合吧| 国产欧美日韩麻豆91| 欧美精品自拍偷拍动漫精品| 性欧美1819sex性高清| 亚洲免费观看高清在线观看 | 欧美一区亚洲二区| 99国内精品| 亚洲国产精品久久久久婷婷884 | a4yy欧美一区二区三区| 精品91视频| 国产女人水真多18毛片18精品视频| 欧美大片免费观看在线观看网站推荐| 午夜精品久久久久久久99水蜜桃 | 久久国产精品久久w女人spa| 制服丝袜激情欧洲亚洲| 最新中文字幕一区二区三区| 免费在线亚洲| 久久另类ts人妖一区二区| 午夜精品久久久久久久久| 这里只有精品视频在线| 日韩视频永久免费| 亚洲精品国产拍免费91在线| 亚洲高清不卡一区| **欧美日韩vr在线| 好男人免费精品视频| 国产一区清纯| 激情六月婷婷久久| 精品福利电影| 亚洲第一在线综合在线| 亚洲第一伊人| 亚洲精品综合久久中文字幕| 亚洲欧洲精品一区二区三区波多野1战4 | 久热成人在线视频| 久久全国免费视频| 美女诱惑一区| 欧美女主播在线| 欧美日韩国产一区二区| 欧美日韩精品一区二区三区| 欧美日韩一二三四五区| 国产精品久久久久aaaa| 国产精品一级在线| 国产主播一区二区三区四区| 韩日精品在线| 亚洲精品久久久久久久久久久久久| 91久久精品一区二区别| 日韩一级在线| 午夜日韩福利| 欧美成人有码| 99re6这里只有精品| 亚洲一区影音先锋| 久久久久久91香蕉国产| 欧美刺激午夜性久久久久久久| 欧美日韩国产在线播放| 国产老女人精品毛片久久| 黄色成人av| 在线视频免费在线观看一区二区| 亚洲综合色在线| 久久久久久欧美| 亚洲国产精品久久久久秋霞不卡 | 亚洲国产成人久久综合一区| 亚洲乱码一区二区| 午夜亚洲视频| 欧美xxx成人| 国产欧美日韩视频| 亚洲欧洲综合| 久久精品在线观看| 亚洲精品视频中文字幕| 欧美在线国产精品| 欧美午夜激情视频| 在线观看一区二区视频| 亚洲图片在线| 免费91麻豆精品国产自产在线观看| 亚洲精品网站在线播放gif| 性久久久久久| 欧美色视频在线| 亚洲电影自拍| 久久精品毛片| 亚洲视频在线观看| 欧美不卡在线| 极品尤物一区二区三区| 日韩一二三区视频|