《计算机程序的构造和解释》(SICP)给读者介绍计算的核心思想,采用的方法是为计算建立一系列的概念模型。第1章到第3章涵盖了所有时新的高级程序设计语言所共有的程序设计概念。在原SICP的两个版本里,程序设计示例用程序设计语言Scheme描述,该语言具有极简的风格和基于表达式的语法形式,这些使原书可以聚焦于基础概念,而不是所选语言本身的设计。第4章和第5章使用Scheme构造Scheme的处理器,用以加深读者对概念模型的理解,并探索了语言的一些扩充和替代结构。
自1984年出版,以及1996年第2版出版后,SICP被全世界许多大学和学院选作教科书。新加坡国立大学(NUS)1997年开始开设基于SICP的引论课程CS1101S。20世纪90年代中期,Python、JavaScript和Ruby等语言发展起来,它们都共享了Scheme的核心设计元素,但采用了更复杂的基于语句的语法结构,使用了人们更熟悉的代数表达形式(中缀形式)。这些语言的兴起,导致一些教师调整基于SICP的课程,典型方法是把其中的示例程序都翻译为他们所选的语言,再加上一些特别的与语言相关的材料,并略去原书的第4章和第5章。
把SICP改编到JavaScript
在NUS,把SICP的第2版改编到JavaScript(SCIP JS)的工作开始于2008年,2012年CS1101S课程转到了JavaScript。ECMAScript 2015语言标准引进了lambda表达式、尾递归和分程序作用域的变量和常量,这些使有关的改编更接近原书。我们对SICP的实质性修改不多,只出现在JavaScript与Scheme的差异使我们感到不得不修改的地方。这本书只涉及JavaScript的很少一部分,所以绝不建议读者用它学习这个语言。举例说,JavaScript对象的概念在本书里就完全没有提及——而对象被认为是该语言最基本的成分。
通过加入一些模拟Scheme原语的库,包括支持表结构的库,并相应修改正文中的文字,翻译第1~3章的程序是直截了当的。然而,转到JavaScript,也迫使我们对第4章和第5章的解释器和编译器做了一些实质性的修改,以便处理返回语句。Scheme的基于表达式的语法里没有返回语句,而这种语句是基于语句的语言中不可或缺的特征。
通过使用JavaScript,第1章到第3章给读者介绍了今天大多数主流语言的语法风格。然而,在第4章,语法风格产生了重大变化,因为把程序直接表示为数据结构已经无法看作是理所当然了。但这也为我们提供了一个机会,在4.1节为读者介绍语法分析,这是程序设计语言处理器的一个重要组成部分。在4.4节,JavaScript严格的语法结构使展示逻辑程序设计系统的工作大大复杂化,显示出用JavaScript作为程序语言设计工具的局限性。
使用SICP JS资源
MIT出版社有关SICP JS的网页上有针对本书使用者的支持链接,那里提供了书中所有程序和扩展教学资源,包括一大批附加练习,以及安排典型的大学一学期课程的SICP JS选学子集的建议。本书中的JavaScript程序可以在符合ECMAScript 2020规范(ECMA 2020)的任何JavaScript解释器推荐的严格模式下运行。MIT出版社的网页包含一个名为sicp的JavaScript包,它提供了本书中当作“原语”的所有JavaScript函数。
致读者
我们真诚地希望,如果你在阅读本书时第一次遇到程序设计,你将能运用自己对计算机程序的构造和解释的新理解去学习更多的程序设计语言,包括Scheme和完整的JavaScript。如果你在拿起SICP JS之前已经学过JavaScript,你可能得到有关该语言背后的基本概念的一些新见解,并看到只需要多么少的东西就可以得到多么多。如果你遇到SICP JS时已经学过有关原SICP的知识,你可能看到熟悉的思想如何用一种新形式表达,还可以欣赏在线的对照版本(在本书的网页上可用),它使你可以并排地对照着看SICP和SICP JS。
Martin Henz和Tobias Wrigstad