- 計算機程序的構造和解釋(JavaScript版)
- (美)哈羅德·阿貝爾森等
- 3385字
- 2024-06-06 19:10:09
1984年版《計算機程序的構造和解釋》的原序
教育家、將軍、減肥專家、心理學家和父母做規劃(program),而軍隊、學生和另一些社會階層則被規劃(are programmed)。解決大規模問題需要做好一系列規劃,其中大部分東西只能在工作過程中做好。在這些規劃里,充斥著與手頭問題的特殊性相關的情況。而要想把做規劃這件事本身作為一種智力活動來欣賞,就必須轉到計算機程序設計(programming),你需要讀或寫計算機程序——而且要大量地做。這些程序具體是關于什么、服務于哪一類應用等的情況常常不太重要,重要的是它們的性能如何,在用于構造更大的程序時能否與其他程序平滑銜接。程序員必須同時追求具體部分的完美和匯合的適宜性。在這本書里使用“程序設計”一詞時,我們關注的是程序的創建、執行和研究,這些程序用一種Lisp方言書寫,為了在數字計算機上執行。采用Lisp不會對我們可以做程序設計的范圍強加任何約束或限制,只不過是確定了程序描述的記法形式。
本書將要討論的問題都要求我們聚焦于三類現象:人的大腦,計算機程序的集合,以及計算機本身。每個計算機程序都是現實的或者精神中的某個過程的一個模型,通過人的頭腦孵化出來。這些過程出自人們的經驗或者思維,數不勝數,細節繁雜而瑣碎,任何時候都只被部分地理解。通過程序模擬相應過程,幾乎不可能做到永遠令人滿意的程度。正因為這些,即使我們寫出的程序是一堆經過仔細雕琢的離散符號,是交織互聯的一組函數,它們也需要不斷演化:當我們對模型的認識更深入、更擴大、更廣泛時,就需要去修改程序,直至這一模型最終到達一種亞穩定狀態。而在這時,程序中就又會出現另一個需要我們去為之奮斗的模型。計算機程序設計領域之令人興奮的源泉,就在于它所引起的連綿不絕的發現,在我們的頭腦中,在由程序表達的計算機制中,以及在由此所推動的認知爆炸中。如果藝術解釋了我們的夢想,那么計算機就是以程序的名義執行著它們。
就本身的所有能力而言,計算機就是一位一絲不茍的工匠:它的程序必須正確,我們希望說的所有東西,都必須表述得準確到每一點細節。就像在其他所有符號活動中一樣,我們需要通過論證使自己相信程序的真。我們可以為Lisp本身賦予一個語義(可以說是另一個模型)。假如說,一個程序的功能可以在(例如)謂詞演算里精確描述,那么就可以用邏輯方法做出一個可接受的正確性論證。不幸的是,隨著程序變得更大、更復雜(實際上它們幾乎總是如此),這種描述本身的適宜性、一致性和正確性也都會變得更令人懷疑。因此,很少能看到有關大型程序正確性的完全形式化的論證。因為大程序是從小東西成長起來的,所以,開發出標準化的程序結構的“武器庫”,并確認其中每種物件的正確性——我們稱這些為慣用法,再學會如何去利用一些已經證明很有價值的組織技術,把這些結構組合成更大的結構,這些都是至關重要的。本書將詳細地討論這些技術。理解它們,對參與這種被稱為程序設計的富于創造性的事業是最本質的。特別值得說明的是,發現并掌握強有力的組織技術,能大大提升我們構造大型重要程序的能力。反過來,寫大規模的程序非常耗時費力,這種情況也推動我們去發明新方法,減輕由于大程序的功能和細節而引起的沉重負擔。
與程序不同,計算機必須遵守物理定律。如果要快速執行——幾納秒完成一次狀態變換——就必須在很短的距離(至多1 ? ft[1])內傳導電子,還需要消除由于在小空間里集聚了大量元件而產生的熱量。人們已經開發了一些精致的工程藝術,能夠在功能多樣性與元件密度之間取得平衡。在任何情況下,硬件都在比我們編程時需要關心的層次更基礎的層次上操作。把我們的Lisp程序變換到“機器”程序的過程本身,也是通過程序設計做出的抽象模型。研究和構造這類程序,能使人更深刻地理解與構造抽象模型的程序設計有關的程序組織問題。當然,計算機本身也可以這樣模擬。請想一想:最小的物理開關元件在量子力學里建模,量子力學由一組微分方程描述,這些方程的細節行為可以通過數值近似來把握,這種數值用計算機程序描述,而計算機程序的組成……!
區分上述三類需要關注的事物,不僅是為了策略上的便利。即使有人說這些區分不過是在人的頭腦里,這種邏輯區分也會帶來這些關注點之間符號的加速流動,其在人們經驗中的豐富性、活力和潛力,只能由生活自身的演進去超越。我們至多能說,這些關注點之間的關系是元穩定的。計算機從來都不夠大也不夠快。硬件技術的每次突破都帶來了更大規模的程序設計事業,一些新的組織原理,以及抽象模型的豐收。每個讀者都應該反復自問“往哪里去?往哪里去?”——但不要問得過于頻繁,以免你忽略了程序設計的樂趣,把自己禁閉到一種自尋煩惱的哲學中。
在我們寫出的程序里,有些就是計算一個精確的數學函數(但是絕不夠精確),例如排序,或者找出一系列數中的最大元,或者確定素數性,或者找出平方根。我們把這種程序稱為算法,人們對它們的最佳行為已經有了許多認識,特別是關于兩個重要參數:執行的時間和對數據存儲的需求。程序員應該追求好的算法和慣用法。即使某些程序難以精確描述,程序員也有責任去估計它們的性能,并且要繼續設法改進之。
Lisp是幸存者,已經被使用了四分之一世紀。在現存的程序設計語言里,只有Fortran比它的壽命更長些。這兩種語言都支持一些重要領域中的程序設計需求,Fortran用于科學與工程計算,Lisp用于人工智能。這兩個領域現在仍然很重要,它們的程序員都如此傾心于這兩種語言,因此,Lisp和Fortran都還可能繼續生存至少四分之一世紀。
Lisp一直在改變。本教科書使用的Scheme方言就是從原本的Lisp演化出來的,并在若干重要方面與之相異,包括變量約束的靜態作用域,以及允許函數生成函數作為值。在語義結構上,Scheme更接近Algol 60而不是早期的Lisp。Algol 60不可能再變成活語言了,但它還活在Scheme和Pascal的基因里。很難找到這樣兩種語言,它們如此清晰地代表著圍繞這兩種語言聚集起來的兩種差異巨大的文化。Pascal是為了建造金字塔——宏大壯觀、激動人心,是由各就其位的巨石筑起的靜態結構。而Lisp則是為了構造有機體——同樣壯觀且激動人心,是由各就其位但卻永不靜止的無數簡單有機體片段構成的動態結構。這兩種語言采用了同樣的組織原則,除了特別重要的一點不同:托付給Lisp程序員個人的對所提供功能的自由支配權,遠遠超過在Pascal領域可以看到的東西。Lisp程序極大地提升了函數庫的地位,使其可用性超越了催生它們的具體應用。Lisp的內置數據結構——表——對這種可用性提升起著最重要的作用。表的簡單結構和自然可用性反射回函數,使它們具有了奇異的普適性。而在Pascal里,數據結構的過度聲明帶來函數的特異性,阻礙并懲罰臨時性的合作。用100個函數在一種數據結構上操作,優于用10個函數在10種數據結構上操作。作為這些的必然后果,金字塔矗立在那里千年不變,而有機體則必須演化,否則就會消亡。
為了看清這種差異,請將本書中展示的材料和練習與任何采用Pascal的第一門課程的教科書中的材料做個比較。請不要費力地去想象,說這不過是一本MIT采用的教科書,其特異性僅僅是因為它出自那個地方。準確地說,任何一本嚴肅的關于Lisp程序設計的書都應該如此,無論其學生是誰,在什么地方使用。
請注意,這是一本關于程序設計的教科書,它不像大部分有關Lisp的書,因為那些書多半是為幫助人們在人工智能領域工作做好準備。當然,無論如何,隨著研究中系統規模的不斷增長,軟件工程和人工智能關心的重要程序設計問題正趨于融合。這也解釋了為什么在人工智能領域之外的人們對Lisp的興趣在不斷增加。
根據人工智能的目標可以預見,有關的研究將產生許多重要的程序設計問題。在其他程序設計文化中,問題的洪水孵化出一種又一種新語言。確實,在任何極大規模的程序設計工作中,為了控制和隔離作業模塊之間的信息流動,一條有用的組織原則就是發明新語言。當我們逐漸逼近系統的邊界,在那里人們需要最頻繁的交互,相關的語言也傾向于越來越不基礎。作為結果,系統里包含大量重復的復雜語言處理功能。Lisp有如此簡單的語法和語義,程序的語法分析可以看作很簡單的工作。這樣,語法分析技術對Lisp程序幾乎沒價值,語言處理器的構造從來都不是大型Lisp系統的成長和變化速度的障礙。最后,正是這種語法和語義的極端簡單性,導致了Lisp程序員的所有負擔和自由。任何規模的Lisp程序,除了只有幾行的小程序,都飽含著根據情況精心設計的各種函數。發明并調整,調配恰當之后再去發明!讓我們舉起杯,祝福那些把他們的思想鑲嵌在重重括號之間的Lisp程序員。
Alan J.Perlis
康涅狄格州,紐黑文
[1]1ft=30.48cm。——編輯注
- 編寫高質量代碼:改善Python程序的91個建議
- Java:High-Performance Apps with Java 9
- Getting Started with LLVM Core Libraries
- Java實戰(第2版)
- Visual Basic程序設計習題與上機實踐
- Hadoop 2.X HDFS源碼剖析
- 愛上C語言:C KISS
- 嵌入式Linux C語言程序設計基礎教程
- 計算機應用基礎(第二版)
- 算法訓練營:海量圖解+競賽刷題(入門篇)
- INSTANT EaselJS Starter
- Visual C++ 開發從入門到精通
- 深度剖析ApacheDubbo核心技術內幕
- WCF 4.5 Multi-Layer Services Development with Entity Framework(Third Edition)
- 嵌入式網絡編程