這本書帶給你面對面的體驗,關於計算機程式設計世界的基礎思想:“程式設計語言的直譯器不過是另外一個程式”。聽起來好像是一件很顯而易見的事情,是嗎?但是它的含義卻又是非常深遠的。如果你是計算機領域的理論研究人員,直譯器的思想實際上要往回追溯到哥德爾發現的關於形式化邏輯系統的侷限性(哥德爾不完備定理),圖靈通用機器(圖靈機),馮諾依曼可儲存機器的基本思想(馮諾依曼機)。如果你是一個程式設計師,掌握瞭解釋器的思想,它會成為你強大力量的來源。它會顛覆你原有的觀念,造成你在思考程式設計時的一些最根本的改變。在我學習直譯器之前,我曾編寫過大量的程式,也做過一些很牢靠的程式。例如,其中一個是用PL/I編寫的大型資料錄入和資訊檢索系統。當我順利完成這個系統時,我意識到PL/I是由一群有紛爭的程式語言設計人員編寫的一系列修修補補的語法規則。我感覺我的系統不是很適應這些規則,從而導致它理解起來十分困難,更別提那本(超級)巨大的參考手冊了,最後只從裡面選兩三個能用的特性來程式設計。這樣的經歷讓我的腦子出現了一個組織程式語言的基本結構,我本來可能會想到重新組織一下這個語言的設計,但是我從沒這樣去思考過。我不知道如何建立嵌入式的語言幫助我自己的開發,所以這個完整的程式看起來是一個又龐大,又複雜的鑲嵌物,一片套著一片,而不是一系列的語言以便在這些系統的部分間可伸縮地組合起來。如果你不理解直譯器,你也會這樣寫程式,你當然可以是一個稱職的編碼人員,可遺憾的是,你沒辦法成為一個大師。程式設計師應該學習直譯器的原因有三個。首先,你需要一部分技術,它們屬於直譯器技術的一部分,可能並不是完整且通用的直譯器或者語言,但是直譯器的實現實際上是一樣的思路。大多數人們使用的靈活又複雜的計算機軟體系統,例如計算機繪圖工具和資訊檢索系統,包含某些直譯器用來構建互動。這些程式可能包含複雜卻獨特的操作--渲染螢幕的某些區域,執行資料庫查詢--但是直譯器賦予了你組合這些獨特的操作到方便的模式裡面的能力。你可以使用一個操作的結果作為另一個操作的輸入嗎?你可以給一系列的操作命名嗎?這些名稱是區域性的還是全域性的呢?你可以引數化一系列的操作,然後把名字交給它的輸出嗎?等等。無論這些特殊操作如何複雜和突出,它通常都是這類系統的質量得到保證的內部決定因素。在程式中找出這些特定的行為是簡單的事情,但是組合起來是很醜陋的;再往回看我那個PL/I資料庫系統真的是非常糟糕的組合。第二,即使程式本身不是作為直譯器的一部分,它也擁有一些類似直譯器的地方。觀察計算機輔助設計系統,你會發現幾何定義語言,幾何互動直譯器,基於規則的控制直譯器,還有一個面向物件的語言直譯器在工作。設計複雜程式最強大的方法就是一系列語言的組合,每一種語言提供了一種關注點,用到這些程式設計元素不同的工作方式。把合適的程式語言用於對應的目的,理解到使用每種語言的權衡利弊:這就是直譯器需要研究的地方。第三個原因則是為了瞭解直譯器是一種直接關係到程式語言結構的程式設計技術,它正在變得越來越重要。現在的軟體工程化,設計和組織裡面,面向物件是這樣一種趨勢的例子。不可避免的,我們的軟體會越來越複雜--直接從語言層面考慮問題也許會是一個比較好的處理複雜性的辦法。再次考慮最基本的問題:直譯器本身也只是一個程式。但是這個程式是用某些語言編寫而成的,直譯器的直譯器又是另外一些語言編寫而成...也許在程式和程式語言之間的距離是一種遐想,未來的程式可能並不是某種語言編寫而成的應用程式,而是為了某一個新的應用程式建立一門新的程式語言。Friedman和Wand已經做出了里程碑的工作,他們的書會改變程式語言課程的面貌。他們不只是告訴你直譯器是什麼樣;他們將它展示給你看。本書的核心是一次程式語言界的旅行,從一個高度抽象的語言,逐漸深入到語言內部的特性直到狀態機。你毫無疑問可以執行這些程式碼,研究它,修改它,然後改變某些直譯器的控制代碼和作用域,控制流等等。在使用直譯器學習語言的執行機制之後,作者會展示如何將相同的想法用於分析程式而無需執行。在接下來的兩章裡,它們展示瞭如何實現型別檢查和推導,以及這些功能如何與現代的面嚮物件語言互動。這種方法之所以吸引人的部分原因在於,作者選擇了一個很好的工具--scheme語言,它結合了lisp的詞法作用域,垃圾回收和資料抽象功能,還有algol的塊結構。但是強大的工具還得要在大師的手上。本書中的例項直譯器是傑出的模型。當然,由於它們是可執行的模型,因此我確信考量這些直譯器,研究的人會發現自己站在未來幾年許多程式設計系統的核心層面。這不是一本輕鬆的書,掌握直譯器並不容易,這是有充分理由的。與普通的應用程式設計師相比,語言設計者是站在高於使用者的層次看待問題。在設計應用程式的時候,你要考慮人們可能想要實現的各種功能以及實現方式,他們可能會使用它們。你的語言應該是靜態的,還是動態的,還是混合?需要繼承嗎?它的引數是引用傳遞還是值傳遞?續延應該是明確的還是隱式的?這完全取決於你期望使用語言的方式,各個功能應該是易於編寫的,並且還能夠承載更復雜的任務。另外,直譯器的確是很微妙的程式。簡單的更改內部的程式碼會使得你的直譯器行為產生巨大的差異。不要以為你可以輕鬆看懂並且預測這些程式,世界上很少有人可以看一看新的直譯器就能知道它將會發生什麼,即使在很簡單的程式上。所以學習這些程式最好的辦法就是執行它們,這些程式碼是有效的,嘗試解釋一些簡單的表示式,然後是更加複雜的表示式。新增錯誤訊息,修改直譯器,嘗試設計自己的變體,試著真正掌握這些程式,不只是對它們的工作模稜兩可。如果這樣做,您將改變對程式設計的看法以及對自己作為程式設計師的看法。 您會發現自己是語言的設計師,而不僅僅是語言的使用者,是選擇語言組合規則的人,而不僅僅是其他人選擇的規則的追隨者。
最新評論