# 前言

> 译者： [https://sicp.comp.nus.edu.sg/chapters/123](https://sicp.comp.nus.edu.sg/chapters/123)

 <matter># JavaScript改编序言

您正在阅读Harold Abelson和Gerald Jay Sussman编写的教科书_计算机程序的结构和解释_-有点曲折。 该教科书强调了抽象对于管理复杂性的重要性，并向读者介绍了计算机科学领域核心的许多概念。 这些想法中的大多数与编写程序所用的语言无关，后者使用这些想法来解决计算问题。 然后，这种折衷包括替换全文中使用的编程语言，以用实际的计算机程序来说明这些想法。 当作者使用编程语言Scheme时，这种改编使用了JavaScript语言。

更准确地说，这种改编使用了五个精心设计的JavaScript子语言。 这些语言称为_源§1_，_源§2_，_源§3_和_源§4_，分别对应于第1章。 ，教科书的2、3和4。 Source§1语言仅包含第1章中包含的程序中所需的构造：_构建具有功能_的抽象所需的构造。 源§2是源§1的超集，在源§1的功能之上添加了使用数据构建抽象所需的功能。 同样，资料来源§3和4扩展了解决相应教科书章节主题所需的先前语言功能。 （第5章不需要Source§4以外的任何功能。）所有这些语言都是JavaScript的子语言； 任何源程序也是JavaScript程序，但事实并非如此。 JavaScript语言具有许多本教科书未涵盖的功能。 确实，源语言是如此之小，以至于可以在几页文本中充分描述它们。 联机文件夹[源](https://sicp.comp.nus.edu.sg/source)包含源语言的规范，以供读者参考。

这本教科书是交互式的。 大多数程序都是链接。 单击它们会将读者带到称为 [_Source Academy_](https://sourceacademy.nus.edu.sg) 的基于Web的编程环境。 在Source Academy中，读者可以运行程序，对其进行修改并对其进行实验，而无需安装任何软件，并且只要使用Internet浏览器，对使用的计算机也没有任何要求。

即使一年级的大学或大学生对要覆盖的语言功能施加限制，也很难在课程中使用复杂的编程语言（例如JavaScript）。 具有该语言先验知识的学生必须在他们的程序中使用其他功能。 他们的同学会合法地向老师询问这些功能，任何答案都会使学生感到沮丧或导致切线很可能不利于当前的学习目标。 对于JavaScript来说，这个问题尤为严重，而JavaScript的系统设计并不为人所知。 我们对这一挑战的解决方案是激进的：当学生单击特定章节的程序时，源学院_强制_使用相应的源语言。 使用超出该语言的构造的程序将被Source Academy拒绝。 这样一来，基于SICP的课程的讲师就可以采用JavaScript（当今最广泛使用的编程语言之一），而不会被JavaScript的众多特有功能所困扰。

最初的教科书由Jacob Katzenelson于1997年引入新加坡国立大学，作为为计算机科学专业学生提供的常规&lt;quote&gt;编程方法论&lt;/quote&gt;课程的更高级替代方案。 该课程自1998年以来被称为 &lt;quote&gt;CS1101S&lt;/quote&gt; ，于2012年改用JavaScript，并于2018年成为计算机科学本科专业的新生编程方法论课程。

> Martin Henz

# 1996年SICP第二版前言

> 软件是否有可能与其他任何东西都不一样，应该被丢弃：重点是始终将其视为肥皂泡？Alan J. Perlis

自1980年以来，本书中的材料一直是麻省理工学院入门级计算机科学课程的基础。自第一版出版以来，我们已经教授该材料四年了，直到第二版面世为止已经过去了十二年。 我们很高兴我们的工作已被广泛采用并纳入其他文本。 我们已经看到我们的学生采用本书中的思想和程序，并将其构建为新计算机系统和语言的核心。 通过对古代Talmudic双关语的字面理解，我们的学生成为了我们的建设者。 我们很幸运能拥有如此有能力的学生和如此有造accomplished的建设者。

在编写此版本时，我们结合了我们自己的教学经验以及麻省理工学院和其他机构的同事的评论提出的数百项澄清说明。 我们已经重新设计了本书中的大多数主要编程系统，包括通用算术系统，解释器，寄存器机模拟器和编译器； 并且我们重写了所有程序示例，以确保任何符合IEEE Scheme标准（IEEE 1990）的Scheme实现都能够运行该代码。

此版本强调了几个新主题。 其中最重要的是计算模型中处理时间的不同方法所起的核心作用：具有状态的对象，并发编程，函数编程，惰性求值和非确定性编程。 我们增加了关于并发性和不确定性的新章节，并且我们试图将这一主题整合到整本书中。

该书的第一版紧随我们的麻省理工学院一个学期课程提纲。 有了第二版中的所有新材料，将不可能在一个学期内涵盖所有内容，因此讲师将不得不选择。 在我们自己的教学中，我们有时会跳过逻辑编程这一节，我们让学生使用寄存器机器模拟器，但是我们不介绍其实现，并且仅给出了编译器的粗略概述。 即使这样，这仍然是一个激烈的过程。 一些讲师可能只希望覆盖前三或四章，而将其他材料留给以后的课程。

MIT Press 的万维网站点[为本书的用户提供支持。 这包括本书中的程序，示例编程任务，补充材料以及Lisp计划方言的可下载实现。](http://www-mitpress.mit.edu/sicp)

> Harold Abelson和Gerald Jay Sussman

# 1984年SICP第一版的序言

> 电脑就像小提琴。 您可以想象一个新手先尝试留声机，然后再尝试小提琴。 他说，后者听起来很糟糕。 这是我们从人文主义者和大多数计算机科学家那里听到的论据。 他们说，出于特定目的，计算机程序是好的，但它们并不灵活。 在学习使用方法之前，既不是小提琴也不是打字机。Marvin Minsky &lt;quote&gt;为什么编程是表达理解不足和草率表述的好方法&lt;/quote&gt;

&lt;quote&gt;计算机程序的结构和解释&lt;/quote&gt;是麻省理工学院计算机科学的入门级学科。 麻省理工学院所有电气工程或计算机科学专业的学生都必须参加，这是&lt;quote&gt;通用核心课程（HTG3）的四分之一，其中还包括电路和线性系统两门课程以及设计一门课程 数字系统。 自1978年以来，我们一直参与该学科的发展，自1980年秋季以来，我们就以目前的形式教该材料，每年有600至700名学生。 这些学生中的大多数都没有或几乎没有接受过计算机方面的正规培训，尽管许多人有点玩过计算机，还有一些人具有广泛的编程或硬件设计经验。&lt;/quote&gt;

我们对计算机科学入门课程的设计反映了两个主要问题。 首先，我们要确立一种思想，即计算机语言不仅是使计算机执行操作的一种方式，而且是表达方法论思想的一种新颖的形式媒介。 因此，必须编写程序供人们阅读，并且只能偶然地使机器执行。 其次，我们认为，在此级别上，主题所要解决的基本材料既不是特定的编程语言构造的语法，也不是有效地计算特定功能的聪明算法，甚至不是算法的数学分析和计算基础， 而是用来控制大型软件系统的知识复杂性的技术。

我们的目标是使完成本课程的学生对样式的元素和编程的美学有良好的感觉。 他们应该掌握控制大型系统复杂性的主要技术。 如果以楷模的形式编写，他们应该能够阅读50页长的程序。 他们应该知道什么都不读，什么时候也不需要了解。 他们应该对修改程序感到安全，同时保留原始作者的精神和风格。

这些技能绝不是计算机编程所独有的。 我们教授和借鉴的技术是所有工程设计所共有的。 我们通过构建适当时隐藏细节的抽象来控制复杂性。 我们通过建立常规接口来控制复杂性，这些接口使我们能够以&lt;quote&gt;混合并匹配&lt;/quote&gt;的方式组合标准的，易于理解的部件来构建系统。 我们通过建立用于描述设计的新语言来控制复杂性，每种语言都强调设计的特定方面，而不再强调其他方面。

我们坚信，&lt;quote&gt;计算机科学&lt;/quote&gt;不是一门科学，并且其重要性与计算机无关，因此我们坚信这一点。 计算机革命是我们思维方式和表达思维方式的革命。 这种变化的本质是最有可能被称为_程序认识论_的出现-从命令式的角度来研究知识结构，而不是经典数学所采用的更具说明性的观点 科目。 数学提供了一个框架，可以精确处理&lt;quote&gt;的概念。&lt;/quote&gt; 计算提供了一个框架，用于精确处理&lt;quote&gt;操作方法的概念。&lt;/quote&gt;

在讲授我们的材料时，我们使用编程语言Lisp的方言。 我们从来没有正式教语言，因为我们没有必要。 我们只是使用它，几天后学生就会把它捡起来。 这是类似Lisp的语言的一大优势：它们几乎没有形成复合表达式的方式，而且几乎没有语法结构。 象棋规则一样，所有正式财产都可以在一个小时内被覆盖。 片刻之后，我们忘记了该语言的语法细节（因为没有语法细节），然后着手解决实际问题-弄清楚我们要计算的内容，如何将问题分解为可管理的部分以及如何处理 部分。 Lisp的另一个优点是，它比我们所知道的任何其他语言都支持（但不强制执行）更多的模块化程序分解大规模策略。 我们可以进行过程和数据抽象，可以使用高阶函数来捕获常见的用法模式，可以使用赋值和数据突变来对局部状态进行建模，可以将程序的各个部分与流和延迟的评估相链接，并且可以轻松地 实现嵌入式语言。 所有这些都嵌入在交互式环境中，并为增量程序设计，构建，测试和调试提供了出色的支持。 我们感谢所有一代Lisp巫师，从约翰·麦卡锡（John McCarthy）开始，他们塑造了前所未有的强大功能和优雅的精美工具。

Scheme，我们使用的Lisp的方言，是试图将Lisp和Algol的力量和优雅融合在一起。 从Lisp中，我们获得了元语言能力，其源于简单的语法，程序作为数据对象的统一表示以及垃圾收集的堆分配数据。 在Algol中，我们采用词法作用域和块结构，这是Algol委员会中编程语言设计先驱的礼物。 我们希望引用约翰·雷诺兹（John Reynolds）和彼得·兰丁（Peter Landin）对Church的lambda演算与编程语言结构之间关系的见解。 我们还认识到我们对数学家的欠债，这些数学家在计算机出现之前数十年来一直在这片土地上进行搜索。 这些先驱包括Alonzo Church，Barkley Rosser，Stephen Kleene和Haskell Curry。

> Harold Abelson and Gerald Jay Sussman</matter>