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. 译注:“哥德尔命题”。

相关文章
相关标签/搜索