天天看點

關于程式設計語言的一些趣史

關于程式設計語言的一些趣史

回顧曆史做仔細的分析與研究,總能給人意想不到的發現和驚歎。從認知的難易程度上來看,程式設計語言的範式可以按照如下的方式排序:最容易了解的是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這個語言範式下做事具備了很好的能力。可工作中所涉及到的軟體設計,則是在OO範式和functional programming範式下進行的。領域不同,自然是新手,碰壁也是自然之事。

再回到我們最開始的那個問題,為什麼程式設計範式會是以相反的認知方向來發展?因為這是按照“建構計算機領域”的難易程度在走,也即是背後的數學發展在展開,而不是程式設計語言使用的難易程度在發展。這是一門新興學科初期的發展特點——先考慮的是生産的便利性,再來是消費者的便利性。

========

Comments for 《Clean Architecture》

近期回顧

《他人皆蠢,嗎?》

《從Facebook面試看網際網路行業》

《GeekArtT兩周年》

如果你喜歡我的文章或分享,請長按下面的二維碼關注我的微信公衆号,謝謝!

關于程式設計語言的一些趣史

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

關于程式設計語言的一些趣史

繼續閱讀