├── .editorconfig ├── .gitignore ├── README.md ├── Tutorials.md ├── book ├── .vuepress │ └── config.js ├── README.md ├── acknowledgments.md ├── chapter1.1.md ├── chapter1.2.md ├── chapter1.md ├── content.md ├── foreword.md ├── images │ ├── ch1-1-8-1.svg │ ├── ch1_1_3-1.png │ ├── ch1_1_6-1.png │ ├── ch1_1_7-1.png │ ├── ch1_1_7-2.png │ └── ch1_1_7-3.png ├── prefaces.md └── references.md ├── docs ├── 404.html ├── acknowledgments.html ├── assets │ ├── css │ │ └── 0.styles.929c33a3.css │ ├── img │ │ ├── ch1-1-8-1.f03f002b.svg │ │ └── search.83621669.svg │ └── js │ │ ├── 10.c16c198a.js │ │ ├── 11.d8727b0b.js │ │ ├── 12.8fdb12a3.js │ │ ├── 13.de801693.js │ │ ├── 14.f2872d53.js │ │ ├── 2.ad7305f8.js │ │ ├── 3.f04bf293.js │ │ ├── 4.d8e6dabe.js │ │ ├── 5.07c65855.js │ │ ├── 6.da87f603.js │ │ ├── 7.f06457f4.js │ │ ├── 8.72cdcc71.js │ │ ├── 9.89efac31.js │ │ └── app.857a548d.js ├── chapter1.1.html ├── chapter1.2.html ├── chapter1.html ├── content.html ├── foreword.html ├── index.html ├── prefaces.html └── references.html ├── package.json └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 4 6 | charset = utf-8 7 | trim_trailing_whitespace = false 8 | insert_final_newline = true 9 | end_of_line = lf 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | 25 | # external 26 | 27 | Chapter1.1 copy.md* 28 | preface copy 2.md* -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 源于兴趣的动力自然强烈,也易随兴趣的消失而消逝。因精力有限,本仓库不再继续维护。 2 | 3 | 时过多年,没想到 [@飞龙](https://github.com/wizardforcel) 竟然肝出来了中文版,当年读的 python 版的 sicp ,也是 [@飞龙](https://github.com/wizardforcel) 翻译的。结合最近的经历,不由得令人感慨,那些优秀的人总是反复出现在自己的学习之路上。 4 | 5 | # 有意阅读 SICP JavaScript 中文版的可移步 https://github.com/apachecn/sicp-js-zh 6 | 7 | -------------------------------------------------------------------------------- /Tutorials.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyf0/sicp-javascript-zh/2bf6943dc92bf415f4094851aebf967dc21ca341/Tutorials.md -------------------------------------------------------------------------------- /book/.vuepress/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | base: '/sicp-javascript-zh/', 3 | dest: './docs', 4 | title: '《SICP in JavaScript》', 5 | description: '《计算机程序的构造与解释》JavaScript版', 6 | themeConfig: { 7 | repo: 'iheyunfei/sicp-javascript-zh', 8 | // displayAllHeaders: true, 9 | lastUpdated: true, 10 | sidebarDepth: 2, 11 | sidebar: [ 12 | '/', 13 | '/foreword', 14 | '/prefaces', 15 | { 16 | title: '第一章', 17 | collapsable: false, 18 | children: [ 19 | '/chapter1', 20 | '/chapter1.1', 21 | '/chapter1.2', 22 | ], 23 | }, 24 | 25 | ] 26 | }, 27 | 28 | } 29 | -------------------------------------------------------------------------------- /book/README.md: -------------------------------------------------------------------------------- 1 | # 目录 2 | 3 | - [Foreword](./foreword.md) 4 | - [Prefaces](./prefaces.md) 5 | - [Acknowledgments](./acknowledgments.md) 6 | - [1 使用函数构造抽象](./chapter1.md) 7 | - [1.1 编程的基本元素(翻译中 90%)](./chapter1.1.md) 8 | - [1.2 Functions and the Processes They Generate(翻译中)](./chapter1.2.md) 9 | - [1.3 Formulating Abstractions with Higher-Order Functions]() 10 | - [2 Building Abstractions with Data]() 11 | - [3 Modularity, Objects, and State]() 12 | - [4 Metalinguistic Abstraction]() 13 | - [文献参考](./references.md) 14 | - [Index]() 15 | -------------------------------------------------------------------------------- /book/acknowledgments.md: -------------------------------------------------------------------------------- 1 | # 谢言 2 | 3 | We would like to thank the many people who have helped us develop this book and this curriculum. 4 | 5 | Our subject is a clear intellectual descendant of 6.231, a wonderful subject on programming linguistics and the lambda calculus taught at MIT in the late 1960s by Jack Wozencraft and Arthur Evans, Jr. 6 | 7 | We owe a great debt to Robert Fano, who reorganized MIT's introductory curriculum in electrical engineering and computer science to emphasize the principles of engineering design. He led us in starting out on this enterprise and wrote the first set of subject notes from which this book evolved. 8 | 9 | Much of the style and aesthetics of programming that we try to teach were developed in conjunction with Guy Lewis Steele Jr., who collaborated with Gerald Jay Sussman in the initial development of the Scheme language. In addition, David Turner, Peter Henderson, Dan Friedman, David Wise, and Will Clinger have taught us many of the techniques of the functional programming community that appear in this book. 10 | 11 | Joel Moses taught us about structuring large systems. His experience with the Macsyma system for symbolic computation provided the insight that one should avoid complexities of control and concentrate on organizing the data to reflect the real structure of the world being modeled. 12 | 13 | Marvin Minsky and Seymour Papert formed many of our attitudes about programming and its place in our intellectual lives. To them we owe the understanding that computation provides a means of expression for exploring ideas that would otherwise be too complex to deal with precisely. They emphasize that a student's ability to write and modify programs provides a powerful medium in which exploring becomes a natural activity. 14 | 15 | We also strongly agree with Alan Perlis that programming is lots of fun and we had better be careful to support the joy of programming. Part of this joy derives from observing great masters at work. We are fortunate to have been apprentice programmers at the feet of Bill Gosper and Richard Greenblatt. 16 | 17 | It is difficult to identify all the people who have contributed to the development of our curriculum. We thank all the lecturers, recitation instructors, and tutors who have worked with us over the past fifteen years and put in many extra hours on our subject, especially Bill Siebert, Albert Meyer, Joe Stoy, Randy Davis, Louis Braida, Eric Grimson, Rod Brooks, Lynn Stein, and Peter Szolovits. We would like to specially acknowledge the outstanding teaching contributions of Franklyn Turbak, now at Wellesley; his work in undergraduate instruction set a standard that we can all aspire to. We are grateful to Jerry Saltzer and Jim Miller for helping us grapple with the mysteries of concurrency, and to Peter Szolovits and David McAllester for their contributions to the exposition of nondeterministic evaluation in chapter~4. 18 | 19 | Many people have put in significant effort presenting this material at other universities. Some of the people we have worked closely with are Jacob Katzenelson at the Technion, Hardy Mayer at the University of California at Irvine, Joe Stoy at Oxford, Elisha Sacks at Purdue, and Jan Komorowski at the Norwegian University of Science and Technology. We are exceptionally proud of our colleagues who have received major teaching awards for their adaptations of this subject at other universities, including Kenneth Yip at Yale, Brian Harvey at the University of California at Berkeley, and Dan Huttenlocher at Cornell. 20 | 21 | Al Moyée arranged for us to teach this material to engineers at Hewlett-Packard, and for the production of videotapes of these lectures. We would like to thank the talented instructors—in particular Jim Miller, Bill Siebert, and Mike Eisenberg—who have designed continuing education courses incorporating these tapes and taught them at universities and industry all over the world. 22 | 23 | Many educators in other countries have put in significant work translating the first edition. Michel Briand, Pierre Chamard, and André Pic produced a French edition; Susanne Daniels-Herold produced a German edition; and Fumio Motoyoshi produced a Japanese edition. We do not know who produced the Chinese edition, but we consider it an honor to have been selected as the subject of an unauthorized translation. 24 | 25 | It is hard to enumerate all the people who have made technical contributions to the development of the Scheme systems we use for instructional purposes. In addition to Guy Steele, principal wizards have included Chris Hanson, Joe Bowbeer, Jim Miller, Guillermo Rozas, and Stephen Adams. Others who have put in significant time are Richard Stallman, Alan Bawden, Kent Pitman, Jon Taft, Neil Mayle, John Lamping, Gwyn Osnos, Tracy Larrabee, George Carrette, Soma Chaudhuri, Bill Chiarchiaro, Steven Kirsch, Leigh Klotz, Wayne Noss, Todd Cass, Patrick O'Donnell, Kevin Theobald, Daniel Weise, Kenneth Sinclair, Anthony Courtemanche, Henry M. Wu, Andrew Berlin, and Ruth Shyu. 26 | 27 | Beyond the MIT implementation, we would like to thank the many people who worked on the IEEE Scheme standard, including William Clinger and Jonathan Rees, who edited the R4RS, and Chris Haynes, David Bartley, Chris Hanson, and Jim Miller, who prepared the IEEE standard. 28 | 29 | Dan Friedman has been a long-time leader of the Scheme community. The community's broader work goes beyond issues of language design to encompass significant educational innovations, such as the high-school curriculum based on EdScheme by Schemer's Inc., and the wonderful books by Mike Eisenberg and by Brian Harvey and Matthew Wright. 30 | 31 | We appreciate the work of those who contributed to making this a real book, especially Terry Ehling, Larry Cohen, and Paul Bethge at the MIT Press. Ella Mazel found the wonderful cover image. For the second edition we are particularly grateful to Bernard and Ella Mazel for help with the book design, and to David Jones, TEX wizard extraordinaire. We also are indebted to those readers who made penetrating comments on the new draft: Jacob Katzenelson, Hardy Mayer, Jim Miller, and especially Brian Harvey, who did unto this book as Julie did unto his book Simply Scheme. 32 | 33 | Finally, we would like to acknowledge the support of the organizations that have encouraged this work over the years, including suppport from Hewlett-Packard, made possible by Ira Goldstein and Joel Birnbaum, and support from DARPA, made possible by Bob Kahn. 34 | 35 | > —— Harold Abelson and Gerald Jay Sussman 36 | -------------------------------------------------------------------------------- /book/chapter1.2.md: -------------------------------------------------------------------------------- 1 | # 1.2 Functions and the Processes They Generate 2 | 3 | > - 来源:[Functions and the Processes They Generate](https://sicp.comp.nus.edu.sg/chapters/11) 4 | > - 译者:[塔希](https://github.com/iheyunfei/) 5 | > - 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 6 | 7 | --- 8 | 9 | 现在,我们已经见识了一些编程的要素:我们使用过基本的数学运算操作,然后将这些操作组合起来,并且通过声明复合函数来抽象这些组合后的的操作。但是,了解这些并不足以声称我们学会了如何去编程。我们现在的情况和刚学会如何移动国际象棋棋子的人一样,虽然了解基本的规则,但是对开局,策略,战术一无所知。和国际象棋初学者一样,我们还不知道编程领域中各种模式的用法。我们缺乏足够的知识去判断棋子的哪一步是值得的?(哪一个函数值得声明?)。我们缺乏足够的经验判断每一步的后果(比如,执行一个函数)。 10 | 11 | 把正在考虑的行为的结果进行可视化的能力,对于成为一名专业编程人员来说,是至关重要的,就像这种能力在其他合成性,创造性活动中的作用一样。举个例子,在成为一个专业摄影家的过程中,一个人必须学习如何观察各种景象,知道在各种可能的曝光和显影的条件 [\[1\]]() 下,镜像中的各个区域在影像中的明暗程度。只有这样,人才能反推对于想要效果应该作的取景、 亮度、曝光、和显影行为。对于编程来说也是一样的,我们需要对于计算过程中各种动作行为作出规划和通过程序去控制其进程。为了成为一个专家,我们必须学会如何看清各种类型函数产生的计算过程。这样,我们才能学着如何去构造出可靠的程序,并使其表现出我们想要的行为。 12 | 13 | 一个函数就是相对于于计算过程局部演化的一种形式。它描述了计算过程的每一步是如何建立在上一步上。We would like to be able to make statements about the overall, or *global*, behavior of a process whose local evolution has been specified by a function. This is very difficult to do in general, but we can at least try to describe some typical patterns of process evolution. 14 | 15 | 在这一节里,我们将会考察一些由简单函数产生的计算过程的“形状”。我们同样会研究计算过程消耗的各种重要的时间和空间计算资源的速率。将要考察的函数是非常简单的。它们在这里扮演的角色就像是是摄影技术中测试模式:作为极度简化的摄影模式,对其来说,而非实际的例子。 16 | 17 | 18 | 19 | [1] The textbook was written at a time when photography commonly involved photographic development, a chemical process for making paper prints from photographic film. 20 | 21 | 22 | -------------------------------------------------------------------------------- /book/chapter1.md: -------------------------------------------------------------------------------- 1 | # 1 使用函数构造抽象 2 | 3 | > - 来源:[Building Abstractions with Functions](https://sicp.comp.nus.edu.sg/chapters/1) 4 | > - 译者:[塔希](https://github.com/iheyunfei/) 5 | > - 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 6 | 7 | --- 8 | 9 | > The acts of the mind, wherein it exerts its power over simple ideas, are chiefly these three: 1. Combining several simple ideas into one compound one, and thus all complex ideas are made. 2. The second is bringing two ideas, whether simple or complex, together, and setting them by one another so as to take a view of them at once, without uniting them into one, by which it gets all its ideas of relations. 3. The third is separating them from all other ideas that accompany them in their real existence: this is called abstraction, and thus all its general ideas are made. —— John Locke An Essay Concerning Human Understanding (1690) 10 | 11 | 我们即将学习有关 *计算过程(computational process)* 的概念。计算过程是一种栖息于电脑中、抽象的存在。经过演化,过程可以操控另一种被称为 *数据(data)* 的抽象事物。人们创建程序来指导、控制各种过程,而 *程序(program)* 是一种含有许多规则的形式,主导着过程的运行。从形式上看,就像我们通过自己编写的咒语控制计算机中的精灵一样。 12 | 13 | 对于一个计算过程的理解可以参照巫师如何理解小精灵。小精灵并非由物质组成的实体,它们无法被看见和触摸。但是,它们却又是实际存在的。它们能完成智力性的任务、可以回答问题,并且通过在银行付钱或者控制工厂里机器人的手臂来对世界产生实际影响。我们用来“变出”过程的程序就如同巫师们用来召唤小精灵的咒语一样。程序是由神秘、晦涩的 *编程语言(programming languages)* 中各种符号表达式精心构建的,它们被用来描述可以完成我们所关心任务的计算过程。 14 | 15 | 在一台正常工作的计算机里,一个计算过程会严格且准确地的执行对应的程序。因此,“菜鸟”程序员就像巫师的学徒一样,必须经过事先学习,以图理解和预测他们通过咒语使用的各种“魔法”的后果。程序中即使很微小的的错误都可能导致复杂且无法预料的后果。 16 | 17 | 幸运的是,学习编程要比学习魔法安全得多,因为我们要面对的“小精灵”被一种安全的方式保存着。不过,现实世界中的编程依然要求谨慎、专业和智慧。举个例子,一个小小的程序错误都可能导致使用计算机辅助操控的飞机发生坠机、水坝崩坏或者工业机器人产生自毁行为。 18 | 19 | 软件工程大师们掌握着高超的构建程序的能力,所以他们才能合理地确信程序产生的过程,能够正确地完成其被安排的任务。软件工程大师们能够“预视”到系统的行为,知道该怎么组织程序的结构来避免意料之外的错误以及可能导致的严重后果,并且明白当错误出现时该怎么*定位、解决*它们。设计优良的计算系统,就像一个设计优良的汽车或核反应堆,是采用模块化设计的,所以每一部分都可以独立地被构建、替换和除错(debug)。 20 | 21 | 22 | ## 使用JavaScript编程 23 | 24 | 我们需要合适的语言来描述过程,为了达成这个目的,我们将会使用编程语言JavaScript。就如我们每天会用自然语言(英语,法语,日语)来表达我们日常的想法,用数学符号来描述数量的概念,我们的过程将会使用JavaScript来描述。JavaScript产生于1990年早期,通过内嵌于网页内部作为脚本,用来控制网页浏览器的行为。这门语言由Brendan Eich设计出,开始被称为Mocha,后改为*LiveScript*,最终命名为JavaScript。这个名字“JavaScript”是属于Sun Microsystems公司的一个商标。 25 | 26 | 尽管JavaScript作为一门语言,其诞生时的目的是为了控制网页浏览器,但JavaScript依然是一个通用编程语言。一个JavaScript *解释器(interpreter)* 就是一部用来执行由JavaScript编写的过程的机器。第一个JavaScript解释器是由Eich就职于Netscape Communications公司期间实现的,用在Netscape Navigator网页浏览器上。JavaScript的主要语言特性继承自Scheme和Self编程语言。Scheme是Lisp的一个方言,并且被当作原版《SICP》书籍的编程语言。从Scheme里,JavaScript继承了其大部分的函数式设计原则,例如静态作用域、一等函数公民和动态类型,这种继承的直接结果就是本书中的程序可以很直接、简单的从原书中的Scheme语言翻译成JavaScript语言。 27 | 28 | JavaScript仅仅与Java在表面上有相似之处,最大的关联点就是名字中都带个Java而已。JavaScript和Java都沿用了C语言的程序块(block structure)结构。与Java和C这种编译成底层语言后执行的过程相比,JavaScript常常是被浏览器内建的解释器解释执行。在Netscape Navigator浏览器出现后,其他网页浏览器也开始提供内嵌的JavaScript解释器,包括微软的Internet Explorer浏览器(微软称其为JScript而非JavaScript)。JavaScript因为可以控制浏览器的行为而普及后,广受大众欢迎,进而引起了对JavaScript进行标准化的工作,最终产生了一个标准化的语言标准,被称为 *ECMAScript*。第一版的ECMAScript(ECMA 1997)标准由Guy Lewis Steele Jr. 主导制定于1997年6月。本书使用的是第六版,由Allen Wirfs-Brock主导制定,在2015年6月的ECMA大会上被接受。 29 | 30 | 网页可以执行内嵌其中的JavaScript程序已经成为互联网的共识,这促使了网页浏览器的开发者去实现JavaScript解释器。随着JavaScript程序变得越来越复杂,解释器的效率也变得越来越高,其中使用了一些精巧、复杂的技巧,例如 **[即时编译(JIT)](https://zh.wikipedia.org/wiki/%E5%8D%B3%E6%99%82%E7%B7%A8%E8%AD%AF)** 技术。大部分的JavaScript程序内嵌于网页,被浏览器解释执行,但是JavaScript也被用于编写苹果电脑桌面仪表板的小控件,以及控制一些软件或硬件的行为,比如Adobe Reader、Adobe Flash和一些通用的远程桌面设备。 31 | 32 | 不管怎样,对于一个在线教学编程书籍来说,可以被浏览器解释执行的能力使JavaScript成为了一门理想的编程语言。对JavaScript来说,通过在网页上点击执行JavaScript程序是非常自然的一件事——毕竟这就是JavaScript被设计出来的目的。从根本上来说,JavaScript拥有的语言特性使其成为了一个完美的工具,非常适合被用来学习、理解程序结构和数据结构的概念。同时也是一个完美的媒介,将程序结构和数据结构与支持它们的JavaScript语言特性联系起来。JavaScript的静态作用域、一等函数公民语言特性提供了一种简单、直接的途径来理解、应用抽象机制,动态类型则使得程序使用数据时不需要提前声明其类型。除了以上所有的考量之外,还有一点——使用JavaScript编程是很有趣的。 33 | -------------------------------------------------------------------------------- /book/content.md: -------------------------------------------------------------------------------- 1 | # 目录 2 | 3 | - [Foreword](./book/foreword.md) 4 | - [Prefaces](./book/prefaces.md) 5 | - [Acknowledgments](./book/acknowledgments.md) 6 | - [1 使用函数构造抽象](./book/chapter1.md) 7 | - [1.1 The Elements of Programming(翻译中)](./book/chapter1.1.md) 8 | - [1.2 Functions and the Processes They Generate]() 9 | - [1.3 Formulating Abstractions with Higher-Order Functions]() 10 | - [2 Building Abstractions with Data]() 11 | - [3 Modularity, Objects, and State]() 12 | - [4 Metalinguistic Abstraction]() 13 | - [文献参考](./references.md) 14 | - [Index]() -------------------------------------------------------------------------------- /book/foreword.md: -------------------------------------------------------------------------------- 1 | # 荐言 2 | 3 | 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. 4 | 5 | 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! 6 | 7 | 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. 8 | 9 | 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 112 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 …! 10 | 11 | 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. 12 | 13 | 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. 14 | 15 | 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. 16 | 17 | 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. 18 | 19 | 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. 20 | 21 | 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. 22 | 23 | As one would expect from its goals, artificial intelligence research gen\-e\-rates 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. 24 | 25 | > By Alan J. Perlis New Haven, Connecticut 26 | -------------------------------------------------------------------------------- /book/images/ch1-1-8-1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 38 | 40 | 42 | 51 | 52 | 54 | image/svg+xml 55 | 57 | 58 | 59 | 60 | 64 | square 74 | / 83 | good_enough 93 | \ 102 | abs 112 | average 122 | \ 131 | improve 141 | / 150 | \ 159 | sqrt_iter 169 | | 178 | sqrt 188 | 189 | 190 | -------------------------------------------------------------------------------- /book/images/ch1_1_3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyf0/sicp-javascript-zh/2bf6943dc92bf415f4094851aebf967dc21ca341/book/images/ch1_1_3-1.png -------------------------------------------------------------------------------- /book/images/ch1_1_6-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyf0/sicp-javascript-zh/2bf6943dc92bf415f4094851aebf967dc21ca341/book/images/ch1_1_6-1.png -------------------------------------------------------------------------------- /book/images/ch1_1_7-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyf0/sicp-javascript-zh/2bf6943dc92bf415f4094851aebf967dc21ca341/book/images/ch1_1_7-1.png -------------------------------------------------------------------------------- /book/images/ch1_1_7-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyf0/sicp-javascript-zh/2bf6943dc92bf415f4094851aebf967dc21ca341/book/images/ch1_1_7-2.png -------------------------------------------------------------------------------- /book/images/ch1_1_7-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyf0/sicp-javascript-zh/2bf6943dc92bf415f4094851aebf967dc21ca341/book/images/ch1_1_7-3.png -------------------------------------------------------------------------------- /book/prefaces.md: -------------------------------------------------------------------------------- 1 | # 前言 2 | 3 | ## Preface of JavaScript Adaptation 4 | 5 | You are reading the textbook Structure and Interpretation of Computer Programs by Harold Abelson and Gerald Sussman—with a twist. The textbook emphasizes the importance of abstraction for managing complexity, and introduces the reader to a host of concepts that lie at the heart of the field of computer science. Most of these ideas are independent of the programming language used to express them to employ actual computers for solving computational problems. They are programming-language independent. The twist then consists of replacing the programming language that is used in the examples. While the authors had used the programming language Scheme, this adaptation uses the language JavaScript. 6 | 7 | More precisely, this adaptation uses five tiny, carefully designed, sublanguages of JavaScript. The languages are called Source §1, Source §2, Source §3, Source §4 and Source §5, corresponding to the respective chapters 1, 2, 3, 4 and 5 of the textbook. The Source §1 language contains only constructs that are needed in the programs contained in chapter 1: constructs required to build abstractions with functions. Source §2 is a superset of Source §1; adding features required to build abstractions with data, on top of the features of Source §1. Similarly, Source §3, 4 and 5 extend the previous language features required to address the subject of the respective textbook chapter. All these languages are sub-languages of JavaScript; any Source program is also a JavaScript program. The reverse is not true. The JavaScript language has many features that are not covered in this textbook. Indeed, the Source languages are so small that they can be quite adquately described in a few pages of text. The online folder source contains the specifications of the Source languages, as reference for the reader. 8 | 9 | This textbook is interactive. Most programs are links. Clicking on them takes the reader to a web-based programming environment called the Source Academy. In the Source Academy, the reader can run the programs, modify them and experiment with them, without the need to install any software, and without any requirements on the computer that they use, as long as it comes with an internet browser. 10 | 11 | The language Scheme has been designed as a sublanguage of Lisp with its use in education as a central design objective. The language JavaScript, on the other hand, was not designed with the needs of learners in mind. This makes it difficult to use JavaScript in a course, even if one imposes constraints on the language features to be covered. The reason is that students with prior knowledge of the language are bound to make use of other features in their programs. Fellow students will legitimately ask the instructors about those features, and any answer will either frustate the student or lead to a tangent that is most likely not conducive to the learning objectives. This problem is especially severe for JavaScript, which is not known for its systematic design. Our solution to this challenge is radical: The Source Academy enforces the use of the respective Source language when the student clicks on a program of a particular chapter. Programs that use constructs beyond that language are rejected by the Source Academy. This allows instructors of a SICP-based course to adopt JavaScript—one of the most widely used programming languages today—without getting bogged down in JavaScript's plethora of idiosyncratic features. 12 | 13 | The original textbook was introduced to the National University of Singapore by Jacob Katzenelson in 1997, as a more advanced alternative to the regular Programming Methodology course offered to computer science students. The course, known as CS1101S since 1998, switched to JavaScript in 2012, and became the required freshmen programming methodology course for Computer Science undergraduate majors in 2018. 14 | 15 | > —— Martin Henz 16 | 17 | ## Preface to the Second Edition 18 | 19 | > Is it possible that software is not like anything else, that it is meant to be discarded: that the whole point is to always see it as a soap bubble? 20 | > —— Alan J. Perlis 21 | 22 | The material in this book has been the basis of MIT's entry-level computer science subject since 1980. We had been teaching this material for four years when the first edition was published, and twelve more years have elapsed until the appearance of this second edition. We are pleased that our work has been widely adopted and incorporated into other texts. We have seen our students take the ideas and programs in this book and build them in as the core of new computer systems and languages. In literal realization of an ancient Talmudic pun, our students have become our builders. We are lucky to have such capable students and such accomplished builders. 23 | 24 | In preparing this edition, we have incorporated hundreds of clarifications suggested by our own teaching experience and the comments of colleagues at MIT and elsewhere. We have redesigned most of the major programming systems in the book, including the generic-arithmetic system, the interpreters, the register-machine simulator, and the compiler; and we have rewritten all the program examples to ensure that any Scheme implementation conforming to the IEEE Scheme standard (IEEE 1990) will be able to run the code. 25 | 26 | This edition emphasizes several new themes. The most important of these is the central role played by different approaches to dealing with time in computational models: objects with state, concurrent programming, functional programming, lazy evaluation, and nondeterministic programming. We have included new sections on concurrency and nondeterminism, and we have tried to integrate this theme throughout the book. 27 | 28 | The first edition of the book closely followed the syllabus of our MIT one-semester subject. With all the new material in the second edition, it will not be possible to cover everything in a single semester, so the instructor will have to pick and choose. In our own teaching, we sometimes skip the section on logic programming (section ), we have students use the register-machine simulator but we do not cover its implementation (section ), and we give only a cursory overview of the compiler (section ). Even so, this is still an intense course. Some instructors may wish to cover only the first three or four chapters, leaving the other material for subsequent courses. 29 | 30 | The World-Wide-Web site of MIT Press provides support for users of this book. This includes programs from the book, sample programming assignments, supplementary materials, and downloadable implementations of the Scheme dialect of Lisp. 31 | 32 | > —— Harold Abelson and Gerald Jay Sussman 33 | 34 | ## Preface to the First Edition 35 | 36 | > A computer is like a violin. You can imagine a novice trying first a phonograph and then a violin. The latter, he says, sounds terrible. That is the argument we have heard from our humanists and most of our computer scientists. Computer programs are good, they say, for particular purposes, but they aren't flexible. Neither is a violin, or a typewriter, until you learn how to use it. 37 | > —— Marvin Minsky, "Why Programming Is a Good Medium for Expressing Poorly-Understood and Sloppily-Formulated Ideas" 38 | 39 | "The Structure and Interpretation of Computer Programs" is the entry-level subject in computer science at the Massachusetts Institute of Technology. It is required of all students at MIT who major in electrical engineering or in computer science, as one-fourth of the "common core curriculum", which also includes two subjects on circuits and linear systems and a subject on the design of digital systems. We have been involved in the development of this subject since 1978, and we have taught this material in its present form since the fall of 1980 to between 600 and 700 students each year. Most of these students have had little or no prior formal training in computation, although many have played with computers a bit and a few have had extensive programming or hardware-design experience. 40 | 41 | Our design of this introductory computer-science subject reflects two major concerns. First, we want to establish the idea that a computer language is not just a way of getting a computer to perform operations but rather that it is a novel formal medium for expressing ideas about methodology. Thus, programs must be written for people to read, and only incidentally for machines to execute. Second, we believe that the essential material to be addressed by a subject at this level is not the syntax of particular programming-language constructs, nor clever algorithms for computing particular functions efficiently, nor even the mathematical analysis of algorithms and the foundations of computing, but rather the techniques used to control the intellectual complexity of large software systems. 42 | 43 | Our goal is that students who complete this subject should have a good feel for the elements of style and the aesthetics of programming. They should have command of the major techniques for controlling complexity in a large system. They should be capable of reading a 50-page-long program, if it is written in an exemplary style. They should know what not to read, and what they need not understand at any moment. They should feel secure about modifying a program, retaining the spirit and style of the original author. 44 | 45 | These skills are by no means unique to computer programming. The techniques we teach and draw upon are common to all of engineering design. We control complexity by building abstractions that hide details when appropriate. We control complexity by establishing conventional interfaces that enable us to construct systems by combining standard, well-understood pieces in a mix and match way. We control complexity by establishing new languages for describing a design, each of which emphasizes particular aspects of the design and deemphasizes others. 46 | 47 | Underlying our approach to this subject is our conviction that computer science is not a science and that its significance has little to do with computers. The computer revolution is a revolution in the way we think and in the way we express what we think. The essence of this change is the emergence of what might best be called procedural epistemology—the study of the structure of knowledge from an imperative point of view, as opposed to the more declarative point of view taken by classical mathematical subjects. Mathematics provides a framework for dealing precisely with notions of what is. Computation provides a framework for dealing precisely with notions of how to. 48 | 49 | In teaching our material we use a dialect of the programming language Lisp. We never formally teach the language, because we don't have to. We just use it, and students pick it up in a few days. This is one great advantage of Lisp-like languages: They have very few ways of forming compound expressions, and almost no syntactic structure. All of the formal properties can be covered in an hour, like the rules of chess. After a short time we forget about syntactic details of the language (because there are none) and get on with the real issues—figuring out what we want to compute, how we will decompose problems into manageable parts, and how we will work on the parts. Another advantage of Lisp is that it supports (but does not enforce) more of the large-scale strategies for modular decomposition of programs than any other language we know. We can make procedural and data abstractions, we can use higher-order functions to capture common patterns of usage, we can model local state using assignment and data mutation, we can link parts of a program with streams and delayed evaluation, and we can easily implement embedded languages. All of this is embedded in an interactive environment with excellent support for incremental program design, construction, testing, and debugging. We thank all the generations of Lisp wizards, starting with John McCarthy, who have fashioned a fine tool of unprecedented power and elegance. 50 | 51 | Scheme, the dialect of Lisp that we use, is an attempt to bring together the power and elegance of Lisp and Algol. From Lisp we take the metalinguistic power that derives from the simple syntax, the uniform representation of programs as data objects, and the garbage-collected heap-allocated data. From Algol we take lexical scoping and block structure, which are gifts from the pioneers of programming-language design who were on the Algol committee. We wish to cite John Reynolds and Peter Landin for their insights into the relationship of Church's lambda calculus to the structure of programming languages. We also recognize our debt to the mathematicians who scouted out this territory decades before computers appeared on the scene. These pioneers include Alonzo Church, Barkley Rosser, Stephen Kleene, and Haskell Curry. 52 | 53 | > —— Harold Abelson and Gerald Jay Sussman -------------------------------------------------------------------------------- /book/references.md: -------------------------------------------------------------------------------- 1 | - Abelson, Harold, Andrew Berlin, Jacob Katzenelson, William McAllister, Guillermo Rozas, Gerald Jay Sussman, and Jack Wisdom. 1992. The Supercomputer Toolkit: A general framework for special-purpose computing. International Journal of High-Speed Electronics 3(3):337-361. 2 | 3 | - Allen, John. 1978. Anatomy of Lisp. New York: McGraw-Hill. 4 | 5 | - ANSI X3.226-1994. American National Standard for Information Systems—Programming Language—Common Lisp. 6 | 7 | - Appel, Andrew W. 1987. Garbage collection can be faster than stack allocation. Information Processing Letters 25(4):275-279. 8 | 9 | - Backus, John. 1978. Can programming be liberated from the von Neumann style? Communications of the ACM 21(8):613-641. 10 | 11 | - Baker, Henry G., Jr. 1978. List processing in real time on a serial computer. Communications of the ACM 21(4):280-293. 12 | 13 | - Batali, John, Neil Mayle, Howard Shrobe, Gerald Jay Sussman, and Daniel Weise. 1982. The Scheme-81 architecture—System and chip. In Proceedings of the MIT Conference on Advanced Research in VLSI, edited by Paul Penfield, Jr. Dedham, MA: Artech House. 14 | 15 | - Borning, Alan. 1977. ThingLab—An object-oriented system for building simulations using constraints. In Proceedings of the 5th International Joint Conference on Artificial Intelligence. 16 | 17 | - Borodin, Alan, and Ian Munro. 1975. The Computational Complexity of Algebraic and Numeric Problems. New York: American Elsevier. 18 | 19 | - Chaitin, Gregory J. 1975. Randomness and mathematical proof. Scientific American 232(5):47-52. 20 | 21 | - Church, Alonzo. 1941. The Calculi of Lambda-Conversion. Princeton, N.J.: Princeton University Press. 22 | 23 | - Clark, Keith L. 1978. Negation as failure. In Logic and Data Bases. New York: Plenum Press, pp. 293-322. 24 | 25 | - Clinger, William. 1982. Nondeterministic call by need is neither lazy nor by name. In Proceedings of the ACM Symposium on Lisp and Functional Programming, pp. 226-234. 26 | 27 | - Clinger, William, and Jonathan Rees. 1991. Macros that work. In Proceedings of the 1991 ACM Conference on Principles of Programming Languages, pp. 155-162. 28 | 29 | - Colmerauer A., H. Kanoui, R. Pasero, and P. Roussel. 1973. Un système de communication homme-machine en français. Technical report, Groupe Intelligence Artificielle, Université d'Aix Marseille, Luminy. 30 | 31 | - Cormen, Thomas, Charles Leiserson, and Ronald Rivest. 1990. Introduction to Algorithms. Cambridge, MA: MIT Press. 32 | 33 | - Darlington, John, Peter Henderson, and David Turner. 1982. Functional Programming and Its Applications. New York: Cambridge University Press. 34 | 35 | - Dijkstra, Edsger W. 1968a. The structure of the THE multiprogramming system. Communications of the ACM 11(5):341-346. 36 | 37 | - Dijkstra, Edsger W. 1968b. Cooperating sequential processes. In Programming Languages, edited by F. Genuys. New York: Academic Press, pp. 43-112. 38 | 39 | - Dinesman, Howard P. 1968. Superior Mathematical Puzzles. New York: Simon and Schuster. 40 | 41 | - deKleer, Johan, Jon Doyle, Guy Steele, and Gerald J. Sussman. 1977. AMORD: Explicit control of reasoning. In Proceedings of the ACM Symposium on Artificial Intelligence and Programming Languages, pp. 116-125. 42 | 43 | - Doyle, Jon. 1979. A truth maintenance system. Artificial Intelligence 12:231-272. 44 | 45 | - Feigenbaum, Edward, and Howard Shrobe. 1993. The Japanese National Fifth Generation Project: Introduction, survey, and evaluation. In Future Generation Computer Systems, vol. 9, pp. 105-117. 46 | 47 | - Feeley, Marc. 1986. Deux approches à l'implantation du language Scheme. Masters thesis, Université de Montréal. 48 | 49 | - Feeley, Marc and Guy Lapalme. 1987. Using closures for code generation. Journal of Computer Languages 12(1):47-66. 50 | 51 | - Feller, William. 1957. An Introduction to Probability Theory and Its Applications, volume 1. New York: John Wiley & Sons. 52 | 53 | - Fenichel, R., and J. Yochelson. 1969. A Lisp garbage collector for virtual memory computer systems. Communications of the ACM 12(11):611-612. 54 | 55 | - Floyd, Robert. 1967. Nondeterministic algorithms. JACM, 14(4):636-644. 56 | 57 | - Forbus, Kenneth D., and Johan deKleer. 1993. Building Problem Solvers. Cambridge, MA: MIT Press. 58 | 59 | - Friedman, Daniel P., and David S. Wise. 1976. CONS should not evaluate its arguments. In Automata, Languages, and Programming: Third International Colloquium, edited by S. Michaelson and R. Milner, pp. 257-284. 60 | 61 | - Friedman, Daniel P., Mitchell Wand, and Christopher T. Haynes. 1992. Essentials of Programming Languages. Cambridge, MA: MIT Press/McGraw-Hill. 62 | 63 | - Gabriel, Richard P. 1988. The Why of Y. Lisp Pointers 2(2):15-25. 64 | 65 | - Goldberg, Adele, and David Robson. 1983. Smalltalk-80: The Language and Its Implementation. Reading, MA: Addison-Wesley. 66 | 67 | - Gordon, Michael, Robin Milner, and Christopher Wadsworth. 1979. Edinburgh LCF. Lecture Notes in Computer Science, volume 78. New York: Springer-Verlag. 68 | 69 | - Gray, Jim, and Andreas Reuter. 1993. Transaction Processing: Concepts and Models. San Mateo, CA: Morgan-Kaufman. 70 | 71 | - Green, Cordell. 1969. Application of theorem proving to problem solving. In Proceedings of the International Joint Conference on Artificial Intelligence, pp. 219-240. 72 | 73 | - Green, Cordell, and Bertram Raphael. 1968. The use of theorem-proving techniques in question-answering systems. In Proceedings of the ACM National Conference, pp. 169-181. 74 | 75 | - Griss, Martin L. 1981. Portable Standard Lisp, a brief overview. Utah Symbolic Computation Group Operating Note 58, University of Utah. 76 | 77 | - Guttag, John V. 1977. Abstract data types and the development of data structures. Communications of the ACM 20(6):397-404. 78 | 79 | - Hamming, Richard W. 1980. Coding and Information Theory. Englewood Cliffs, N.J.: Prentice-Hall. 80 | 81 | - Hanson, Christopher P. 1990. Efficient stack allocation for tail-recursive languages. In Proceedings of ACM Conference on Lisp and Functional Programming, pp. 106-118. 82 | 83 | - Hanson, Christopher P. 1991. A syntactic closures macro facility. Lisp Pointers, 4(3). 84 | 85 | - Hardy, Godfrey H. 1921. Srinivasa Ramanujan. Proceedings of the London Mathematical Society XIX(2). 86 | 87 | - Hardy, Godfrey H., and E. M. Wright. 1960. An Introduction to the Theory of Numbers. 4th edition. New York: Oxford University Press. 88 | 89 | - Havender, J. 1968. Avoiding deadlocks in multi-tasking systems. IBM Systems Journal 7(2):74-84. 90 | 91 | - Hearn, Anthony C. 1969. Standard Lisp. Technical report AIM-90, Artificial Intelligence Project, Stanford University. 92 | 93 | - Henderson, Peter. 1980. Functional Programming: Application and Implementation. Englewood Cliffs, N.J.: Prentice-Hall. 94 | 95 | - Henderson. Peter. 1982. Functional Geometry. In Conference Record of the 1982 ACM Symposium on Lisp and Functional Programming, pp. 179-187. 96 | 97 | - Hewitt, Carl E. 1969. PLANNER: A language for proving theorems in robots. In Proceedings of the International Joint Conference on Artificial Intelligence, pp. 295-301. 98 | 99 | - Hewitt, Carl E. 1977. Viewing control structures as patterns of passing messages. Journal of Artificial Intelligence 8(3):323-364. 100 | 101 | - Hoare, C. A. R. 1972. Proof of correctness of data representations. Acta Informatica 1(1). 102 | 103 | - Hodges, Andrew. 1983. Alan Turing: The Enigma. New York: Simon and Schuster. 104 | 105 | - Hofstadter, Douglas R. 1979. Gödel, Escher, Bach: An Eternal Golden Braid. New York: Basic Books. 106 | 107 | - Hughes, R. J. M. 1990. Why functional programming matters. In Research Topics in Functional Programming, edited by David Turner. Reading, MA: Addison-Wesley, pp. 17-42. 108 | 109 | - IEEE Std 1178-1990. 1990. IEEE Standard for the Scheme Programming Language. 110 | 111 | - Ingerman, Peter, Edgar Irons, Kirk Sattley, and Wallace Feurzeig; assisted by M. Lind, Herbert Kanner, and Robert Floyd. 1960. THUNKS: A way of compiling procedure statements, with some comments on procedure declarations. Unpublished manuscript. (Also, private communication from Wallace Feurzeig.) 112 | 113 | - Kaldewaij, Anne. 1990. Programming: The Derivation of Algorithms. New York: Prentice-Hall. 114 | 115 | - Kohlbecker, Eugene Edmund, Jr. 1986. Syntactic extensions in the programming language Lisp. Ph.D. thesis, Indiana University. 116 | 117 | - Konopasek, Milos, and Sundaresan Jayaraman. 1984. The TK!Solver Book: A Guide to Problem-Solving in Science, Engineering, Business, and Education. Berkeley, CA: Osborne/McGraw-Hill. 118 | 119 | - Knuth, Donald E. 1973. Fundamental Algorithms. Volume 1 of The Art of Computer Programming. 2nd edition. Reading, MA: Addison-Wesley. 120 | 121 | - Knuth, Donald E. 1981. Seminumerical Algorithms. Volume 2 of The Art of Computer Programming. 2nd edition. Reading, MA: Addison-Wesley. 122 | 123 | - Kowalski, Robert. 1973. Predicate logic as a programming language. Technical report 70, Department of Computational Logic, School of Artificial Intelligence, University of Edinburgh. 124 | 125 | - Kowalski, Robert. 1979. Logic for Problem Solving. New York: North-Holland. 126 | 127 | - Lamport, Leslie. 1978. Time, clocks, and the ordering of events in a distributed system. Communications of the ACM 21(7):558-565. 128 | 129 | - Lampson, Butler, J. J. Horning, R. London, J. G. Mitchell, and G. K. Popek. 1981. Report on the programming language Euclid. Technical report, Computer Systems Research Group, University of Toronto. 130 | 131 | - Landin, Peter. 1965. A correspondence between Algol 60 and Church's lambda notation: Part I. Communications of the ACM 8(2):89-101. 132 | 133 | - Lieberman, Henry, and Carl E. Hewitt. 1983. A real-time garbage collector based on the lifetimes of objects. Communications of the ACM 26(6):419-429. 134 | 135 | - Liskov, Barbara H., and Stephen N. Zilles. 1975. Specification techniques for data abstractions. IEEE Transactions on Software Engineering 1(1):7-19. 136 | 137 | - McAllester, David Allen. 1978. A three-valued truth-maintenance system. Memo 473, MIT Artificial Intelligence Laboratory. 138 | 139 | - McAllester, David Allen. 1980. An outlook on truth maintenance. Memo 551, MIT Artificial Intelligence Laboratory. 140 | 141 | - McCarthy, John. 1960. Recursive functions of symbolic expressions and their computation by machine. Communications of the ACM 3(4):184-195. 142 | 143 | - McCarthy, John. 1967. A basis for a mathematical theory of computation. In Computer Programing and Formal Systems, edited by P. Braffort and D. Hirschberg. North-Holland. 144 | 145 | - McCarthy, John. 1978. The history of Lisp. In Proceedings of the ACM SIGPLAN Conference on the History of Programming Languages. 146 | 147 | - McCarthy, John, P. W. Abrahams, D. J. Edwards, T. P. Hart, and M. I. Levin. 1965. Lisp 1.5 Programmer's Manual. 2nd edition. Cambridge, MA: MIT Press. 148 | 149 | - McDermott, Drew, and Gerald Jay Sussman. 1972. Conniver reference manual. Memo 259, MIT Artificial Intelligence Laboratory. 150 | 151 | - Miller, Gary L. 1976. Riemann's Hypothesis and tests for primality. Journal of Computer and System Sciences 13(3):300-317. 152 | 153 | - Miller, James S., and Guillermo J. Rozas. 1994. Garbage collection is fast, but a stack is faster. Memo 1462, MIT Artificial Intelligence Laboratory. 154 | 155 | - Moon, David. 1978. MacLisp reference manual, Version 0. Technical report, MIT Laboratory for Computer Science. 156 | 157 | - Moon, David, and Daniel Weinreb. 1981. Lisp machine manual. Technical report, MIT Artificial Intelligence Laboratory. 158 | 159 | - Morris, J. H., Eric Schmidt, and Philip Wadler. 1980. Experience with an applicative string processing language. In Proceedings of the 7th Annual ACM SIGACT/SIGPLAN Symposium on the Principles of Programming Languages. 160 | 161 | - Phillips, Hubert. 1934. The Sphinx Problem Book. London: Faber and Faber. 162 | 163 | - Pitman, Kent. 1983. The revised MacLisp Manual (Saturday evening edition). Technical report 295, MIT Laboratory for Computer Science. 164 | 165 | - Rabin, Michael O. 1980. Probabilistic algorithm for testing primality. Journal of Number Theory 12:128-138. 166 | 167 | - Raymond, Eric. 1993. The New Hacker's Dictionary. 2nd edition. Cambridge, MA: MIT Press. 168 | 169 | - Raynal, Michel. 1986. Algorithms for Mutual Exclusion. Cambridge, MA: MIT Press. 170 | 171 | - Rees, Jonathan A., and Norman I. Adams IV. 1982. T: A dialect of Lisp or, lambda: The ultimate software tool. In Conference Record of the 1982 ACM Symposium on Lisp and Functional Programming, pp. 114-122. 172 | 173 | - Rees, Jonathan, and William Clinger (eds). 1991. The revised44 report on the algorithmic language Scheme. Lisp Pointers, 4(3). 174 | 175 | - Rivest, Ronald, Adi Shamir, and Leonard Adleman. 1977. A method for obtaining digital signatures and public-key cryptosystems. Technical memo LCS/TM82, MIT Laboratory for Computer Science. 176 | 177 | - Robinson, J. A. 1965. A machine-oriented logic based on the resolution principle. Journal of the ACM 12(1):23. 178 | 179 | - Robinson, J. A. 1983. Logic programming—Past, present, and future. New Generation Computing 1:107-124. 180 | 181 | - Sagade, Y. 2015. SICP exercise 1.14 182 | 183 | - Spafford, Eugene H. 1989. The Internet Worm: Crisis and aftermath. Communications of the ACM 32(6):678-688. 184 | 185 | - Steele, Guy Lewis, Jr. 1977. Debunking the expensive procedure call myth. In Proceedings of the National Conference of the ACM, pp. 153-62. 186 | 187 | - Steele, Guy Lewis, Jr. 1982. An overview of Common Lisp. In Proceedings of the ACM Symposium on Lisp and Functional Programming, pp. 98-107. 188 | 189 | - Steele, Guy Lewis, Jr. 1990. Common Lisp: The Language. 2nd edition. Digital Press. 190 | 191 | - Steele, Guy Lewis, Jr., and Gerald Jay Sussman. 1975. Scheme: An interpreter for the extended lambda calculus. Memo 349, MIT Artificial Intelligence Laboratory. 192 | 193 | - Steele, Guy Lewis, Jr., Donald R. Woods, Raphael A. Finkel, Mark R. Crispin, Richard M. Stallman, and Geoffrey S. Goodfellow. 1983. The Hacker's Dictionary. New York: Harper & Row. 194 | 195 | - Stoy, Joseph E. 1977. Denotational Semantics. Cambridge, MA: MIT Press. 196 | 197 | - Sussman, Gerald Jay, and Richard M. Stallman. 1975. Heuristic techniques in computer-aided circuit analysis. IEEE Transactions on Circuits and Systems CAS-22(11):857-865. 198 | 199 | - Sussman, Gerald Jay, and Guy Lewis Steele Jr. 1980. Constraints—A language for expressing almost-hierachical descriptions. AI Journal 14:1-39. 200 | 201 | - Sussman, Gerald Jay, and Jack Wisdom. 1992. Chaotic evolution of the solar system. Science 257:256-262. 202 | 203 | - Sussman, Gerald Jay, Terry Winograd, and Eugene Charniak. 1971. Microplanner reference manual. Memo 203A, MIT Artificial Intelligence Laboratory. 204 | 205 | - Sutherland, Ivan E. 1963. SKETCHPAD: A man-machine graphical communication system. Technical report 296, MIT Lincoln Laboratory. 206 | 207 | - Teitelman, Warren. 1974. Interlisp reference manual. Technical report, Xerox Palo Alto Research Center. 208 | 209 | - Thatcher, James W., Eric G. Wagner, and Jesse B. Wright. 1978. Data type specification: Parameterization and the power of specification techniques. In Conference Record of the Tenth Annual ACM Symposium on Theory of Computing, pp. 119-132. Turner, David. 1981. The future of applicative languages. In Proceedings of the 3rd European Conference on Informatics, Lecture Notes in Computer Science, volume 123. New York: Springer-Verlag, pp. 334-348. 210 | 211 | - Wand, Mitchell. 1980. Continuation-based program transformation strategies. Journal of the ACM 27(1):164-180. 212 | 213 | - Waters, Richard C. 1979. A method for analyzing loop programs. IEEE Transactions on Software Engineering 5(3):237-247. 214 | 215 | - Winograd, Terry. 1971. Procedures as a representation for data in a computer program for understanding natural language. Technical report AI TR-17, MIT Artificial Intelligence Laboratory. 216 | 217 | - Winston, Patrick. 1992. Artificial Intelligence. 3rd edition. Reading, MA: Addison-Wesley. 218 | 219 | - Zabih, Ramin, David McAllester, and David Chapman. 1987. Non-deterministic Lisp with dependency-directed backtracking. AAAI-87, pp. 59-64. 220 | 221 | - Zippel, Richard. 1979. Probabilistic algorithms for sparse polynomials. Ph.D. dissertation, Department of Electrical Engineering and Computer Science, MIT. 222 | 223 | - Zippel, Richard. 1993. Effective Polynomial Computation. Boston, MA: Kluwer Academic Publishers. -------------------------------------------------------------------------------- /docs/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 《SICP in JavaScript》 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

404

Looks like we've got some broken links.
Take me home.
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /docs/acknowledgments.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 谢言 | 《SICP in JavaScript》 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

谢言

We would like to thank the many people who have helped us develop this book and this curriculum.

Our subject is a clear intellectual descendant of 6.231, a wonderful subject on programming linguistics and the lambda calculus taught at MIT in the late 1960s by Jack Wozencraft and Arthur Evans, Jr.

We owe a great debt to Robert Fano, who reorganized MIT's introductory curriculum in electrical engineering and computer science to emphasize the principles of engineering design. He led us in starting out on this enterprise and wrote the first set of subject notes from which this book evolved.

Much of the style and aesthetics of programming that we try to teach were developed in conjunction with Guy Lewis Steele Jr., who collaborated with Gerald Jay Sussman in the initial development of the Scheme language. In addition, David Turner, Peter Henderson, Dan Friedman, David Wise, and Will Clinger have taught us many of the techniques of the functional programming community that appear in this book.

Joel Moses taught us about structuring large systems. His experience with the Macsyma system for symbolic computation provided the insight that one should avoid complexities of control and concentrate on organizing the data to reflect the real structure of the world being modeled.

Marvin Minsky and Seymour Papert formed many of our attitudes about programming and its place in our intellectual lives. To them we owe the understanding that computation provides a means of expression for exploring ideas that would otherwise be too complex to deal with precisely. They emphasize that a student's ability to write and modify programs provides a powerful medium in which exploring becomes a natural activity.

We also strongly agree with Alan Perlis that programming is lots of fun and we had better be careful to support the joy of programming. Part of this joy derives from observing great masters at work. We are fortunate to have been apprentice programmers at the feet of Bill Gosper and Richard Greenblatt.

It is difficult to identify all the people who have contributed to the development of our curriculum. We thank all the lecturers, recitation instructors, and tutors who have worked with us over the past fifteen years and put in many extra hours on our subject, especially Bill Siebert, Albert Meyer, Joe Stoy, Randy Davis, Louis Braida, Eric Grimson, Rod Brooks, Lynn Stein, and Peter Szolovits. We would like to specially acknowledge the outstanding teaching contributions of Franklyn Turbak, now at Wellesley; his work in undergraduate instruction set a standard that we can all aspire to. We are grateful to Jerry Saltzer and Jim Miller for helping us grapple with the mysteries of concurrency, and to Peter Szolovits and David McAllester for their contributions to the exposition of nondeterministic evaluation in chapter~4.

Many people have put in significant effort presenting this material at other universities. Some of the people we have worked closely with are Jacob Katzenelson at the Technion, Hardy Mayer at the University of California at Irvine, Joe Stoy at Oxford, Elisha Sacks at Purdue, and Jan Komorowski at the Norwegian University of Science and Technology. We are exceptionally proud of our colleagues who have received major teaching awards for their adaptations of this subject at other universities, including Kenneth Yip at Yale, Brian Harvey at the University of California at Berkeley, and Dan Huttenlocher at Cornell.

Al Moyée arranged for us to teach this material to engineers at Hewlett-Packard, and for the production of videotapes of these lectures. We would like to thank the talented instructors—in particular Jim Miller, Bill Siebert, and Mike Eisenberg—who have designed continuing education courses incorporating these tapes and taught them at universities and industry all over the world.

Many educators in other countries have put in significant work translating the first edition. Michel Briand, Pierre Chamard, and André Pic produced a French edition; Susanne Daniels-Herold produced a German edition; and Fumio Motoyoshi produced a Japanese edition. We do not know who produced the Chinese edition, but we consider it an honor to have been selected as the subject of an unauthorized translation.

It is hard to enumerate all the people who have made technical contributions to the development of the Scheme systems we use for instructional purposes. In addition to Guy Steele, principal wizards have included Chris Hanson, Joe Bowbeer, Jim Miller, Guillermo Rozas, and Stephen Adams. Others who have put in significant time are Richard Stallman, Alan Bawden, Kent Pitman, Jon Taft, Neil Mayle, John Lamping, Gwyn Osnos, Tracy Larrabee, George Carrette, Soma Chaudhuri, Bill Chiarchiaro, Steven Kirsch, Leigh Klotz, Wayne Noss, Todd Cass, Patrick O'Donnell, Kevin Theobald, Daniel Weise, Kenneth Sinclair, Anthony Courtemanche, Henry M. Wu, Andrew Berlin, and Ruth Shyu.

Beyond the MIT implementation, we would like to thank the many people who worked on the IEEE Scheme standard, including William Clinger and Jonathan Rees, who edited the R4RS, and Chris Haynes, David Bartley, Chris Hanson, and Jim Miller, who prepared the IEEE standard.

Dan Friedman has been a long-time leader of the Scheme community. The community's broader work goes beyond issues of language design to encompass significant educational innovations, such as the high-school curriculum based on EdScheme by Schemer's Inc., and the wonderful books by Mike Eisenberg and by Brian Harvey and Matthew Wright.

We appreciate the work of those who contributed to making this a real book, especially Terry Ehling, Larry Cohen, and Paul Bethge at the MIT Press. Ella Mazel found the wonderful cover image. For the second edition we are particularly grateful to Bernard and Ella Mazel for help with the book design, and to David Jones, TEX wizard extraordinaire. We also are indebted to those readers who made penetrating comments on the new draft: Jacob Katzenelson, Hardy Mayer, Jim Miller, and especially Brian Harvey, who did unto this book as Julie did unto his book Simply Scheme.

Finally, we would like to acknowledge the support of the organizations that have encouraged this work over the years, including suppport from Hewlett-Packard, made possible by Ira Goldstein and Joel Birnbaum, and support from DARPA, made possible by Bob Kahn.

—— Harold Abelson and Gerald Jay Sussman

Last Updated: 9/5/2019, 9:58:27 AM
19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /docs/assets/img/ch1-1-8-1.f03f002b.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 38 | 40 | 42 | 51 | 52 | 54 | image/svg+xml 55 | 57 | 58 | 59 | 60 | 64 | square 74 | / 83 | good_enough 93 | \ 102 | abs 112 | average 122 | \ 131 | improve 141 | / 150 | \ 159 | sqrt_iter 169 | | 178 | sqrt 188 | 189 | 190 | -------------------------------------------------------------------------------- /docs/assets/img/search.83621669.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/assets/js/10.c16c198a.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[10],{272:function(t,r,e){"use strict";e.r(r);var a=e(38),o=Object(a.a)({},function(){var t=this,r=t.$createElement,e=t._self._c||r;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"目录"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#目录","aria-hidden":"true"}},[t._v("#")]),t._v(" 目录")]),t._v(" "),e("ul",[e("li",[e("router-link",{attrs:{to:"/book/foreword.html"}},[t._v("Foreword")])],1),t._v(" "),e("li",[e("router-link",{attrs:{to:"/book/prefaces.html"}},[t._v("Prefaces")])],1),t._v(" "),e("li",[e("router-link",{attrs:{to:"/book/acknowledgments.html"}},[t._v("Acknowledgments")])],1),t._v(" "),e("li",[e("router-link",{attrs:{to:"/book/chapter1.html"}},[t._v("1 使用函数构造抽象")]),t._v(" "),e("ul",[e("li",[e("router-link",{attrs:{to:"/book/chapter1.1.html"}},[t._v("1.1 The Elements of Programming(翻译中)")])],1),t._v(" "),e("li",[e("a",{attrs:{href:""}},[t._v("1.2 Functions and the Processes They Generate")])]),t._v(" "),e("li",[e("a",{attrs:{href:""}},[t._v("1.3 Formulating Abstractions with Higher-Order Functions")])])])],1),t._v(" "),e("li",[e("a",{attrs:{href:""}},[t._v("2 Building Abstractions with Data")])]),t._v(" "),e("li",[e("a",{attrs:{href:""}},[t._v("3 Modularity, Objects, and State")])]),t._v(" "),e("li",[e("a",{attrs:{href:""}},[t._v("4 Metalinguistic Abstraction")])]),t._v(" "),e("li",[e("router-link",{attrs:{to:"/references.html"}},[t._v("文献参考")])],1),t._v(" "),e("li",[e("a",{attrs:{href:""}},[t._v("Index")])])])])},[],!1,null,null,null);r.default=o.exports}}]); -------------------------------------------------------------------------------- /docs/assets/js/11.d8727b0b.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[11],{276:function(e,t,a){"use strict";a.r(t);var i=a(38),o=Object(i.a)({},function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[a("h1",{attrs:{id:"荐言"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#荐言","aria-hidden":"true"}},[e._v("#")]),e._v(" 荐言")]),e._v(" "),a("p",[e._v("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.")]),e._v(" "),a("p",[e._v("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!")]),e._v(" "),a("p",[e._v("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.")]),e._v(" "),a("p",[e._v("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 112 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 …!")]),e._v(" "),a("p",[e._v("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.")]),e._v(" "),a("p",[e._v("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.")]),e._v(" "),a("p",[e._v("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.")]),e._v(" "),a("p",[e._v("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.")]),e._v(" "),a("p",[e._v("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.")]),e._v(" "),a("p",[e._v("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.")]),e._v(" "),a("p",[e._v("As one would expect from its goals, artificial intelligence research gen-e-rates 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.")]),e._v(" "),a("blockquote",[a("p",[e._v("By Alan J. Perlis New Haven, Connecticut")])])])},[],!1,null,null,null);t.default=o.exports}}]); -------------------------------------------------------------------------------- /docs/assets/js/12.8fdb12a3.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[12],{281:function(e,t,a){"use strict";a.r(t);var o=a(38),n=Object(o.a)({},function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[a("h1",{attrs:{id:"前言"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#前言","aria-hidden":"true"}},[e._v("#")]),e._v(" 前言")]),e._v(" "),a("h2",{attrs:{id:"preface-of-javascript-adaptation"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#preface-of-javascript-adaptation","aria-hidden":"true"}},[e._v("#")]),e._v(" Preface of JavaScript Adaptation")]),e._v(" "),a("p",[e._v("You are reading the textbook Structure and Interpretation of Computer Programs by Harold Abelson and Gerald Sussman—with a twist. The textbook emphasizes the importance of abstraction for managing complexity, and introduces the reader to a host of concepts that lie at the heart of the field of computer science. Most of these ideas are independent of the programming language used to express them to employ actual computers for solving computational problems. They are programming-language independent. The twist then consists of replacing the programming language that is used in the examples. While the authors had used the programming language Scheme, this adaptation uses the language JavaScript.")]),e._v(" "),a("p",[e._v("More precisely, this adaptation uses five tiny, carefully designed, sublanguages of JavaScript. The languages are called Source §1, Source §2, Source §3, Source §4 and Source §5, corresponding to the respective chapters 1, 2, 3, 4 and 5 of the textbook. The Source §1 language contains only constructs that are needed in the programs contained in chapter 1: constructs required to build abstractions with functions. Source §2 is a superset of Source §1; adding features required to build abstractions with data, on top of the features of Source §1. Similarly, Source §3, 4 and 5 extend the previous language features required to address the subject of the respective textbook chapter. All these languages are sub-languages of JavaScript; any Source program is also a JavaScript program. The reverse is not true. The JavaScript language has many features that are not covered in this textbook. Indeed, the Source languages are so small that they can be quite adquately described in a few pages of text. The online folder source contains the specifications of the Source languages, as reference for the reader.")]),e._v(" "),a("p",[e._v("This textbook is interactive. Most programs are links. Clicking on them takes the reader to a web-based programming environment called the Source Academy. In the Source Academy, the reader can run the programs, modify them and experiment with them, without the need to install any software, and without any requirements on the computer that they use, as long as it comes with an internet browser.")]),e._v(" "),a("p",[e._v("The language Scheme has been designed as a sublanguage of Lisp with its use in education as a central design objective. The language JavaScript, on the other hand, was not designed with the needs of learners in mind. This makes it difficult to use JavaScript in a course, even if one imposes constraints on the language features to be covered. The reason is that students with prior knowledge of the language are bound to make use of other features in their programs. Fellow students will legitimately ask the instructors about those features, and any answer will either frustate the student or lead to a tangent that is most likely not conducive to the learning objectives. This problem is especially severe for JavaScript, which is not known for its systematic design. Our solution to this challenge is radical: The Source Academy enforces the use of the respective Source language when the student clicks on a program of a particular chapter. Programs that use constructs beyond that language are rejected by the Source Academy. This allows instructors of a SICP-based course to adopt JavaScript—one of the most widely used programming languages today—without getting bogged down in JavaScript's plethora of idiosyncratic features.")]),e._v(" "),a("p",[e._v("The original textbook was introduced to the National University of Singapore by Jacob Katzenelson in 1997, as a more advanced alternative to the regular Programming Methodology course offered to computer science students. The course, known as CS1101S since 1998, switched to JavaScript in 2012, and became the required freshmen programming methodology course for Computer Science undergraduate majors in 2018.")]),e._v(" "),a("blockquote",[a("p",[e._v("—— Martin Henz")])]),e._v(" "),a("h2",{attrs:{id:"preface-to-the-second-edition"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#preface-to-the-second-edition","aria-hidden":"true"}},[e._v("#")]),e._v(" Preface to the Second Edition")]),e._v(" "),a("blockquote",[a("p",[e._v("Is it possible that software is not like anything else, that it is meant to be discarded: that the whole point is to always see it as a soap bubble?\n—— Alan J. Perlis")])]),e._v(" "),a("p",[e._v("The material in this book has been the basis of MIT's entry-level computer science subject since 1980. We had been teaching this material for four years when the first edition was published, and twelve more years have elapsed until the appearance of this second edition. We are pleased that our work has been widely adopted and incorporated into other texts. We have seen our students take the ideas and programs in this book and build them in as the core of new computer systems and languages. In literal realization of an ancient Talmudic pun, our students have become our builders. We are lucky to have such capable students and such accomplished builders.")]),e._v(" "),a("p",[e._v("In preparing this edition, we have incorporated hundreds of clarifications suggested by our own teaching experience and the comments of colleagues at MIT and elsewhere. We have redesigned most of the major programming systems in the book, including the generic-arithmetic system, the interpreters, the register-machine simulator, and the compiler; and we have rewritten all the program examples to ensure that any Scheme implementation conforming to the IEEE Scheme standard (IEEE 1990) will be able to run the code.")]),e._v(" "),a("p",[e._v("This edition emphasizes several new themes. The most important of these is the central role played by different approaches to dealing with time in computational models: objects with state, concurrent programming, functional programming, lazy evaluation, and nondeterministic programming. We have included new sections on concurrency and nondeterminism, and we have tried to integrate this theme throughout the book.")]),e._v(" "),a("p",[e._v("The first edition of the book closely followed the syllabus of our MIT one-semester subject. With all the new material in the second edition, it will not be possible to cover everything in a single semester, so the instructor will have to pick and choose. In our own teaching, we sometimes skip the section on logic programming (section ), we have students use the register-machine simulator but we do not cover its implementation (section ), and we give only a cursory overview of the compiler (section ). Even so, this is still an intense course. Some instructors may wish to cover only the first three or four chapters, leaving the other material for subsequent courses.")]),e._v(" "),a("p",[e._v("The World-Wide-Web site of MIT Press provides support for users of this book. This includes programs from the book, sample programming assignments, supplementary materials, and downloadable implementations of the Scheme dialect of Lisp.")]),e._v(" "),a("blockquote",[a("p",[e._v("—— Harold Abelson and Gerald Jay Sussman")])]),e._v(" "),a("h2",{attrs:{id:"preface-to-the-first-edition"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#preface-to-the-first-edition","aria-hidden":"true"}},[e._v("#")]),e._v(" Preface to the First Edition")]),e._v(" "),a("blockquote",[a("p",[e._v('A computer is like a violin. You can imagine a novice trying first a phonograph and then a violin. The latter, he says, sounds terrible. That is the argument we have heard from our humanists and most of our computer scientists. Computer programs are good, they say, for particular purposes, but they aren\'t flexible. Neither is a violin, or a typewriter, until you learn how to use it.\n—— Marvin Minsky, "Why Programming Is a Good Medium for Expressing Poorly-Understood and Sloppily-Formulated Ideas"')])]),e._v(" "),a("p",[e._v('"The Structure and Interpretation of Computer Programs" is the entry-level subject in computer science at the Massachusetts Institute of Technology. It is required of all students at MIT who major in electrical engineering or in computer science, as one-fourth of the "common core curriculum", which also includes two subjects on circuits and linear systems and a subject on the design of digital systems. We have been involved in the development of this subject since 1978, and we have taught this material in its present form since the fall of 1980 to between 600 and 700 students each year. Most of these students have had little or no prior formal training in computation, although many have played with computers a bit and a few have had extensive programming or hardware-design experience.')]),e._v(" "),a("p",[e._v("Our design of this introductory computer-science subject reflects two major concerns. First, we want to establish the idea that a computer language is not just a way of getting a computer to perform operations but rather that it is a novel formal medium for expressing ideas about methodology. Thus, programs must be written for people to read, and only incidentally for machines to execute. Second, we believe that the essential material to be addressed by a subject at this level is not the syntax of particular programming-language constructs, nor clever algorithms for computing particular functions efficiently, nor even the mathematical analysis of algorithms and the foundations of computing, but rather the techniques used to control the intellectual complexity of large software systems.")]),e._v(" "),a("p",[e._v("Our goal is that students who complete this subject should have a good feel for the elements of style and the aesthetics of programming. They should have command of the major techniques for controlling complexity in a large system. They should be capable of reading a 50-page-long program, if it is written in an exemplary style. They should know what not to read, and what they need not understand at any moment. They should feel secure about modifying a program, retaining the spirit and style of the original author.")]),e._v(" "),a("p",[e._v("These skills are by no means unique to computer programming. The techniques we teach and draw upon are common to all of engineering design. We control complexity by building abstractions that hide details when appropriate. We control complexity by establishing conventional interfaces that enable us to construct systems by combining standard, well-understood pieces in a mix and match way. We control complexity by establishing new languages for describing a design, each of which emphasizes particular aspects of the design and deemphasizes others.")]),e._v(" "),a("p",[e._v("Underlying our approach to this subject is our conviction that computer science is not a science and that its significance has little to do with computers. The computer revolution is a revolution in the way we think and in the way we express what we think. The essence of this change is the emergence of what might best be called procedural epistemology—the study of the structure of knowledge from an imperative point of view, as opposed to the more declarative point of view taken by classical mathematical subjects. Mathematics provides a framework for dealing precisely with notions of what is. Computation provides a framework for dealing precisely with notions of how to.")]),e._v(" "),a("p",[e._v("In teaching our material we use a dialect of the programming language Lisp. We never formally teach the language, because we don't have to. We just use it, and students pick it up in a few days. This is one great advantage of Lisp-like languages: They have very few ways of forming compound expressions, and almost no syntactic structure. All of the formal properties can be covered in an hour, like the rules of chess. After a short time we forget about syntactic details of the language (because there are none) and get on with the real issues—figuring out what we want to compute, how we will decompose problems into manageable parts, and how we will work on the parts. Another advantage of Lisp is that it supports (but does not enforce) more of the large-scale strategies for modular decomposition of programs than any other language we know. We can make procedural and data abstractions, we can use higher-order functions to capture common patterns of usage, we can model local state using assignment and data mutation, we can link parts of a program with streams and delayed evaluation, and we can easily implement embedded languages. All of this is embedded in an interactive environment with excellent support for incremental program design, construction, testing, and debugging. We thank all the generations of Lisp wizards, starting with John McCarthy, who have fashioned a fine tool of unprecedented power and elegance.")]),e._v(" "),a("p",[e._v("Scheme, the dialect of Lisp that we use, is an attempt to bring together the power and elegance of Lisp and Algol. From Lisp we take the metalinguistic power that derives from the simple syntax, the uniform representation of programs as data objects, and the garbage-collected heap-allocated data. From Algol we take lexical scoping and block structure, which are gifts from the pioneers of programming-language design who were on the Algol committee. We wish to cite John Reynolds and Peter Landin for their insights into the relationship of Church's lambda calculus to the structure of programming languages. We also recognize our debt to the mathematicians who scouted out this territory decades before computers appeared on the scene. These pioneers include Alonzo Church, Barkley Rosser, Stephen Kleene, and Haskell Curry.")]),e._v(" "),a("blockquote",[a("p",[e._v("—— Harold Abelson and Gerald Jay Sussman")])])])},[],!1,null,null,null);t.default=n.exports}}]); -------------------------------------------------------------------------------- /docs/assets/js/13.de801693.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[13],{277:function(e,n,i){"use strict";i.r(n);var a=i(38),o=Object(a.a)({},function(){var e=this,n=e.$createElement,i=e._self._c||n;return i("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[i("ul",[i("li",[i("p",[e._v("Abelson, Harold, Andrew Berlin, Jacob Katzenelson, William McAllister, Guillermo Rozas, Gerald Jay Sussman, and Jack Wisdom. 1992. The Supercomputer Toolkit: A general framework for special-purpose computing. International Journal of High-Speed Electronics 3(3):337-361.")])]),e._v(" "),i("li",[i("p",[e._v("Allen, John. 1978. Anatomy of Lisp. New York: McGraw-Hill.")])]),e._v(" "),i("li",[i("p",[e._v("ANSI X3.226-1994. American National Standard for Information Systems—Programming Language—Common Lisp.")])]),e._v(" "),i("li",[i("p",[e._v("Appel, Andrew W. 1987. Garbage collection can be faster than stack allocation. Information Processing Letters 25(4):275-279.")])]),e._v(" "),i("li",[i("p",[e._v("Backus, John. 1978. Can programming be liberated from the von Neumann style? Communications of the ACM 21(8):613-641.")])]),e._v(" "),i("li",[i("p",[e._v("Baker, Henry G., Jr. 1978. List processing in real time on a serial computer. Communications of the ACM 21(4):280-293.")])]),e._v(" "),i("li",[i("p",[e._v("Batali, John, Neil Mayle, Howard Shrobe, Gerald Jay Sussman, and Daniel Weise. 1982. The Scheme-81 architecture—System and chip. In Proceedings of the MIT Conference on Advanced Research in VLSI, edited by Paul Penfield, Jr. Dedham, MA: Artech House.")])]),e._v(" "),i("li",[i("p",[e._v("Borning, Alan. 1977. ThingLab—An object-oriented system for building simulations using constraints. In Proceedings of the 5th International Joint Conference on Artificial Intelligence.")])]),e._v(" "),i("li",[i("p",[e._v("Borodin, Alan, and Ian Munro. 1975. The Computational Complexity of Algebraic and Numeric Problems. New York: American Elsevier.")])]),e._v(" "),i("li",[i("p",[e._v("Chaitin, Gregory J. 1975. Randomness and mathematical proof. Scientific American 232(5):47-52.")])]),e._v(" "),i("li",[i("p",[e._v("Church, Alonzo. 1941. The Calculi of Lambda-Conversion. Princeton, N.J.: Princeton University Press.")])]),e._v(" "),i("li",[i("p",[e._v("Clark, Keith L. 1978. Negation as failure. In Logic and Data Bases. New York: Plenum Press, pp. 293-322.")])]),e._v(" "),i("li",[i("p",[e._v("Clinger, William. 1982. Nondeterministic call by need is neither lazy nor by name. In Proceedings of the ACM Symposium on Lisp and Functional Programming, pp. 226-234.")])]),e._v(" "),i("li",[i("p",[e._v("Clinger, William, and Jonathan Rees. 1991. Macros that work. In Proceedings of the 1991 ACM Conference on Principles of Programming Languages, pp. 155-162.")])]),e._v(" "),i("li",[i("p",[e._v("Colmerauer A., H. Kanoui, R. Pasero, and P. Roussel. 1973. Un système de communication homme-machine en français. Technical report, Groupe Intelligence Artificielle, Université d'Aix Marseille, Luminy.")])]),e._v(" "),i("li",[i("p",[e._v("Cormen, Thomas, Charles Leiserson, and Ronald Rivest. 1990. Introduction to Algorithms. Cambridge, MA: MIT Press.")])]),e._v(" "),i("li",[i("p",[e._v("Darlington, John, Peter Henderson, and David Turner. 1982. Functional Programming and Its Applications. New York: Cambridge University Press.")])]),e._v(" "),i("li",[i("p",[e._v("Dijkstra, Edsger W. 1968a. The structure of the THE multiprogramming system. Communications of the ACM 11(5):341-346.")])]),e._v(" "),i("li",[i("p",[e._v("Dijkstra, Edsger W. 1968b. Cooperating sequential processes. In Programming Languages, edited by F. Genuys. New York: Academic Press, pp. 43-112.")])]),e._v(" "),i("li",[i("p",[e._v("Dinesman, Howard P. 1968. Superior Mathematical Puzzles. New York: Simon and Schuster.")])]),e._v(" "),i("li",[i("p",[e._v("deKleer, Johan, Jon Doyle, Guy Steele, and Gerald J. Sussman. 1977. AMORD: Explicit control of reasoning. In Proceedings of the ACM Symposium on Artificial Intelligence and Programming Languages, pp. 116-125.")])]),e._v(" "),i("li",[i("p",[e._v("Doyle, Jon. 1979. A truth maintenance system. Artificial Intelligence 12:231-272.")])]),e._v(" "),i("li",[i("p",[e._v("Feigenbaum, Edward, and Howard Shrobe. 1993. The Japanese National Fifth Generation Project: Introduction, survey, and evaluation. In Future Generation Computer Systems, vol. 9, pp. 105-117.")])]),e._v(" "),i("li",[i("p",[e._v("Feeley, Marc. 1986. Deux approches à l'implantation du language Scheme. Masters thesis, Université de Montréal.")])]),e._v(" "),i("li",[i("p",[e._v("Feeley, Marc and Guy Lapalme. 1987. Using closures for code generation. Journal of Computer Languages 12(1):47-66.")])]),e._v(" "),i("li",[i("p",[e._v("Feller, William. 1957. An Introduction to Probability Theory and Its Applications, volume 1. New York: John Wiley & Sons.")])]),e._v(" "),i("li",[i("p",[e._v("Fenichel, R., and J. Yochelson. 1969. A Lisp garbage collector for virtual memory computer systems. Communications of the ACM 12(11):611-612.")])]),e._v(" "),i("li",[i("p",[e._v("Floyd, Robert. 1967. Nondeterministic algorithms. JACM, 14(4):636-644.")])]),e._v(" "),i("li",[i("p",[e._v("Forbus, Kenneth D., and Johan deKleer. 1993. Building Problem Solvers. Cambridge, MA: MIT Press.")])]),e._v(" "),i("li",[i("p",[e._v("Friedman, Daniel P., and David S. Wise. 1976. CONS should not evaluate its arguments. In Automata, Languages, and Programming: Third International Colloquium, edited by S. Michaelson and R. Milner, pp. 257-284.")])]),e._v(" "),i("li",[i("p",[e._v("Friedman, Daniel P., Mitchell Wand, and Christopher T. Haynes. 1992. Essentials of Programming Languages. Cambridge, MA: MIT Press/McGraw-Hill.")])]),e._v(" "),i("li",[i("p",[e._v("Gabriel, Richard P. 1988. The Why of Y. Lisp Pointers 2(2):15-25.")])]),e._v(" "),i("li",[i("p",[e._v("Goldberg, Adele, and David Robson. 1983. Smalltalk-80: The Language and Its Implementation. Reading, MA: Addison-Wesley.")])]),e._v(" "),i("li",[i("p",[e._v("Gordon, Michael, Robin Milner, and Christopher Wadsworth. 1979. Edinburgh LCF. Lecture Notes in Computer Science, volume 78. New York: Springer-Verlag.")])]),e._v(" "),i("li",[i("p",[e._v("Gray, Jim, and Andreas Reuter. 1993. Transaction Processing: Concepts and Models. San Mateo, CA: Morgan-Kaufman.")])]),e._v(" "),i("li",[i("p",[e._v("Green, Cordell. 1969. Application of theorem proving to problem solving. In Proceedings of the International Joint Conference on Artificial Intelligence, pp. 219-240.")])]),e._v(" "),i("li",[i("p",[e._v("Green, Cordell, and Bertram Raphael. 1968. The use of theorem-proving techniques in question-answering systems. In Proceedings of the ACM National Conference, pp. 169-181.")])]),e._v(" "),i("li",[i("p",[e._v("Griss, Martin L. 1981. Portable Standard Lisp, a brief overview. Utah Symbolic Computation Group Operating Note 58, University of Utah.")])]),e._v(" "),i("li",[i("p",[e._v("Guttag, John V. 1977. Abstract data types and the development of data structures. Communications of the ACM 20(6):397-404.")])]),e._v(" "),i("li",[i("p",[e._v("Hamming, Richard W. 1980. Coding and Information Theory. Englewood Cliffs, N.J.: Prentice-Hall.")])]),e._v(" "),i("li",[i("p",[e._v("Hanson, Christopher P. 1990. Efficient stack allocation for tail-recursive languages. In Proceedings of ACM Conference on Lisp and Functional Programming, pp. 106-118.")])]),e._v(" "),i("li",[i("p",[e._v("Hanson, Christopher P. 1991. A syntactic closures macro facility. Lisp Pointers, 4(3).")])]),e._v(" "),i("li",[i("p",[e._v("Hardy, Godfrey H. 1921. Srinivasa Ramanujan. Proceedings of the London Mathematical Society XIX(2).")])]),e._v(" "),i("li",[i("p",[e._v("Hardy, Godfrey H., and E. M. Wright. 1960. An Introduction to the Theory of Numbers. 4th edition. New York: Oxford University Press.")])]),e._v(" "),i("li",[i("p",[e._v("Havender, J. 1968. Avoiding deadlocks in multi-tasking systems. IBM Systems Journal 7(2):74-84.")])]),e._v(" "),i("li",[i("p",[e._v("Hearn, Anthony C. 1969. Standard Lisp. Technical report AIM-90, Artificial Intelligence Project, Stanford University.")])]),e._v(" "),i("li",[i("p",[e._v("Henderson, Peter. 1980. Functional Programming: Application and Implementation. Englewood Cliffs, N.J.: Prentice-Hall.")])]),e._v(" "),i("li",[i("p",[e._v("Henderson. Peter. 1982. Functional Geometry. In Conference Record of the 1982 ACM Symposium on Lisp and Functional Programming, pp. 179-187.")])]),e._v(" "),i("li",[i("p",[e._v("Hewitt, Carl E. 1969. PLANNER: A language for proving theorems in robots. In Proceedings of the International Joint Conference on Artificial Intelligence, pp. 295-301.")])]),e._v(" "),i("li",[i("p",[e._v("Hewitt, Carl E. 1977. Viewing control structures as patterns of passing messages. Journal of Artificial Intelligence 8(3):323-364.")])]),e._v(" "),i("li",[i("p",[e._v("Hoare, C. A. R. 1972. Proof of correctness of data representations. Acta Informatica 1(1).")])]),e._v(" "),i("li",[i("p",[e._v("Hodges, Andrew. 1983. Alan Turing: The Enigma. New York: Simon and Schuster.")])]),e._v(" "),i("li",[i("p",[e._v("Hofstadter, Douglas R. 1979. Gödel, Escher, Bach: An Eternal Golden Braid. New York: Basic Books.")])]),e._v(" "),i("li",[i("p",[e._v("Hughes, R. J. M. 1990. Why functional programming matters. In Research Topics in Functional Programming, edited by David Turner. Reading, MA: Addison-Wesley, pp. 17-42.")])]),e._v(" "),i("li",[i("p",[e._v("IEEE Std 1178-1990. 1990. IEEE Standard for the Scheme Programming Language.")])]),e._v(" "),i("li",[i("p",[e._v("Ingerman, Peter, Edgar Irons, Kirk Sattley, and Wallace Feurzeig; assisted by M. Lind, Herbert Kanner, and Robert Floyd. 1960. THUNKS: A way of compiling procedure statements, with some comments on procedure declarations. Unpublished manuscript. (Also, private communication from Wallace Feurzeig.)")])]),e._v(" "),i("li",[i("p",[e._v("Kaldewaij, Anne. 1990. Programming: The Derivation of Algorithms. New York: Prentice-Hall.")])]),e._v(" "),i("li",[i("p",[e._v("Kohlbecker, Eugene Edmund, Jr. 1986. Syntactic extensions in the programming language Lisp. Ph.D. thesis, Indiana University.")])]),e._v(" "),i("li",[i("p",[e._v("Konopasek, Milos, and Sundaresan Jayaraman. 1984. The TK!Solver Book: A Guide to Problem-Solving in Science, Engineering, Business, and Education. Berkeley, CA: Osborne/McGraw-Hill.")])]),e._v(" "),i("li",[i("p",[e._v("Knuth, Donald E. 1973. Fundamental Algorithms. Volume 1 of The Art of Computer Programming. 2nd edition. Reading, MA: Addison-Wesley.")])]),e._v(" "),i("li",[i("p",[e._v("Knuth, Donald E. 1981. Seminumerical Algorithms. Volume 2 of The Art of Computer Programming. 2nd edition. Reading, MA: Addison-Wesley.")])]),e._v(" "),i("li",[i("p",[e._v("Kowalski, Robert. 1973. Predicate logic as a programming language. Technical report 70, Department of Computational Logic, School of Artificial Intelligence, University of Edinburgh.")])]),e._v(" "),i("li",[i("p",[e._v("Kowalski, Robert. 1979. Logic for Problem Solving. New York: North-Holland.")])]),e._v(" "),i("li",[i("p",[e._v("Lamport, Leslie. 1978. Time, clocks, and the ordering of events in a distributed system. Communications of the ACM 21(7):558-565.")])]),e._v(" "),i("li",[i("p",[e._v("Lampson, Butler, J. J. Horning, R. London, J. G. Mitchell, and G. K. Popek. 1981. Report on the programming language Euclid. Technical report, Computer Systems Research Group, University of Toronto.")])]),e._v(" "),i("li",[i("p",[e._v("Landin, Peter. 1965. A correspondence between Algol 60 and Church's lambda notation: Part I. Communications of the ACM 8(2):89-101.")])]),e._v(" "),i("li",[i("p",[e._v("Lieberman, Henry, and Carl E. Hewitt. 1983. A real-time garbage collector based on the lifetimes of objects. Communications of the ACM 26(6):419-429.")])]),e._v(" "),i("li",[i("p",[e._v("Liskov, Barbara H., and Stephen N. Zilles. 1975. Specification techniques for data abstractions. IEEE Transactions on Software Engineering 1(1):7-19.")])]),e._v(" "),i("li",[i("p",[e._v("McAllester, David Allen. 1978. A three-valued truth-maintenance system. Memo 473, MIT Artificial Intelligence Laboratory.")])]),e._v(" "),i("li",[i("p",[e._v("McAllester, David Allen. 1980. An outlook on truth maintenance. Memo 551, MIT Artificial Intelligence Laboratory.")])]),e._v(" "),i("li",[i("p",[e._v("McCarthy, John. 1960. Recursive functions of symbolic expressions and their computation by machine. Communications of the ACM 3(4):184-195.")])]),e._v(" "),i("li",[i("p",[e._v("McCarthy, John. 1967. A basis for a mathematical theory of computation. In Computer Programing and Formal Systems, edited by P. Braffort and D. Hirschberg. North-Holland.")])]),e._v(" "),i("li",[i("p",[e._v("McCarthy, John. 1978. The history of Lisp. In Proceedings of the ACM SIGPLAN Conference on the History of Programming Languages.")])]),e._v(" "),i("li",[i("p",[e._v("McCarthy, John, P. W. Abrahams, D. J. Edwards, T. P. Hart, and M. I. Levin. 1965. Lisp 1.5 Programmer's Manual. 2nd edition. Cambridge, MA: MIT Press.")])]),e._v(" "),i("li",[i("p",[e._v("McDermott, Drew, and Gerald Jay Sussman. 1972. Conniver reference manual. Memo 259, MIT Artificial Intelligence Laboratory.")])]),e._v(" "),i("li",[i("p",[e._v("Miller, Gary L. 1976. Riemann's Hypothesis and tests for primality. Journal of Computer and System Sciences 13(3):300-317.")])]),e._v(" "),i("li",[i("p",[e._v("Miller, James S., and Guillermo J. Rozas. 1994. Garbage collection is fast, but a stack is faster. Memo 1462, MIT Artificial Intelligence Laboratory.")])]),e._v(" "),i("li",[i("p",[e._v("Moon, David. 1978. MacLisp reference manual, Version 0. Technical report, MIT Laboratory for Computer Science.")])]),e._v(" "),i("li",[i("p",[e._v("Moon, David, and Daniel Weinreb. 1981. Lisp machine manual. Technical report, MIT Artificial Intelligence Laboratory.")])]),e._v(" "),i("li",[i("p",[e._v("Morris, J. H., Eric Schmidt, and Philip Wadler. 1980. Experience with an applicative string processing language. In Proceedings of the 7th Annual ACM SIGACT/SIGPLAN Symposium on the Principles of Programming Languages.")])]),e._v(" "),i("li",[i("p",[e._v("Phillips, Hubert. 1934. The Sphinx Problem Book. London: Faber and Faber.")])]),e._v(" "),i("li",[i("p",[e._v("Pitman, Kent. 1983. The revised MacLisp Manual (Saturday evening edition). Technical report 295, MIT Laboratory for Computer Science.")])]),e._v(" "),i("li",[i("p",[e._v("Rabin, Michael O. 1980. Probabilistic algorithm for testing primality. Journal of Number Theory 12:128-138.")])]),e._v(" "),i("li",[i("p",[e._v("Raymond, Eric. 1993. The New Hacker's Dictionary. 2nd edition. Cambridge, MA: MIT Press.")])]),e._v(" "),i("li",[i("p",[e._v("Raynal, Michel. 1986. Algorithms for Mutual Exclusion. Cambridge, MA: MIT Press.")])]),e._v(" "),i("li",[i("p",[e._v("Rees, Jonathan A., and Norman I. Adams IV. 1982. T: A dialect of Lisp or, lambda: The ultimate software tool. In Conference Record of the 1982 ACM Symposium on Lisp and Functional Programming, pp. 114-122.")])]),e._v(" "),i("li",[i("p",[e._v("Rees, Jonathan, and William Clinger (eds). 1991. The revised44 report on the algorithmic language Scheme. Lisp Pointers, 4(3).")])]),e._v(" "),i("li",[i("p",[e._v("Rivest, Ronald, Adi Shamir, and Leonard Adleman. 1977. A method for obtaining digital signatures and public-key cryptosystems. Technical memo LCS/TM82, MIT Laboratory for Computer Science.")])]),e._v(" "),i("li",[i("p",[e._v("Robinson, J. A. 1965. A machine-oriented logic based on the resolution principle. Journal of the ACM 12(1):23.")])]),e._v(" "),i("li",[i("p",[e._v("Robinson, J. A. 1983. Logic programming—Past, present, and future. New Generation Computing 1:107-124.")])]),e._v(" "),i("li",[i("p",[e._v("Sagade, Y. 2015. SICP exercise 1.14")])]),e._v(" "),i("li",[i("p",[e._v("Spafford, Eugene H. 1989. The Internet Worm: Crisis and aftermath. Communications of the ACM 32(6):678-688.")])]),e._v(" "),i("li",[i("p",[e._v("Steele, Guy Lewis, Jr. 1977. Debunking the expensive procedure call myth. In Proceedings of the National Conference of the ACM, pp. 153-62.")])]),e._v(" "),i("li",[i("p",[e._v("Steele, Guy Lewis, Jr. 1982. An overview of Common Lisp. In Proceedings of the ACM Symposium on Lisp and Functional Programming, pp. 98-107.")])]),e._v(" "),i("li",[i("p",[e._v("Steele, Guy Lewis, Jr. 1990. Common Lisp: The Language. 2nd edition. Digital Press.")])]),e._v(" "),i("li",[i("p",[e._v("Steele, Guy Lewis, Jr., and Gerald Jay Sussman. 1975. Scheme: An interpreter for the extended lambda calculus. Memo 349, MIT Artificial Intelligence Laboratory.")])]),e._v(" "),i("li",[i("p",[e._v("Steele, Guy Lewis, Jr., Donald R. Woods, Raphael A. Finkel, Mark R. Crispin, Richard M. Stallman, and Geoffrey S. Goodfellow. 1983. The Hacker's Dictionary. New York: Harper & Row.")])]),e._v(" "),i("li",[i("p",[e._v("Stoy, Joseph E. 1977. Denotational Semantics. Cambridge, MA: MIT Press.")])]),e._v(" "),i("li",[i("p",[e._v("Sussman, Gerald Jay, and Richard M. Stallman. 1975. Heuristic techniques in computer-aided circuit analysis. IEEE Transactions on Circuits and Systems CAS-22(11):857-865.")])]),e._v(" "),i("li",[i("p",[e._v("Sussman, Gerald Jay, and Guy Lewis Steele Jr. 1980. Constraints—A language for expressing almost-hierachical descriptions. AI Journal 14:1-39.")])]),e._v(" "),i("li",[i("p",[e._v("Sussman, Gerald Jay, and Jack Wisdom. 1992. Chaotic evolution of the solar system. Science 257:256-262.")])]),e._v(" "),i("li",[i("p",[e._v("Sussman, Gerald Jay, Terry Winograd, and Eugene Charniak. 1971. Microplanner reference manual. Memo 203A, MIT Artificial Intelligence Laboratory.")])]),e._v(" "),i("li",[i("p",[e._v("Sutherland, Ivan E. 1963. SKETCHPAD: A man-machine graphical communication system. Technical report 296, MIT Lincoln Laboratory.")])]),e._v(" "),i("li",[i("p",[e._v("Teitelman, Warren. 1974. Interlisp reference manual. Technical report, Xerox Palo Alto Research Center.")])]),e._v(" "),i("li",[i("p",[e._v("Thatcher, James W., Eric G. Wagner, and Jesse B. Wright. 1978. Data type specification: Parameterization and the power of specification techniques. In Conference Record of the Tenth Annual ACM Symposium on Theory of Computing, pp. 119-132. Turner, David. 1981. The future of applicative languages. In Proceedings of the 3rd European Conference on Informatics, Lecture Notes in Computer Science, volume 123. New York: Springer-Verlag, pp. 334-348.")])]),e._v(" "),i("li",[i("p",[e._v("Wand, Mitchell. 1980. Continuation-based program transformation strategies. Journal of the ACM 27(1):164-180.")])]),e._v(" "),i("li",[i("p",[e._v("Waters, Richard C. 1979. A method for analyzing loop programs. IEEE Transactions on Software Engineering 5(3):237-247.")])]),e._v(" "),i("li",[i("p",[e._v("Winograd, Terry. 1971. Procedures as a representation for data in a computer program for understanding natural language. Technical report AI TR-17, MIT Artificial Intelligence Laboratory.")])]),e._v(" "),i("li",[i("p",[e._v("Winston, Patrick. 1992. Artificial Intelligence. 3rd edition. Reading, MA: Addison-Wesley.")])]),e._v(" "),i("li",[i("p",[e._v("Zabih, Ramin, David McAllester, and David Chapman. 1987. Non-deterministic Lisp with dependency-directed backtracking. AAAI-87, pp. 59-64.")])]),e._v(" "),i("li",[i("p",[e._v("Zippel, Richard. 1979. Probabilistic algorithms for sparse polynomials. Ph.D. dissertation, Department of Electrical Engineering and Computer Science, MIT.")])]),e._v(" "),i("li",[i("p",[e._v("Zippel, Richard. 1993. Effective Polynomial Computation. Boston, MA: Kluwer Academic Publishers.")])])])])},[],!1,null,null,null);n.default=o.exports}}]); -------------------------------------------------------------------------------- /docs/assets/js/14.f2872d53.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[14],{225:function(n,w,o){}}]); -------------------------------------------------------------------------------- /docs/assets/js/4.d8e6dabe.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[4],{239:function(t,e,n){},269:function(t,e,n){"use strict";var i=n(239);n.n(i).a},280:function(t,e,n){"use strict";n.r(e);var i={functional:!0,props:{type:{type:String,default:"tip"},text:String,vertical:{type:String,default:"top"}},render:function(t,e){var n=e.props,i=e.slots;return t("span",{class:["badge",n.type],style:{verticalAlign:n.vertical}},n.text||i().default)}},r=(n(269),n(38)),a=Object(r.a)(i,void 0,void 0,!1,null,"c13ee5b0",null);e.default=a.exports}}]); -------------------------------------------------------------------------------- /docs/assets/js/5.07c65855.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[5],{271:function(t,e,s){"use strict";s.r(e);var o=["There's nothing here.","How did we get here?","That's a Four-Oh-Four.","Looks like we've got some broken links."],n={methods:{getMsg:function(){return o[Math.floor(Math.random()*o.length)]}}},i=s(38),h=Object(i.a)(n,function(){var t=this.$createElement,e=this._self._c||t;return e("div",{staticClass:"theme-container"},[e("div",{staticClass:"theme-default-content"},[e("h1",[this._v("404")]),this._v(" "),e("blockquote",[this._v(this._s(this.getMsg()))]),this._v(" "),e("router-link",{attrs:{to:"/"}},[this._v("Take me home.")])],1)])},[],!1,null,null,null);e.default=h.exports}}]); -------------------------------------------------------------------------------- /docs/assets/js/6.da87f603.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[6],{279:function(t,r,e){"use strict";e.r(r);var a=e(38),l=Object(a.a)({},function(){var t=this,r=t.$createElement,e=t._self._c||r;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"目录"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#目录","aria-hidden":"true"}},[t._v("#")]),t._v(" 目录")]),t._v(" "),e("ul",[e("li",[e("router-link",{attrs:{to:"/foreword.html"}},[t._v("Foreword")])],1),t._v(" "),e("li",[e("router-link",{attrs:{to:"/prefaces.html"}},[t._v("Prefaces")])],1),t._v(" "),e("li",[e("router-link",{attrs:{to:"/acknowledgments.html"}},[t._v("Acknowledgments")])],1),t._v(" "),e("li",[e("router-link",{attrs:{to:"/chapter1.html"}},[t._v("1 使用函数构造抽象")]),t._v(" "),e("ul",[e("li",[e("router-link",{attrs:{to:"/chapter1.1.html"}},[t._v("1.1 编程的基本元素(翻译中 90%)")])],1),t._v(" "),e("li",[e("router-link",{attrs:{to:"/chapter1.2.html"}},[t._v("1.2 Functions and the Processes They Generate(翻译中)")])],1),t._v(" "),e("li",[e("a",{attrs:{href:""}},[t._v("1.3 Formulating Abstractions with Higher-Order Functions")])])])],1),t._v(" "),e("li",[e("a",{attrs:{href:""}},[t._v("2 Building Abstractions with Data")])]),t._v(" "),e("li",[e("a",{attrs:{href:""}},[t._v("3 Modularity, Objects, and State")])]),t._v(" "),e("li",[e("a",{attrs:{href:""}},[t._v("4 Metalinguistic Abstraction")])]),t._v(" "),e("li",[e("router-link",{attrs:{to:"/references.html"}},[t._v("文献参考")])],1),t._v(" "),e("li",[e("a",{attrs:{href:""}},[t._v("Index")])])])])},[],!1,null,null,null);r.default=l.exports}}]); -------------------------------------------------------------------------------- /docs/assets/js/7.f06457f4.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[7],{275:function(e,t,a){"use strict";a.r(t);var o=a(38),n=Object(o.a)({},function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[a("h1",{attrs:{id:"谢言"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#谢言","aria-hidden":"true"}},[e._v("#")]),e._v(" 谢言")]),e._v(" "),a("p",[e._v("We would like to thank the many people who have helped us develop this book and this curriculum.")]),e._v(" "),a("p",[e._v("Our subject is a clear intellectual descendant of 6.231, a wonderful subject on programming linguistics and the lambda calculus taught at MIT in the late 1960s by Jack Wozencraft and Arthur Evans, Jr.")]),e._v(" "),a("p",[e._v("We owe a great debt to Robert Fano, who reorganized MIT's introductory curriculum in electrical engineering and computer science to emphasize the principles of engineering design. He led us in starting out on this enterprise and wrote the first set of subject notes from which this book evolved.")]),e._v(" "),a("p",[e._v("Much of the style and aesthetics of programming that we try to teach were developed in conjunction with Guy Lewis Steele Jr., who collaborated with Gerald Jay Sussman in the initial development of the Scheme language. In addition, David Turner, Peter Henderson, Dan Friedman, David Wise, and Will Clinger have taught us many of the techniques of the functional programming community that appear in this book.")]),e._v(" "),a("p",[e._v("Joel Moses taught us about structuring large systems. His experience with the Macsyma system for symbolic computation provided the insight that one should avoid complexities of control and concentrate on organizing the data to reflect the real structure of the world being modeled.")]),e._v(" "),a("p",[e._v("Marvin Minsky and Seymour Papert formed many of our attitudes about programming and its place in our intellectual lives. To them we owe the understanding that computation provides a means of expression for exploring ideas that would otherwise be too complex to deal with precisely. They emphasize that a student's ability to write and modify programs provides a powerful medium in which exploring becomes a natural activity.")]),e._v(" "),a("p",[e._v("We also strongly agree with Alan Perlis that programming is lots of fun and we had better be careful to support the joy of programming. Part of this joy derives from observing great masters at work. We are fortunate to have been apprentice programmers at the feet of Bill Gosper and Richard Greenblatt.")]),e._v(" "),a("p",[e._v("It is difficult to identify all the people who have contributed to the development of our curriculum. We thank all the lecturers, recitation instructors, and tutors who have worked with us over the past fifteen years and put in many extra hours on our subject, especially Bill Siebert, Albert Meyer, Joe Stoy, Randy Davis, Louis Braida, Eric Grimson, Rod Brooks, Lynn Stein, and Peter Szolovits. We would like to specially acknowledge the outstanding teaching contributions of Franklyn Turbak, now at Wellesley; his work in undergraduate instruction set a standard that we can all aspire to. We are grateful to Jerry Saltzer and Jim Miller for helping us grapple with the mysteries of concurrency, and to Peter Szolovits and David McAllester for their contributions to the exposition of nondeterministic evaluation in chapter~4.")]),e._v(" "),a("p",[e._v("Many people have put in significant effort presenting this material at other universities. Some of the people we have worked closely with are Jacob Katzenelson at the Technion, Hardy Mayer at the University of California at Irvine, Joe Stoy at Oxford, Elisha Sacks at Purdue, and Jan Komorowski at the Norwegian University of Science and Technology. We are exceptionally proud of our colleagues who have received major teaching awards for their adaptations of this subject at other universities, including Kenneth Yip at Yale, Brian Harvey at the University of California at Berkeley, and Dan Huttenlocher at Cornell.")]),e._v(" "),a("p",[e._v("Al Moyée arranged for us to teach this material to engineers at Hewlett-Packard, and for the production of videotapes of these lectures. We would like to thank the talented instructors—in particular Jim Miller, Bill Siebert, and Mike Eisenberg—who have designed continuing education courses incorporating these tapes and taught them at universities and industry all over the world.")]),e._v(" "),a("p",[e._v("Many educators in other countries have put in significant work translating the first edition. Michel Briand, Pierre Chamard, and André Pic produced a French edition; Susanne Daniels-Herold produced a German edition; and Fumio Motoyoshi produced a Japanese edition. We do not know who produced the Chinese edition, but we consider it an honor to have been selected as the subject of an unauthorized translation.")]),e._v(" "),a("p",[e._v("It is hard to enumerate all the people who have made technical contributions to the development of the Scheme systems we use for instructional purposes. In addition to Guy Steele, principal wizards have included Chris Hanson, Joe Bowbeer, Jim Miller, Guillermo Rozas, and Stephen Adams. Others who have put in significant time are Richard Stallman, Alan Bawden, Kent Pitman, Jon Taft, Neil Mayle, John Lamping, Gwyn Osnos, Tracy Larrabee, George Carrette, Soma Chaudhuri, Bill Chiarchiaro, Steven Kirsch, Leigh Klotz, Wayne Noss, Todd Cass, Patrick O'Donnell, Kevin Theobald, Daniel Weise, Kenneth Sinclair, Anthony Courtemanche, Henry M. Wu, Andrew Berlin, and Ruth Shyu.")]),e._v(" "),a("p",[e._v("Beyond the MIT implementation, we would like to thank the many people who worked on the IEEE Scheme standard, including William Clinger and Jonathan Rees, who edited the R4RS, and Chris Haynes, David Bartley, Chris Hanson, and Jim Miller, who prepared the IEEE standard.")]),e._v(" "),a("p",[e._v("Dan Friedman has been a long-time leader of the Scheme community. The community's broader work goes beyond issues of language design to encompass significant educational innovations, such as the high-school curriculum based on EdScheme by Schemer's Inc., and the wonderful books by Mike Eisenberg and by Brian Harvey and Matthew Wright.")]),e._v(" "),a("p",[e._v("We appreciate the work of those who contributed to making this a real book, especially Terry Ehling, Larry Cohen, and Paul Bethge at the MIT Press. Ella Mazel found the wonderful cover image. For the second edition we are particularly grateful to Bernard and Ella Mazel for help with the book design, and to David Jones, TEX wizard extraordinaire. We also are indebted to those readers who made penetrating comments on the new draft: Jacob Katzenelson, Hardy Mayer, Jim Miller, and especially Brian Harvey, who did unto this book as Julie did unto his book Simply Scheme.")]),e._v(" "),a("p",[e._v("Finally, we would like to acknowledge the support of the organizations that have encouraged this work over the years, including suppport from Hewlett-Packard, made possible by Ira Goldstein and Joel Birnbaum, and support from DARPA, made possible by Bob Kahn.")]),e._v(" "),a("blockquote",[a("p",[e._v("—— Harold Abelson and Gerald Jay Sussman")])])])},[],!1,null,null,null);t.default=n.exports}}]); -------------------------------------------------------------------------------- /docs/assets/js/8.72cdcc71.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[8],{273:function(e,t,r){"use strict";r.r(t);var o=r(38),n=Object(o.a)({},function(){var e=this,t=e.$createElement,r=e._self._c||t;return r("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[r("h1",{attrs:{id:"_1-2-functions-and-the-processes-they-generate"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#_1-2-functions-and-the-processes-they-generate","aria-hidden":"true"}},[e._v("#")]),e._v(" 1.2 Functions and the Processes They Generate")]),e._v(" "),r("blockquote",[r("ul",[r("li",[e._v("来源:"),r("a",{attrs:{href:"https://sicp.comp.nus.edu.sg/chapters/11",target:"_blank",rel:"noopener noreferrer"}},[e._v("Functions and the Processes They Generate"),r("OutboundLink")],1)]),e._v(" "),r("li",[e._v("译者:"),r("a",{attrs:{href:"https://github.com/iheyunfei/",target:"_blank",rel:"noopener noreferrer"}},[e._v("塔希"),r("OutboundLink")],1)]),e._v(" "),r("li",[e._v("协议:"),r("a",{attrs:{href:"http://creativecommons.org/licenses/by-nc-sa/4.0/",target:"_blank",rel:"noopener noreferrer"}},[e._v("CC BY-NC-SA 4.0"),r("OutboundLink")],1)])])]),e._v(" "),r("hr"),e._v(" "),r("p",[e._v("现在,我们已经见识了一些编程的要素:我们使用过基本的数学运算操作,然后将这些操作组合起来,并且通过声明复合函数来抽象这些组合后的的操作。但是,了解这些并不足以声称我们学会了如何去编程。我们现在的情况和刚学会如何移动国际象棋棋子的人一样,虽然了解基本的规则,但是对开局,策略,战术一无所知。和国际象棋初学者一样,我们还不知道编程领域中各种模式的用法。我们缺乏足够的知识去判断棋子的哪一步是值得的?(哪一个函数值得声明?)。我们缺乏足够的经验判断每一步的后果(比如,执行一个函数)。")]),e._v(" "),r("p",[e._v("把正在考虑的行为的结果进行可视化的能力,对于成为一名专业编程人员来说,是至关重要的,就像这种能力在其他合成性,创造性活动中的作用一样。举个例子,在成为一个专业摄影家的过程中,一个人必须学习如何观察各种景象,知道在各种可能的曝光和显影的条件"),r("sup",[r("a",{attrs:{href:""}},[e._v("[1]")])]),e._v("下,镜像中的各个区域在影像中的明暗程度。只有这样,人才能反推对于想要效果应该作的取景、 亮度、曝光、和显影行为。对于编程来说也是一样的,我们需要对于计算过程中各种动作行为作出规划和通过程序去控制其进程。为了成为一个专家,我们必须学会如何看清各种类型函数产生的计算过程。这样,我们才能学着如何去构造出可靠的程序,并使其表现出我们想要的行为。")]),e._v(" "),r("p",[e._v("一个函数就是相对于于计算过程局部演化的一种形式。它描述了计算过程的每一步是如何建立在上一步上。We would like to be able to make statements about the overall, or "),r("em",[e._v("global")]),e._v(", behavior of a process whose local evolution has been specified by a function. This is very difficult to do in general, but we can at least try to describe some typical patterns of process evolution.")]),e._v(" "),r("p",[e._v("在这一节里,我们将会考察一些由简单函数产生的计算过程的“形状”。我们同样会研究计算过程消耗的各种重要的时间和空间计算资源的速率。将要考察的函数是非常简单的。它们在这里扮演的角色就像是是摄影技术中测试模式:作为极度简化的摄影模式,对其来说,而非实际的例子。")]),e._v(" "),r("small",[r("p",[e._v("[1] The textbook was written at a time when photography commonly involved photographic development, a chemical process for making paper prints from photographic film.")]),e._v(" "),r("small")])])},[],!1,null,null,null);t.default=n.exports}}]); -------------------------------------------------------------------------------- /docs/assets/js/9.89efac31.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[9],{274:function(a,e,t){"use strict";t.r(e);var r=t(38),i=Object(r.a)({},function(){var a=this,e=a.$createElement,t=a._self._c||e;return t("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[t("h1",{attrs:{id:"_1-使用函数构造抽象"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#_1-使用函数构造抽象","aria-hidden":"true"}},[a._v("#")]),a._v(" 1 使用函数构造抽象")]),a._v(" "),t("blockquote",[t("ul",[t("li",[a._v("来源:"),t("a",{attrs:{href:"https://sicp.comp.nus.edu.sg/chapters/1",target:"_blank",rel:"noopener noreferrer"}},[a._v("Building Abstractions with Functions"),t("OutboundLink")],1)]),a._v(" "),t("li",[a._v("译者:"),t("a",{attrs:{href:"https://github.com/iheyunfei/",target:"_blank",rel:"noopener noreferrer"}},[a._v("塔希"),t("OutboundLink")],1)]),a._v(" "),t("li",[a._v("协议:"),t("a",{attrs:{href:"http://creativecommons.org/licenses/by-nc-sa/4.0/",target:"_blank",rel:"noopener noreferrer"}},[a._v("CC BY-NC-SA 4.0"),t("OutboundLink")],1)])])]),a._v(" "),t("hr"),a._v(" "),t("blockquote",[t("p",[a._v("The acts of the mind, wherein it exerts its power over simple ideas, are chiefly these three: 1. Combining several simple ideas into one compound one, and thus all complex ideas are made. 2. The second is bringing two ideas, whether simple or complex, together, and setting them by one another so as to take a view of them at once, without uniting them into one, by which it gets all its ideas of relations. 3. The third is separating them from all other ideas that accompany them in their real existence: this is called abstraction, and thus all its general ideas are made. —— John Locke An Essay Concerning Human Understanding (1690)")])]),a._v(" "),t("p",[a._v("我们即将学习有关 "),t("em",[a._v("计算过程(computational process)")]),a._v(" 的概念。计算过程是一种栖息于电脑中、抽象的存在。经过演化,过程可以操控另一种被称为 "),t("em",[a._v("数据(data)")]),a._v(" 的抽象事物。人们创建程序来指导、控制各种过程,而 "),t("em",[a._v("程序(program)")]),a._v(" 是一种含有许多规则的形式,主导着过程的运行。从形式上看,就像我们通过自己编写的咒语控制计算机中的精灵一样。")]),a._v(" "),t("p",[a._v("对于一个计算过程的理解可以参照巫师如何理解小精灵。小精灵并非由物质组成的实体,它们无法被看见和触摸。但是,它们却又是实际存在的。它们能完成智力性的任务、可以回答问题,并且通过在银行付钱或者控制工厂里机器人的手臂来对世界产生实际影响。我们用来“变出”过程的程序就如同巫师们用来召唤小精灵的咒语一样。程序是由神秘、晦涩的 "),t("em",[a._v("编程语言(programming languages)")]),a._v(" 中各种符号表达式精心构建的,它们被用来描述可以完成我们所关心任务的计算过程。")]),a._v(" "),t("p",[a._v("在一台正常工作的计算机里,一个计算过程会严格且准确地的执行对应的程序。因此,“菜鸟”程序员就像巫师的学徒一样,必须经过事先学习,以图理解和预测他们通过咒语使用的各种“魔法”的后果。程序中即使很微小的的错误都可能导致复杂且无法预料的后果。")]),a._v(" "),t("p",[a._v("幸运的是,学习编程要比学习魔法安全得多,因为我们要面对的“小精灵”被一种安全的方式保存着。不过,现实世界中的编程依然要求谨慎、专业和智慧。举个例子,一个小小的程序错误都可能导致使用计算机辅助操控的飞机发生坠机、水坝崩坏或者工业机器人产生自毁行为。")]),a._v(" "),t("p",[a._v("软件工程大师们掌握着高超的构建程序的能力,所以他们才能合理地确信程序产生的过程,能够正确地完成其被安排的任务。软件工程大师们能够“预视”到系统的行为,知道该怎么组织程序的结构来避免意料之外的错误以及可能导致的严重后果,并且明白当错误出现时该怎么"),t("em",[a._v("定位、解决")]),a._v("它们。设计优良的计算系统,就像一个设计优良的汽车或核反应堆,是采用模块化设计的,所以每一部分都可以独立地被构建、替换和除错(debug)。")]),a._v(" "),t("h2",{attrs:{id:"使用javascript编程"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#使用javascript编程","aria-hidden":"true"}},[a._v("#")]),a._v(" 使用JavaScript编程")]),a._v(" "),t("p",[a._v("我们需要合适的语言来描述过程,为了达成这个目的,我们将会使用编程语言JavaScript。就如我们每天会用自然语言(英语,法语,日语)来表达我们日常的想法,用数学符号来描述数量的概念,我们的过程将会使用JavaScript来描述。JavaScript产生于1990年早期,通过内嵌于网页内部作为脚本,用来控制网页浏览器的行为。这门语言由Brendan Eich设计出,开始被称为Mocha,后改为"),t("em",[a._v("LiveScript")]),a._v(",最终命名为JavaScript。这个名字“JavaScript”是属于Sun Microsystems公司的一个商标。")]),a._v(" "),t("p",[a._v("尽管JavaScript作为一门语言,其诞生时的目的是为了控制网页浏览器,但JavaScript依然是一个通用编程语言。一个JavaScript "),t("em",[a._v("解释器(interpreter)")]),a._v(" 就是一部用来执行由JavaScript编写的过程的机器。第一个JavaScript解释器是由Eich就职于Netscape Communications公司期间实现的,用在Netscape Navigator网页浏览器上。JavaScript的主要语言特性继承自Scheme和Self编程语言。Scheme是Lisp的一个方言,并且被当作原版《SICP》书籍的编程语言。从Scheme里,JavaScript继承了其大部分的函数式设计原则,例如静态作用域、一等函数公民和动态类型,这种继承的直接结果就是本书中的程序可以很直接、简单的从原书中的Scheme语言翻译成JavaScript语言。")]),a._v(" "),t("p",[a._v("JavaScript仅仅与Java在表面上有相似之处,最大的关联点就是名字中都带个Java而已。JavaScript和Java都沿用了C语言的程序块(block structure)结构。与Java和C这种编译成底层语言后执行的过程相比,JavaScript常常是被浏览器内建的解释器解释执行。在Netscape Navigator浏览器出现后,其他网页浏览器也开始提供内嵌的JavaScript解释器,包括微软的Internet Explorer浏览器(微软称其为JScript而非JavaScript)。JavaScript因为可以控制浏览器的行为而普及后,广受大众欢迎,进而引起了对JavaScript进行标准化的工作,最终产生了一个标准化的语言标准,被称为 "),t("em",[a._v("ECMAScript")]),a._v("。第一版的ECMAScript(ECMA 1997)标准由Guy Lewis Steele Jr. 主导制定于1997年6月。本书使用的是第六版,由Allen Wirfs-Brock主导制定,在2015年6月的ECMA大会上被接受。")]),a._v(" "),t("p",[a._v("网页可以执行内嵌其中的JavaScript程序已经成为互联网的共识,这促使了网页浏览器的开发者去实现JavaScript解释器。随着JavaScript程序变得越来越复杂,解释器的效率也变得越来越高,其中使用了一些精巧、复杂的技巧,例如 "),t("strong",[t("a",{attrs:{href:"https://zh.wikipedia.org/wiki/%E5%8D%B3%E6%99%82%E7%B7%A8%E8%AD%AF",target:"_blank",rel:"noopener noreferrer"}},[a._v("即时编译(JIT)"),t("OutboundLink")],1)]),a._v(" 技术。大部分的JavaScript程序内嵌于网页,被浏览器解释执行,但是JavaScript也被用于编写苹果电脑桌面仪表板的小控件,以及控制一些软件或硬件的行为,比如Adobe Reader、Adobe Flash和一些通用的远程桌面设备。")]),a._v(" "),t("p",[a._v("不管怎样,对于一个在线教学编程书籍来说,可以被浏览器解释执行的能力使JavaScript成为了一门理想的编程语言。对JavaScript来说,通过在网页上点击执行JavaScript程序是非常自然的一件事——毕竟这就是JavaScript被设计出来的目的。从根本上来说,JavaScript拥有的语言特性使其成为了一个完美的工具,非常适合被用来学习、理解程序结构和数据结构的概念。同时也是一个完美的媒介,将程序结构和数据结构与支持它们的JavaScript语言特性联系起来。JavaScript的静态作用域、一等函数公民语言特性提供了一种简单、直接的途径来理解、应用抽象机制,动态类型则使得程序使用数据时不需要提前声明其类型。除了以上所有的考量之外,还有一点——使用JavaScript编程是很有趣的。")])])},[],!1,null,null,null);e.default=i.exports}}]); -------------------------------------------------------------------------------- /docs/chapter1.2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 1.2 Functions and the Processes They Generate | 《SICP in JavaScript》 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

1.2 Functions and the Processes They Generate


现在,我们已经见识了一些编程的要素:我们使用过基本的数学运算操作,然后将这些操作组合起来,并且通过声明复合函数来抽象这些组合后的的操作。但是,了解这些并不足以声称我们学会了如何去编程。我们现在的情况和刚学会如何移动国际象棋棋子的人一样,虽然了解基本的规则,但是对开局,策略,战术一无所知。和国际象棋初学者一样,我们还不知道编程领域中各种模式的用法。我们缺乏足够的知识去判断棋子的哪一步是值得的?(哪一个函数值得声明?)。我们缺乏足够的经验判断每一步的后果(比如,执行一个函数)。

把正在考虑的行为的结果进行可视化的能力,对于成为一名专业编程人员来说,是至关重要的,就像这种能力在其他合成性,创造性活动中的作用一样。举个例子,在成为一个专业摄影家的过程中,一个人必须学习如何观察各种景象,知道在各种可能的曝光和显影的条件[1]下,镜像中的各个区域在影像中的明暗程度。只有这样,人才能反推对于想要效果应该作的取景、 亮度、曝光、和显影行为。对于编程来说也是一样的,我们需要对于计算过程中各种动作行为作出规划和通过程序去控制其进程。为了成为一个专家,我们必须学会如何看清各种类型函数产生的计算过程。这样,我们才能学着如何去构造出可靠的程序,并使其表现出我们想要的行为。

一个函数就是相对于于计算过程局部演化的一种形式。它描述了计算过程的每一步是如何建立在上一步上。We would like to be able to make statements about the overall, or global, behavior of a process whose local evolution has been specified by a function. This is very difficult to do in general, but we can at least try to describe some typical patterns of process evolution.

在这一节里,我们将会考察一些由简单函数产生的计算过程的“形状”。我们同样会研究计算过程消耗的各种重要的时间和空间计算资源的速率。将要考察的函数是非常简单的。它们在这里扮演的角色就像是是摄影技术中测试模式:作为极度简化的摄影模式,对其来说,而非实际的例子。

[1] The textbook was written at a time when photography commonly involved photographic development, a chemical process for making paper prints from photographic film.

Last Updated: 9/5/2019, 9:58:27 AM
23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /docs/chapter1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 1 使用函数构造抽象 | 《SICP in JavaScript》 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

1 使用函数构造抽象


The acts of the mind, wherein it exerts its power over simple ideas, are chiefly these three: 1. Combining several simple ideas into one compound one, and thus all complex ideas are made. 2. The second is bringing two ideas, whether simple or complex, together, and setting them by one another so as to take a view of them at once, without uniting them into one, by which it gets all its ideas of relations. 3. The third is separating them from all other ideas that accompany them in their real existence: this is called abstraction, and thus all its general ideas are made. —— John Locke An Essay Concerning Human Understanding (1690)

我们即将学习有关 计算过程(computational process) 的概念。计算过程是一种栖息于电脑中、抽象的存在。经过演化,过程可以操控另一种被称为 数据(data) 的抽象事物。人们创建程序来指导、控制各种过程,而 程序(program) 是一种含有许多规则的形式,主导着过程的运行。从形式上看,就像我们通过自己编写的咒语控制计算机中的精灵一样。

对于一个计算过程的理解可以参照巫师如何理解小精灵。小精灵并非由物质组成的实体,它们无法被看见和触摸。但是,它们却又是实际存在的。它们能完成智力性的任务、可以回答问题,并且通过在银行付钱或者控制工厂里机器人的手臂来对世界产生实际影响。我们用来“变出”过程的程序就如同巫师们用来召唤小精灵的咒语一样。程序是由神秘、晦涩的 编程语言(programming languages) 中各种符号表达式精心构建的,它们被用来描述可以完成我们所关心任务的计算过程。

在一台正常工作的计算机里,一个计算过程会严格且准确地的执行对应的程序。因此,“菜鸟”程序员就像巫师的学徒一样,必须经过事先学习,以图理解和预测他们通过咒语使用的各种“魔法”的后果。程序中即使很微小的的错误都可能导致复杂且无法预料的后果。

幸运的是,学习编程要比学习魔法安全得多,因为我们要面对的“小精灵”被一种安全的方式保存着。不过,现实世界中的编程依然要求谨慎、专业和智慧。举个例子,一个小小的程序错误都可能导致使用计算机辅助操控的飞机发生坠机、水坝崩坏或者工业机器人产生自毁行为。

软件工程大师们掌握着高超的构建程序的能力,所以他们才能合理地确信程序产生的过程,能够正确地完成其被安排的任务。软件工程大师们能够“预视”到系统的行为,知道该怎么组织程序的结构来避免意料之外的错误以及可能导致的严重后果,并且明白当错误出现时该怎么定位、解决它们。设计优良的计算系统,就像一个设计优良的汽车或核反应堆,是采用模块化设计的,所以每一部分都可以独立地被构建、替换和除错(debug)。

使用JavaScript编程

我们需要合适的语言来描述过程,为了达成这个目的,我们将会使用编程语言JavaScript。就如我们每天会用自然语言(英语,法语,日语)来表达我们日常的想法,用数学符号来描述数量的概念,我们的过程将会使用JavaScript来描述。JavaScript产生于1990年早期,通过内嵌于网页内部作为脚本,用来控制网页浏览器的行为。这门语言由Brendan Eich设计出,开始被称为Mocha,后改为LiveScript,最终命名为JavaScript。这个名字“JavaScript”是属于Sun Microsystems公司的一个商标。

尽管JavaScript作为一门语言,其诞生时的目的是为了控制网页浏览器,但JavaScript依然是一个通用编程语言。一个JavaScript 解释器(interpreter) 就是一部用来执行由JavaScript编写的过程的机器。第一个JavaScript解释器是由Eich就职于Netscape Communications公司期间实现的,用在Netscape Navigator网页浏览器上。JavaScript的主要语言特性继承自Scheme和Self编程语言。Scheme是Lisp的一个方言,并且被当作原版《SICP》书籍的编程语言。从Scheme里,JavaScript继承了其大部分的函数式设计原则,例如静态作用域、一等函数公民和动态类型,这种继承的直接结果就是本书中的程序可以很直接、简单的从原书中的Scheme语言翻译成JavaScript语言。

JavaScript仅仅与Java在表面上有相似之处,最大的关联点就是名字中都带个Java而已。JavaScript和Java都沿用了C语言的程序块(block structure)结构。与Java和C这种编译成底层语言后执行的过程相比,JavaScript常常是被浏览器内建的解释器解释执行。在Netscape Navigator浏览器出现后,其他网页浏览器也开始提供内嵌的JavaScript解释器,包括微软的Internet Explorer浏览器(微软称其为JScript而非JavaScript)。JavaScript因为可以控制浏览器的行为而普及后,广受大众欢迎,进而引起了对JavaScript进行标准化的工作,最终产生了一个标准化的语言标准,被称为 ECMAScript。第一版的ECMAScript(ECMA 1997)标准由Guy Lewis Steele Jr. 主导制定于1997年6月。本书使用的是第六版,由Allen Wirfs-Brock主导制定,在2015年6月的ECMA大会上被接受。

网页可以执行内嵌其中的JavaScript程序已经成为互联网的共识,这促使了网页浏览器的开发者去实现JavaScript解释器。随着JavaScript程序变得越来越复杂,解释器的效率也变得越来越高,其中使用了一些精巧、复杂的技巧,例如 即时编译(JIT) 技术。大部分的JavaScript程序内嵌于网页,被浏览器解释执行,但是JavaScript也被用于编写苹果电脑桌面仪表板的小控件,以及控制一些软件或硬件的行为,比如Adobe Reader、Adobe Flash和一些通用的远程桌面设备。

不管怎样,对于一个在线教学编程书籍来说,可以被浏览器解释执行的能力使JavaScript成为了一门理想的编程语言。对JavaScript来说,通过在网页上点击执行JavaScript程序是非常自然的一件事——毕竟这就是JavaScript被设计出来的目的。从根本上来说,JavaScript拥有的语言特性使其成为了一个完美的工具,非常适合被用来学习、理解程序结构和数据结构的概念。同时也是一个完美的媒介,将程序结构和数据结构与支持它们的JavaScript语言特性联系起来。JavaScript的静态作用域、一等函数公民语言特性提供了一种简单、直接的途径来理解、应用抽象机制,动态类型则使得程序使用数据时不需要提前声明其类型。除了以上所有的考量之外,还有一点——使用JavaScript编程是很有趣的。

Last Updated: 9/5/2019, 9:58:27 AM
27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /docs/content.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 目录 | 《SICP in JavaScript》 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /docs/foreword.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 荐言 | 《SICP in JavaScript》 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

荐言

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.

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.

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 112 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 …!

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 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.

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.

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.

As one would expect from its goals, artificial intelligence research gen-e-rates 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.

By Alan J. Perlis New Haven, Connecticut

Last Updated: 9/5/2019, 9:58:27 AM
27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 目录 | 《SICP in JavaScript》 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /docs/prefaces.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 前言 | 《SICP in JavaScript》 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

前言

Preface of JavaScript Adaptation

You are reading the textbook Structure and Interpretation of Computer Programs by Harold Abelson and Gerald Sussman—with a twist. The textbook emphasizes the importance of abstraction for managing complexity, and introduces the reader to a host of concepts that lie at the heart of the field of computer science. Most of these ideas are independent of the programming language used to express them to employ actual computers for solving computational problems. They are programming-language independent. The twist then consists of replacing the programming language that is used in the examples. While the authors had used the programming language Scheme, this adaptation uses the language JavaScript.

More precisely, this adaptation uses five tiny, carefully designed, sublanguages of JavaScript. The languages are called Source §1, Source §2, Source §3, Source §4 and Source §5, corresponding to the respective chapters 1, 2, 3, 4 and 5 of the textbook. The Source §1 language contains only constructs that are needed in the programs contained in chapter 1: constructs required to build abstractions with functions. Source §2 is a superset of Source §1; adding features required to build abstractions with data, on top of the features of Source §1. Similarly, Source §3, 4 and 5 extend the previous language features required to address the subject of the respective textbook chapter. All these languages are sub-languages of JavaScript; any Source program is also a JavaScript program. The reverse is not true. The JavaScript language has many features that are not covered in this textbook. Indeed, the Source languages are so small that they can be quite adquately described in a few pages of text. The online folder source contains the specifications of the Source languages, as reference for the reader.

This textbook is interactive. Most programs are links. Clicking on them takes the reader to a web-based programming environment called the Source Academy. In the Source Academy, the reader can run the programs, modify them and experiment with them, without the need to install any software, and without any requirements on the computer that they use, as long as it comes with an internet browser.

The language Scheme has been designed as a sublanguage of Lisp with its use in education as a central design objective. The language JavaScript, on the other hand, was not designed with the needs of learners in mind. This makes it difficult to use JavaScript in a course, even if one imposes constraints on the language features to be covered. The reason is that students with prior knowledge of the language are bound to make use of other features in their programs. Fellow students will legitimately ask the instructors about those features, and any answer will either frustate the student or lead to a tangent that is most likely not conducive to the learning objectives. This problem is especially severe for JavaScript, which is not known for its systematic design. Our solution to this challenge is radical: The Source Academy enforces the use of the respective Source language when the student clicks on a program of a particular chapter. Programs that use constructs beyond that language are rejected by the Source Academy. This allows instructors of a SICP-based course to adopt JavaScript—one of the most widely used programming languages today—without getting bogged down in JavaScript's plethora of idiosyncratic features.

The original textbook was introduced to the National University of Singapore by Jacob Katzenelson in 1997, as a more advanced alternative to the regular Programming Methodology course offered to computer science students. The course, known as CS1101S since 1998, switched to JavaScript in 2012, and became the required freshmen programming methodology course for Computer Science undergraduate majors in 2018.

—— Martin Henz

Preface to the Second Edition

Is it possible that software is not like anything else, that it is meant to be discarded: that the whole point is to always see it as a soap bubble? 19 | —— Alan J. Perlis

The material in this book has been the basis of MIT's entry-level computer science subject since 1980. We had been teaching this material for four years when the first edition was published, and twelve more years have elapsed until the appearance of this second edition. We are pleased that our work has been widely adopted and incorporated into other texts. We have seen our students take the ideas and programs in this book and build them in as the core of new computer systems and languages. In literal realization of an ancient Talmudic pun, our students have become our builders. We are lucky to have such capable students and such accomplished builders.

In preparing this edition, we have incorporated hundreds of clarifications suggested by our own teaching experience and the comments of colleagues at MIT and elsewhere. We have redesigned most of the major programming systems in the book, including the generic-arithmetic system, the interpreters, the register-machine simulator, and the compiler; and we have rewritten all the program examples to ensure that any Scheme implementation conforming to the IEEE Scheme standard (IEEE 1990) will be able to run the code.

This edition emphasizes several new themes. The most important of these is the central role played by different approaches to dealing with time in computational models: objects with state, concurrent programming, functional programming, lazy evaluation, and nondeterministic programming. We have included new sections on concurrency and nondeterminism, and we have tried to integrate this theme throughout the book.

The first edition of the book closely followed the syllabus of our MIT one-semester subject. With all the new material in the second edition, it will not be possible to cover everything in a single semester, so the instructor will have to pick and choose. In our own teaching, we sometimes skip the section on logic programming (section ), we have students use the register-machine simulator but we do not cover its implementation (section ), and we give only a cursory overview of the compiler (section ). Even so, this is still an intense course. Some instructors may wish to cover only the first three or four chapters, leaving the other material for subsequent courses.

The World-Wide-Web site of MIT Press provides support for users of this book. This includes programs from the book, sample programming assignments, supplementary materials, and downloadable implementations of the Scheme dialect of Lisp.

—— Harold Abelson and Gerald Jay Sussman

Preface to the First Edition

A computer is like a violin. You can imagine a novice trying first a phonograph and then a violin. The latter, he says, sounds terrible. That is the argument we have heard from our humanists and most of our computer scientists. Computer programs are good, they say, for particular purposes, but they aren't flexible. Neither is a violin, or a typewriter, until you learn how to use it. 20 | —— Marvin Minsky, "Why Programming Is a Good Medium for Expressing Poorly-Understood and Sloppily-Formulated Ideas"

"The Structure and Interpretation of Computer Programs" is the entry-level subject in computer science at the Massachusetts Institute of Technology. It is required of all students at MIT who major in electrical engineering or in computer science, as one-fourth of the "common core curriculum", which also includes two subjects on circuits and linear systems and a subject on the design of digital systems. We have been involved in the development of this subject since 1978, and we have taught this material in its present form since the fall of 1980 to between 600 and 700 students each year. Most of these students have had little or no prior formal training in computation, although many have played with computers a bit and a few have had extensive programming or hardware-design experience.

Our design of this introductory computer-science subject reflects two major concerns. First, we want to establish the idea that a computer language is not just a way of getting a computer to perform operations but rather that it is a novel formal medium for expressing ideas about methodology. Thus, programs must be written for people to read, and only incidentally for machines to execute. Second, we believe that the essential material to be addressed by a subject at this level is not the syntax of particular programming-language constructs, nor clever algorithms for computing particular functions efficiently, nor even the mathematical analysis of algorithms and the foundations of computing, but rather the techniques used to control the intellectual complexity of large software systems.

Our goal is that students who complete this subject should have a good feel for the elements of style and the aesthetics of programming. They should have command of the major techniques for controlling complexity in a large system. They should be capable of reading a 50-page-long program, if it is written in an exemplary style. They should know what not to read, and what they need not understand at any moment. They should feel secure about modifying a program, retaining the spirit and style of the original author.

These skills are by no means unique to computer programming. The techniques we teach and draw upon are common to all of engineering design. We control complexity by building abstractions that hide details when appropriate. We control complexity by establishing conventional interfaces that enable us to construct systems by combining standard, well-understood pieces in a mix and match way. We control complexity by establishing new languages for describing a design, each of which emphasizes particular aspects of the design and deemphasizes others.

Underlying our approach to this subject is our conviction that computer science is not a science and that its significance has little to do with computers. The computer revolution is a revolution in the way we think and in the way we express what we think. The essence of this change is the emergence of what might best be called procedural epistemology—the study of the structure of knowledge from an imperative point of view, as opposed to the more declarative point of view taken by classical mathematical subjects. Mathematics provides a framework for dealing precisely with notions of what is. Computation provides a framework for dealing precisely with notions of how to.

In teaching our material we use a dialect of the programming language Lisp. We never formally teach the language, because we don't have to. We just use it, and students pick it up in a few days. This is one great advantage of Lisp-like languages: They have very few ways of forming compound expressions, and almost no syntactic structure. All of the formal properties can be covered in an hour, like the rules of chess. After a short time we forget about syntactic details of the language (because there are none) and get on with the real issues—figuring out what we want to compute, how we will decompose problems into manageable parts, and how we will work on the parts. Another advantage of Lisp is that it supports (but does not enforce) more of the large-scale strategies for modular decomposition of programs than any other language we know. We can make procedural and data abstractions, we can use higher-order functions to capture common patterns of usage, we can model local state using assignment and data mutation, we can link parts of a program with streams and delayed evaluation, and we can easily implement embedded languages. All of this is embedded in an interactive environment with excellent support for incremental program design, construction, testing, and debugging. We thank all the generations of Lisp wizards, starting with John McCarthy, who have fashioned a fine tool of unprecedented power and elegance.

Scheme, the dialect of Lisp that we use, is an attempt to bring together the power and elegance of Lisp and Algol. From Lisp we take the metalinguistic power that derives from the simple syntax, the uniform representation of programs as data objects, and the garbage-collected heap-allocated data. From Algol we take lexical scoping and block structure, which are gifts from the pioneers of programming-language design who were on the Algol committee. We wish to cite John Reynolds and Peter Landin for their insights into the relationship of Church's lambda calculus to the structure of programming languages. We also recognize our debt to the mathematicians who scouted out this territory decades before computers appeared on the scene. These pioneers include Alonzo Church, Barkley Rosser, Stephen Kleene, and Haskell Curry.

—— Harold Abelson and Gerald Jay Sussman

Last Updated: 9/5/2019, 9:58:27 AM
29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sicp-javascript-zh", 3 | "version": "1.0.0", 4 | "description": "原文:[Structure and Interpretation of Computer Programs JavaScript Adaptation](https://sicp.comp.nus.edu.sg/)", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "dev": "vuepress dev book", 9 | "build": "vuepress build book", 10 | "build:commit": "npm run build && git add -A && git commit -m 'build docs' ", 11 | "b:c": "npm run build:commit" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/iheyunfei/sicp-javascript-zh.git" 16 | }, 17 | "keywords": [], 18 | "author": "", 19 | "license": "ISC", 20 | "bugs": { 21 | "url": "https://github.com/iheyunfei/sicp-javascript-zh/issues" 22 | }, 23 | "homepage": "https://github.com/iheyunfei/sicp-javascript-zh#readme", 24 | "devDependencies": { 25 | "vuepress": "^1.0.3" 26 | } 27 | } 28 | --------------------------------------------------------------------------------