教育者梁钾、將領(lǐng)、飲食專家逊抡、心理學(xué)家姆泻,以及父母們,皆編程(規(guī)劃)冒嫡。士兵拇勃、學(xué)生和某些社群,皆被編程(規(guī)劃)孝凌。攻克大型問題方咆,要使用一系列程序,其中大部分產(chǎn)生于求解問題的途中蟀架。程序充斥著各種狀況瓣赂,于著手的問題,狀況各異辜窑。編程作為一項(xiàng)智力活動(dòng)钩述,為了自個(gè)兒能領(lǐng)會(huì),你必須開始使用計(jì)算機(jī)去編程;你必須閱讀穆碎、書寫大量的計(jì)算機(jī)程序。程序是怎樣的职恳,又是干什么的所禀,這些都不大重要方面。重要的是,執(zhí)行有多快色徘,在構(gòu)造更大規(guī)模的程序過程中恭金,配合其他程序有多流暢。 程序員必須努力尋求部分的完善性以及整體的融洽性褂策。本書中横腿,”程序設(shè)計(jì)(program)”一詞的使用將集中于程序的創(chuàng)建、執(zhí)行和研究斤寂,這些程序用Lisp方言寫就耿焊,運(yùn)行于數(shù)字式計(jì)算機(jī)。使用該方言遍搞,不會(huì)限制我們的編程范圍罗侯,這僅是程序的一種描述記號罷了。
縱觀本書主旨溪猿,我們將涉及三大關(guān)鍵點(diǎn):人的思維方式钩杰,計(jì)算機(jī)程序集,以及計(jì)算機(jī)本身诊县。程序皆模型讲弄,它誕生于人的心智,是真實(shí)世界或精神世界的進(jìn)程依痊。此些進(jìn)程垂睬,起于人的經(jīng)驗(yàn)和思考,數(shù)目巨大抗悍,細(xì)節(jié)復(fù)雜驹饺,無論何時(shí),都僅能被部分理解缴渊。進(jìn)程通過計(jì)算機(jī)程序進(jìn)行模擬赏壹,并不能一勞永逸。即便程序是精雕細(xì)琢的離散符號集衔沼,是交織嵌套的函數(shù)蝌借,它們依然需要不斷演化:當(dāng)對模型的理解深化了,擴(kuò)大了指蚁,推廣了菩佑,我們就修改模型,直到取得相對穩(wěn)定的狀態(tài)凝化。接著稍坯,又得探尋另一個(gè)更好的模型。用計(jì)算機(jī)編程的歡欣之源,在于思維的不斷拓展瞧哟,在于計(jì)算機(jī)裝置的程序表示混巧,在于其激發(fā)的理解力之飛升 。藝術(shù)詮釋夢想勤揩,計(jì)算機(jī)化用程序咧党,實(shí)現(xiàn)夢想!
盡管計(jì)算機(jī)功能強(qiáng)大陨亡,它卻是個(gè)苛刻的工頭傍衡。它要求程序必須正確,我們的表述必須精細(xì)無誤负蠕。正如其他使用符號的場合蛙埂,通過論證,我們也將相信程序的正確性虐急。Lisp本身就能被賦予一套語義(也就是另一個(gè)模型)箱残,如果將程序的函數(shù)加以規(guī)范化,那么就能用邏輯學(xué)的證明方法——謂詞演算止吁,來做經(jīng)得起考驗(yàn)的論證被辑。遺憾的是,一直以來敬惦,程序都在變大盼理、變復(fù)雜,規(guī)范本身的適用性俄删、兼容性宏怔,以及正確性也變得值得懷疑。因此畴椰,正確性的完全形式化論證很少出現(xiàn)在大型程序中臊诊。由于大型程序源于小程序,那么斜脂,建立正確性業(yè)已確定的抓艳、標(biāo)準(zhǔn)化的程序結(jié)構(gòu)的倉庫就顯得尤其重要了。我們稱其為慣用語帚戳。接著學(xué)習(xí)將其組合成更大型的結(jié)構(gòu)玷或,而這就要利用到有價(jià)值的組織技術(shù)。這些技術(shù)都充分展現(xiàn)在本書中片任,理解它們偏友,對于投入編程這項(xiàng)創(chuàng)造性事業(yè)來說,是不可或缺的对供。最為重要的是位他,發(fā)現(xiàn)并掌握強(qiáng)有力的組織技術(shù),以增進(jìn)我們創(chuàng)建大型、重要之程序的能力棱诱。反過來說泼橘,正是因?qū)懘笮统绦蛱^費(fèi)力涝动,才刺激我們?nèi)グl(fā)明新方法迈勋,來減少大型程序中的大量函數(shù)和細(xì)節(jié)。
與程序不同醋粟,計(jì)算機(jī)必須遵守物理定律靡菇。如果計(jì)算機(jī)想快速執(zhí)行——幾個(gè)納秒一次狀態(tài)轉(zhuǎn)換,那么傳輸?shù)碾娮泳捅仨毾拗圃谛【嚯x內(nèi)(最多1.5英尺)米愿。熱量因大量元器件而產(chǎn)生并匯聚厦凤,這必須消除。精湛的工程技藝的開發(fā)育苟,平衡了功能多樣性與器件密集性間的矛盾较鼓。不論何種情況,硬件都比我們所關(guān)注的軟件工作在更底層违柏。將Lisp程序轉(zhuǎn)換為“機(jī)器”程序的過程博烂,本身就是用程序所設(shè)計(jì)的抽象模型。對此過程的研究和創(chuàng)建漱竖,為設(shè)計(jì)其他模型的相關(guān)組織技術(shù)提供了大量真知灼見禽篱。當(dāng)然,計(jì)算機(jī)本身亦能被如此建模馍惹。試想:最小的物理開關(guān)元件用量子力學(xué)建模躺率,量子力學(xué)可用微分方程組來描述,微分方程的的細(xì)節(jié)特性能用數(shù)值逼近獲得万矾,數(shù)值逼近能用計(jì)算機(jī)上執(zhí)行的程序來表示悼吱,計(jì)算機(jī)程序由……組成 ,……良狈!
區(qū)分上述三大關(guān)鍵點(diǎn)后添,不僅是為了方法上的便捷。雖然有人說它們皆存于自然人之頭腦们颜,但邏輯上的劃分導(dǎo)致三者間符號流動(dòng)的加速吕朵。這使得它們的豐富性、鮮活性窥突,以及無限可能性遠(yuǎn)勝于其在人類實(shí)踐中的自然演化(Even though, as they say, it's all in the head, this logical separation induces an acceleration of symbolic traffic between these foci whose richness, vitality, and potential is exceeded in human experience only by the evolution of life itself.)努溃。在最好情況下,三者間的關(guān)系是相對穩(wěn)定的阻问。計(jì)算機(jī)內(nèi)存永遠(yuǎn)不夠大梧税,計(jì)算速度永遠(yuǎn)不夠快。每一次硬件技術(shù)的突破都產(chǎn)生更大規(guī)模的程序設(shè)計(jì)產(chǎn)業(yè),產(chǎn)生新的組織技術(shù)第队,產(chǎn)生更豐富的抽象模型哮塞。每個(gè)讀者都應(yīng)定期反問自己,“到哪兒才是頭凳谦,到哪才是頭忆畅?”——但不要問得太頻繁,不然這會(huì)讓你泥淖在悲喜交加之中尸执,從而喪失編程的樂趣家凯。
我們所寫的程序中,有些(但不夠多)具有精確的數(shù)學(xué)的功能如失。比如:數(shù)列排序绊诲,找出數(shù)列中的的最大值,素?cái)?shù)檢驗(yàn)褪贵,或者計(jì)算平方根掂之。我們稱如上述的程序?yàn)樗惴ǎ渲写罅康囊蚱渚哂凶顑?yōu)性能而被大家所熟知脆丁,這里要特別提及兩個(gè)重要性能參數(shù)世舰,程序的執(zhí)行時(shí)間和數(shù)據(jù)存儲(chǔ)要求。程序員應(yīng)該追求良好的算法和慣用法偎快。雖然有些程序難以精確描述冯乘,但程序員有責(zé)任去估計(jì)并不斷地設(shè)法改進(jìn)程序的性能。
Lisp是個(gè)幸存者晒夹,已被使用了約四分之一世紀(jì)裆馒。在用的語言中,只有Fortran比它久遠(yuǎn)丐怯。這兩語言都支持某些重要的應(yīng)用領(lǐng)域的程序設(shè)計(jì)需要喷好。Fortran用于科學(xué)和工程計(jì)算,Lisp用于人工智能读跷。這兩領(lǐng)域?qū)⒁蝗缂韧刂匾=粒渲谐绦騿T是如此傾心于Lisp和Fortran,以致它們可能繼續(xù)被活躍使用至少四分之一世紀(jì)效览。
Lisp一直在改變著无切。本書使用的方言Scheme就是演化自最初的Lisp,并與后者在若干重要方面有所不同丐枉,包括變量約束的靜態(tài)作用域哆键,以及允許函數(shù)生成函數(shù)作為函數(shù)值。在語義結(jié)構(gòu)方面瘦锹,與早期Lisp族相比籍嘹,Scheme更加接近于Algol 60闪盔。Algol 60再也不能重新流行了,只能存活在Scheme和Pascal的基因里辱士。 比起縈繞其周圍的其他語言泪掀,很難找到像這樣兩種語言去更好地溝通兩個(gè)差異如此之巨大的文化。(It would be difficult to find two languages that are the communicating coin of two more different cultures than those gathered around these two languages.)Pascal是用來建造金字塔的——由大群人推笨重的大石到指定地點(diǎn)颂碘,壯麗輝煌异赫、令人震撼、靜態(tài)的結(jié)構(gòu)凭涂。Lisp是用來建造有機(jī)體的——由小分隊(duì)把無數(shù)更簡單的處于變化之中的有機(jī)體安置在指定位置祝辣,壯麗輝煌贴妻、令人震撼切油、動(dòng)態(tài)的結(jié)構(gòu)。組織原理在兩語言中是相同的名惩,除了極其重要的一點(diǎn)不同外:把自由輸出功能托付給Lisp程序員個(gè)體澎胡。這在Pascal程序員那里也能找到,卻降低了不止一個(gè)數(shù)量級娩鹉。Lisp程序大大充實(shí)了函數(shù)庫攻谁,這些函數(shù)的實(shí)用性超過了催生它們的應(yīng)用。表弯予,Lisp的固有數(shù)據(jù)結(jié)構(gòu)戚宦,為函數(shù)實(shí)用性的提升貢獻(xiàn)巨大。表的簡單結(jié)構(gòu)和天然的適用性反映在函數(shù)锈嫩,就是函數(shù)那令人驚訝的普適性受楼。而在Pascal,數(shù)據(jù)結(jié)構(gòu)的過度聲明導(dǎo)致函數(shù)的專用性呼寸,這阻礙并惡化了函數(shù)間的臨時(shí)配合艳汽。擁有100個(gè)函數(shù),工作在1個(gè)數(shù)據(jù)結(jié)構(gòu)之上对雪,好過擁有10個(gè)函數(shù)河狐,工作在10種數(shù)據(jù)結(jié)構(gòu)之上。結(jié)果瑟捣,金字塔必定是矗立千年而不變馋艺,有機(jī)體要么演化,要么死亡迈套。
為了看清上述差異捐祠,請?jiān)囍容^Pascal入門書與本書對材料和練習(xí)的處理方法。不要困于假象交汤,說雏赦,這是本僅適用于MIT的教科書劫笙,它的獨(dú)特性只不過是因?yàn)樗鲎訫IT.準(zhǔn)確地說,任何一本Lisp編程書籍都應(yīng)該如本書星岗,無論其學(xué)生是誰填大,書本在何處使用。
注意俏橘,本書是關(guān)于程序設(shè)計(jì)的允华,異于大多數(shù)Lisp書籍,因那些書是為人工智能準(zhǔn)備的寥掐⊙ゼ牛總之,隨著被研究的系統(tǒng)的不斷擴(kuò)大召耘,程序設(shè)計(jì)的關(guān)鍵問題百炬,在軟件工程和人工智能之間將趨于統(tǒng)一。這就解釋了為何在人工智能領(lǐng)域之外污它,對Lisp的興趣也正不斷地在提高剖踊。
從人工智能的目標(biāo)出發(fā),可以預(yù)見衫贬,其研究將產(chǎn)生大量有意義的程序設(shè)計(jì)問題德澈。在其他程序設(shè)計(jì)文化里,這一連串的問題將引生新的語言固惯。誠然梆造,在任何極大型的程序設(shè)計(jì)工作中,一個(gè)有效的組織原理就是控制并隔離任務(wù)(作業(yè))模塊間的信息流動(dòng)葬毫,而這要通過新語言的發(fā)明方可實(shí)現(xiàn)镇辉。當(dāng)人們接近到與之最常交互的系統(tǒng)的邊界時(shí),這些語言趨于變得高級供常。結(jié)果摊聋,這些系統(tǒng)就包含了大量重復(fù)的復(fù)雜的語言處理功能。Lisp擁有簡潔的語法和語義栈暇,這使得語法分析被看作是一項(xiàng)基本任務(wù)麻裁。這使得語法分析技術(shù)在Lisp程序里幾乎沒有地位,同時(shí)使得語言處理器的構(gòu)造對大型Lisp系統(tǒng)的發(fā)展變更速度而言源祈,鮮有阻礙煎源。最后,正是語法和語義的極端簡潔性香缺,導(dǎo)致了Lisp程序員的自由以及負(fù)擔(dān)手销。任何規(guī)模的Lisp程序,除了寥寥數(shù)行的之外图张,無不充盈著各類函數(shù)锋拖。發(fā)明函數(shù)诈悍,組裝函數(shù);得到函數(shù),再利用之發(fā)明函數(shù)(Invent and fit; have fits and reinvent!)兽埃!讓我們舉杯慶賀那些將思想寫進(jìn)層層括號之巢的Lisp程序員吧侥钳。
Alan J. Perlis
紐黑文市,康涅狄格