Haskell與Python中的一些概念,若有所悟

來源:互聯網
上載者:User

轉自:http://blog.csdn.net/tangboyun/archive/2010/04/03/5447688.aspx

    首先,必須聲明的是,下面所寫的內容,只是我個人的一些體驗和感悟,受限於個人的水平,肯定會有所紕漏甚至是誤導。

    2天前,我在Why learning Haskell/Python makes you a worse programmer連結了一幅Language Fans的搞笑圖片,如上。那時,並沒有細想,只是覺得單純的好玩。今天在學習Haskell中的Lazy IO特性的時候,突然,我想我想通了不少自學Haskell以來一些心中無人能解答的疑惑。同時也理解了,為什麼Haskell存在這麼一些令人非常不習慣的古怪的特性。

    everything,就在上面那幅圖片裡,它不僅僅只是為了搞笑,它有部分內容是實實在在的事實:你在haskell裡做的每一件事,就是圖片上愛因斯坦在黑板上寫的東西,“你一直都在寫公式 ”。

    什麼意思呢?在以C為鼻祖的過程式程式設計語言中,變數是變數,函數是函數。變數代表了資料的儲存,函數則代表了運算。可能你會說,不對阿,可以有函數指標阿。這裡要說明的是,為什麼說過程式編程裡變數和函數是分家的呢?因為過程式語言缺少Lazy evaluation。

當你寫下:

 

view plaincopy to clipboardprint?
  1. typedef int myFunTy(const char*)  
  2. //some code  
  3. myFunTy fp = atoi  

 

程式運行至第三行時,fp裡,就已經包含了函數地址。所以“=”在c這類語言裡,就叫做“賦值 ”,值就是資料。在過程式編程中所寫的程式的每一行,它的位置,都表示了“在實際運行中,執行的順序”,每執行完畢一行,則儲存結果以備後用。所以寫c程式,更像是在寫一份完整的實驗操作protocol,

然後把它交給聽話的乖學生去執行,這些三好學生從不偷懶,老師說什麼(也就是程式員你),他們就做什麼,說到哪裡,做到哪裡。(就跟提線木偶一樣)

    而在Haskell中,沒有資料這個概念,everything is a function,而且也沒有嚴格意義上的“賦值 ”,賦的是一種關係,或者裝b些,賦的是一種映射,“=”表明的是一種聲明、定義的意思(在c/c++中)。你做的任何事情都是在定義一個f(x)= .....,既然沒有“資料”,所以必須得有函數的函數,必須支援函數的局部聲明(這就是局部變數),寫整個程式就是f(x)=g(h(i(j(x))))這麼遞迴的定義下去,也因為這樣,Haskell裡才如此看中函數的pure屬性(純函數,同樣的輸入必定得到同樣的輸出),凡是與IO輸入輸出的都是impure的。。。。還記得小學四、五年級的數學考試嗎?我依稀記得,那時候最後幾道題叫啥“應用題”,解法基本就是先按照題目意思,寫個方程組, y=ax+b之類的,然後按照題目給的數字,把x用數字代入,之後就能求解了。在Haskell中,這個代入,不是你程式寫到哪裡,就馬上迭代的,而是使用了lazy evaluation。就好比,小時候放寒暑假,都是一開始稀裡糊塗的玩,到最後一兩周,哇,假期作業,那本大本子一個字都沒動,馬上開學要交了怎麼辦阿,假期最後幾天通宵惡補。。。。

    函數式編程和過程式編程在OOP上的實現也不同,不過或許確切的說,haskell並不算oop吧,在c++中,程式是通過類,也就是資料和與之相關的函數,作為整個程式的積木,最後一塊塊搭起來。而Haskell則似乎先把程式劈成兩半,一半是pure部分,也就是內部運算,不涉及io,這部分由各式多態函數拼接組成模組(強化了類似於shell中通道的概念),而另一半則由涉及io的impure部分組成介面,最後由介面掛載模組,組成程式,不過這一部分,讓我現在來談的話,功力還差太遠太遠。。。。。。。。。

    同樣有意思的,是Python語言,因為之前胡亂翻過一周的《Python學習手冊》(一不小心暴露了我的廢柴本質 ),也許是因為python之父有數學背景吧,很明顯的,我找到了Pyhon中,借鑒過Haskell的痕迹。

第一: python中的變數命名,使用的絕對不是自c/c++這類強型別過程式一脈手法,也和Perl這個弱類型不同(perl雖是弱類型並不能隨意綁定symbol),Python的處理更像是編譯器直接使用符號表中的符號,可以隨意綁定任何資料類型和函數。很明顯,在Python中,變數不過僅僅是一種映射關係f(x),並不是任何實體。

第二: python中也有著函數的局部定義和Lazy evaluation。函數可以嵌套在函數中定義,同時也可以在if../else..這類條件判別式中,根據條件判斷結果,將同一個symbol綁定到不同的函數上去,這點,是python具有lazy evaluation的證明。也就是必須在運行時決議出使用的函數,在直譯器解析原始碼階段是無法做到這點的。

第三: 這第三點,有了以上兩點以後,就很容易推斷出了。那就是現在的Python直譯器需要嚴格的縮排一致(Haskell也需要縮排一致,看出來了麼,為什嗎?),這並不是一個附帶的產物,或者說,像一般推薦讀物上說的那樣,是為了保持什麼代碼的美觀而刻意附帶的要求云云。No,事實不是這樣的,這個要求是因為如果不給局部函數定義以特殊的文法標示(lambada函數不是這裡所談的局部函數,因為不是條件編譯的,lambada只是個文法糖),就無法和全域函數定義進行區分,而如果所有函數都一律在運行時解析,效能會是慘不忍睹的。所以,縮排一致,是因為文法要求必須這樣做(否則就得修改,另行添加局部函數定義關鍵字),不然編譯器是無法完成推斷的,並支援lazy evaluation的條件編譯的。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.