標籤:

流派未月亭

流派未月亭

來自專欄霧雨魔法店92 人贊了文章

最近在群聊的時候,我們聊到了一個觀點。

亞里士多德時代的科學不可能容許黑魔法,因為亞式科學的核心是 - 用直覺觀察事物,得出物體的本質。黑魔法這種反常識的東西,只可能在可證偽科學體系下出現 - 這不你看,js就是現代產物(

我的一個寫C++的朋友趁機黑一把:『函數式編程也是現代產物』。

我想了想,拿出了收藏已久的The Craft Of Programming。

為什麼呢?很簡單:這本書是本Gateway Drug。

這是第13頁。很簡單的Imperative程序,跟FP的學院派黑魔法正好形成鮮明對比。

17頁開始教你怎麼自頂向下寫程序,很穩啊,一步一步來。

22頁。給出程序的時候還加入了大量assertion,保證出錯能debug到問題的那一行,很健壯啊。

這本書有400多頁,太長了,我得加快進度。跳到了第44頁,好像還行啊,這在說,假設滿足P下運行程序S1,會滿足Q,滿足Q下運行S2,會滿足R,滿足P下運行S1後接S2會滿足R。

直覺上還挺好理解的。。。不過為啥越來越學院派了?

89頁。我是在上邏輯學課程嗎?

95 97頁。函數出來情有可原,為啥出現了交換圖?喵喵喵?

159頁。be。。beta reduction?

178頁。有高階函數已經算不了啥了。

206頁。Environment跟Denotational Semantic都出來了。

到了這一步我們有啥?

program calculation(stepwise refinement)

equivalence law

type derivation

simply typed lambda calculus

environment

denotational semantic

這跟SML還差啥?

HM?(我們可以寫generic program,這些program等價於inline,然後因為是inline,所以有equivalence constraint。用這些constraint可以導致不需要寫類型,可以去推導)

ADT?(其實這門語言是Algol W,已經有ADT了)

First Class Reference?(且不說Reference怎麼算作函數式特性,這本書作者,John Reynold的Essence of Algol裡面就很好的引入了Reference。)

Garbage Collection?(試想像下C程序員指著Java程序員說你丫太學院派了)

所以說,你看看,Imperative Programming跟Functional Programming有啥本質區別呢?這些特性,每一個的加入都如此理所當然,但是那一步才算是一個『函數式編程語言』?

我們早就過了亞里士多德時代,發現了世界並沒有這麼多『本質』。無論是那種語言,都是一步步從已有語言摸索出來的,只要你跟著,每次都學一個最小改動,到最後,你也會發現『就這回事啊』。Lambda Cube是如此,Algol到Prolog是如此,Algol到Haskell更是如此。

既然編程語言之間並沒有本質差別,那,什麼是編程的流派?什麼是面向對象/函數式/過程式?編譯語言/解釋語言/機器語言/電路描述語言?

答:流派未月亭。沒有打錯。沒有發瘋。

在起初,John Mccarthy沒搞懂Lambda Calculus,導致JMC Lisp並不對應Lambda Calculus,連Lexical Scope都沒有。Lexical Scope是Algol加入的,而編程語言跟Lambda Calculus的對應是Landin發現的。但這不是跟ISWIM對應,是跟Algol!OOP的元老之一,Luca,做過ML Module的奠基性工作,另一個元老,Alan Kay,藉助了FExpr(MACLISP)的概念。Backus寫出了Fortran後廣播了不朽的Can Programming be liberated from Von Neumann Style?。借鑒了OO的Actor跟Algol的Scope的Guy Steel,又寫出了Scheme,之後本人更是投身於Java跟Fortress這兩門OO語言。而Algol,則受到了JMC吹枕邊風,加入了if else expression跟recursion。The craft of programming並不是偶然,而是必然:所有流派都在誕生之初互相糾纏,至今從未分開 - 這不你看,ICFP還會接OO paper,OOPSLA不也一樣,更不用說Scala這種融合兩種範式的語言(當然,這樣的work歷史上屢見不鮮。)。

另,各種編程語言之間,只要發展到了一定地步,就可以用庫實現各種feature。Scheme有lambda the ultimate imperative/goto,說只需要lambda就能實現assignment/dynamic scope/while/goto,Haskell有lazy functional state thread有typing dynamic typing有final tagless,要狀態要動態類型要封裝要可擴展性都可以自己隨手實現,smalltalk能用object代表conditional,scala能用object代表module。OCaml也實現了effect system,發現go full circle,跟Haskell用monad表示的extensible effect殊途同歸。而Haskell中通過first class Typeclass(Constraint,Dict)跟Constraint上定義subtyping typeclass,再加上Existential Type,就能隨意控制擴展性 - 我就玩過這樣的trick剛好3次。只要語言支持一定的功能,什麼範式都能加進去。所以你看,所有主流語言都是多』範式『的。到了這種地步,何必繼續拘泥於這種劃分?

編譯語言/解釋語言等更是虛妄,要知道,一個scheme就可以編譯成機器碼/有直接吃scheme表達式的機器/還有把scheme 程序弄成電路的嘗試。連system verilog都有class了,這等劃分的意義可在?

如果我想寫得好聽點,我可以說,因為絕大部分語言都有多種範式,範式定義永不明確,是由很多更小的,正交的feature一個個組成的,所以我們應該求同存異,拋棄各種範式的偏見,就跟過去跟現在一樣繼續互相學習。。。但是我不。

因為流派未月亭。

這就是編程的本質,編程的流派,編程的範式。流派未月亭。

就是如此荒謬,毫無意義。

只要我們一天還在用著『範式』去討論編程語言,我們就會永遠陷入這種情況:

如何通俗易懂地舉例說明「面向對象」和「面向過程」有什麼區別??

www.zhihu.com圖標面向對象編程是否是從根本上反模塊化且反並行的?為什麼??

www.zhihu.com圖標面向對象編程的弊端是什麼??

www.zhihu.com圖標如何通俗易懂地舉例說明「面向對象」和「面向過程」有什麼區別??

www.zhihu.com圖標

永遠。大家只是互相豎起遠離實際的符號,互相實施稻草人謬誤。Ad hoc polymorphism跟module成為OO的專利(而前者在Algol 68就有了,後者pascal的作者也加入了modula裡面)。而需要描述OO缺點的時候,則去稱之為『反模塊化』。structural programming最初是為了解決complexity產生的,卻稱為會造成雜亂的代碼。而函數式編程?大家都默認了ref,effect跟extensibility solution(final, row polymorphism, tagless)的不存在。。。

為什麼我們不能改變一下呢?比如說,談論subtyping,我們這樣做:

子類型(subtyping)是不是錯誤(ill-defined)的東西??

www.zhihu.com圖標subtyping和inheritance的區別是什麼??

www.zhihu.com圖標程序語言設計界是否開始認為 Subtyping 是 Anti-pattern??

www.zhihu.com圖標

談論mutability的時候,我們聊gedanken裡面的三種variable設計:

假設聲明了struct Point { int x, int y },

0:identifier就是指針,所有Point的x跟y都共享,毫無意義(只有snobol這樣做)

1:identifier綁定上指針,每一個Point內的x y都是可變的,無法控制mutability(C,Java)

2:identifier綁定上Value,然後有指針類型/值。如果需要任何的可變性,用Point*,然後update x通過構造新的point。然後通過sharing跟編譯手段降低開銷。(SML,OCaml,Haskell)

又或者,我們也可以談論各種effect system(MTL,State,ST,IO,Extensible,跟語言內建的effect system)來討論mutability。。。而不是,談論到mutability,就只會immutability是大勢所趨,implicit parallelism大法好,又或者immutable不符合計算機基本模型等myth。

這樣有啥壞處呢?為啥我們不這樣做?我不知道。也許,這樣我們就不能喊些看上去很酷的名字,就跟聖鬥士不能喊天馬流星拳一樣。

唉。


推薦閱讀:

WHAT?Ruby竟然失寵了?
編程語言-------7/25
mycat實現mysql分庫分表
簡析 Python 的 `NotImplemented`
如果每一種編程語言都是一位動漫美女,你會為誰打Call?

TAG:編程語言 |