關于編程語言的一些趣史

回顧歷史做仔細的分析與研究,總能給人意想不到的發現和驚嘆。從認知的難易程度上來看,編程語言的范式可以按照如下的方式排序:最容易理解的是structured programming,一根線從上往下;再來會稍微費點功夫理解的是object-oriented(OO)programming;更困難的是functional programming,相當抽象,整個就是一數學的抽象思維。
自然地,歷史的發展都是由簡單到復雜,我們會下意識地認為編程語言在歷史上的出現順序也應該是:structured programming、OO、functional programming。
但翻閱歷史,卻會驚訝地發現它們的出現順序竟然是反過來的!
-
structured programming是在1968年出現,其標志是Dijkstra(對,那個最短路徑算法里出現的名字)發表他的seminal paper 'Cooperating sequential processes’。
-
再來是更早的1966年,Dahl和Nygaard發現function call stack frame可以被放到heap去做,這標志著OO的出現。
-
而似乎最難以理解的functional programming,則幾乎可以追溯到1936年計算機被發明的時期。其標志是Alonzo Church推出lambda calculus。
另一件值得探討的事情是:為什么Dijkstra要引入structured programming?雖然從現在來看structured programming是如此的直觀,以至于你會問,為什么會過了那么久才引入structured programming?
在Dijkstra的時代,主流編程語言都不是structured的,到處充斥著goto所帶來的跳轉。為什么會遍地的goto呢?因為在計算機語言的莽荒時期,一切都是向機器看齊的。對于機器語言、匯編來講,指令集的各種jump操作是再平常不過的事情了。既然它們都有之靈跳轉,對應的編程語言怎么好意思說不支持goto呢?
所以,structured programming反而在當時是一種極端的非主流,因為它為programming給予了相當大的限制。
Dijkstra之所以要引入structured programming源自于他要把“計算機”這門學科變為科學的嘗試:將數學的公理化體系引入computer science(CS)。但經過大量嘗試后,他發現要為代碼構建牢固的數學公理體系著實不是一件容易的事情。而其中最大的問題障礙,就是goto帶來的不確定性。
于是,Dijkstra采用了數學家常用的研究方法:當需要推出一個漂亮的理論卻發現前提條件不夠時,就反過來先引入這個結論需要的前提假設。
于是,Dijkstra就直接把goto(至少是被濫用的goto)廢除掉。沒有了goto,雖然引入數學的嚴格證明會變得相當簡單,但這樣會不會限制語言的表達?又或者說,有些代碼是不是沒有了goto就無法寫出來呢?
說來也是歷史機緣,恰好在這個時候,Bohm and Jacopini在理論上證明了:所有的程序都可以被以下三種句式所替代: sequence, selection(if/then/else), iteration(for/while)。而這正好是Dijkstra所需要的,因為實現這三種語句完全用不到goto。于是,Dijkstra的為CS引入嚴格數學公理體系的壯舉也就水到渠成:所有的由sequence、selection(if/then/else)語句構成的程序,可以由數學枚舉法證明。而由iteration(for/while)語句構成的程序,則可以由數學歸納法完成。而structured programming這種被做了更多限制的編程范式也就應運而生。(很有意思的事情是,三種編程范式structured programming、OO、functional programming的引入,都是通過“限制功能”而非增加功能做出的,也即是,為了更強你需要更弱一點。更多討論可以參考我以前的一篇文章《為了快一點為什么卻要慢一點》。)
如果按照這樣的思維框架去思考算法,比如LeetCode中的算法題目,又會有一些驚人發現。我的一個想轉行做程序員的朋友曾跟我聊過這樣一段刷題感受:似乎算法題目都或多或少地在使用數學歸納法。這確實是很強的洞見。回顧起來,無論是divide-and-conquere還是dynamic programmming,這兩種作為算法基石的工具都運用到了數學歸納法的思維方式。前者(遞歸)是天然的數學歸納法處理方式,而后者則是做了空間復雜度優化的遞歸,同樣按照數學歸納法的方式做處理。
進一步,我們可以考察一些工作中遇到的問題。剛畢業工作的小白程序員常常會疑惑這樣一個事情,明明自己在學校中算法的造詣頗高,按道理說算法好不就是編程的功底好么,但為什么到了工作崗位中還是各種碰壁?
按照我們上面構建的思維框架,我們其實可以給出一種解釋:因為算法部分的修煉,僅僅保證了你在structured programming這個語言范式下做事具備了很好的能力??晒ぷ髦兴婕暗降能浖O計,則是在OO范式和functional programming范式下進行的。領域不同,自然是新手,碰壁也是自然之事。
再回到我們最開始的那個問題,為什么編程范式會是以相反的認知方向來發展?因為這是按照“構建計算機領域”的難易程度在走,也即是背后的數學發展在展開,而不是編程語言使用的難易程度在發展。這是一門新興學科初期的發展特點——先考慮的是生產的便利性,再來是消費者的便利性。
========
Comments for 《Clean Architecture》
近期回顧
《他人皆蠢,嗎?》
《從Facebook面試看互聯網行業》
《GeekArtT兩周年》
如果你喜歡我的文章或分享,請長按下面的二維碼關注我的微信公眾號,謝謝!

更多信息交流和觀點分享,可加入知識星球:

浙公網安備 33010602011771號