ESSENTIALS OF PROGRAMMING LANGUAGES (THIRD EDITION) :編程語言的本質 —— (一)

# Foreword
> # 序程序員

This book brings you face-to-face with the most fundamental idea in computer programming:算法

> 關於計算機的基礎理念,這本書會給您帶來一個直觀的理解:數據庫

**The interpreter for a computer language is just another program.**

> **計算機語言的處理程序只是另外一個程序。**express

It sounds obvious, doesn’t it? But the implications are profound. If you are a computational theorist, the interpreter idea recalls Gödel’s discovery of the limitations of formal logical systems, Turing’s concept of a universal computer, and von Neumann’s basic notion of the stored-program machine. If you are a programmer, mastering the idea of an interpreter is a source of great power. It provokes a real shift in mindset, a basic change in the way you think about programming.編程

> 貌似是顯而易見的,是麼?不過這個看法是有深度的。若是你是一個計算理論家,計算思想可追溯到哥德爾(Gödel)對正式邏輯系統限制的發現^**1** ,圖靈機的概念和馮諾依曼存儲程序機的基本概念。若是你是一個程序員,掌握翻譯思想是本身的強力能力的來源之一。它會引起你思惟上的一個真正的升級,一個你對「編程」見解的根本的改變。數組

I did a lot of programming before I learned about interpreters, and I produced some substantial programs. One of them, for example, was a large data-entry and information-retrieval system written in PL/I. When I implemented my system, I viewed PL/I as a fixed collection of rules established by some unapproachable group of language designers. I saw my job as not to modify these rules, or even to understand them deeply, but rather to pick through the (very) large manual, selecting this or that feature to use. The notion that there was some underlying structure to the way the language was organized, and that I might want to override some of the language designers’ decisions, never occurred to me. I didn’t know how to create embedded sublanguages to help organize my implementation, so the entire program seemed like a large, complex mosaic, where each piece had to be carefully shaped and fitted into place, rather than a cluster of languages, where the pieces could be flexibly combined. If you don’t understand interpreters, you can still write programs; you can even be a competent programmer. But you can’t be a master.瀏覽器

> 在我學習翻譯技術以前我作過不少編程工做,而且寫了大量的程序。例如,其中一個是用PL/I寫的大型數據錄入與信息檢索系統。當我寫這個系統時,我把PL/I看作是一幫牛人創建的一個一系列規則的固定集合。我意識到個人工做不是修改這些規則,甚至不須要深刻理解它,而是從一個「巨」大的手冊中選擇本身想要什麼,選擇這個或那個特性去使用。對語言組織的底層結構上的概念,我想要重寫一些語言設計者的決策。我不知道如何建立一個完備的子語言來幫助我組織個人實現,因此整個程序看起來就像一個又大又複雜的馬賽克,每一塊都要當心的放在安排好的適合位置,而不是像一組語句,句與句以前優雅的組合。若是你不理解翻譯技術,你也能夠寫代碼;你甚至能夠成爲一個頗有能力的程序員,但你成不了大師。服務器

There are three reasons why as a programmer you should learn about interpreters.網絡

> 作爲程序員,你有三個理由來學習翻譯技術。app

First, you will need at some point to implement interpreters, perhaps not interpreters for full-blown general-purpose languages, but interpreters just the same. Almost every complex computer system with which people interact in flexible ways—a computer drawing tool or an information-retrieval system, for example—includes some sort of interpreter that structures the interaction. These programs may include complex individual operations—shading a region on the display screen, or performing a database search—but the interpreter is the glue that lets you combine individual operations into useful patterns. Can you use the result of one operation as the input to another operation? Can you name a sequence of operations? Is the name local or global? Can you parameterize a sequence of operations, and give names to its inputs? And so on. No matter how complex and polished the individual operations are, it is often the quality of the glue that most directly determines the power of the system. It’s easy to find examples of programs with good individual operations, but lousy glue; looking back on it, I can see that my PL/I database program certainly had lousy glue.

> 首先,你可能須要對一些點來實現翻譯,可能不是實現一個完備的通用語言,但原理是同樣的。幾乎全部以優雅的方式建立的複雜系統——例如一個計算機做圖工具或一個信息檢索系統——都是由一系列的解釋器配合組織起來的。這些程序可能包含複雜的個性操做——在屏幕上顯示陰影或優化一個數據庫查詢——解釋器是使你能夠組合個性化操做爲有用的模式的「粘合劑」。你能使用一個操做作爲另外一個操做的輸入嗎?你能命名一個操做序列嗎?這個名字是本地的仍是全局的?你能參數化一個操做序列並把每一個輸入命名嗎?等等。不管你的個性化操做有多麼複雜且優雅,「粘合劑」的質量直接取決於系統的能力。很容易找到一些好的個性化操做的程序的例子,但也能夠找到很多垃圾的;回過頭來看,個人PL/I數據庫程序就包含一些垃圾的粘合。

Second, even programs that are not themselves interpreters have important interpreter-like pieces. Look inside a sophisticated computer-aided design system and you’re likely to find a geometric recognition language, a graphics interpreter, a rule-based control interpreter, and an object-oriented language interpreter all working together. One of the most powerful ways to structure a complex program is as a collection of languages, each of which provides a different perspective, a different way of working with the program elements. Choosing the right kind of language for the right purpose, and understanding the implementation tradeoffs involved: that’s what the study of interpreters is about.

> 第二,即便是一個非自解釋的程序也會包含一些相似解釋器的功能。深刻一個精密的計算機輔助設計系統(CAD),你會極可能會發現一個幾何識別這語言,一個圖形解釋器,一個基於規則的控制器和一個面嚮對象語言互相搭配工做。大多數組織一個複雜我只能說的有效方法都是一系列不一樣視角、不一樣工做方式的語言集合共同組成的。爲正確的目的選擇正確的語言,並理解不一樣實現的權衡:這正是學習解釋思想的緣由。

The third reason for learning about interpreters is that programming techniques that explicitly involve the structure of language are becoming increasingly important. Today’s concern with designing and manipulating class hierarchies in object-oriented systems is only one example of this trend. Perhaps this is an inevitable consequence of the fact that our programs are becoming increasingly complex—thinking more explicitly about languages may be our best tool for dealing with this complexity. Consider again the basic idea: the interpreter itself is just a program. But that program is written in some language, whose interpreter is itself just a program written in some language whose interpreter is itself . . . Perhaps the whole distinction between program and programming language is a misleading idea, and future programmers will see themselves not as writing programs in particular, but as creating new languages for each new application.

> 學習解釋器的第三個緣由是語言結構愈來愈在編程技術中佔有更重要的地位。如今對面向對象系統的類結構的設計與操控的關注只是一個這種趨勢的例子。也許咱們的程序變得愈來愈複雜是一個不可避免的趨勢,更明確的思考關於語言的只是或許是咱們可以更好的解決這種複雜性的工具。再次考慮一下基本概念:解釋器自己只是一個程序。但程序是被一些語言寫成的,這些語言的又能解釋它們本身……也許在程序和編程語言以前的區別就是一個誤導的想法,在將來程序員會發現本身不是在寫我寫的程序,而是在爲每一個應用建立一個新的語言。

Friedman and Wand have done a landmark job, and their book will change the landscape of programming-language courses. They don’t just tell you about interpreters; they show them to you. The core of the book is a tour deforce sequence of interpreters starting with an abstract high-level language and progressively making linguistic features explicit until we reach a state machine. You can actually run this code, study and modify it, and change the way these interpreters handle scoping, parameter-passing, control structure, etc.

> 弗裏德曼和王德作了一個里程碑式的工做,他們的書會改變編程語言課程的風景。他們不只僅告訴你關於解釋的一切,他們還把這些展現給你看。這本書的核心是從一個高級語言開始的解釋原理的知識序列,並不段豐富語言特性直到咱們獲得一個狀態機。你能夠運行這個代碼、學習和修改它,並改變這些解釋的運行方式:做用域,參數傳遞,控制結構,等等。

Having used interpreters to study the execution of languages, the authors show how the same ideas can be used to analyze programs without running them. In two new chapters, they show how to implement type checkers and inferencers, and how these features interact in modern object-oriented languages.

> 一般咱們用翻譯器來研究語言的執行過程,做者在這裏展現瞭如何用同一種思想不執行程序來分析程序。在兩個新章節中,他們展現瞭如何實現類型檢查及推倒,這些特性如何做用於現代面嚮對象語言。

Part of the reason for the appeal of this approach is that the authors have chosen a good tool—the Scheme language, which combines the uniform syntax and data-abstraction capabilities of Lisp with the lexical scoping and block structure of Algol. But a powerful tool becomes most powerful in the hands of masters. The sample interpreters in this book are outstanding models. Indeed, since they are runnable models, I’m sure that these interpreters and analyzers will find themselves at the cores of many programming systems over the coming years.

> 這本書的一個吸引人的緣由是做者選擇了一個很是好的工具來闡釋——Scheme語言,這個語言組合了Lisp語言的統一的語法形式和數據抽象能力以及Algol語言的詞法做用域和塊結構。但一個牛逼的工具在大師的手裏會變得更牛逼。本書的實例解釋器是一個優秀的模型。的確,正由於它們是可運行的模型,我相信這些解釋器和分析器會發現本身將來會成爲不少編程系統的核心。

This is not an easy book. Mastery of interpreters does not come easily, and for good reason. The language designer is a further level removed from the end user than is the ordinary application programmer. In designing an application program, you think about the specific tasks to be performed, and consider what features to include. But in designing a language, you consider the various applications people might want to implement, and the ways in which they might implement them. Should your language have static or dynamic scope, or a mixture? Should it have inheritance? Should it pass parameters by reference or by value? Should continuations be explicit or implicit? It all depends on how you expect your language to be used, which kinds of programs should be easy to write, and which you can afford to make more difficult.

> 這不是一本容易讀的書。精通解釋器並不容易。相對於普通的程序開發者來講,語言設計者是離用戶更遠的層次。在設計一個應用程序時,你想的是執行一些特定的任務,考慮哪些特性需求包含在裏面。可是在設計一個語言時,你考慮的是各類各樣的程序中,人們可能想要實現什麼,以及人們可能實現它們的方式。你的語言是靜態做用域仍是動態的,或者是混合的?它有繼承麼?它的傳參方式是傳值仍是傳址?這都取決於你指望你的語言如何被使用,哪些程序會很容易用你的語言實現,同時哪些實現會形成必定的困難。

Also, interpreters really are subtle programs. A simple change to a line of code in an interpreter can make an enormous difference in the behavior of the resulting language. Don’t think that you can just skim these programs—very few people in the world can glance at a new interpreter and predict from that how it will behave even on relatively simple programs. So study these programs. Better yet, run them—this is working code. Try interpreting some simple expressions, then more complex ones. Add error messages. Modify the interpreters. Design your own variations. Try to really master these programs, not just get a vague feeling for how they work.

> 一樣,解釋器真的是一個微妙的程序。對解釋器的一行代碼進行一個微小的修改都會使語言的行爲發生巨大的改變。不要認爲你能夠瀏覽這些程序——世上幾乎沒有人能夠一瞥一個新的解釋器程序就能夠高效能它的行爲,即便是一個相對簡單的程序。因此學習這些程序最好去運行它們——這些都是可運行的代碼。試着解釋一些簡單的表達式,而後試試更復雜的。添加錯誤信息。修改解釋器。設計你本身的變種。試着真正的精通這些程序,而不只僅是對它的工做原理有一個表面的感受。

If you do this, you will change your view of your programming, and your view of yourself as a programmer. You’ll come to see yourself as a designer of languages rather than only a user of languages, as a person who chooses the rules by which languages are put together, rather than only a follower of rules that other people have chosen.

> 若是你這樣作,你會改變你看待編程的方式,你會把本身當作一個真正的程序員。你會把本身當作一個語言的設計者,而不只僅是一個語言的用戶,一個選擇不一樣語言的規則協同使用,而不只僅是跟隨其它人所作的選擇。

## Postscript to the Third Edition

> ## 第三版補充

The foreword above was written only seven years ago. Since then, information applications and services have entered the lives of people around the world in ways that hardly seemed possible in 1990. They are powered by an ever—growing collection of programming languages and programming frameworks—all erected on an ever-expanding platform of interpreters.

> 這個前言寫完公過了七年。從那時起,信息應用和服務以1990年沒法想像的方式進入了人員的生活。它們由日益增加的語言集合和編程框架支持,全部這些都創建在不斷膨脹的解釋器平臺上。

Do you want to create Web pages? In 1990, that meant formatting static text and graphics, in effect, creating a program to be run by browsers executing only a single 「print」 statement. Today’s dynamic Web pages make full use of scripting languages (another name for interpreted languages) like Javascript. The browser programs can be complex, and including asynchronous calls to a Web server that is typically running a program in a completely different programming framework possibly with a host of services, each with its own individual language.

> 你是否想建立一個網頁?在1990年,那意味着格式化靜態文本和圖象,其實是建立一個程序來經過瀏覽器執行一個打印語句。如今的動態網頁充分利用腳本語言(或叫解釋語言),例如Javascript。瀏覽器程序能夠很複雜,包含對Web服務器的異步調用,這是典型的運行一個完整的不一樣編程框架的程序,一般這是在一個用我寫語言編寫的主服務中。

Or you might be creating a bot for enhancing the performance of your avatar in a massive online multiplayer game like World of Warcraft. In that case, you’re probably using a scripting language like Lua, possibly with an object-oriented extension to help in expressing classes of behaviors.

> 或者你可能會建立一個外掛用來在一個巨大的多人在線遊戲中提升你的英雄的能力,例如魔獸世界。在這個例子中,你可能使用一個像Lua同樣的腳本語言,可能使用一個面向對象的擴展來輔助表達類的行爲。

Or maybe you’re programming a massive computing cluster to do indexing and searching on a global scale. If so, you might be writing your programs using the map-reduce paradigm of functional programming to relieve you of dealing explicitly with the details of how the individual processors are scheduled.

> 或者可能你正在編寫一個巨大的計算集羣用來在全球範圍內進行索引和查找。若是是那樣,你可能在使用一個MapReduce模型的函數式語言編寫你的程序,這樣能夠減輕你對調度處理器使用細節的工做。

Or perhaps you’re developing new algorithms for sensor networks, and exploring the use of lazy evaluation to better deal with parallelism and data aggregation. Or exploring transformation systems like XSLT for controlling Web pages. Or designing frameworks for transforming and remixing multimedia streams. Or . . .

> 或者可能你在爲神經網絡開發一個新的算法,並探索使用延遲計算能夠更好的處理並行計算和數據聚合。或者探索爲控制網頁的轉換系統,相似XSLT。或者設計一個框架來轉換和混合多媒體流。或者……
So many new applications! So many new languages! So many new interpreters!

> 如此多的新程序!如此多的新語言!如此多的新解釋器!

As ever, novice programmers, even capable ones, can get along viewing each new framework individually, working within its fixed set of rules. But creating new frameworks requires skills of the master: understanding the principles that run across languages, appreciating which language features are best suited for which type of application, and knowing how to craft the interpreters that bring these languages to life. These are the skills you will learn from this book.

> 像之前同樣,新手程序員甚至高手程序員均可以分別看每個新框架,用它的完備的規則幾何來工做。可是建立一個新的框架須要大師級的技能:理解語言運行的原則,體會哪一種語言我最適合於哪徙類型的應用程序,而且知道如何製做解釋器來把這些語言帶入咱們的生活。這些就是你會在這本書中學到的技能。

Hal Abelson Cambridge,Massachusetts September 2007

-------1. 譯註:「哥德爾命題」。

相關文章
相關標籤/搜索