1972 ACM Turing Award Lecture [摘錄自 M.D. McIlroy,ACM Turing Award Committee 主席,於 1972 年 8 月 14 日在波士頓舉行的 ACM 年度會議上宣讀的圖靈獎致辭]

全球程式設計師的工作詞彙中,充滿了由 E.W. Dijkstra 開創或大力推廣的詞語——display、deadly embrace、semaphore、go-to-less programming、structured programming。但他對程式設計的影響力遠不止任何詞彙表所能概括。這份圖靈獎所表彰的珍貴禮物是 Dijkstra 的風格:他將程式設計視為一種崇高的智力挑戰;他雄辯地堅持並實際示範程式應該被正確地組成,而不僅僅是透過除錯達到正確性;以及他對程式設計基礎問題的獨到見解。他發表了約十多篇論文,既有技術性的,也有反思性的,其中尤其值得注意的是他在 IFIP a 的哲學性演講、他關於協同工作的循序程序的經典論文 b 以及他對 go-to 陳述式的難忘批判 c。Dijkstra 的一系列富有影響力的信件最近以經過潤飾的專著形式出現,論述了構成程式的藝術 d

我們珍視好的程式,其方式與我們珍視好的文學作品大致相同。而在這場運動的中心,E.W. Dijkstra 創造並反映著既美麗又有用的模式。

謙遜的程式設計師 (The Humble Programmer)

由 Edsger W. Dijkstra

由於一連串的巧合,我在 1952 年春天第一個早晨正式進入了程式設計專業,據我所知,我是我國第一個這樣做的荷蘭人。回想起來,最令人驚訝的是,至少在我所處的地方,程式設計專業出現的速度如此緩慢,現在看來這緩慢是如此令人難以置信。但我很感激在那段時期有兩個生動的回憶,它們毫無疑問地證實了這種緩慢。

在我程式設計大約三年後,我與當時在阿姆斯特丹 Mathematical Centre 擔任我老闆的 van Wijngaarden 進行了一次討論——我將終生感激他這次討論。當時的問題是,我理應在 Leiden 大學同時學習理論物理學,但由於我發現這兩項活動越來越難以兼顧,我必須下定決心,要么停止程式設計,成為一個真正的、受人尊敬的理論物理學家,要么只將物理學的學習形式化地完成,付出最少的努力,然後成為……,對,成為什麼?一個程式設計師?但這是一個受人尊敬的職業嗎?畢竟,程式設計是什麼?支撐它成為一門智力上受人尊敬的學科的健全知識體系在哪裡?我清晰地記得我當時多麼羨慕我的硬體同事們,當被問及他們的專業能力時,他們至少可以指出他們對真空管、放大器等一切都瞭若指掌,而我感覺到,當面對這個問題時,我將無言以對。我滿懷疑慮地敲開 van Wijngaarden 的辦公室門,問他是否可以與他談一會兒;幾個小時後,當我離開他的辦公室時,我已經是另一個人了。因為在他耐心聽完我的問題後,他同意當時程式設計還沒有太多學科規範,但他接著平靜地解釋說,自動計算機將會一直存在,我們只是剛剛起步,而我難道不能成為未來幾年將程式設計打造成一門受人尊敬的學科的人之一嗎?這是我生命中的一個轉捩點,我盡快形式化地完成了我的物理學學業。當然,上面故事的一個寓意是,我們在給年輕人建議時必須非常小心:有時他們真的會聽從!

兩年後,即 1957 年,我結婚了,而荷蘭的結婚儀式要求你陳述你的職業,我當時說我是個程式設計師。但阿姆斯特丹的市政府官員不接受,理由是沒有這個職業。信不信由你,我的結婚記錄上在「職業」一欄寫著荒謬的「理論物理學家」!

這就是我自己在國家程式設計專業緩慢出現的情況。從那以後,我走遍了更多地方,我的總體印象是,在其他國家,除了日期可能有所不同外,發展模式大致相同。

早期計算機環境 (The Early Computing Environment)

讓我試著更詳細地描繪那些老日子的情況,希望能夠更好地理解今天的狀況。當我們進行分析時,我們將看到許多關於程式設計任務真正本質的常見誤解都可以追溯到那個遙遠的過去。

第一批自動電子計算機都是獨一無二的單一複本機器,它們全都位於充滿實驗室興奮氛圍的環境中。一旦自動計算機的願景出現,其實現對當時可用的電子技術是一個巨大的挑戰,有一點是肯定的:我們不能否認決定嘗試建造如此奇妙設備的團隊的勇氣。因為它們確實是奇妙的設備:回想起來,我們只能驚訝於那些第一批機器竟然能夠運轉,至少有時是如此。壓倒一切的問題是讓機器處於並保持工作狀態。對自動計算物理方面的全神貫注,至今仍反映在該領域較老的學術團體的名稱中,例如 Association for Computing Machinery 或 British Computer Society,這些名稱明確提到了物理設備。

那可憐的程式設計師呢?老實說,他幾乎沒有被注意到。首先,第一批機器太笨重了,幾乎無法移動,除此之外,它們需要大量的維護,因此人們嘗試使用機器的地方恰好是機器開發所在的實驗室,這完全是順理成章的。其次,程式設計師有些不為人知的工作沒有任何光環:你可以向訪客展示機器,這比幾頁程式碼壯觀幾個數量級。但最重要的是,程式設計師本人對自己的工作抱持著非常謙遜的看法:他的工作所有的意義都來自於那台奇妙機器的存在。因為那是一台獨一無二的機器,他非常清楚他的程式只有局部意義,而且因為很明顯這台機器壽命有限,他也知道他的工作很少會具有持久價值。

最後,還有另一個情況對程式設計師對待工作的態度產生了深遠的影響:一方面,他的機器除了不可靠之外,通常太慢且記憶體太小,換句話說,他面臨著束縛,而另一方面,它通常有點奇特的指令集卻能應付最意想不到的結構。在那些日子裡,許多聰明的程式設計師從他們設法將不可能的事情擠進設備限制中的巧妙技巧中獲得了巨大的智力滿足感。

早期觀點與軟體危機 (Early Views and the Software Crisis)

關於程式設計的兩種觀點可以追溯到那些日子。我現在提及它們;稍後我將回到它們。一種觀點是,一個真正有能力的程式設計師應該喜歡解謎並且非常喜歡巧妙的技巧;另一種觀點是,程式設計不過是為了優化計算過程的效率,無論是在哪個方向。

後一種觀點是當時可用設備通常嚴重不足的結果,那些日子裡經常遇到天真的期望,一旦有了更強大的機器,程式設計就不再是問題,因為屆時就不再需要為了將機器推向極限而奮鬥,而程式設計不就是關於這個嗎?但在接下來的幾十年裡,發生了一些完全不同的事情:出現了更強大的機器,不僅僅是強大了一個數量級,甚至幾個數量級。但我們發現自己並沒有處於永恆幸福、所有程式設計問題都已解決的狀態,而是深陷軟體危機!這是怎麼回事?

有一個次要原因:在一個或兩個方面,現代機器本質上比老機器更難處理。首先,我們有了 I/O interrupts,它們發生在不可預測和不可重現的時刻;與假裝是一個完全確定的自動機的舊循序機器相比,這是一個戲劇性的變化,許多系統程式設計師的白髮證明了我們不應輕描淡寫地談論這個功能所創造的邏輯問題。其次,我們有了配備 multilevel stores 的機器,這給我們帶來了管理策略的問題,儘管有大量文獻探討這個主題,但這些問題仍然相當難以捉摸。這是由於實際機器的結構變化而增加的複雜性。

但我稱這是一個次要原因;主要原因在於…機器已經變得強大幾個數量級了!坦白說:只要沒有機器,程式設計就完全不是問題;當我們有一些弱小的計算機時,程式設計成為一個溫和的問題,而現在我們有了巨大的計算機,程式設計也成為一個同樣巨大的問題。從這個意義上說,電子工業沒有解決任何一個問題,它只是創造了問題——它創造了如何使用其產品的問題。換句話說:只要機器是預算中的最大項,程式設計專業就可以用其笨拙的技術矇混過關;但這把保護傘將非常迅速地消失。總之,我們的第二個條件似乎也得到了滿足。

然後,在六十年代中期,發生了一些可怕的事情:所謂的第三代計算機出現了。官方文獻告訴我們,它們的價格/性能比是主要設計目標之一。但如果你將「性能」定義為機器各個元件的工作週期,這將無法阻止你最終設計出一種將大部分性能目標通過可疑的內部清理活動來實現的機器。如果你將價格定義為硬體成本,這也無法阻止你最終設計出一種極難程式設計的機器:例如,指令集可能強迫程式設計師或系統進行早期綁定決策,而這些決策導致的衝突實際上無法解決。在很大程度上,這些令人不快的情況似乎都變成了現實。

當這些機器宣佈並得知其功能規格時,我們中的許多人一定感到非常痛苦;至少我是如此。這種機器預計會大量湧入計算社群,因此其設計盡可能健全就顯得尤為重要。但其設計包含如此嚴重的缺陷,以至於我感覺計算科學的進步因此一次性被延遲了至少十年;那是我整個職業生涯中最黑暗的一周。或許現在最令人難過的是,即使經過這麼多年的挫折經驗,仍然有這麼多人真心相信某種自然法則告訴我們機器就應該那樣。他們通過觀察這些機器售出了多少台來平息他們的疑慮,並從這個觀察中獲得一種錯誤的安全感,認為設計畢竟沒有那麼糟。但仔細觀察,這種辯護與「吸菸一定是健康的,因為這麼多人吸菸」的論點具有相同的說服力。

正是在這方面,我感到遺憾的是,計算領域的科學期刊不習慣像評論科學出版物那樣評論新發佈的計算機:評論機器至少同樣重要。在這裡我必須承認一件事:在六十年代早期,我寫了一篇這樣的評論,打算提交給 Communications,但儘管我諮詢過的少數同事都極力建議我這樣做,我還是不敢,擔心這對我自己或編輯委員會來說都將會帶來太大的困難。這次壓制是我怯懦的行為,我對此越來越自責。我預見到的困難是因為缺乏普遍接受的準則,儘管我相信我選擇應用的準則的有效性,但我擔心我的評論會被拒絕或被視為「個人品味問題」而拋棄。我仍然認為這樣的評論將會極其有用,我渴望看到它們出現,因為它們的被接受出現將是計算社群成熟的明確標誌。

軟體發展里程碑 (Software Development Milestones)

我之所以關注硬體方面,是因為我感覺任何計算工具最重要的方面之一是它對嘗試使用它的人的思維習慣的影響,而且我有理由相信這種影響比人們通常認為的要強許多倍。現在讓我們將注意力轉向軟體方面。

這方面的多樣性如此之大,我必須僅限於幾個墊腳石。我痛苦地意識到我的選擇的任意性,並懇請你們不要對我對許多將不被提及的努力的讚賞得出任何結論。

最初有劍橋的 EDSAC [^1],我認為從一開始,副程式庫的概念就在該機器的設計及其使用方式中扮演了核心角色,這相當令人印象深刻。現在已經過去了將近 25 年,計算領域發生了巨大的變化,但基礎軟體的概念仍然存在,封閉副程式的概念仍然是程式設計的關鍵概念之一。我們應該將封閉副程式視為最偉大的軟體發明之一;它經歷了三代計算機,並且還將經歷幾代,因為它滿足了我們基本抽象模式的實現。遺憾的是,在第三代計算機的設計中,它的重要性被低估了,第三代計算機的算術單元中有大量明確命名的暫存器,這意味著副程式機制有很大的開銷。但即使這樣也沒有扼殺副程式的概念,我們只能祈禱這個突變不會是遺傳性的。

我想提及的軟體領域的第二個重大發展是 FORTRAN 的誕生。當時這是一個非常大膽的項目,負責它的團隊值得我們極大的讚賞。將僅在使用十年或更長時間後才顯現出的缺點歸咎於他們是絕對不公平的:具有十年成功預見能力的團隊是極其罕見的!回想起來,我們必須將 FORTRAN 評為一種成功的編碼技術,但它對概念構建的有效輔助非常少,而現在這種輔助是如此迫切需要,以至於可以將 FORTRAN 視為過時了。我們越早忘記 FORTRAN 的存在越好,因為作為一種思考工具,它已不再足夠:它浪費我們的腦力,而且使用它風險太大,因此成本太高。FORTRAN 的悲慘命運在於其廣泛的接受度,它在精神上將成千上萬的程式設計師束縛在我們過去的錯誤上。我每天都在祈禱我的程式設計師同胞們能找到辦法從相容性的詛咒中解脫出來。

我不想遺漏的第三個項目是 Lisp,這是一個性質完全不同的引人入勝的事業。它以一些非常基本的原則為基礎,展現了非凡的穩定性。除此之外,Lisp 還承載了相當多,從某種意義上說,是我們最複雜的計算機應用。Lisp 被戲稱為「濫用計算機最聰明的方式」。我認為這個描述是一個極大的讚美,因為它傳達了完全解放的味道:它幫助了我們許多最有天賦的同胞思考以前不可能思考的事情。

第四個要提及的項目是 ALGOL 60。至今 FORTRAN 程式設計師仍然傾向於根據他們正在使用的特定實現來理解他們的程式設計語言——因此八進制或十六進制轉儲的盛行——而 Lisp 的定義仍然是語言的含義和機制的工作方式的奇怪混合,著名的《ALGOL 60 演算法語言報告》(Report on the Algorithmic Language ALGOL 60) 是一個真正努力將抽象化向前推進關鍵一步,並以一種實作獨立的方式定義程式設計語言的成果。有人可能會爭辯說,在這方面它的作者們是如此成功,以至於產生了對其是否能被實現的嚴重疑問 [^e]!該報告光榮地展示了形式化方法 BNF (現在廣為人知的 Backus-Naur-Form,巴科斯-瑙爾範式) 的力量,以及仔細措辭的英文的力量,至少當被像 Peter Naur 這樣傑出的人使用時。我認為可以公平地說,很少有如此短的文檔對計算社群產生如此深遠的影響。多年後,ALGOL 和 ALGOL-like 這兩個名稱如此容易地被用作一個未受保護的商標,為一些有時幾乎不相關的較新項目增添榮耀,這對於 ALGOL 的地位來說是一種令人震驚的讚美。BNF 作為一種定義工具的力量導致了我認為是該語言弱點之一的地方:一個過於精巧且不太系統化的語法現在可以被塞進非常少的頁面中。藉助像 BNF 這樣強大的工具,《ALGOL 60 演算法語言報告》本應短得多。除此之外,我對 ALGOL 60 的參數機制越來越感到懷疑:它給予程式設計師太多的組合自由度,以至於其自信的使用需要程式設計師有強大的紀律。除了實現成本高昂之外,使用它似乎也很危險。

最後,儘管這不是一個令人愉快的話題,我必須提及 PL/I,一種程式設計語言,其定義文檔的規模和複雜性令人望而生畏。使用 PL/I 就像駕駛一架有 7000 個按鈕、開關和操縱桿需要操作的鋼琴。我完全無法理解,當我們基本的工具——程式設計語言——本身就因為其過於華麗而逃脫我們的智力控制時,我們如何能夠將日益增大的程式牢牢地掌握在我們的智力掌控之中。如果我必須描述 PL/I 對其使用者可能產生的影響,最接近的比喻就是毒品。我記得在一個關於高階程式設計語言的研討會上,一個自稱是 PL/I 熱心使用者的人發表了一個為 PL/I 辯護的演講。但在一個小時讚美 PL/I 的演講中,他卻設法要求增加約 50 個新的「功能」,完全沒想到他的主要問題來源很可能就是它已經包含了太多「功能」。這位演講者展現了所有令人沮喪的成癮症狀,他已經陷入精神停滯的狀態,只能不斷要求更多、更多、更多…

如果說 FORTRAN 被稱為一種嬰兒期疾病,那麼 PL/I,一個完全長成、具有危險腫瘤生長特徵的怪物,可能被證明是一種致命的疾病。

未來的願景與技術可行性 (Vision for the Future and Technical Feasibility)

過去就說到這裡。犯錯如果不能從中學習就沒有意義。事實上,我認為我們已經學到了很多,以至於在未來幾年內,程式設計可能與現在截然不同,如此不同,以至於我們最好為這種衝擊做好準備。讓我為你們描繪一種可能的未來。乍一看,這種關於程式設計在不遠的將來可能發生的願景可能會讓你們覺得完全不可思議。因此,請允許我補充一些可能會引導人們得出結論認為這個願景可能是非常真實的可能性。

這個願景是,在七十年代結束之前,我們將能夠以現在成本僅為百分之幾的人力年成本來設計和實現目前令我們的程式設計能力緊張的系統,而且除此之外,這些系統將幾乎沒有錯誤。這兩項改進是相輔相成的。在後一方面,軟體似乎與許多其他產品不同,在其他產品中,更高的品質通常意味著更高的價格。那些想要真正可靠軟體的人將會發現他們必須找到避免從一開始就引入大部分錯誤的方法,因此程式設計過程將變得更便宜。如果你想要更有效的程式設計師,你會發現他們不應該浪費時間除錯——他們根本不應該從一開始就引入錯誤。換句話說,這兩個目標都指向了同一個變化。

如此劇烈的變化在如此短的時間內發生將是一場革命,對於所有那些基於近期過去的平穩推斷——援引某些未成文的社會和文化慣性法則——來預測未來的人來說,這種劇烈變化的可能性一定微乎其微。但我們都知道,有時革命確實會發生!那麼這場革命的可能性有多大呢?

似乎有三個必須滿足的主要條件。首先,全世界必須認識到變革的必要性;其次,變革的經濟需求必須足夠強烈;第三,變革必須在技術上可行。讓我按順序討論這三個條件。

關於認識到對軟體更高可靠性的需求,我認為不再會有爭議了。僅僅幾年前情況還不是這樣:談論軟體危機簡直是褻瀆。轉捩點是 1968 年 10 月在 Garmisch 舉行的軟體工程會議,那次會議引起了轟動,因為它是第一次公開承認軟體危機。如今,設計任何大型複雜系統將是一項非常困難的工作已普遍被認識到,每當遇到負責這類任務的人時,你會發現他們對可靠性問題非常關切,這是理所當然的。總之,我們的第一個條件似乎得到了滿足。

現在談經濟需求。如今經常聽到一種觀點,認為在六十年代程式設計是一個過度支付的職業,未來幾年程式設計師的薪水可能會下降。這種觀點通常與經濟衰退聯繫在一起,但它可能是一種不同且相當健康的症狀的體現,即過去十年程式設計師的工作可能不如他們應有的那麼好。社會對程式設計師及其產品的表現感到不滿。但還有另一個重量更大的因素。在目前情況下,對於一個特定系統,軟體開發成本與所需硬體成本數量級相同是很常見的,社會或多或少地接受了這一點。但硬體製造商告訴我們,未來十年硬體價格預計將下降十倍。如果軟體開發繼續像現在這樣笨拙且昂貴,情況將完全失衡。你不能指望社會接受這一點,因此我們必須學會將程式設計的效率提高一個數量級。換句話說:只要機器是預算中最大的一項,程式設計專業就可以憑其笨拙的技術混日子;但這把保護傘將非常迅速地消失。總之,我們的第二個條件似乎也得到了滿足。

現在是第三個條件:技術上是否可行?我認為可能,我將提出六個論點來支持這個觀點。

對程式結構的研究表明,程式——即使是針對同一任務且具有相同數學內容的替代程式——在智力可管理性方面可能差異巨大。人們已經發現了一些規則,違反這些規則將嚴重損害或完全破壞程式的智力可管理性。這些規則分為兩類。第一類規則很容易通過機械方式實現,例如通過選擇合適的程式設計語言。例子包括排除 goto 陳述式和具有一個以上輸出參數的程序。對於第二類規則,至少我——這可能是我能力不足的原因——看不出如何通過機械方式實現它們,因為它似乎需要某種自動定理證明器,而我對其存在證明沒有把握。因此,目前以及可能永遠,第二類規則是程式設計師所需紀律的組成部分。我心中有一些規則如此清晰,可以教授它們,而且對於給定程式是否違反這些規則,永遠不需要爭論。例子包括任何迴圈都必須提供終止證明或說明不被重複陳述式執行破壞的不變關係的要求。

我現在建議我們將自己限制在智力上可管理的程式的設計和實現上。如果有人擔心這個限制太嚴格,我們無法接受,我可以向他保證:智力上可管理的程式的類別仍然足夠豐富,可以包含許多對於任何可算法解決的問題來說非常現實的程式。我們不能忘記,我們的業務不是製作程式;我們的業務是設計能展現期望行為的計算類別。將自己限制在智力上可管理的程式的建議是我的六個論點中前兩個的基礎。

論點一:由於程式設計師只需要考慮智力上可管理的程式,他所選擇的替代方案將變得容易處理得多。

論點二:一旦我們決定將自己限制在智力上可管理的程式的子集內,我們就已經一勞永逸地實現了對要考慮的解空間的巨大縮減。這個論點與論點一不同。

論點三基於程式正確性問題的建構性方法。現今常用的技術是先寫程式,然後再測試。但是:程式測試對於顯示錯誤的存在可能非常有效,但對於證明沒有錯誤則完全不足。顯著提高程式信心水平的唯一有效方法是給出令人信服的正確性證明。但不應先寫程式再證明其正確性,因為這樣做只會增加可憐程式設計師的負擔。相反:程式設計師應該讓正確性證明與程式同步發展。論點三主要基於以下觀察:如果首先問自己令人信服的證明結構是什麼,找到之後再構建一個滿足證明要求的程式,那麼這些關於正確性的考慮會轉變為非常有效的啟發式引導。這個方法根據定義只適用於我們將自己限制在智力上可管理的程式時,但它為我們提供尋找其中令人滿意的程式的有效手段。

論點四與設計程式所需的智力投入量如何取決於程式長度有關。有人認為存在某種自然法則告訴我們所需的智力投入量隨程式長度的平方增長。但是,謝天謝地,沒有人能夠證明這個法則,這是因為它不一定是真的。我們都知道,一個非常有限的推理能涵蓋無數情況的唯一心智工具稱為「抽象化」;因此,有效利用其抽象能力必須被視為一個稱職程式設計師最關鍵的活動之一。在這方面,指出抽象化的目的不是模糊,而是創造一個新的語義層次,在這個層次中可以絕對精確,這或許是值得的。當然,我曾嘗試找到一個根本原因,會阻止我們的抽象機制足夠有效。但無論我如何努力,我都沒有找到這樣的原因。因此,我傾向於假設——到目前為止尚未被經驗證偽——通過適當應用我們的抽象能力,構思或理解一個程式所需的智力投入不一定會超過與程式長度成比例的增長。這些調查的一個副產品可能具有更大的實際意義,並且事實上是我的第四個論點的基礎。這個副產品是識別出在整個程式構成過程中扮演關鍵角色的許多抽象模式。關於這些抽象模式的知識已經足夠多,你可以為其中每一個模式專門舉辦一場演講。當我意識到如果這些抽象模式在 15 年前是常識,那麼從 BNF 到語法導向編譯器的步驟,舉例來說,可能只需幾分鐘而不是幾年時,對這些抽象模式的熟悉和有意識的認識對我的影響才顯現出來。因此,我將我們近期關於重要抽象模式的知識作為第四個論點提出。

現在是第五個論點。它與我們試圖使用的工具對我們自身思維習慣的影響有關。我觀察到一種文化傳統,這種傳統很可能起源於文藝復興時期,即忽視這種影響,將人類心智視為其造物的至高無上且自主的主宰。但如果我開始分析我自己和我的同胞們的思維習慣,無論我是否願意,我都會得出一個完全不同的結論,即我們試圖使用的工具以及我們用來表達或記錄思想的語言或符號是決定我們能思考或表達什麼的主要因素!分析程式設計語言對其使用者思維習慣的影響,以及認識到,腦力如今是我們最稀缺的資源,這兩者共同為我們比較各種程式設計語言的相對優劣提供了一套新的標準。稱職的程式設計師完全了解自己頭腦的嚴格有限大小;因此,他以完全謙遜的態度處理程式設計任務,並且除其他外,他像躲避瘟疫一樣避免巧妙的技巧。就一種廣為人知的對話式程式設計語言而言,我從各方得知,一旦一個程式設計社群配備了該語言的終端,就會出現一種特定的現象,這種現象甚至有一個固定名稱:它被稱為「單行程式」(the one-liners)。它有兩種不同的形式:一個程式設計師將一個單行程式放在另一個程式設計師的桌子上,然後要么他驕傲地說它做什麼,並加上問題「你能用更少的符號編寫這個嗎?」——好像這有任何概念上的意義似的!——要么他只是說「猜猜它做什麼!」從這個觀察中我們必須得出結論,這種語言作為一種工具,是巧妙技巧的公開邀請;雖然這可能正是它吸引人的原因,即那些喜歡展示自己多麼聰明的人,但我很抱歉,我必須將這視為關於一種程式設計語言能說的最糟糕的事情之一。我們應該從近期過去學到的另一個教訓是,「更豐富」或「更強大」的程式設計語言的發展是一個錯誤,因為這些華麗的怪獸,這些特性的大雜燴,在機械和心智上都確實難以管理。我認為非常系統化且非常謙遜的程式設計語言有光明的前景。當我說「謙遜」時,我的意思是,例如,不僅 ALGOL 60 的「for 子句」,甚至 FORTRAN 的「DO 迴圈」都可能因為過於華麗而被淘汰。我用真正經驗豐富的志願者進行了一個小型的程式設計實驗,但出現了一些完全意想不到且完全偶然的事情。沒有一個志願者找到明顯且最優雅的解決方案。經過更仔細的分析,這發現有一個共同的來源:他們對重複的概念與與之相關的、需要逐步增加的控制變數的想法緊密相連,以至於他們在心智上被阻礙而無法看到明顯的解決方案。他們的解決方案效率較低,難以理解得多,並且他們花了很長時間才找到。這對我來說是一個啟示,也是一個令人震驚的經歷。最後,在某一方面,希望明天的程式設計語言與我們現在習慣的會有很大的不同:它們應該比以往任何時候都更大程度地鼓勵我們在我們寫下的結構中反映出為概念性地處理我們正在設計的複雜性所需的所有抽象化。這就是關於我們未來工具更具足夠性方面的內容,這是第五個論點的基礎。

順帶一提,我想警告那些將程式設計任務的難度等同於與我們目前工具不足之處的鬥爭的人,因為他們可能會得出結論,一旦我們的工具大大改善,程式設計就不再是問題了。程式設計仍然會非常困難,因為一旦我們從環境的繁瑣中解放出來,我們就會發現自己可以去解決目前超出我們程式設計能力的問題。

層次結構與挑戰 (Hierarchy and Challenge)

你們可能會質疑我的第六個論點,因為很難收集支持它的實驗證據,這個事實並不會阻止我相信它的有效性。直到現在我還沒有提到「層次結構」(hierarchy) 這個詞,但我認為可以公平地說,這是所有體現一個漂亮分解解法的系統的關鍵概念。我甚至可以更進一步,將它變成一個信條,即我們真正能夠滿意地解決的問題只有那些最終允許一個漂亮分解解法的問題。乍一看,這種對人類局限性的看法可能會讓你們覺得我們目前的困境相當令人沮喪,但我並不這麼覺得。恰恰相反,學習與我們的局限性共存的最好方法是了解它們。當我們足夠謙遜,只嘗試分解解法,因為其他努力都超出了我們的智力掌控時,我們將盡力避免所有那些損害我們以有益方式分解系統的介面。我不能不預期這將會一再地發現,一個最初難以處理的問題畢竟是可以被分解的。任何見過編譯階段中稱為「程式碼生成」(code generation) 的大部分麻煩都可以追溯到指令集的奇怪特性的人,就會知道一個簡單的例子,這是我心中所想的事情。漂亮分解解法更廣泛的適用性是我的第六個也是最後一個論點,支持當前十年內可能發生的革命在技術上是可行的。

原則上,我將由你們自己決定要給予我的考量多少權重,我非常清楚我無法強迫任何人分享我的信念。正如任何嚴肅的革命一樣,它將引起劇烈的反對,人們可能會問,阻礙這種發展的保守勢力會在哪裡。我預計它們不會主要存在於大型企業,甚至不會存在於計算機產業;我更預計它們存在於提供現今培訓的教育機構中,以及那些認為他們的舊程式非常重要而不值得重寫和改進的保守計算機用戶群體中。在這方面,令人遺憾的是,在許多大學校園裡,中心計算設施的選擇往往是由一些已經確立但昂貴的應用程式的需求決定的,而忽略了有多少成千上萬願意自己編寫程式的「小型用戶」將會因此選擇而受苦。例如,高能物理學太常以其剩餘實驗設備的價格來要脅科學社群。當然,最簡單的回應是斷然否認技術可行性,但我擔心你需要非常有力的論點來支持這一點。可惜的是,無法從「現今普通程式設計師的智力上限將阻止革命發生」的評論中獲得任何保證:既然其他人程式設計效率如此之高,他很可能無論如何都會被邊緣化。

也可能存在政治障礙。即使我們知道如何教育明天的專業程式設計師,我們所生活的社會是否會允許我們這樣做也不確定。教授方法論——而不是傳播知識——的第一個影響是增強那些已經有能力的人的能力,從而擴大智力差異。在一個利用教育系統作為建立同質文化的工具的社會中,在這種文化中,精英被阻止向上發展,培養有能力的程式設計師可能是政治上不可接受的。

讓我做個結論。自動計算機已經與我們共處了四分之一世紀。它們作為工具對我們的社會產生了巨大影響,但在這一能力方面,它們的影響與它們作為智力挑戰所產生的更深遠的影響相比,只是我們文化表面的漣漪。後者在人類文化史中是前所未有的。層次結構系統似乎具有這樣的特性:在一個層次被視為不可分割的實體,在下一層次更細緻的更低層次則被視為一個複合對象;因此,在每個層次可應用的空間或時間的自然粒度,當我們將注意力從一個層次轉移到下一層時,會下降一個數量級。我們理解牆壁是用磚砌成的,磚塊是用晶體構成的,晶體是用分子構成的,等等。因此,在一個層次結構系統中可以有意義區分的層次數量與最大和最小粒度之比的對數成正比,因此,除非這個比率非常大,否則我們不能期望有很多層次。在計算機程式設計中,我們的基本構件具有小於微秒的時間粒度,但我們的程式可能需要數小時的計算時間。我不知道有任何其他技術能覆蓋 10¹⁰ 或更大的比率:計算機,憑藉其驚人的速度,似乎是第一個為我們提供一個高度層次結構的人造物既可能又必要的環境。這個挑戰,即與程式設計任務的對抗,如此獨特,以至於這種新穎的體驗可以教導我們很多關於我們自身的事情。它應該加深我們對設計和創造過程的理解;它應該讓我們更好地掌控組織我們思緒的任務。如果它沒有做到這一點,依我看,我們根本就不配擁有計算機!

它已經教會了我們一些教訓,我在這次演講中選擇強調的是以下這一點。只要我們帶著對其巨大困難的充分認識來處理程式設計任務,只要我們堅持使用謙遜且優雅的程式設計語言,只要我們尊重人類心智固有的局限性,並以「非常謙遜的程式設計師」(Very Humble Programmers) 的姿態來處理這項任務,我們就能做得好得多。

[以下註腳的參考資料可在 859 頁的圖靈獎致辭摘錄中找到。]


  1. Some meditations on advanced programming, Proceedings of the IFIP Congress 1962, 535-538; Programming considered as a human activity, Proceedings of the IFIP Congress 1965, 213-217.
  2. Solution of a problem in concurrent programming, control, CACM 8 (Sept. 1965), 569; The structure of the "THE" multi-programming system, CACM 11 (May, 1968), 341-346.
  3. Go to statement considered harmful, CACM 11 (Mar. 1968), 147-148.
  4. A short introduction to the art of computer programming, Technische Hogeschool, Eindhoven, 1971.