# 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.**
> **计算机语言的处理程序只是另一个程序。**
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.
> 做为程序员,你有三个理由来学习翻译技术。
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. 译注:“哥德尔命题”。