0.0.0 序

This book is dedicated, in respect and admiration, to the spirit that lives in the computer.

带着崇敬和赞美,将本书献给活在计算机里的神灵。

``I think that it's extraordinarily important that we in computer science keep fun in computing. When it started out, it was an awful lot of fun. Of course, the paying customers got shafted every now and then, and after a while we began to take their complaints seriously. We began to feel as if we really were responsible for the successful, error-free perfect use of these machines. I don't think we are. I think we're responsible for stretching them, setting them off in new directions, and keeping fun in the house. I hope the field of computer science never loses its sense of fun. Above all, I hope we don't become missionaries. Don't feel as if you're Bible salesmen. The world has too many of those already. What you know about computing other people will learn. Don't feel as if the key to successful computing is only in your hands. What's in your hands, I think and hope, is intelligence: the ability to see the machine as more than when you were first led up to it, that you can make it more.''

“我认为,在计算机科学中保持计算中的趣味性是特别重要的 事情。这一学科在起步时饱含着趣味性。当然那些付钱的客户们时常觉得受了骗。一段时间之后,我们开始严肃地看待他们的抱怨。我们开始感觉到,自己真的像是 要负起成功地、无差错地、完美地使用这些机器的责任。我不认为我们可以做到这些。我认为我们的责任是去拓展这一领域,将其发展到新的方向,并在自己的家里 保持趣味性。我希望计算机科学的领域绝不要丧失其趣味意识。最重要的是,我希望我们不要变成传道士,不要认为你是兜售圣经的人,世界上这种人已经太多了。 你所知道的有关计算的东西,其他人也都能学到。绝不要认为似乎成功计算的钥匙就掌握在你的手里。你所掌握的,也是我认为并希望的,也就是智慧:那种看到这 一机器比你第一次站在它面前时能做得更多的能力,这样你才能将它向前推进。“

Alan J. Perlis (April 1, 1922-February 7, 1990)

Foreword


Educators, generals, dieticians, psychologists, and parents program. Armies, students, and some societies are programmed. An assault on large problems employs a succession of programs, most of which spring into existence en route. These programs are rife with issues that appear to be particular to the problem at hand. To appreciate programming as an intellectual activity in its own right you must turn to computer programming; you must read and write computer programs -- many of them. It doesn't matter much what the programs are about or what applications they serve. What does matter is how well they perform and how smoothly they fit with other programs in the creation of still greater programs. The programmer must seek both perfection of part and adequacy of collection. In this book the use of ``program'' is focused on the creation, execution, and study of programs written in a dialect of Lisp for execution on a digital computer. Using Lisp we restrict or limit not what we may program, but only the notation for our program descriptions.

教育者、将军、减肥专家、心理学家和父母做规划(program),而军人,学生和另一些社会阶层则被人规划(are programmed)。解决大规模问题需要经过一系列规划,其中的大部分东西只有在工作进程中才能做出来,这些规划中充满着与手头问题的特殊性相关的情况。如果想要把做规划这件事情本身作为一种智力活动来欣赏,你就必须转到计算机的程序设计(programming),你需要读或者写计算机程序——而且要大量地做。有关这些程序具体是关于什么的、服务于哪类应用等等的情况常常并不重要,重要的是它们的性能如何,在用于构造更大的程序时能否与其他程序平滑衔接。程序员们必须同时追求具体部分的完美和汇合的适宜性。在这部书里使用“程序设计”一词时,所关注的是程序的创建、执行和研究,这些程序是用一种 Lisp 方言书写的,为了在数字计算机上执行。采用 Lisp 并没有对我们可以编程的范围施以任何约束或者限制,而只不过确定了程序描述的记法形式。

Our traffic with the subject matter of this book involves us with three foci of phenomena: the human mind, collections of computer programs, and the computer. Every computer program is a model, hatched in the mind, of a real or mental process. These processes, arising from human experience and thought, are huge in number, intricate in detail, and at any time only partially understood. They are modeled to our permanent satisfaction rarely by our computer programs. Thus even though our programs are carefully handcrafted discrete collections of symbols, mosaics of interlocking functions, they continually evolve: we change them as our perception of the model deepens, enlarges, generalizes until the model ultimately attains a metastable place within still another model with which we struggle. The source of the exhilaration associated with computer programming is the continual unfolding within the mind and on the computer of mechanisms expressed as programs and the explosion of perception they generate. If art interprets our dreams, the computer executes them in the guise of programs!

本书中要讨论的各种问题都牵涉到三类需要关注的对象:人的大脑、计算机程序的集合以及计算机本身,每一个计算机程序都是现实中的或者精神中的某个过程的一个模型,通过人的头脑孵化出来。这些过程出现在人们的经验或者思维之中,数量上数不胜数,详情琐碎繁杂,任何时候人们都只能部分地理解它们。我们很少能通过自己的程序将这种过程模拟到永远令人满意的程序。正因为如此,即使我们写出的程序是一集经过仔细雕琢的离散符号,是交织在一起的一组函数,它们也需要不断地演化:当我们对于模型的认识更深入、更扩大、更广泛时,就需要去修改程序,直到这一模型最终到达了一种亚稳定状态。而在这时,程序中就又会出现另一个需要我们去为之奋斗的模型。计算机程序设计领域之令人兴奋的源泉,就在于它所引起连绵不绝的发现,在我们的头脑之中,在由程序所表达的计算机制之中,以及在由此所导致的认识爆炸之中。如果说艺术解释了我们的梦想,那么计算机就是以程序的名义执行着它们。

For all its power, the computer is a harsh taskmaster. Its programs must be correct, and what we wish to say must be said accurately in every detail. As in every other symbolic activity, we become convinced of program truth through argument. Lisp itself can be assigned a semantics (another model, by the way), and if a program's function can be specified, say, in the predicate calculus, the proof methods of logic can be used to make an acceptable correctness argument. Unfortunately, as programs get large and complicated, as they almost always do, the adequacy, consistency, and correctness of the specifications themselves become open to doubt, so that complete formal arguments of correctness seldom accompany large programs. Since large programs grow from small ones, it is crucial that we develop an arsenal of standard program structures of whose correctness we have become sure -- we call them idioms -- and learn to combine them into larger structures using organizational techniques of proven value. These techniques are treated at length in this book, and understanding them is essential to participation in the Promethean enterprise called programming. More than anything else, the uncovering and mastery of powerful organizational techniques accelerates our ability to create large, significant programs. Conversely, since writing large programs is very taxing, we are stimulated to invent new methods of reducing the mass of function and detail to be fitted into large programs.

就其本身的所有能力而言,计算机是一位一丝不苟的工匠:它的程序必须正确,我们希望说的所有东西,都必须表述得准确到每一点细节。就像在其他所有使用符号的活动中一样。我们需要通过论证使自己相信程序的真。可以为 Lisp 本身赋予一个语义(可以说是另一个模型),假如说,一个程序的功能可以在(例如)谓词演算里描述,那么就可以用逻辑方法做出一个可接受的正确性论证。不幸的是,随着程序变得更大更复杂(实际上它们几乎总是如此),这种描述本身的适宜性、一致性和正确性也都变得非常值得怀疑了。因此,很少能够看到有关大程序正确性的完全形式化的论证。因为大的程序是从小东西成长起来的,开发出一个标准化的程序结构的武器库,并保证其中每种结构的正确性——我们称它们为惯用法,再学会如何利用一些已经证明很有价值的组织技术。理解这些技术,对于参与这种被称为程序设计的具有创造性的事业是最最本质的。特别值得提出的是,发现并掌握强有力的组织技术,将提升我们构造大型的重要程序的能力。反过来说,因为写大程序非常耗时费力,这也推动着我们去发明新方法,减轻由于大程序的功能和细节而引起的沉重负担。

Unlike programs, computers must obey the laws of physics. If they wish to perform rapidly -- a few nanoseconds per state change -- they must transmit electrons only small distances (at most 1 1/2 feet). The heat generated by the huge number of devices so concentrated in space has to be removed. An exquisite engineering art has been developed balancing between multiplicity of function and density of devices. In any event, hardware always operates at a level more primitive than that at which we care to program. The processes that transform our Lisp programs to ``machine'' programs are themselves abstract models which we program. Their study and creation give a great deal of insight into the organizational programs associated with programming arbitrary models. Of course the computer itself can be so modeled. Think of it: the behavior of the smallest physical switching element is modeled by quantum mechanics described by differential equations whose detailed behavior is captured by numerical approximations represented in computer programs executing on computers composed of ...!

与程序不同,计算机必须遵守物理定律。如果它们要快速执行——几个纳秒做一次状态转换——那么就必须在很短的距离内传导电子(至多 1.5 英尺)。必须消除由于大量元件而产生的热量集中。人们已经开发出了一些巧妙的工程艺术,用于在功能多样性与元件密度之间求得一种平衡。在任何情况下,硬件都是在比我们编程时所需要关心的层次更低的层次上操作的。将我们的 Lisp 程序变换到“机器”程序的过程本身也是抽象模型,是通过程序设计做出来的。研究和构造它们,能使人更加深刻地理解与任何模型的程序设计有关的程序组织问题。当然,计算机本身也可以这样模拟。请想一想:最小的物理开关元件在量子力学里建模,而量子力学以由一组微分方程描述,微分方程的细节行为可以由数值去近似,这种数值又由计算机程序所描述,计算机程序的组成……

It is not merely a matter of tactical convenience to separately identify the three foci. 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. At best, relationships between the foci are metastable. The computers are never large enough or fast enough. Each breakthrough in hardware technology leads to more massive programming enterprises, new organizational principles, and an enrichment of abstract models. Every reader should ask himself periodically ``Toward what end, toward what end?'' -- but do not ask it too often lest you pass up the fun of programming for the constipation of bittersweet philosophy.

区分出上述三类需要关注的对象,并不仅仅是为了策略上的便利。即使有人说它不过是人头脑里的东西,这种逻辑区分也引起了这些关注焦点之间符号流动的加速,它们在人们经验中的丰富性、活力和潜力,只能由现实生活中的不断演化去超越。我们至多只能说,这些关注焦点之间的关系是基本稳定的。计算机永远都不够大也不够快。硬件技术的每一次突破都带来了更大规模的程序设计事业,新的组织原理,以及更加丰富的抽象模型。每个读者都应该反复地问自己“到哪里才是头儿,到哪里才是头儿?”——但是不要问得过于频繁,以免忽略了程序设计的乐趣,使自己陷入一种喜忧参半的呆滞状态中。

Among the programs we write, some (but never enough) perform a precise mathematical function such as sorting or finding the maximum of a sequence of numbers, determining primality, or finding the square root. We call such programs algorithms, and a great deal is known of their optimal behavior, particularly with respect to the two important parameters of execution time and data storage requirements. A programmer should acquire good algorithms and idioms. Even though some programs resist precise specifications, it is the responsibility of the programmer to estimate, and always to attempt to improve, their performance.

在我们写出的程序里,有些程序执行了某个精确的数学函数(但是绝不够精确),例如排序,或者找出一系列数中的最大元,确定素数性,或者找出平方根。我们将这种程序称为算法,关于它们的最佳行为已经有了许多认识,特别是关于两个重要的参数:执行的时间和对于数据存储的需求。程序员应该追求好的算法和惯用法。即使某些程序难以精确地描述,程序员也有责任去估计它们的性能,并要继续设法去改进之。

Lisp is a survivor, having been in use for about a quarter of a century. Among the active programming languages only Fortran has had a longer life. Both languages have supported the programming needs of important areas of application, Fortran for scientific and engineering computation and Lisp for artificial intelligence. These two areas continue to be important, and their programmers are so devoted to these two languages that Lisp and Fortran may well continue in active use for at least another quarter-century.

Lisp 是一个幸存者,已经使用了四分之一个世纪。在现在的活语言里,只有 Fortran 比它的寿命更长些。这两种语言都支持着一些重要领域中的程序设计需要,Fortran 用于科学与工程计算,Lisp 用于人工智能。这两个领域现在仍然很重要,它们的程序员都如此倾心于这两种语言,因此,Lisp 和 Fortran 都还可能继续生存至少四分之一个世纪。

Lisp changes. The Scheme dialect used in this text has evolved from the original Lisp and differs from the latter in several important ways, including static scoping for variable binding and permitting functions to yield functions as values. In its semantic structure Scheme is as closely akin to Algol 60 as to early Lisps. Algol 60, never to be an active language again, lives on in the genes of Scheme and Pascal. 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 is for building pyramids -- imposing, breathtaking, static structures built by armies pushing heavy blocks into place. Lisp is for building organisms -- imposing, breathtaking, dynamic structures built by squads fitting fluctuating myriads of simpler organisms into place. The organizing principles used are the same in both cases, except for one extraordinarily important difference: The discretionary exportable functionality entrusted to the individual Lisp programmer is more than an order of magnitude greater than that to be found within Pascal enterprises. Lisp programs inflate libraries with functions whose utility transcends the application that produced them. The list, Lisp's native data structure, is largely responsible for such growth of utility. The simple structure and natural applicability of lists are reflected in functions that are amazingly nonidiosyncratic. In Pascal the plethora of declarable data structures induces a specialization within functions that inhibits and penalizes casual cooperation. It is better to have 100 functions operate on one data structure than to have 10 functions operate on 10 data structures. As a result the pyramid must stand unchanged for a millennium; the organism must evolve or perish.

Lisp 一直在改变着。这本教科书中所用的 Scheme 方言就是从原来的 Lisp 里演化出来的,并在若干重要方面与之相异,包括变量约束的静态作用域,以及允许函数产生出函数作为值。在语义结构上,Scheme 更接近于 Algol 60 而不是早期的 Lisp。Algol 60 已经不可能再变为活的语言了,但它还活在 Scheme 和 Pascal 的基因里。很难找到这样的两种语言,它们能如此清晰地代表着围绕这两种语言而聚集起来的两种差异巨大的文化。Pascal 是为了建造金字塔——壮丽辉煌、令人震撼,是由各就其位的沉重巨石筑起的静态结构。而 Lisp 则是为了构造有机体——同样的壮丽辉煌并令人震撼,是由各就其位的沉重巨石筑起的静态结构。而 Lisp 则是为了构造有机体——同样的壮丽辉煌并令人震撼,由各就其位但却永不静止的无数简单的有机体片段构成的动态结构。在两种语言里都采用了同样的组织原则,除了其中特别重要的一点不同之外:托付给 Lisp 程序员个人可用的自由支配权,要远远超过在 Pascal 社团里可找到的东西。Lisp 程序大大抬高了函数库的地位,使其可用性超越了催生它们的那些具体应用。作为 Lisp 的内在数据结构,表对于这种可用性的提升起着最重要的作用。表的简单结构和自然可用性反应到函数里,就使它们具有了一种奇异的普适性。而在 Pascal 里,数据结构的过度声明导致函数的专用性,阻碍并惩罚临时性的合作。采用 100 个函数在一种数据结构上操作,远远优于用 10 个函数在 10 个数据结构上操作。作为这些情况的必然后果,金字塔矗立在那里千年不变,而,有机体则必须演化,否则就会死亡。

To illustrate this difference, compare the treatment of material and exercises within this book with that in any first-course text using Pascal. Do not labor under the illusion that this is a text digestible at MIT only, peculiar to the breed found there. It is precisely what a serious book on programming Lisp must be, no matter who the student is or where it is used.

为了看清楚这种差异,请将本书中给出的材料和练习与任何第一门 Pascal 课程的教科书中的材料做一个比较。请不要费力地去想象,说这不过是一本在 MIT 采用的教科书,其特异性仅仅是因为它出自那个地方。准确地说,任何一本严肃的关于 Lisp 程序设计的书都应该如此,无论其学生是谁,在什么地方使用。

Note that this is a text about programming, unlike most Lisp books, which are used as a preparation for work in artificial intelligence. After all, the critical programming concerns of software engineering and artificial intelligence tend to coalesce as the systems under investigation become larger. This explains why there is such growing interest in Lisp outside of artificial intelligence.

请注意,这是一本有关程序设计的教科书,它不像大部分关于 Lisp 的书,因为那些书多半是为人们在人工智能领域工作做准备。当然,无论如何,在研究工作规模不断增长的过程中,软件工程和人工智能所关心的重要程序设计工作正趋于相互结合。这也解释了为什么在人工智能领域之外的人们对 Lisp 的兴趣在不断增加。

As one would expect from its goals, artificial intelligence research generates many significant programming problems. In other programming cultures this spate of problems spawns new languages. Indeed, in any very large programming task a useful organizing principle is to control and isolate traffic within the task modules via the invention of language. These languages tend to become less primitive as one approaches the boundaries of the system where we humans interact most often. As a result, such systems contain complex language-processing functions replicated many times. Lisp has such a simple syntax and semantics that parsing can be treated as an elementary task. Thus parsing technology plays almost no role in Lisp programs, and the construction of language processors is rarely an impediment to the rate of growth and change of large Lisp systems. Finally, it is this very simplicity of syntax and semantics that is responsible for the burden and freedom borne by all Lisp programmers. No Lisp program of any size beyond a few lines can be written without being saturated with discretionary functions. Invent and fit; have fits and reinvent! We toast the Lisp programmer who pens his thoughts within nests of parentheses.

正如由其目标可以预见到的,人工智能的研究产生出许多重要的程序设计问题。在其他程序设计文化中,问题的洪水孵化出一种又一种新的语言。确实,在任何非常大的程序设计工作中,一条有用的组织原则就是通过发明新语言,去控制和隔离作业模块之间的信息流动。这些语言趋向于变得越来越不基本,逐渐逼近系统的边界,逼近我们作为人最经常与之交互的地方。作为这一情况的结果,在这种系统里包含着大量重复的复杂的语言处理功能。Lisp 有着如此简单的语法和语义,程序的语法分析可以看作一种很简单的工作。这样,语法分析技术对于 Lisp 程序几乎就没有价值,语言处理器的构造对于大型 Lisp 系统的成长和变化不会成为阻碍。最后,正是这种语法和语义的极端简单性,产生出了所有 Lisp 程序员的负担和自由。任何规模的 Lisp 程序,除了那种寥寥几行的程序外,都饱含着考虑周到的各种功能。发明并调整,调整恰当后再去发明!让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的 Lisp 程序员。

Alan J. Perlis
New Haven, Connecticut

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值