8.3 戴克斯特拉(Dijkstra)與「GOTO 害人論」:結構化控制流的勝利#
1968 年:一封兩頁的信改寫了行業#
Edsger W. Dijkstra(1930–2002,荷蘭)1968 年 3 月在 ACM 的 Communications 上發表了程式設計史上最著名的書信:〈GOTO 語句有害論〉(標題是主編的編輯成果,Dijkstra 原題更溫和)。
核心論證只用一段話:
我們的智力能力在處理「非靜態關係」時最為吃力。而 GOTO 的罪惡,正在於它使程式的執行位置無法被靜態文本所刻畫——變數的值在變化,而程式的位置也在跳躍,兩者的組合超出了人腦的分析能力。
翻譯成現代語言:「程式碼的文本結構應當與執行結構同構」。while 迴圈的文本邊界就是執行邊界;GOTO 則讓執行流像義大利麵——閱讀成本隨規模超線性增長。
論證的理論後盾:Böhm–Jacopini 定理(1966)#
結構化運動不是純修辭。1966 年 Böhm 與 Jacopini 證明:
任何可用 GOTO 表達的流程圖,都可以用三種結構——順序(sequence)、選擇(if)、迴圈(while)——組合表達。
即:結構化控制流在表達力上無損失。理論保證了可行性,Dijkstra 提供了品味與論證,二者合力完成了範式轉移。「先證明可以不失去什麼,再號召放棄它」——這是技術變革論證的黃金結構。
Dijkstra 其人:一位「反直覺」的程式設計哲學家#
Dijkstra 的貢獻遠超 GOTO 之戰(最短路徑演算法 1959、信號量與並行原語 1965、哲學家進餐問題、自穩定系統)。他的風格是程式設計史獨特的風景:
- 手寫 EWD 筆記(終身以鋼筆書寫,拒用電腦寫作!),編號 EWD1 至 EWD1318——一個人的思想期刊成為學科經典
- 名言製造機:「測試只能證明錯誤的存在,不能證明錯誤的不存在」;「電腦科學和電腦的關係,不大於天文學和望遠鏡的關係」
- 他的立場源於數學家的驕傲:程式應當像定理一樣可證、可推演——正確性靠設計而非除錯。這條路線後來成為形式化方法(Hoare 邏輯、SPARK、TLA+)的靈魂
「軟體危機」與 NATO 會議(1968):GOTO 之戰的制度背景#
GOTO 之戰不是孤立事件。1968 年秋,北大西洋公約組織在德國召開軟體工程會議——第一次把「軟體專案普遍超支、延期、失控」命名為危機。背景:
- 1960s 大型專案(IBM OS/360——布魯克斯《人月神話》1975 的素材庫)屢屢失控
- 硬體效能每兩年翻倍,軟體規模爆炸但人類的方法仍是手工藝
- 會議的藥方:結構化設計、模組化——「軟體工程」一詞誕生
GOTO 廢除 = 軟體危機的第一劑藥。之後的藥方依序登場:模組化(Parnas 1972 資訊隱藏)、物件導向(10–11 章)、敏捷(14.1)、DevOps、乃至今天的 AI 輔助——六十年來的軟體工程史,就是「馴服複雜性」的工具迭代史。
結構化程式設計的勝利路徑#
| 年份 | 事件 |
|---|---|
| 1966 | Böhm–Jacopini 定理 |
| 1968 | Dijkstra 書信 + NATO 會議 |
| 1971 | Wirth 的「逐步精化」方法論 |
| 1972 | Parnas〈模組化準則〉(資訊隱藏) |
| 1975 | 布魯克斯《人月神話》——危機的病理報告 |
| 1976 | McCabe 圈複雜度(用數字執行 GOTO 之戰) |
| 1980s | 結構化成為行業標準 |
有趣的最終形態:GOTO 沒有被語言層面禁止(C 至今保留),而是被文化與工具邊緣化(程式碼審查、靜態分析、圈複雜度指標)。範式轉移的最終載體不是語法,是社群的品味。
教育史的一課#
1970s–80s,結構化程式設計成為全球大學課綱(Pascal 是載體);BASIC 的 GOTO 教學法(Dijkstra 曾毒舌「受過 BASIC 訓練的學生在智力上不可挽回」)被逐步淘汰。這場教育的連鎖反應:
- 一代程式員養成了「程式 = 可推演的數學對象」的直覺
- 這種直覺是物件導向(封裝=結構化的延伸)與測試驅動開發(正確性可設計)的心理地基
- 而動態語言時代(14 章)與 AI 時代(17 章)的「快速原型」文化,實際上是對 Dijkstra 嚴格主義的反彈——紀律與速度的鐘擺,每二十年擺一輪
小結#
| 概念 | 內容 | 遺產 |
|---|---|---|
| GOTO 有害論 | 文本結構應與執行結構同構 | 可讀性成為工程核心價值 |
| Böhm–Jacopini | 順序/選擇/迴圈足夠 | 結構化有理論保證 |
| 軟體危機(NATO 1968) | 複雜性失控被制度化命名 | 軟體工程學科誕生 |
| Dijkstra 的嚴格主義 | 正確性靠設計不靠除錯 | 形式化方法傳統 |
ALGOL 與結構化運動為「組織大型軟體」備好了地基。第三篇的兩位主角——C 與 Smalltalk——將從「系統」與「建模」兩端接手。