OOP和FP錯在哪裡?

banq發表於2013-11-13
物件導向和麵向函式一直在爭論,實際上純粹的OOP和純粹的FP都是極端的,對於OOP來講:存在的並一定都是物件,函式就不是物件;對於FP來說:存在的並不總是純粹的,副作用總是真實存在。

What’s Wrong with OOP and FP提出了以上觀點。

首先,OOP錯在哪裡?

對於OOP來講:存在的並一定都是物件,函式就不是物件。

OOP是錯誤的,因為其定義“物件”企圖適應一切。當到了極致時便是“一切都是物件”。但這種觀念是錯誤的。

你可能會認為,在Python或Scala 函式也是物件。在Python中,每一個物件的方法的__call__是一個函式。同樣,在Scala中,物件的方法命名也適用函式。但經過一番深思熟慮,你會看到,這是混淆了傳遞和根本基礎兩個概念,函式才是根本基礎,而傳遞的是包裝它們的物件。Python和Scala只是綁架了函式,把它們打入了牢獄“物件” ,然後給他們一個標籤是__call__或apply,然後再呼叫這些物件的方法。

當你包裝成函式成為一個物件時,你可以使用像一個物件去使用函式,但是這並不意味著你就可以說“函式也是物件” 。

大多數物件導向的語言也缺乏正確實現first-class的函式。一個極端是Java,不允許函式作為資料傳遞。您可以隨時用物件包裝函式,稱他們為“方法” ,但正如我所說,這是綁架。first-class的缺乏是主要原因,為什麼在Java有這麼多的“設計模式” 。一旦你有first-class函式,您將不需要任何設計模式

其次,FP錯在哪裡?
FP是錯誤的,當你走到極端,變成一個純粹的函式性語言,也是錯誤的,見Amr Sabry :What is a Purely Functional Language

對於FP來說:存在的並不總是純粹的,副作用總是真實存在。

純粹函式語言試圖重新實現宇宙,透過將宇宙一切輸入輸出。但是真實世界和模擬之間有一個相差,副作用是真實世界的,它真實存在物理世界,當我們進行模擬計算是也是必不可缺少的,純函式模擬它們註定是低效的,複雜的,甚至是醜陋的。 Haskell的同樣是不正確的。

純粹的函式性語言造成了巨大的認知成本。如果你看看他們的深入,monads單子使程式複雜,很難寫,monad單子變壓器只是醜陋的駭客而已,monads同樣於設計模式,用單子代表副作用很類似用訪問者模式去寫直譯器一樣。

當你使用Haskell做事時,你有沒有注意到其他語言實現起來多麼容易嗎?

Amr Sabry可能是世界上最純粹的函數語言程式設計語言知識最淵博的人,他透過一個小故事告訴我們:他們使事情不必要地複雜化。

有人說單子的價值是他們“劃去了”的副作用,但是單子不能使你的程式更容易分析或安全,這種劃去有什麼意義呢?

當然過度使用的副作用會讓程式更加難以分析,但你也可以在C語言中寫純函式:
int f(int x) {
int y = 0;
int z = 0;
y = 2 * x;
z = y + 1;
return z / 3;
}
你也可以使用匯編寫,純函式不只是屬於純函式語言,你可以在任何語言中編寫純函式,前提是,你得允許也能使用副作用。

回顧歷史,數學的理想主義是純粹的函式性語言的原動力。數學函式是簡單而美麗的,但不幸的是,只有當你的模型是純粹的,它們才工作得很好。否則,它變成難看。

不要害怕“範疇論”等流行語。我知道有相當數量的範疇論。即使類別理論家自己稱之為“抽象的廢話” ,因為它基本上是一個怪誕的方式表達你已經知道的東西!如果你讀了Gottlob Frege弗雷格文章的函式和概念,你會驚奇地發現,大多數數學家在他寫作之前就得到了錯誤的函式,這大概已經追溯到一百年以前。事實上,數學家用其語言已經做了這麼多錯誤的事情,特別是微積分之類的東西。沒有理由今天程式語言的設計者應該盲目地學習數學。


[該貼被banq於2013-11-13 14:14修改過]

相關文章