天天看點

1972年Dijkstra的圖靈獎演講:謙遜的程式員

http://blog.jobbole.com/59449/

1952年初春的早晨,由于一系列巧合,我正式進入了程式設計界,成為了程式員曆史上第一位荷蘭人。回想起來,程式員作為一種職業,是以現在很難相信的緩慢速度出現的,至少在我所了解的範圍内是這樣,這讓人非常驚奇。那個緩慢時期的兩段清晰回憶讓我心存感激。

在有了三年程式設計經驗後,我和當時我在阿姆斯特丹數學中心的老闆 A. Van Wijngaarden(譯注:荷蘭數學家和計算機科學家),進行了一場讨論,關于這場讨論我在有生之年都會感激他。讨論的焦點在于,我本來是要在程式設計的同時,在萊頓大學學習理論實體,但是當發現魚和熊掌不可兼得時,我不得不做出選擇,要麼停止程式設計,成為一個名符其實的可敬的理論實體學家;或者把我的實體學研究敷衍了事,而成為一個…那個叫什麼?程式員?但那是個受人尊敬的職業麼?什麼又是程式設計呢?它作為一門學科所需要的完備知識體系又在哪裡呢?我非常清晰得記得自己有多嫉妒我從事硬體的同僚們,因為當被問到專業技能時,他們至少可以談自己所知道關于真空管,放大器,和其他一些硬體的一切;而被問到這個問題時,我隻能茫然無措。滿心焦慮,我敲開了 van Wijngaarden 的辦公室大門,問道:“是否能占用他一點時間”;而在幾個小時後離開他辦公室時,我整個人煥然一新。在耐心聽完我的問題後,他同意當時并沒有學科是關于程式設計的,但是他接下來解釋說,自動化電腦會繼續發展,而我們正處于摸索階段,那我能不能成為先驅者之一,使程式設計在未來成為一個受人認可的學科呢?這成了我人生中的一個轉折點,促使我盡快完成了我的實體學研究。上述故事的寓意是,我們必須謹慎地向年輕人提供意見,因為有時他們真的會聽的!

荷蘭婚禮儀式上有要求新人陳述職業的傳統,而兩年後的1957年,當我結婚時我宣告自己是一名程式員。但是阿姆斯特丹的市政當局沒有接受,理由是并不存在程式員這樣一種職業。不管你信不信,在我婚姻證書上“職業”這一欄裡,可笑的寫着“理論實體學家”!

關于程式員作為一種職業在我國的緩慢出現,就說這麼多了。從那時起,我見識到了外面的世界,留下的總體印象是,盡管起步的時間不同,但是其他國家的發展模式是大同小異的。

讓我嘗試更多地回顧下昔日的一些細節,以期更好地了解現在的情況。現在我們對問題進行分析時,應該知道,關于程式設計任務很多常見誤解是可以追溯到很久以前的。

1972年Dijkstra的圖靈獎演講:謙遜的程式員

Edsger W. Dijkstra

第一代的電子計算機是獨特的機器,并且隻能在各種進行開拓性試驗的實驗室裡被找到。從人類見識了自動化計算機那天起,實作它就是對當時現有的電子技術一個巨大挑戰,不過有一件事很确定,那就是我們不能否認那些緻力于開發這些裝置先驅們的勇氣。這些裝置是如此的令人驚奇,回想起來,至少是有時候,人們隻能懷疑,這些機器是否真的運作起來了。最難解決的問題就在于讓機器跑起來并讓其保持工作秩序。一些較老的計算機科學學會的命名中依然反映着自動計算機硬體方面的當務之急,如美國計算機協會(ACM)和英國計算機協會,這些協會的名稱中明确提到了實體裝置。

那麼可憐的程式員又是什麼樣的處境呢?實情是:他根本沒有被人注意。一方面,第一代計算機是如此得笨重,以至于無法搬來搬去,同時,它們又需要大規模的維護,是以很自然的,人們就在發明這些計算機的實驗室裡使用它們。另一方面,程式員的工作既不為人所知又缺少魅力,在打動參觀者的程度上,展示機器比展示幾頁代碼要高出幾個數量級。但是最重要的是,程式員以非常謙遜的眼光看待自己的工作:程式員工作的所有重要性都繼承自硬體裝置。因為每一台計算機都是不同的,程式員非常清楚,他的程式隻有在特定計算機上才能運作,并且由于計算機的壽命有限,導緻他的工作會随着機器的老化而喪失價值。最後,還有一種情況對程式員的工作态度産生了深遠的影響:一方面,除了不穩定,他工作的機器一般還存在運作緩慢、記憶體太小等問題,這讓巧婦難為無米之炊;另一方面,程式中通常又會存在少量古怪代碼來應對突發的狀況。在那些日子裡,有很多聰明的程式員通過一些巧妙的方法,使他的裝置可以完成一些本來不可能完成的任務,以這樣的方式來獲得智力上的巨大滿足感。

關于程式設計的兩種觀點就起源于那個時期。我現在提下這件事,等下會回到這個話題。一種觀點認為真正專業的程式員應該具有解決問題的頭腦,并且非常喜歡聰明的伎倆;另一種觀點認為,程式設計就是在某個方向上優化計算效率的過程。

後一種觀點源自于裝置落後的年代,那時候有些人簡單的期望着,一旦機器變得更為強大,程式設計将不會成為難題,到那時想盡辦法榨幹機器的性能将不再有必要,這就是程式設計的目的,難道不是嗎?但是下一個十年裡發生了巨變,更為強大的機器被造出來了,不是一個數量級的強大,而是好幾個數量級的強大。但是出人意料的是,我們并沒有一勞永逸地解決所有的問題,反而發現自己處在了軟體危機中!這是怎麼回事呢?

一個小小的原因是:現代計算機在一個或兩個方面比老式的計算機更難以操作。首先,現代計算機有I/O中斷,中斷的發生不可預知也不可重制,這個特性與能完全掌控運作過程的舊式計算機相比,是一個巨大的變化,但是這個特性會産生難以預料的邏輯錯誤,很多程式員花白的頭發見證了這一點。第二,現在的計算機配置了多級儲存設備,關于裝置管理的政策,雖然已經有大量的文獻,但是對我們來說仍然相當難以捉摸。關于計算機結構的變化所增加的複雜性就講這麼多了。

但是上面所舉的隻是“小”原因,真正大的原因是…現代計算機性能比原來強大了好幾個數量級!可以不客氣的說:當世上沒有計算機的時候,根本就不會有程式設計問題;當我們有了幾台性能弱小的計算機後,程式設計就出現小問題了,現在我們有了性能強大的計算機,程式設計自然變成了巨大的問題。在這樣的發展過程中,電子産業非但沒有解決一個問題,而是産生了問題,即使用産品所帶來的問題。換種方式說,如果現有計算機性能增長了千分之一,那麼社會對于使用這些機器的期望也會以同樣的比例增長,而可憐的程式員會發現自己處于到底是目的優先還是方式優先的緊張選擇中。硬體性能的提升,加上其可靠性甚至更急劇的提升,使得幾年前程式員做夢都不敢想的問題變得可以實作。而幾年後,他不得不夢見這個問題,更糟的是,他不得不将這樣的夢變成現實!那麼我們發現自己仍身處于軟體危機中是不是一個奇迹呢?當然不是了,正如你猜測的那樣,這些甚至是可以提前預知的,隻不過這種小衆預測的問題在于五年後你才能知道它是正确的。

接着在六十年代中期,有一件可怕的事情發生:所謂的第三代計算機出現了。官方的文獻表示,成本效益一直是他們主要的設計目标之一。但是如果你将機器衆多元件的占空比作為“表現”的衡量标準,你會看到一個記憶體被必要性存疑的内部常駐活動所占據的設計。如果你對于價格的定義是硬體的價值,你會看到一個對其程式設計極其困難的設計:舉個例子,無論對于程式員還是系統,用于執行的指令碼早期綁定所帶來的問題都不能真正得到解決。并且在很大程度上,這些令人不快的可能性看起來已經成為了現實。

當這樣的機器宣布發售,其功能規格為人所知後,我們之中的不少人肯定相當難受,至少我是這樣。第三代計算機的發行肯定會席卷計算機界,而人們更加期待它的設計能夠盡量健全。但是因為這樣一個有着如此嚴重缺陷的設計,讓我感覺到計算機科學至少退步了十年:這也讓我的職業生涯經曆了最為黑暗的一個星期。也許最可悲的事情是,即使有了這麼多年令人沮喪的經驗,依然有如此多的人天真的相信計算機必須是這樣。他們用機器的銷量來打消自己的疑慮,并且從這種觀察中得到使用這些機器是安全的錯覺,畢竟,機器的設計不可能那樣糟糕。但是仔細想想,這種被銷量欺騙的安全感就和吸煙必須是健康的說法相差無幾,因為吸煙的人很多。

正是這方面,我很遺憾,在發表對最新公布的計算機的評論時,計算機領域的科學期刊并沒有習慣像其他科學出版物那樣做出複查:對機器的複查至少應該同樣重要。這裡我要檢讨:在六十年代早期,我寫過這樣的評論并準備送出給CACM,盡管我沒有向同僚們尋求建議,但他們極力主張我這樣做,可我還是不敢,因為擔心這樣無論對我還是對編委會來說,困難都太大。是懦弱沒有讓我送出這樣一份報告,對此我越來越自責。我預見到的困難是當時缺乏普遍接受的标準,雖然确信自己的标準是正确的,但我還是擔心我的報告會被拒絕,或者被貼上“個人口味問題”的标簽。我仍然認為這樣的報告是及其有用的,并且渴望着它們的出現,因為它們的出現将代表着計算機界的成熟。

之是以對硬體保持上面提到那樣的關注,是因為我相信影響那些使用者的思考習慣是任何計算工具最重要的作用之一,并且我有理由相信,這種影響力比預期的更為強烈。現在讓我們的注意力回到軟體上。

由于軟體具有顯著的多樣性,我必須将自己限制在幾個立足點上。這使得我做出的選擇顯得很武斷,也讓我覺得很痛苦,希望大家不要是以懷疑我對其他沒有提到的努力的欣賞。

剛開始的時候,EDSAC 在英國的劍橋興起,我對其起初讓子程式庫在機器設計和使用方法中發揮主要作業的觀點印象深刻。接近25年後的今天,計算領域徹底的變化了,但是軟體的基本觀念還伴随着我們,閉合子程式的觀念也還是我們程式設計的核心概念之一。我們應該認可閉合子程式作為最偉大的軟體發明之一,它經曆了三代計算機的發展并且仍将繼續存活幾代,因為它迎合了我們基本抽象模式的接口思想。遺憾的是,在第三代計算機的設計中,它的重要性被低估了,而這個設計中,大量明确命名為寄存器的算術計算機關揭示了子程式機制的廣泛使用。盡管如此,也沒有讓子程式的概念就此消失,我們隻能祈禱這種變化不會在下一代的計算機中被遺傳。

我要講的第二個軟體業的主要發展是FORTRAN的誕生。在當時這是一個偉大而冒失的計劃,負責這個計劃的人們值得我們大聲地贊美。因為大約10年後才日漸明顯的外延錯誤用法而去責備他們是顯然不公平的:能夠成功預測十年後的團隊相當罕見。當我們回顧過去時,必須把FORTRAN看做一項成功但是對其産生概念基本沒啥幫助的編碼技術,在需求如此迫切的現在,這項技術已經過時了。我們應該盡快忘記FORTRAN,對于思想的馬車而言,它不再勝任:它浪費了我們的腦力,使用它過于冒險,是以也太過奢侈。FORTRAN的悲慘命運已經因為它廣泛的接受度,影響了數以千計的程式員為我們過去的錯誤買單。我每天都祈禱,會有更多程式員小夥伴找到從通用性的禍害中解脫出來的方法。

第三個不能忽略的就是LISP,一個完全與衆不同的迷人設計。基于LISP的幾個基本原則使得LISP展示出了非凡的健壯性。除此以外,LISP成為了相當多的複雜計算機載體。LISP曾經被調侃為濫用電腦的最智能方法。我想這種描述是一種很高的贊美,因為它傳遞了解放的氣息——它已經幫助我們之中最有天賦的人思考了之前不可能思考的東西。

第四個要提到的就是 ALGOL 60。到目前為止,FORTRAN程式員仍然傾向于從他們的開發中了解他們的程式設計語言——八進制的興起和十六進制的衰落;而LISP的定義依然是一種令人好奇的混合體,其中包括這門語言意味着什麼和這門機制是怎麼工作的,《算法語言》那篇著名的報告中說道,ALGOL 60是真正努力去承載抽象概念至關重要的一步,再加上通過獨立于語言之外的方法定義一門程式設計語言的成果。有人會說,ALGOL 60的作者們已經如此的成功,以至于他們自己引出這門語言是否可以實作産生的嚴肅疑問!那篇報告冠冕堂皇地展示了BNF範式(即現在人盡皆知的Backs-Naur-Form)的作用,和英語謹慎措辭的力量,至少是像Peter Naur一樣聰明的人使用時。我覺得可以負責任地說,基本沒有像它這麼短而在計算機界有相同影響力的文檔存在。人們習慣于使用用“ALGOL”或者是“類ALGOL”這樣未經保護的标簽,向大量基本不相關的年輕語言分享ALGOL的榮耀,這本身某種程度上就是對ALGOL驚人生命力的極大緻敬。BNF作為一種嚴格定義的語言,它的長處導緻了我個人認為是這門語言的缺點——過分精心制作并且文法定義不規則,很難在幾頁紙中完全說明。如果有個BNF般強大的裝置,《算術語言》中那篇關于ALGOL60的報告可以變得更短很多。除此以外,我對ALGOL60的參數機制表示懷疑,它賦予程式員如此多的組合自由,以至于要求程式員更自律。除了開發成本外,它使用起來似乎也很危險。

最後,盡管令人不太愉快,但我必須提及——PL/1,一門描述文檔非常龐大而且複雜的程式設計語言。使用PL/1就像開着一架有着7000個按鈕,使用開關和扳手操作的飛機。我完全不能了解怎麼靠智力來把握這種完全怪異的程式設計語言(我們的基本工具),使之保持穩定的發展,提醒你,這已經脫離我們智力的掌控了。還有如果非要描述PL/1對其使用者的影響,我腦海中最為形象的隐喻就是毒品。我記得這個出自一個自稱是PL/1的忠實使用者在一個進階語言的專題讨論會上做的一個演講。但是,在這個為期一小時充滿對PL/1贊美的演講中,他希望大家添加50種新特性,卻沒有想過他問題的源頭是這門語言已經包含了太多的特性。演講者展示了所有令人沮喪大的症狀,他陷入内心停滞,但是渴求更多。當FORTRAN被稱為嬰兒期的淩亂時,完整的PL/1卻是危險的惡性良性腫瘤,最後成長為了一種緻命病毒。

關于過去的事,就講這麼多吧。但是如果我們不能從中汲取教訓的話,制造錯誤是沒有任何意義的。事實上,我覺得我們學習了如此多的錯誤,以至于幾年後的程式設計可以和之前截然不同。讓我簡述下你們可能的未來。乍看一下,這種程式設計的想象也許會讓你不久的将來變得非常的不切實際。是以也允許加上也許會讓人得出“這個人的想象相對實際”的結論的考慮吧。

這種想象就是,在七十年代結束之前,我們有可能設計和實作那種盡量利用程式設計能力,開支是許多年前百分之幾的系統。此外,這些系統可以幾乎擺脫bug。這兩項提升相輔相成。在後一個方面,軟體看上去和許多其他産品不同,很多産品品質和價格是成正比的。那些想要真正有效的軟體的人将會發現他們必須從找到避免大多數bug的方法開始,最後,程式設計過程将變得便宜。如果你想要一些有能力的程式員,你将發現他們不會浪費時間在調試上,他們不應該以調試bug作為開始。換句話說,兩種目标指向同樣的變化。

在如此短的一段時間内發生如此激烈的變革,這會是一場革命,對所有人來說,基于他們對未來的期望,對過去(訴諸不成文的社會,文化惰性的法律)做出的和平推斷,這種巨大變革會發生的機會幾乎微不足道。但我們都知道有時候革命真的發生了。 那麼這次變革我們的機遇是什麼呢?

似乎有三個主要條件需要滿足。一般來說,世界必須承認需要變化,第二經濟需求十分強烈,還有第三,變革在技術上是可行的。讓我讨論按順序讨論一下上述三個條件。

談到對軟體更為可靠的需求,我表示完全同意。在幾年前,就不一樣了——讨論軟體危機是對上帝的亵渎。轉折點是 1968年十月在Garmisch舉行的軟體工程的學術會議,一次萌生了知覺承認軟體危機的回憶。到目前為止,普遍認為任何大型系統的設計都是一項十分困難的工作,無論何時,人們遇到負責這樣工作的人,都會發現他們非常關心可靠性問題。簡而言之,我們第一個條件似乎滿足了。

現在說到經濟需求。現在人們總是遇到說六十年代程式設計是一個薪酬過高的職業的觀點,并且說未來幾年内,程式員薪酬希望可以下降。通常,這種觀點的表述與經濟衰退有關,但這是一種不同,健康的事物的征兆——也許過去幾十年裡程式員沒有很好完成他們應該完成的工作。社會對程式員的表現和他們的産品感到不滿意。但還存在另外一種導緻重擔的因素。現在的情況是,對于特定的系統,為軟體更新的價格和更新硬體的價格在同一個數量級,社會或多或少接受了這一點。但硬體制造商告訴我們說在接下來數十年,硬體價格将會以十倍速度下降。如果軟體發展還是一如既往的笨拙,程式一如既往的昂貴,局勢将失去平衡。你不能指望社會接受這一點,是以我們必須學會有效的程式設計。 換句話說,隻要機器還是預算中的大項,那麼笨拙的程式設計技術還能僥幸逃脫,但是保護傘會快的折起來。總之,我們的第二個條件似乎也能滿足。

現在輪到第三個條件,技術上可行嗎?我覺得可行,我會用六個論據支撐我的觀點。

一份程式結構的研究表明程式,即便是同一個任務的替補程式和有着相同的數學内容,在程式管理方面都有着巨大的差異。研究發現許多規律,違反任何一條規律要麼局部或者整體的破壞程式的人為管理。這些規律不外乎兩種。第一種容易在實體上加以利用,即選用合适的程式設計語言。Goto語句的和多輸出參數的程式的剔除是很好的佐證。對于第二種,我至少看不到實體上使之暴露的方法(可能是我能力不足),好像需要一些我沒有證明存在的自動化的定理證明程式。是以,第二種規律時不時作為程式員訓練的要素之一出現。有些規律我清楚的知道以至于可以教給他人和不需要判斷一段給定的程式是否違反了。 我們給出必要的例子——任何循環需要給出終止條件或者聲明不變量之間的關系保證不變量不會被程式的循環語句執行而破壞。

我現在提議把我們限制在智能可控程式的設計和實作的範圍内。如果有些人害怕這種限制過于嚴格,我們沒有辦法存活,我保證智能可控程式的種類足夠的豐富,可以囊括現實很多能夠解決算術問題的程式。我們不能忘記我們的職業不是為了程式設計,而是設計能夠表現預設行為的計算類别。把我們限制在智能可控程式的建議是我所謂的六個論據的前兩個的基礎。

論據一,程式員隻要考慮智能可控問題,選擇更為容易考慮。

論據二,我們一決定把我們限制在智能可控程式的子集内,我們就一勞永逸的實作了考慮解決方案的空間的減少。

論據三是建立在程式正确性問題的建設性方法上的。今天,一項普通的技術就是寫一個程式,然後去測試。 盡管,程式測試是一種非常有效的方法去暴露bugs,但對證明不存在bugs幾乎是完全沒用的。顯著提高程式可信度唯一有效的方法是給出一個令人信服的關于正确性的證據。但是我們不應該首先寫出程式,然後去證明它的正确性,因為要求證明隻會增加苦逼程式員的負擔。相反,程式員應該讓正确性證明和程式互相驗證,發展。論據三本質上是從以下的觀察得來的。如果一個人問自己一個令人信服的證據應該具備什麼,他了解後,寫了一個很好的滿足了證明要求的程式,然後這些關于正确性的擔心變成一種有效的啟發式的指導。當我們把自己限制在智能可控程式時,按照定義,隻有這種方法是可行,但這種方法也提供許多有效的方法,讓我們從中挑選一個滿意的。

設計一個程式需要多少人力根據程式的長度判斷,論據四與此相關。曾經有人指出存在一種自然法則告訴我們耗費人力是程式長度的平方。但是謝天謝地,還沒有人能夠證明這種法則。這是因為它需要是假的。我們都知道能夠解決很多問題的推理論證工具稱之為抽象,抽象能力的有效開發可以被認為一個有能力的程式員至關重要的靈活之一。關于這一點,值得指出抽象的意圖并不是為了模糊本身,而是去創造新的準确語義水準。當然,我曾經嘗試去找到能夠阻止我們抽象機制起作用的基礎原因。但不管我多麼努力,我都找不到任何一個原因。最後,我傾向于假設(直到現在未通過經驗證明)我恰當的抽象化能力,也就是人力需要想象或者了解一個程式的耗費不會根據程式長度按照超過正比例的速度增長。但是這些調查的一個衍生品更有實際意義,實際上,它是我論據四的基礎。衍生品是許多在整個程式設計過程中扮演重要角色的抽象模式的識别。你了解這些抽象模式足夠多,你就可以就每個模式作報告。這些抽象模式的熟悉和了解讓我幡然醒悟,例如從BNF到方向句法編譯,可以用幾分鐘代替幾年的花費。 是以,我把我們最近對重要抽象模式的了解作為論據四。

現在說到論據五,它和我們建立在我們思考習慣上的工具的影響有關。我觀察到一種十有八九來源于文藝複興的文化傳統,為了忽略這種影響,需要把人心視為肉體最高自主的主人。 但我一開始分析我和同類的思考習慣時,我得到一個完全不同的結論,不管我喜歡與否,即我們使用的工具和我們用來表達或者記錄我們想法的語言或記号,是決定我們能夠想到什麼的主要因素。對程式設計影響程式員的思考習慣的分析和腦力是我們幾乎不曾使用的資源的認識,它們給出了從多方面給出不同程式設計語言優缺點的尺度。一個有能力的程式員能夠意識到他自己腦容量的嚴格尺寸,是以,他謙遜的完成程式設計任務,牽涉到其他事情時,他避免小聰明像躲避瘟疫一樣。說到一種著名的會話式程式設計技術,我從不同管道被告知說如果一個計算社群一旦裝備終端,一種特殊的現象就會發生,這種現象甚至有了一個被廣泛接受的名稱——打趣的人。它有一到兩種不同的形式,一個程式員在别人桌面放了一個調侃的程式,他要麼驕傲的展示它的用途并問别人你能用更少的字元寫完嗎(好像有任何概念的相關性一樣),要麼就問說猜猜這是用來幹嘛的。通過這個觀察,我們必須總結說這門語言是一種宣揚奇技淫巧的工具,同時這會是它的一些訴求的解釋,例如說那些喜歡展示他們有多聰明的人,對不起,但是我必須把它視作關于程式設計語言最令人惡心的地方。我們必須從過去學到的另外一課是所謂功能強大,豐富的程式設計語言的發展是一種錯誤,就像這些奇怪龐然大物,某人特有的氣質的聚集,都是心靈上,肉體上不可控的。我從系統的謙遜的程式設計語言上看到很美好的未來。 當我說謙遜時,我的意思是,例如,不僅是ALGOL60的for分支語句,還有FORTRAN的DO循環語句發現因為變得過于怪異而被淘汰。我曾經和一些有經驗的志願者做過一點程式設計實驗,但有些不期望發生和預料不到的事情發生了。我的志願者沒有一個找到明顯而漂亮的解決方法。通過更為細緻的觀察,我們找到相同的源頭:他們對與重複的概念與用于加速的聯合控制變量的聯系過于緊密,以至于他們被蒙蔽了完全看不到明顯的方法。他們的方法低效,晦澀難懂,并且耗費了大量時間。這是一段對我來說具有啟示作用,和令人震驚的經曆。最後,從某個方面上來講,如果一個人希望明天的程式設計語言和現在的大為不同,很大程度的優于現在的,他們應該邀請我們在我們寫下的所有需要用來應付概念上我們如今設計的抽象結構中思考。關于我們未來工具的優越性,也就是我們第五個論據的基礎,就講到這裡。

作為旁觀者,我希望提醒一下那些以現有工具不足而覺得程式設計任務困難的人。程式設計依舊會十分困難因為一旦我們從詳盡的笨重中解放出來,我們将會發現自己得以面對解決遠在我們程式設計能力以外的問題。

你可以不同意我的第六個論據,因為很難收據支援的實驗證據,但不能阻止我相信它的正确性。直到現在,我還沒有提到分層這個詞,但我認為把它作為一個所有收錄着一個精細分解解決方案的系統的核心概念是合理的。我甚至可以走更遠一步寫一篇關于信仰的文章,即我們能夠以令人滿意的方式解決的唯一問題是那些最後接受精細分解解決方案的問題。乍看之下,這種人類局限的觀點是一種令人抑郁的關于我們處境的觀點,但我恰恰相反,不這麼覺得。學會和我們的局限共存的方法就是了解我們的局限。等到我們足夠謙遜去嘗試分解方案的死後,因為其他形式的努力已經超過我們智力的掌控,我們将要盡最大的努力去避免所有這些内部損害我們以有用的方式分解系統的能力的交流。我不得不希望這不停的引領我們發現一個容易解決的問題最終也是可以分解的。任何一個看到了大多數所謂的“代碼生成”的編譯狀态的麻煩都可追溯到指令碼的有趣特性的人,都會知道一個我在腦海中想到的事情簡單示例。适用性更好的分解良好的解決方案是我第六個也是最後一個論據用于支援技術上可行的可能會在這十年發生的革命。

原則上,我把這些論據留給你,讓你決定我的考察占多少分量,因為我很清楚我沒有辦法強迫任何人跟随我的信仰。每次重要的變革都會招緻劇烈反對,每個人都可以問自己希望保守力量抵消多少發展。我不指望主要的大财團,甚至計算機領域的集團,我甯願希望教育機構提供教育訓練,希望那些保守團體的計算機使用者認為他們古老的程式很重要以至于不值得重寫或者優化。關于這一點,很多大學校園的中心電腦裝置的選擇視一些現成但昂貴且不理會千千萬萬願意自己程式設計的小使用者的問題的程式的需求而定,學校将為他們的選擇埋單,這是相當可悲的。這種事情太常發生,例如,高能實體似乎曾經用他們剩下的實驗裝置勒索科學社群。當然,最容易的解決方法,是對技術可行性的幹脆的拒絕,但我擔心你需要足夠支撐這種方法的論據。唉,現在普遍程式員的腦力水準可以阻止變革發生是得不到任何保證的,因為其他人的程式設計變得更為有效,程式員很容易在社會的版圖中被邊緣化。

還有很多政治方面的障礙。即便我們知道怎麼去培養未來的專業的程式員,我們不能确定社會允許我們這樣做。傳授方法論(而不是散布知識)的第一影響是增強了現有的能者的能力,是以拉大了智商上的差異。在一個教育系統是用來建立平均文化的社會,在一個精英不允許出現在頂層的社會,培養有能力的程式員在政治上是不對味的。

讓我總結一下。計算機已經伴随我們走過一個世紀的四分之一了。它們以工具的身份對我們社會産生了深遠的影響,但是和在人類曆史上史無前例的以智力挑戰的形式産生深遠的影響相比,它們隻能以波浪的形式影響我們文化的表面。似乎擁有決定在某種程度上将物體視作一個不可分割整體的權利的分層系統,被視作一個級别更低,細節更多的混合物,最後,當我們将注意力從一級轉向更低一級時,時空的天然粒面會以合适的數量級減少。 我們知道牆以磚為機關,磚以結晶體為機關,結晶體以分子為機關,等等。在分層系統中,許多級别可以有意義的區分出來,這和最大與最小粒度的比率的對數成正比,是以,除非比率很大,我們不能指望能夠分很多層。在計算機程式設計中,我們基本的程式設計語句有低于一微秒的時間粒度,但我們的程式卻可能花費幾小時的計算時間。我不知道任何一種超過10的10次方的比率的技術,以它超凡速度為優點的計算機,似乎是第一個給我們提供需要分層粒度大和實作它的環境的。這樣的挑戰,即面對程式設計任務,是獨一無二的,是以這樣小說一般的經曆可以教會我們很多關于自己的知識。它加深了我們對設計和創造程式的了解,它幫助我們更好的完成想法條理化的任務。如果它沒有這樣做,對我來說,我們根本不值得擁有計算機。

它已經給我們上了幾課,在這次演講中我要強調以下幾點。我們應該更好的程式設計,證明我們用滿是對任務帶來的巨大困難的感激的方法完成任務,證明我們堅持謙遜和優雅的程式設計語言,證明我們尊重人類内心固有的限制和以謙卑的程式員的身份完成任務。

1952年初春的早晨,由于一系列巧合,我正式進入了程式設計界,成為了 程式員曆史上第一位荷蘭人。回想起來,程式員作為一種職業,是以現在很難相信的緩慢速度出現的,至少在我所了解的範圍内是這樣,這讓人非常驚奇。那個緩慢時期的兩段清晰回憶讓我心存感激。

在有了三年程式設計經驗後,我和當時我在阿姆斯特丹數學中心的老闆 A. Van Wijngaarden(譯注:荷蘭數學家和計算機科學家),進行了一場讨論,關于這場讨論我在有生之年都會感激他。讨論的焦點在于,我本來是要在程式設計的同時,在萊頓大學學習理論實體,但是當發現魚和熊掌不可兼得時,我不得不做出選擇,要麼停止程式設計,成為一個名符其實的可敬的理論實體學家;或者把我的實體學研究敷衍了事,而成為一個…那個叫什麼?程式員?但那是個受人尊敬的職業麼?什麼又是程式設計呢?它作為一門學科所需要的完備知識體系又在哪裡呢?我非常清晰得記得自己有多嫉妒我從事硬體的同僚們,因為當被問到專業技能時,他們至少可以談自己所知道關于真空管,放大器,和其他一些硬體的一切;而被問到這個問題時,我隻能茫然無措。滿心焦慮,我敲開了 van Wijngaarden 的辦公室大門,問道:“是否能占用他一點時間”;而在幾個小時後離開他辦公室時,我整個人煥然一新。在耐心聽完我的問題後,他同意當時并沒有學科是關于程式設計的,但是他接下來解釋說,自動化電腦會繼續發展,而我們正處于摸索階段,那我能不能成為先驅者之一,使程式設計在未來成為一個受人認可的學科呢?這成了我人生中的一個轉折點,促使我盡快完成了我的實體學研究。上述故事的寓意是,我們必須謹慎地向年輕人提供意見,因為有時他們真的會聽的!

荷蘭婚禮儀式上有要求新人陳述職業的傳統,而兩年後的1957年,當我結婚時我宣告自己是一名程式員。但是阿姆斯特丹的市政當局沒有接受,理由是并不存在程式員這樣一種職業。不管你信不信,在我婚姻證書上“職業”這一欄裡,可笑的寫着“理論實體學家”!

關于程式員作為一種職業在我國的緩慢出現,就說這麼多了。從那時起,我見識到了外面的世界,留下的總體印象是,盡管起步的時間不同,但是其他國家的發展模式是大同小異的。

讓我嘗試更多地回顧下昔日的一些細節,以期更好地了解現在的情況。現在我們對問題進行分析時,應該知道,關于程式設計任務很多常見誤解是可以追溯到很久以前的。

1972年Dijkstra的圖靈獎演講:謙遜的程式員

Edsger W. Dijkstra

第一代的電子計算機是獨特的機器,并且隻能在各種進行開拓性試驗的實驗室裡被找到。從人類見識了自動化計算機那天起,實作它就是對當時現有的電子技術一個巨大挑戰,不過有一件事很确定,那就是我們不能否認那些緻力于開發這些裝置先驅們的勇氣。這些裝置是如此的令人驚奇,回想起來,至少是有時候,人們隻能懷疑,這些機器是否真的運作起來了。最難解決的問題就在于讓機器跑起來并讓其保持工作秩序。一些較老的計算機科學學會的命名中依然反映着自動計算機硬體方面的當務之急,如美國計算機協會(ACM)和英國計算機協會,這些協會的名稱中明确提到了實體裝置。

那麼可憐的程式員又是什麼樣的處境呢?實情是:他根本沒有被人注意。一方面,第一代計算機是如此得笨重,以至于無法搬來搬去,同時,它們又需要大規模的維護,是以很自然的,人們就在發明這些計算機的實驗室裡使用它們。另一方面,程式員的工作既不為人所知又缺少魅力,在打動參觀者的程度上,展示機器比展示幾頁代碼要高出幾個數量級。但是最重要的是,程式員以非常謙遜的眼光看待自己的工作:程式員工作的所有重要性都繼承自硬體裝置。因為每一台計算機都是不同的,程式員非常清楚,他的程式隻有在特定計算機上才能運作,并且由于計算機的壽命有限,導緻他的工作會随着機器的老化而喪失價值。最後,還有一種情況對程式員的工作态度産生了深遠的影響:一方面,除了不穩定,他工作的機器一般還存在運作緩慢、記憶體太小等問題,這讓巧婦難為無米之炊;另一方面,程式中通常又會存在少量古怪代碼來應對突發的狀況。在那些日子裡,有很多聰明的程式員通過一些巧妙的方法,使他的裝置可以完成一些本來不可能完成的任務,以這樣的方式來獲得智力上的巨大滿足感。

關于程式設計的兩種觀點就起源于那個時期。我現在提下這件事,等下會回到這個話題。一種觀點認為真正專業的程式員應該具有解決問題的頭腦,并且非常喜歡聰明的伎倆;另一種觀點認為,程式設計就是在某個方向上優化計算效率的過程。

後一種觀點源自于裝置落後的年代,那時候有些人簡單的期望着,一旦機器變得更為強大,程式設計将不會成為難題,到那時想盡辦法榨幹機器的性能将不再有必要,這就是程式設計的目的,難道不是嗎?但是下一個十年裡發生了巨變,更為強大的機器被造出來了,不是一個數量級的強大,而是好幾個數量級的強大。但是出人意料的是,我們并沒有一勞永逸地解決所有的問題,反而發現自己處在了軟體危機中!這是怎麼回事呢?

一個小小的原因是:現代計算機在一個或兩個方面比老式的計算機更難以操作。首先,現代計算機有I/O中斷,中斷的發生不可預知也不可重制,這個特性與能完全掌控運作過程的舊式計算機相比,是一個巨大的變化,但是這個特性會産生難以預料的邏輯錯誤,很多程式員花白的頭發見證了這一點。第二,現在的計算機配置了多級儲存設備,關于裝置管理的政策,雖然已經有大量的文獻,但是對我們來說仍然相當難以捉摸。關于計算機結構的變化所增加的複雜性就講這麼多了。

但是上面所舉的隻是“小”原因,真正大的原因是…現代計算機性能比原來強大了好幾個數量級!可以不客氣的說:當世上沒有計算機的時候,根本就不會有程式設計問題;當我們有了幾台性能弱小的計算機後,程式設計就出現小問題了,現在我們有了性能強大的計算機,程式設計自然變成了巨大的問題。在這樣的發展過程中,電子産業非但沒有解決一個問題,而是産生了問題,即使用産品所帶來的問題。換種方式說,如果現有計算機性能增長了千分之一,那麼社會對于使用這些機器的期望也會以同樣的比例增長,而可憐的程式員會發現自己處于到底是目的優先還是方式優先的緊張選擇中。硬體性能的提升,加上其可靠性甚至更急劇的提升,使得幾年前程式員做夢都不敢想的問題變得可以實作。而幾年後,他不得不夢見這個問題,更糟的是,他不得不将這樣的夢變成現實!那麼我們發現自己仍身處于軟體危機中是不是一個奇迹呢?當然不是了,正如你猜測的那樣,這些甚至是可以提前預知的,隻不過這種小衆預測的問題在于五年後你才能知道它是正确的。

接着在六十年代中期,有一件可怕的事情發生:所謂的第三代計算機出現了。官方的文獻表示,成本效益一直是他們主要的設計目标之一。但是如果你将機器衆多元件的占空比作為“表現”的衡量标準,你會看到一個記憶體被必要性存疑的内部常駐活動所占據的設計。如果你對于價格的定義是硬體的價值,你會看到一個對其程式設計極其困難的設計:舉個例子,無論對于程式員還是系統,用于執行的指令碼早期綁定所帶來的問題都不能真正得到解決。并且在很大程度上,這些令人不快的可能性看起來已經成為了現實。

當這樣的機器宣布發售,其功能規格為人所知後,我們之中的不少人肯定相當難受,至少我是這樣。第三代計算機的發行肯定會席卷計算機界,而人們更加期待它的設計能夠盡量健全。但是因為這樣一個有着如此嚴重缺陷的設計,讓我感覺到計算機科學至少退步了十年:這也讓我的職業生涯經曆了最為黑暗的一個星期。也許最可悲的事情是,即使有了這麼多年令人沮喪的經驗,依然有如此多的人天真的相信計算機必須是這樣。他們用機器的銷量來打消自己的疑慮,并且從這種觀察中得到使用這些機器是安全的錯覺,畢竟,機器的設計不可能那樣糟糕。但是仔細想想,這種被銷量欺騙的安全感就和吸煙必須是健康的說法相差無幾,因為吸煙的人很多。

正是這方面,我很遺憾,在發表對最新公布的計算機的評論時,計算機領域的科學期刊并沒有習慣像其他科學出版物那樣做出複查:對機器的複查至少應該同樣重要。這裡我要檢讨:在六十年代早期,我寫過這樣的評論并準備送出給CACM,盡管我沒有向同僚們尋求建議,但他們極力主張我這樣做,可我還是不敢,因為擔心這樣無論對我還是對編委會來說,困難都太大。是懦弱沒有讓我送出這樣一份報告,對此我越來越自責。我預見到的困難是當時缺乏普遍接受的标準,雖然确信自己的标準是正确的,但我還是擔心我的報告會被拒絕,或者被貼上“個人口味問題”的标簽。我仍然認為這樣的報告是及其有用的,并且渴望着它們的出現,因為它們的出現将代表着計算機界的成熟。

之是以對硬體保持上面提到那樣的關注,是因為我相信影響那些使用者的思考習慣是任何計算工具最重要的作用之一,并且我有理由相信,這種影響力比預期的更為強烈。現在讓我們的注意力回到軟體上。

由于軟體具有顯著的多樣性,我必須将自己限制在幾個立足點上。這使得我做出的選擇顯得很武斷,也讓我覺得很痛苦,希望大家不要是以懷疑我對其他沒有提到的努力的欣賞。

剛開始的時候,EDSAC 在英國的劍橋興起,我對其起初讓子程式庫在機器設計和使用方法中發揮主要作業的觀點印象深刻。接近25年後的今天,計算領域徹底的變化了,但是軟體的基本觀念還伴随着我們,閉合子程式的觀念也還是我們程式設計的核心概念之一。我們應該認可閉合子程式作為最偉大的軟體發明之一,它經曆了三代計算機的發展并且仍将繼續存活幾代,因為它迎合了我們基本抽象模式的接口思想。遺憾的是,在第三代計算機的設計中,它的重要性被低估了,而這個設計中,大量明确命名為寄存器的算術計算機關揭示了子程式機制的廣泛使用。盡管如此,也沒有讓子程式的概念就此消失,我們隻能祈禱這種變化不會在下一代的計算機中被遺傳。

我要講的第二個軟體業的主要發展是FORTRAN的誕生。在當時這是一個偉大而冒失的計劃,負責這個計劃的人們值得我們大聲地贊美。因為大約10年後才日漸明顯的外延錯誤用法而去責備他們是顯然不公平的:能夠成功預測十年後的團隊相當罕見。當我們回顧過去時,必須把FORTRAN看做一項成功但是對其産生概念基本沒啥幫助的編碼技術,在需求如此迫切的現在,這項技術已經過時了。我們應該盡快忘記FORTRAN,對于思想的馬車而言,它不再勝任:它浪費了我們的腦力,使用它過于冒險,是以也太過奢侈。FORTRAN的悲慘命運已經因為它廣泛的接受度,影響了數以千計的程式員為我們過去的錯誤買單。我每天都祈禱,會有更多程式員小夥伴找到從通用性的禍害中解脫出來的方法。

第三個不能忽略的就是LISP,一個完全與衆不同的迷人設計。基于LISP的幾個基本原則使得LISP展示出了非凡的健壯性。除此以外,LISP成為了相當多的複雜計算機載體。LISP曾經被調侃為濫用電腦的最智能方法。我想這種描述是一種很高的贊美,因為它傳遞了解放的氣息——它已經幫助我們之中最有天賦的人思考了之前不可能思考的東西。

第四個要提到的就是 ALGOL 60。到目前為止,FORTRAN程式員仍然傾向于從他們的開發中了解他們的程式設計語言——八進制的興起和十六進制的衰落;而LISP的定義依然是一種令人好奇的混合體,其中包括這門語言意味着什麼和這門機制是怎麼工作的,《算法語言》那篇著名的報告中說道,ALGOL 60是真正努力去承載抽象概念至關重要的一步,再加上通過獨立于語言之外的方法定義一門程式設計語言的成果。有人會說,ALGOL 60的作者們已經如此的成功,以至于他們自己引出這門語言是否可以實作産生的嚴肅疑問!那篇報告冠冕堂皇地展示了BNF範式(即現在人盡皆知的Backs-Naur-Form)的作用,和英語謹慎措辭的力量,至少是像Peter Naur一樣聰明的人使用時。我覺得可以負責任地說,基本沒有像它這麼短而在計算機界有相同影響力的文檔存在。人們習慣于使用用“ALGOL”或者是“類ALGOL”這樣未經保護的标簽,向大量基本不相關的年輕語言分享ALGOL的榮耀,這本身某種程度上就是對ALGOL驚人生命力的極大緻敬。BNF作為一種嚴格定義的語言,它的長處導緻了我個人認為是這門語言的缺點——過分精心制作并且文法定義不規則,很難在幾頁紙中完全說明。如果有個BNF般強大的裝置,《算術語言》中那篇關于ALGOL60的報告可以變得更短很多。除此以外,我對ALGOL60的參數機制表示懷疑,它賦予程式員如此多的組合自由,以至于要求程式員更自律。除了開發成本外,它使用起來似乎也很危險。

最後,盡管令人不太愉快,但我必須提及——PL/1,一門描述文檔非常龐大而且複雜的程式設計語言。使用PL/1就像開着一架有着7000個按鈕,使用開關和扳手操作的飛機。我完全不能了解怎麼靠智力來把握這種完全怪異的程式設計語言(我們的基本工具),使之保持穩定的發展,提醒你,這已經脫離我們智力的掌控了。還有如果非要描述PL/1對其使用者的影響,我腦海中最為形象的隐喻就是毒品。我記得這個出自一個自稱是PL/1的忠實使用者在一個進階語言的專題讨論會上做的一個演講。但是,在這個為期一小時充滿對PL/1贊美的演講中,他希望大家添加50種新特性,卻沒有想過他問題的源頭是這門語言已經包含了太多的特性。演講者展示了所有令人沮喪大的症狀,他陷入内心停滞,但是渴求更多。當FORTRAN被稱為嬰兒期的淩亂時,完整的PL/1卻是危險的惡性良性腫瘤,最後成長為了一種緻命病毒。

關于過去的事,就講這麼多吧。但是如果我們不能從中汲取教訓的話,制造錯誤是沒有任何意義的。事實上,我覺得我們學習了如此多的錯誤,以至于幾年後的程式設計可以和之前截然不同。讓我簡述下你們可能的未來。乍看一下,這種程式設計的想象也許會讓你不久的将來變得非常的不切實際。是以也允許加上也許會讓人得出“這個人的想象相對實際”的結論的考慮吧。

這種想象就是,在七十年代結束之前,我們有可能設計和實作那種盡量利用程式設計能力,開支是許多年前百分之幾的系統。此外,這些系統可以幾乎擺脫bug。這兩項提升相輔相成。在後一個方面,軟體看上去和許多其他産品不同,很多産品品質和價格是成正比的。那些想要真正有效的軟體的人将會發現他們必須從找到避免大多數bug的方法開始,最後,程式設計過程将變得便宜。如果你想要一些有能力的程式員,你将發現他們不會浪費時間在調試上,他們不應該以調試bug作為開始。換句話說,兩種目标指向同樣的變化。

在如此短的一段時間内發生如此激烈的變革,這會是一場革命,對所有人來說,基于他們對未來的期望,對過去(訴諸不成文的社會,文化惰性的法律)做出的和平推斷,這種巨大變革會發生的機會幾乎微不足道。但我們都知道有時候革命真的發生了。 那麼這次變革我們的機遇是什麼呢?

似乎有三個主要條件需要滿足。一般來說,世界必須承認需要變化,第二經濟需求十分強烈,還有第三,變革在技術上是可行的。讓我讨論按順序讨論一下上述三個條件。

談到對軟體更為可靠的需求,我表示完全同意。在幾年前,就不一樣了——讨論軟體危機是對上帝的亵渎。轉折點是 1968年十月在Garmisch舉行的軟體工程的學術會議,一次萌生了知覺承認軟體危機的回憶。到目前為止,普遍認為任何大型系統的設計都是一項十分困難的工作,無論何時,人們遇到負責這樣工作的人,都會發現他們非常關心可靠性問題。簡而言之,我們第一個條件似乎滿足了。

現在說到經濟需求。現在人們總是遇到說六十年代程式設計是一個薪酬過高的職業的觀點,并且說未來幾年内,程式員薪酬希望可以下降。通常,這種觀點的表述與經濟衰退有關,但這是一種不同,健康的事物的征兆——也許過去幾十年裡程式員沒有很好完成他們應該完成的工作。社會對程式員的表現和他們的産品感到不滿意。但還存在另外一種導緻重擔的因素。現在的情況是,對于特定的系統,為軟體更新的價格和更新硬體的價格在同一個數量級,社會或多或少接受了這一點。但硬體制造商告訴我們說在接下來數十年,硬體價格将會以十倍速度下降。如果軟體發展還是一如既往的笨拙,程式一如既往的昂貴,局勢将失去平衡。你不能指望社會接受這一點,是以我們必須學會有效的程式設計。 換句話說,隻要機器還是預算中的大項,那麼笨拙的程式設計技術還能僥幸逃脫,但是保護傘會快的折起來。總之,我們的第二個條件似乎也能滿足。

現在輪到第三個條件,技術上可行嗎?我覺得可行,我會用六個論據支撐我的觀點。

一份程式結構的研究表明程式,即便是同一個任務的替補程式和有着相同的數學内容,在程式管理方面都有着巨大的差異。研究發現許多規律,違反任何一條規律要麼局部或者整體的破壞程式的人為管理。這些規律不外乎兩種。第一種容易在實體上加以利用,即選用合适的程式設計語言。Goto語句的和多輸出參數的程式的剔除是很好的佐證。對于第二種,我至少看不到實體上使之暴露的方法(可能是我能力不足),好像需要一些我沒有證明存在的自動化的定理證明程式。是以,第二種規律時不時作為程式員訓練的要素之一出現。有些規律我清楚的知道以至于可以教給他人和不需要判斷一段給定的程式是否違反了。 我們給出必要的例子——任何循環需要給出終止條件或者聲明不變量之間的關系保證不變量不會被程式的循環語句執行而破壞。

我現在提議把我們限制在智能可控程式的設計和實作的範圍内。如果有些人害怕這種限制過于嚴格,我們沒有辦法存活,我保證智能可控程式的種類足夠的豐富,可以囊括現實很多能夠解決算術問題的程式。我們不能忘記我們的職業不是為了程式設計,而是設計能夠表現預設行為的計算類别。把我們限制在智能可控程式的建議是我所謂的六個論據的前兩個的基礎。

論據一,程式員隻要考慮智能可控問題,選擇更為容易考慮。

論據二,我們一決定把我們限制在智能可控程式的子集内,我們就一勞永逸的實作了考慮解決方案的空間的減少。

論據三是建立在程式正确性問題的建設性方法上的。今天,一項普通的技術就是寫一個程式,然後去測試。 盡管,程式測試是一種非常有效的方法去暴露bugs,但對證明不存在bugs幾乎是完全沒用的。顯著提高程式可信度唯一有效的方法是給出一個令人信服的關于正确性的證據。但是我們不應該首先寫出程式,然後去證明它的正确性,因為要求證明隻會增加苦逼程式員的負擔。相反,程式員應該讓正确性證明和程式互相驗證,發展。論據三本質上是從以下的觀察得來的。如果一個人問自己一個令人信服的證據應該具備什麼,他了解後,寫了一個很好的滿足了證明要求的程式,然後這些關于正确性的擔心變成一種有效的啟發式的指導。當我們把自己限制在智能可控程式時,按照定義,隻有這種方法是可行,但這種方法也提供許多有效的方法,讓我們從中挑選一個滿意的。

設計一個程式需要多少人力根據程式的長度判斷,論據四與此相關。曾經有人指出存在一種自然法則告訴我們耗費人力是程式長度的平方。但是謝天謝地,還沒有人能夠證明這種法則。這是因為它需要是假的。我們都知道能夠解決很多問題的推理論證工具稱之為抽象,抽象能力的有效開發可以被認為一個有能力的程式員至關重要的靈活之一。關于這一點,值得指出抽象的意圖并不是為了模糊本身,而是去創造新的準确語義水準。當然,我曾經嘗試去找到能夠阻止我們抽象機制起作用的基礎原因。但不管我多麼努力,我都找不到任何一個原因。最後,我傾向于假設(直到現在未通過經驗證明)我恰當的抽象化能力,也就是人力需要想象或者了解一個程式的耗費不會根據程式長度按照超過正比例的速度增長。但是這些調查的一個衍生品更有實際意義,實際上,它是我論據四的基礎。衍生品是許多在整個程式設計過程中扮演重要角色的抽象模式的識别。你了解這些抽象模式足夠多,你就可以就每個模式作報告。這些抽象模式的熟悉和了解讓我幡然醒悟,例如從BNF到方向句法編譯,可以用幾分鐘代替幾年的花費。 是以,我把我們最近對重要抽象模式的了解作為論據四。

現在說到論據五,它和我們建立在我們思考習慣上的工具的影響有關。我觀察到一種十有八九來源于文藝複興的文化傳統,為了忽略這種影響,需要把人心視為肉體最高自主的主人。 但我一開始分析我和同類的思考習慣時,我得到一個完全不同的結論,不管我喜歡與否,即我們使用的工具和我們用來表達或者記錄我們想法的語言或記号,是決定我們能夠想到什麼的主要因素。對程式設計影響程式員的思考習慣的分析和腦力是我們幾乎不曾使用的資源的認識,它們給出了從多方面給出不同程式設計語言優缺點的尺度。一個有能力的程式員能夠意識到他自己腦容量的嚴格尺寸,是以,他謙遜的完成程式設計任務,牽涉到其他事情時,他避免小聰明像躲避瘟疫一樣。說到一種著名的會話式程式設計技術,我從不同管道被告知說如果一個計算社群一旦裝備終端,一種特殊的現象就會發生,這種現象甚至有了一個被廣泛接受的名稱——打趣的人。它有一到兩種不同的形式,一個程式員在别人桌面放了一個調侃的程式,他要麼驕傲的展示它的用途并問别人你能用更少的字元寫完嗎(好像有任何概念的相關性一樣),要麼就問說猜猜這是用來幹嘛的。通過這個觀察,我們必須總結說這門語言是一種宣揚奇技淫巧的工具,同時這會是它的一些訴求的解釋,例如說那些喜歡展示他們有多聰明的人,對不起,但是我必須把它視作關于程式設計語言最令人惡心的地方。我們必須從過去學到的另外一課是所謂功能強大,豐富的程式設計語言的發展是一種錯誤,就像這些奇怪龐然大物,某人特有的氣質的聚集,都是心靈上,肉體上不可控的。我從系統的謙遜的程式設計語言上看到很美好的未來。 當我說謙遜時,我的意思是,例如,不僅是ALGOL60的for分支語句,還有FORTRAN的DO循環語句發現因為變得過于怪異而被淘汰。我曾經和一些有經驗的志願者做過一點程式設計實驗,但有些不期望發生和預料不到的事情發生了。我的志願者沒有一個找到明顯而漂亮的解決方法。通過更為細緻的觀察,我們找到相同的源頭:他們對與重複的概念與用于加速的聯合控制變量的聯系過于緊密,以至于他們被蒙蔽了完全看不到明顯的方法。他們的方法低效,晦澀難懂,并且耗費了大量時間。這是一段對我來說具有啟示作用,和令人震驚的經曆。最後,從某個方面上來講,如果一個人希望明天的程式設計語言和現在的大為不同,很大程度的優于現在的,他們應該邀請我們在我們寫下的所有需要用來應付概念上我們如今設計的抽象結構中思考。關于我們未來工具的優越性,也就是我們第五個論據的基礎,就講到這裡。

作為旁觀者,我希望提醒一下那些以現有工具不足而覺得程式設計任務困難的人。程式設計依舊會十分困難因為一旦我們從詳盡的笨重中解放出來,我們将會發現自己得以面對解決遠在我們程式設計能力以外的問題。

你可以不同意我的第六個論據,因為很難收據支援的實驗證據,但不能阻止我相信它的正确性。直到現在,我還沒有提到分層這個詞,但我認為把它作為一個所有收錄着一個精細分解解決方案的系統的核心概念是合理的。我甚至可以走更遠一步寫一篇關于信仰的文章,即我們能夠以令人滿意的方式解決的唯一問題是那些最後接受精細分解解決方案的問題。乍看之下,這種人類局限的觀點是一種令人抑郁的關于我們處境的觀點,但我恰恰相反,不這麼覺得。學會和我們的局限共存的方法就是了解我們的局限。等到我們足夠謙遜去嘗試分解方案的死後,因為其他形式的努力已經超過我們智力的掌控,我們将要盡最大的努力去避免所有這些内部損害我們以有用的方式分解系統的能力的交流。我不得不希望這不停的引領我們發現一個容易解決的問題最終也是可以分解的。任何一個看到了大多數所謂的“代碼生成”的編譯狀态的麻煩都可追溯到指令碼的有趣特性的人,都會知道一個我在腦海中想到的事情簡單示例。适用性更好的分解良好的解決方案是我第六個也是最後一個論據用于支援技術上可行的可能會在這十年發生的革命。

原則上,我把這些論據留給你,讓你決定我的考察占多少分量,因為我很清楚我沒有辦法強迫任何人跟随我的信仰。每次重要的變革都會招緻劇烈反對,每個人都可以問自己希望保守力量抵消多少發展。我不指望主要的大财團,甚至計算機領域的集團,我甯願希望教育機構提供教育訓練,希望那些保守團體的計算機使用者認為他們古老的程式很重要以至于不值得重寫或者優化。關于這一點,很多大學校園的中心電腦裝置的選擇視一些現成但昂貴且不理會千千萬萬願意自己程式設計的小使用者的問題的程式的需求而定,學校将為他們的選擇埋單,這是相當可悲的。這種事情太常發生,例如,高能實體似乎曾經用他們剩下的實驗裝置勒索科學社群。當然,最容易的解決方法,是對技術可行性的幹脆的拒絕,但我擔心你需要足夠支撐這種方法的論據。唉,現在普遍程式員的腦力水準可以阻止變革發生是得不到任何保證的,因為其他人的程式設計變得更為有效,程式員很容易在社會的版圖中被邊緣化。

還有很多政治方面的障礙。即便我們知道怎麼去培養未來的專業的程式員,我們不能确定社會允許我們這樣做。傳授方法論(而不是散布知識)的第一影響是增強了現有的能者的能力,是以拉大了智商上的差異。在一個教育系統是用來建立平均文化的社會,在一個精英不允許出現在頂層的社會,培養有能力的程式員在政治上是不對味的。

讓我總結一下。計算機已經伴随我們走過一個世紀的四分之一了。它們以工具的身份對我們社會産生了深遠的影響,但是和在人類曆史上史無前例的以智力挑戰的形式産生深遠的影響相比,它們隻能以波浪的形式影響我們文化的表面。似乎擁有決定在某種程度上将物體視作一個不可分割整體的權利的分層系統,被視作一個級别更低,細節更多的混合物,最後,當我們将注意力從一級轉向更低一級時,時空的天然粒面會以合适的數量級減少。 我們知道牆以磚為機關,磚以結晶體為機關,結晶體以分子為機關,等等。在分層系統中,許多級别可以有意義的區分出來,這和最大與最小粒度的比率的對數成正比,是以,除非比率很大,我們不能指望能夠分很多層。在計算機程式設計中,我們基本的程式設計語句有低于一微秒的時間粒度,但我們的程式卻可能花費幾小時的計算時間。我不知道任何一種超過10的10次方的比率的技術,以它超凡速度為優點的計算機,似乎是第一個給我們提供需要分層粒度大和實作它的環境的。這樣的挑戰,即面對程式設計任務,是獨一無二的,是以這樣小說一般的經曆可以教會我們很多關于自己的知識。它加深了我們對設計和創造程式的了解,它幫助我們更好的完成想法條理化的任務。如果它沒有這樣做,對我來說,我們根本不值得擁有計算機。

它已經給我們上了幾課,在這次演講中我要強調以下幾點。我們應該更好的程式設計,證明我們用滿是對任務帶來的巨大困難的感激的方法完成任務,證明我們堅持謙遜和優雅的程式設計語言,證明我們尊重人類内心固有的限制和以謙卑的程式員的身份完成任務。

繼續閱讀