跳轉到

5.1 告別組合語言:人類如何第一次用接近數學公式的語言寫程式?#

巴庫斯其人:從不務正業到正中靶心#

約翰·巴庫斯(John Backus, 1924–2007)的人生起點與工程師形象相去甚遠:維吉尼亞富家子弟、 化學系輟學、戰時當救護車司機、戰後在音樂學院學習(他自己說「對音樂的數學結構有興趣,但沒有天分」)。1949 年他糊裡糊塗走進 IBM,在 SSEC 電腦上找到了人生方向。他在哥倫比亞大學拿的學位是數學,卻從未正式學過計算——1950s 的計算機科學還不存在,先驅們全是轉行者。

1953 年,巴庫斯向 IBM 老闆提交了一份備忘錄,提議開發一個「自動程式設計」系統。次年(1954.11)著名的 PRELIMINARY REPORT 公布,宣告 Fortran(FORmula TRANslation,公式翻譯)誕生。

顛覆性的承諾#

Fortran 的設計目標寫得赤裸:

讓程式員用接近數學公式的語言寫程式,編譯後的機器碼效率達到手工組合語言的水平。

以當時的常識看,這是自相矛盾的要求。當時的共識是:編譯器必然產生冗餘代碼,高階語言只適合「不重要的小程式」。巴庫斯後來回顧,他們的動機一半是技術野心,一半是懶惰的經濟學:IBM 的客戶抱怨程式設計成本比機器還貴——程式設計人力成本超過硬體成本,這個 1950s 就出現的經濟信號,是每一波抽象化浪潮的根本驅動力(第 17 章的 AI Coding 是同一條經濟邏輯的延續)。

語言長什麼樣#

Fortran I 的典型程式(求二次方程根):

      FUNCTION QUAD(A, B, C)
      DISCR = B**2 - 4.0*A*C
      IF (DISCR) 10, 20, 30
   10 X1 = -999.
      X2 = -999.
      RETURN
   20 X1 = -B/(2.0*A)
      X2 = X1
      RETURN
   30 X1 = (-B + SQRT(DISCR))/(2.0*A)
      X2 = (-B - SQRT(DISCR))/(2.0*A)
      RETURN
      END

與數學公式的距離已經很近:B**2 - 4.0*A*C 幾乎就是 \(b^2 - 4ac\)。但也可見時代的胎記:算術 IF 的三路跳轉(IF (DISCR) 10, 20, 30)直接對應硬體的條件碼——語言的語法深深烙著目標機器的物理結構。列首的空格(第 7 欄之後才寫語句)源自打孔卡的格式傳統——媒介形態滲入語言語法,這個規律將在 Python 的縮排(第 12 章)再次出現。

為什麼是科學計算先行?#

Fortran 的第一市場是科學與工程計算,這不是偶然:

  1. IBM 704 的主要買家是軍方實驗室、核能機構、航空工程師(冷戰科研複合體)
  2. 浮點運算的 1950s 化(IBM 704 第一台硬體浮點)讓「公式」可以直接落地
  3. 科學用戶最痛:數學家不想學組語

Fortran 與核武、太空、氣象的共生:從氫彈計算、阿波羅軌道到氣象模式,Fortran 統治科學計算六十年。今天世界最快的超級電腦上跑的氣候與核融合模擬,核心仍多為 Fortran——一門語言的壽命,取決於它佔據的生態位是否長壽。

「程式設計人口」的第一次爆發#

Fortran 之後,寫程式不再需要理解電腦的內部結構。數據對比:

年代 程式員人口(美國,約) 主力語言
1955 數千 組語
1965 數萬 Fortran / COBOL / 組語
1985 數十萬–百萬 C / COBOL / Fortran
2005 數百萬 Java / C / VB
2025 數千萬 Python / JS / + AI 輔助

每一層抽象 = 一次人口擴容 = 一個新產業。程式語言史同時是勞動力結構史。 而巴庫斯 1977 年的圖靈獎演說《程式設計能從馮·諾伊曼風格中解放嗎?》回頭批判了自己創造的帝國——他晚年轉向函數式(FP 語言),呼喚回到 \(\lambda\) 演算的數學之根:發明者對自己創造物的反思,是語言史最有意味的段落。

為什麼「翻譯」這麼難:編譯器的誕生#

要讓機器理解 X = B**2 - 4.0*A*C,需要:

  1. 詞法分析:切成 token(X, =, B, **, ...)
  2. 語法分析:判斷結構(賦值語句,右邊是表達式樹)
  3. 語義分析:類型檢查(浮點 vs 整數)
  4. 中間表示 + 最佳化:消除冗餘、分配暫存器
  5. 代碼生成:輸出機器碼

這個流水線在 1954–57 年被巴庫斯團隊從零發明——沒有教科書、沒有形式文法理論(喬姆斯基 1956 年才發表第一篇論文!)。下一節我們看編譯器的工程細節,以及它與喬姆斯基的歷史性匯流。


下一節:5.2 編譯器的數學工程