當前位置:編程學習大全網 - 編程語言 - 為什麽說面向對象編程和函數式編程都有問題

為什麽說面向對象編程和函數式編程都有問題

 簡言之,不論是面向對象編程還是函數式編程,如果妳走了極端,那都是錯誤的。面向對象編程的極端是壹切都是對象(純面向對象)。函數式編程的極端是純函數式編程語言。

面向對象編程的問題

面向對象的問題在於它對“對象”的定義,它試圖將所有事情就納入到這個概念裏。這種做法極端化後,妳就得出來壹個壹切皆為對象思想。但這種思想是錯誤的,因為

有些東西不是對象。函數就不是對象。

也許妳會反駁,在Python和Scala語言裏,函數也是對象。在Python中,所有的含有壹個叫做__call__的方法的對象其實都是函數。類似的,在Scala語言裏,函數是擁有壹個叫做apply方法的對象。但是,經過認真的思考後,妳會發現,它混淆了源祖和衍生物的概念。函數是源祖,包含函數的對象實際是衍生物。__call__和apply它們自身首先就是要定義的所謂“函數對象”。Python和Scala實際上是綁架了函數,把它們監禁在“對象”裏,然後打上“__call__” 和 “apply” 標簽,把它們稱作“方法”。當然,如果妳把壹個函數封裝到對象裏,妳可以像使用壹個函數那樣使用對象,但這並不意味著妳可以說”函數也是對象“。

大多數的面向對象語言裏都缺乏正確的實現壹等(first-class)函數的機制。Java語言是壹個極致,它完全不允許將函數當作數據來傳遞。妳可以將全部的函數都封裝進對象,然後稱它們為“方法”,但就像我說的,這是綁架。缺乏壹等函數是為什麽Java裏需要這麽多“設計模式”的主要原因。壹旦有了壹等函數,妳將不再需要大部分的這些設計模式。

函數式編程的問題

相似的,函數式編程走向極端、成為壹種純函數式編程語言後,也是有問題的。為了討論這個問題,我們最好先理解壹下什麽是純函數式編程語言。出於這個目的,妳可能需要閱讀壹下Amr Sabry先生(他是我的博士導師)的What is a Purely Functional Language。概述壹下就是,純函數式編程語言是錯誤的,因為

有些東西不是純的。副作用是真實存在的。

所謂純函數,基本上就是忽略了物質基礎(矽片、晶體等)表現的特性。純函數式的編程語言試圖通過函數——在函數中傳入傳出整個宇宙——來重新實現整個宇宙。但物理的和模擬的是有區別的。“副作用”是物理的。它們真實的存在於自然界中,對計算機的效用的實現起著不可或缺的作用。利用純函數來模擬它們是註定低效的、復雜的、甚至是醜陋的。妳是否發現,在C語言裏實現壹個環形數據結構或隨機數發生器是多麽的簡單?但使用Haskell語言就不是這樣了。

還有,純函數編程語言會帶來巨大的認知成本。如果妳深入觀察它們,妳會看到monads使程序變得復雜,難於編寫,而且monad的變體都是拙劣的修改。monads跟Java的“設計模式”具有相同的精神本質。使用monad來表現副作用就像是visitor模式來寫解釋器。妳是否發現,在很多其它語言裏很簡單的事情,放到Haskell語言就變成了壹個課題來研究如何實現?妳是否經常會看到壹些有著諸如“用Monadic的方式解決壹個已經解決的問題”這樣標題的論文?有趣的是,Amr Sabry先生壹起合著了這樣壹篇論文。他試圖用Haskell語言重新實現Dan Friedman的miniKanren,但他不知道如何構造這些monads。他向Oleg Kiselyov——公認的世界上對Haskell類型系統知識最淵博的人——求教。而且妳可能不知道,Amr Sabry先生應該是世界上對純函數編程語言知識最淵博的人了。他們在 Oleg 的幫助下解決了疑難後壹起合著了這篇論文。諷刺的是,Dan Friedman——這個程序的原作者——在使用Scheme語言開發時卻沒有遇到任何問題。我在Dan的代碼基礎上重新實現了miniKanren,增加了壹個復雜的負操作。為了實現這個,我需要使用約束式邏輯編程和其它壹些高級的技巧。鑒於用Haskell語言重寫基本的miniKanren將兩位世界級程序員都難倒了的事實,我不敢想象如果用Haskell的monads如何能實現這些。

有些人認為monads的價值在於,它們“圈定”了副作用的範圍。但如果monads不能真正的使程序變得易於分析或更安全,這種“圈定”有什麽用呢?事實上就是沒用處。本身就跟副作用壹樣難於分析理解。沒有壹種東西可以說monads能使其簡單而靜態分析辦不到的。所有的靜態分析研究者都知道這點。靜態分析利用了monads的本質,但卻去除了程序員編寫monads代碼的負擔——而不是增加負擔。當然,過度的副作用會使程序很難分析,但妳也可以使用C語言寫出純函數,例如:

int f(int x) {

int y = 0;

int z = 0;

y = 2 * x;

z = y + 1;

return z / 3;

}

妳用匯編語言也能做到這些。純函數並不專屬於純函數式編程語言。妳可以用任何語言寫出純函數,但重要的是,妳必須也應該允許副作用的存在。

回首歷史,妳會發現,數學上的理想主義是純函數編程語言的背後推動力。數學函數簡單漂亮,但不幸的是,它們只是在妳構建原始純粹的模型時才好用。否者它們會變得很醜陋。不要被“範疇論”等標語嚇倒。我對範疇論了解很多。即使是範疇理論學家自己也稱其為“抽象無意義”,因為它們基本上就是用壹種怪誕的方式告訴妳壹些妳已經知道的事情!如果妳讀過Gottlob Frege的文章Function and concept,妳會吃驚的發現,在他的這篇論文前的大多數數學家都錯誤的理解了函數,而這僅僅是剛剛100多年前的事。事實上,數學語言上的很多事情都是有問題的。特別是微積分方面。編程語言的設計者們沒有理由要盲目的學習數學界。

不要盲目的愛上妳的模型

無論任何事情,當走向極端時都是有害的。極端化時,面向對象編程和函數式編程都試圖把整個世界裝入它們的特有模型中,但這個世界是在完全不依賴我們的大腦思考的情況下運轉的。如果以為妳有壹個錘子,就把所有東西都當成釘子,這明顯是不對的。只有通過認清我們的真實世界,才能擺脫信仰對我們的束縛。

不要讓世界適應妳的模型。讓妳的模型適應世界。

  • 上一篇:oracle 怎麽修改最大連接數
  • 下一篇:魔獸世界
  • copyright 2024編程學習大全網