代码拉取完成,页面将自动刷新
1
00:00:01,100 --> 00:00:04,500
哈尔滨工业大学 IBM技术中心
倾情制作
2
00:00:04,600 --> 00:00:09,400
压制&&特效:蔡钟敏(Tacitus)
字幕&&时间轴:邓雄飞(Dysprosium)
3
00:00:09,500 --> 00:00:13,000
特别感谢:裘宗燕
4
00:00:14,264 --> 00:00:17,440
欢迎大家来一起学习这门计算机科学的基础课程
I'd like to welcome you to this course on computer science.
5
00:00:27,952 --> 00:00:29,408
事实上 以这样的方式来表述并不恰当
Actually, that's a terrible way to start.
6
00:00:29,408 --> 00:00:31,890
于此来说 计算机科学是个糟糕的名字
Computer science is a terrible name for this business.
7
00:00:32,384 --> 00:00:33,856
首先 它不算是一门科学
First of all, it's not a science.
8
00:00:35,472 --> 00:00:39,020
它更应该被称为工程或者是艺术
It might be engineering or it might be art,
9
00:00:39,648 --> 00:00:42,464
但我们实际上会发现 这个所谓的计算机科学
but we'll actually see that computer so-called science
10
00:00:42,480 --> 00:00:44,528
却与魔法一样的有众多神奇之处
actually has a lot in common with magic,
11
00:00:44,560 --> 00:00:45,904
这些将会在课程中一一体现
and we'll see that in this course.
12
00:00:46,832 --> 00:00:47,776
所以 不能称其为一门科学
So it's not a science.
13
00:00:48,648 --> 00:00:51,854
这门学科和“计算机”也并非紧密相关
It's also not really very much about computers.
14
00:00:52,944 --> 00:00:55,024
类似的 就像我们说
And it's not about computers in the same sense
15
00:00:55,024 --> 00:00:59,600
物理学中并不仅仅有关粒子加速器
that physics is not really about particle accelerators,
16
00:01:00,352 --> 00:01:05,136
生物学中并不全然是显微镜和培养皿一样
and biology is not really about microscopes and petri dishes.
17
00:01:06,010 --> 00:01:09,800
同理
And it's not about computers in the same sense
18
00:01:09,860 --> 00:01:14,432
几何学中也并不全是介绍如何使用测量仪器
that geometry is not really about using surveying instruments.
19
00:01:16,032 --> 00:01:18,560
事实上 计算机科学和几何学
In fact, there's a lot of commonality
20
00:01:18,880 --> 00:01:21,000
有很多共性
between computer science and geometry.
21
00:01:21,000 --> 00:01:22,213
首先 几何学
Geometry, first of all,
22
00:01:22,579 --> 00:01:24,535
只是另一个有个糟糕名字的学科
is another subject with a lousy name.
23
00:01:25,136 --> 00:01:27,400
这个名字来自于Gaia 意为土地
The name comes from Gaia, meaning the Earth,
24
00:01:27,450 --> 00:01:28,640
以及metron 意为测量
and metron, meaning to measure.
25
00:01:29,376 --> 00:01:32,944
几何学最初意为测地或者勘探
Geometry originally meant measuring the Earth or surveying.
26
00:01:33,920 --> 00:01:36,440
这是因为数千年前的埃及祭司
And the reason for that was that, thousands of years ago,
27
00:01:37,248 --> 00:01:41,248
为了计算如何去修复年年被尼罗河的洪水
the Egyptian priesthood developed the rudiments of geometry
28
00:01:42,144 --> 00:01:45,888
所毁坏的牧田边界
in order to figure out how to restore the boundaries of fields
29
00:01:45,888 --> 00:01:45,904
而建立了几何学基础
that were destroyed in the annual flooding of the Nile.
30
00:01:45,904 --> 00:01:48,240
而建立了几何学基础
that were destroyed in the annual flooding of the Nile.
31
00:01:49,024 --> 00:01:50,208
而对出于这个目的的埃及人来说
And to the Egyptians who did that,
32
00:01:50,208 --> 00:01:53,488
几何学的确是掌握对测量仪器的使用
geometry really was the use of surveying instruments.
33
00:01:55,184 --> 00:01:58,100
现在 我们以为计算机科学就是介绍计算机的使用
Now, the reason that we think computer science is about computers
34
00:01:58,120 --> 00:02:02,048
就正如埃及人认为
is pretty much the same reason that the Egyptians thought geometry
35
00:02:02,064 --> 00:02:03,650
几何学是介绍如何使用测量仪器的
was about surveying instruments.
36
00:02:04,140 --> 00:02:06,928
换句话说 任何一门学科起步的时候
And that is, when some field is just getting started
37
00:02:06,940 --> 00:02:09,410
你都对它了解不深
and you don't really understand it very well,
38
00:02:10,656 --> 00:02:16,192
这很容易使你混淆所做的事与所用之物
it's very easy to confuse the essence of what you're doing with the tools that you use.
39
00:02:17,200 --> 00:02:19,856
确实 就绝对规模来说
And indeed, on some absolute scale of things,
40
00:02:19,856 --> 00:02:24,370
我们对计算机科学的实质的了解
we probably know less about the essence of computer science
41
00:02:24,384 --> 00:02:27,040
比埃及人对几何学的了解还少
than the ancient Egyptians really knew about geometry.
42
00:02:29,808 --> 00:02:32,192
那么 我所谓的计算机科学的本质是什么呢
Well, what do I mean by the essence of computer science?
43
00:02:32,208 --> 00:02:33,960
我所谓的几何学本质又是什么呢
What do I mean by the essence of geometry?
44
00:02:33,968 --> 00:02:36,000
看 可以确认的是 古埃及人确实使用测量仪器
See, it's certainly true that these Egyptians went off
45
00:02:36,016 --> 00:02:37,220
并且已经消失多年
and used surveying instruments,
46
00:02:37,248 --> 00:02:41,104
但当我们在几千年后回过头来重新审视这段历史
but when we look back on them after a couple of thousand years,
47
00:02:41,120 --> 00:02:41,408
我们会说
we say,
48
00:02:41,424 --> 00:02:43,190
天啊 看他们在做什么
gee, what they were doing,
49
00:02:43,264 --> 00:02:45,030
他们的工作是多么的重要
the important stuff they were doing,
50
00:02:45,170 --> 00:02:50,000
已经开始对时间和空间进行形式化表述
was to begin to formalize notions about space and time,
51
00:02:51,136 --> 00:02:57,080
并归纳出一套讨论数学真理的形式化方法
to start a way of talking about mathematical truths formally.
52
00:02:57,568 --> 00:02:59,168
这直接导致了公理化方法
That led to the axiomatic method.
53
00:02:59,168 --> 00:03:02,080
以及各种现代数学的产生
That led to sort of all of modern mathematics,
54
00:03:03,712 --> 00:03:06,450
同时也指明了一种精确讨论
figuring out a way to talk precisely about
55
00:03:06,800 --> 00:03:09,740
所谓的描述真理的陈述性知识的方法
so-called declarative knowledge, what is true.
56
00:03:12,000 --> 00:03:15,808
与此相似的 我认为未来人们会回过头来审视并说
Well, similarly, I think in the future people will look back and say,
57
00:03:15,824 --> 00:03:18,912
啊 这些20世纪的原始人
yes, those primitives in the 20th century were fiddling around
58
00:03:18,912 --> 00:03:20,750
不务正业地玩弄着叫计算机的小玩意
with these gadgets called computers,
59
00:03:21,328 --> 00:03:25,800
但它们真正在做的是开始学习
but really what they were doing is starting to learn
60
00:03:25,808 --> 00:03:32,100
如何去对计算过程进行形式化表述
how to formalize intuitions about process,
61
00:03:32,192 --> 00:03:33,680
如何去解决问题
how to do things,
62
00:03:38,576 --> 00:03:50,800
并结合两者发展一套对问题处理过程精确表述的方法
starting to develop a way to talk precisely about how-to knowledge,
63
00:03:51,312 --> 00:03:55,580
这与讨论真理的几何学形成了对照
as opposed to geometry that talks about what is true.
64
00:03:56,080 --> 00:03:58,120
让我给你们举个例子吧
Let me give you an example of that.
65
00:04:01,856 --> 00:04:02,240
来瞧瞧
Let's take a look
66
00:04:02,256 --> 00:04:09,376
数学中是这样来定义平方根的:
Here is a piece of mathematics that says what a square root is.
67
00:04:09,648 --> 00:04:13,900
定义X的平方根Y是这样一个数
The square root of X is the number Y,
68
00:04:15,536 --> 00:04:19,936
Y的平方等于X 且Y大于等于0
such that Y squared is equal to X and Y is greater than 0.
69
00:04:19,984 --> 00:04:22,050
这是一个很好的定义
Now, that's a fine piece of mathematics,
70
00:04:22,432 --> 00:04:24,800
但它只告诉了你平方根是什么
but just telling you what a square root is
71
00:04:25,184 --> 00:04:29,840
却没有告诉你如何去求取一个平方根
doesn't really say anything about how you might go out and find one.
72
00:04:30,976 --> 00:04:35,456
那么我们将其与一条指令性知识做比较
So let's contrast that with a piece of imperative knowledge,
73
00:04:36,688 --> 00:04:39,472
你如何去求取一个平方根
how you might go out and find a square root.
74
00:04:39,504 --> 00:04:45,296
事实上 这来自于埃及 不太久远的埃及
This, in fact, also comes from Egypt, not ancient, ancient Egypt.
75
00:04:45,310 --> 00:04:48,430
亚历山大的Heron提出的一个算法
This is an algorithm due to Heron of Alexandria,
76
00:04:49,456 --> 00:04:52,320
称作连续取均值求平方根法
called how to find a square root by successive averaging.
77
00:04:52,448 --> 00:04:54,688
这个算法是说
And what it says is that,
78
00:04:54,704 --> 00:04:57,616
为了算出平方根
in order to find a square root,
79
00:05:02,896 --> 00:05:07,880
首先你应该给出一个猜测值guess 并不断改进
you make a guess, you improve that guess --
80
00:05:09,744 --> 00:05:10,992
改进的方法是通过
and the way you improve the guess
81
00:05:11,008 --> 00:05:13,500
不断求猜测值guess与X/guess的平均值
is to average the guess and X over the guess,
82
00:05:13,968 --> 00:05:15,152
我们稍后将会讨论
and we'll talk a little bit later about
83
00:05:15,168 --> 00:05:16,670
为什么这是合理的
why that's a reasonable thing--
84
00:05:16,690 --> 00:05:18,920
通过不断改进 直到它足够精确
and you keep improving the guess until it's good enough.
85
00:05:19,280 --> 00:05:20,400
这就是实现方法
That's a method.
86
00:05:20,540 --> 00:05:24,208
这也是如何完成一项工作与
That's how to do something as opposed to
87
00:05:24,272 --> 00:05:26,880
其对应的陈述性知识的对照
declarative knowledge that says what you're looking for.
88
00:05:27,600 --> 00:05:29,310
这就是一个过程
That's a process.
89
00:05:33,952 --> 00:05:37,808
那么 通常来说什么是过程呢?
Well, what's a process in general?
90
00:05:38,560 --> 00:05:39,690
这定义起来非常困难
It's kind of hard to say.
91
00:05:39,712 --> 00:05:43,270
你可以将它象征性地看成一个活在计算机内
You can think of it as like a magical spirit
92
00:05:44,320 --> 00:05:46,880
并且可以完成一些操作的精灵
that sort of lives in the computer and does something.
93
00:05:47,568 --> 00:05:53,664
一些被称为程序的规则模式
And the thing that directs a process is
94
00:05:53,680 --> 00:05:57,530
指导着这类过程的进行
a pattern of rules called a procedure.
95
00:06:01,536 --> 00:06:04,280
程序可以被认为是符咒
So procedures are the spells, if you like,
96
00:06:04,784 --> 00:06:08,950
使用程序来控制这些精灵完成一些操作就叫做过程
that control these magical spirits that are the processes.
97
00:06:10,304 --> 00:06:12,304
你们知道人人都需要一门魔法语言
I guess you know everyone needs a magical language,
98
00:06:12,320 --> 00:06:14,100
那些魔术师 真正的魔术师 用远古的阿卡狄亚语
and sorcerers, real sorcerers,
99
00:06:14,128 --> 00:06:18,140
或者苏美尔语 或者巴比伦语 或者其它的
use ancient Arcadian or Sumerian or Babylonian or whatever.
100
00:06:18,176 --> 00:06:19,640
而我们将用一门叫Lisp的魔法语言
We're going to conjure our spirits
101
00:06:19,680 --> 00:06:22,260
来召唤出我们的精灵
in a magical language called Lisp,
102
00:06:23,920 --> 00:06:27,568
这门语言是被设计用来
which is a language designed for talking about,
103
00:06:28,128 --> 00:06:31,390
编写如咒语版的程序 来指导过程的进行
for casting the spells that are procedures to direct the processes.
104
00:06:31,424 --> 00:06:33,460
学习Lisp非常容易
Now, it's very easy to learn Lisp.
105
00:06:33,520 --> 00:06:35,536
事实上 我会在几分钟内教会你
In fact, in a few minutes, I'm going to teach you,
106
00:06:35,552 --> 00:06:36,710
整个Lisp
essentially, all of Lisp.
107
00:06:36,926 --> 00:06:38,515
及其所有的规则
I'm going to teach you, essentially, all of the rules.
108
00:06:40,320 --> 00:06:43,200
你不必感到很惊讶
And you shouldn't find that particularly surprising.
109
00:06:43,240 --> 00:06:45,424
这就像你在学习象棋时
That's sort of like saying it's very easy
110
00:06:45,456 --> 00:06:46,560
认为象棋的规则十分简单一样
to learn the rules of chess.
111
00:06:46,592 --> 00:06:47,680
事实也如此 几分钟内
And indeed, in a few minutes,
112
00:06:47,728 --> 00:06:49,250
你可以与任何人谈论象棋的规则
you can tell somebody the rules of chess.
113
00:06:50,368 --> 00:06:51,792
但是 这全然不等同于说
But of course, that's very different from
114
00:06:51,808 --> 00:06:54,928
你所知道这些规则所蕴含的东西
saying you understand the implications of those rules
115
00:06:54,970 --> 00:06:57,600
以及如何利用这些规则去成为象棋大师
and how to use those rules to become a masterful chess player.
116
00:06:58,048 --> 00:06:59,370
Lisp也是如此
Well, Lisp is the same way.
117
00:06:59,968 --> 00:07:01,730
我将在几分钟内道清规则
We're going to state the rules in a few minutes,
118
00:07:01,910 --> 00:07:03,104
这说起来非常容易
and it'll be very easy to see.
119
00:07:03,170 --> 00:07:06,640
但真正困难的是如何运用这些规则
But what's really hard is going to be the implications of those rules,
120
00:07:06,870 --> 00:07:10,010
以及你如何利用这些规则成为编程大师
how you exploit those rules to be a master programmer.
121
00:07:11,610 --> 00:07:14,848
这些规则的应用将占据我们
And the implications of those rules are going to take us the,
122
00:07:14,860 --> 00:07:18,110
余下的课程 甚至更多
well, the whole rest of the subject and, of course, way beyond.
123
00:07:21,008 --> 00:07:22,660
所以 在计算机科学中
OK, so in computer science,
124
00:07:24,048 --> 00:07:25,744
我们的任务则是
we're in the business of
125
00:07:25,760 --> 00:07:30,130
形式化这种如有关“怎么做”的指令性知识
formalizing this sort of how-to imperative knowledge,
126
00:07:30,176 --> 00:07:31,650
并将之付诸实际
how to do stuff.
127
00:07:32,928 --> 00:07:34,944
这也便是计算机科学的真正的议题
And the real issues of computer science are, of course,
128
00:07:34,960 --> 00:07:37,910
当然 并不是告诉人们如何去求平方根
not telling people how to do square roots.
129
00:07:38,640 --> 00:07:39,616
因为如果那是计算机科学的全部的的话
Because if that was all it was,
130
00:07:39,648 --> 00:07:40,896
就不会有什么大问题了
there wouldn't be no big deal.
131
00:07:41,120 --> 00:07:43,600
真正的问题来自于当我们尝试
The real problems come when we try to
132
00:07:43,632 --> 00:07:45,710
构建非常非常大的系统时
build very, very large systems,
133
00:07:46,160 --> 00:07:49,080
程序可能会长达数千页
computer programs that are thousands of pages long,
134
00:07:49,136 --> 00:07:53,536
长得没有人能马上将其装入脑中
so long that nobody can really hold them in their heads all at once.
135
00:07:54,288 --> 00:07:58,360
而使这些得以实现则是因为
And the only reason that that's possible is because
136
00:07:58,410 --> 00:08:18,528
我们有在大系统中控制复杂度的技术
there are techniques for controlling the complexity of these large systems.
137
00:08:19,850 --> 00:08:22,240
这些控制复杂度的技术
And these techniques that are controlling complexity
138
00:08:22,272 --> 00:08:23,728
正是我们课程所讨论的
are what this course is really about.
139
00:08:24,208 --> 00:08:25,024
从某种意义上来说
And in some sense,
140
00:08:25,056 --> 00:08:27,020
这也正是计算机科学的关键所在
that's really what computer science is about.
141
00:08:29,180 --> 00:08:31,440
这样说听起来或许很奇怪
Now, that may seem like a very strange thing to say.
142
00:08:31,472 --> 00:08:35,168
毕竟 除了计算机科学家外
Because after all, a lot of people besides computer scientists
143
00:08:35,200 --> 00:08:37,370
仍然有很多人在做复杂度控制相关的工作
deal with controlling complexity.
144
00:08:37,390 --> 00:08:40,570
一个航班就是一个非常复杂的系统
A large airliner is an extremely complex system,
145
00:08:41,376 --> 00:08:43,344
设计它的航空工程师
and the aeronautical engineers who design that
146
00:08:43,600 --> 00:08:45,680
便在处理这个巨大的复杂度
are dealing with immense complexity.
147
00:08:46,640 --> 00:08:49,740
但这种复杂度又与
But there's a difference between that kind of complexity
148
00:08:50,304 --> 00:08:52,150
计算机科学中的(复杂度)有别
and what we deal with in computer science.
149
00:08:54,736 --> 00:08:57,280
从某种意义上来说
And that is that computer science,
150
00:08:57,344 --> 00:08:59,648
因为计算机科学不是“现实”的
in some sense, isn't real.
151
00:09:02,240 --> 00:09:06,170
例如 当一名工程师设计物理系统时
You see, when an engineer is designing a physical system,
152
00:09:06,690 --> 00:09:08,040
这些都是由实在的物理部件构成
that's made out of real parts.
153
00:09:08,950 --> 00:09:10,736
负责的该工作的工程师
The engineers who worry about that
154
00:09:11,400 --> 00:09:16,208
就得对付系统中的公差、近似值以及噪声
have to address problems of tolerance and approximation and noise in the system.
155
00:09:16,224 --> 00:09:18,576
譬如说 作为一名电气工程师
So for example, as an electrical engineer,
156
00:09:18,640 --> 00:09:21,264
可以很容易的做一个单极放大器
I can go off and easily build a one-stage amplifier
157
00:09:21,280 --> 00:09:22,580
或者是一个双极放大器
or a two-stage amplifier,
158
00:09:22,960 --> 00:09:24,944
也可想象将其大量串联
and I can imagine cascading a lot of them
159
00:09:25,008 --> 00:09:26,464
来建造一个百万极的放大器
to build a million-stage amplifier.
160
00:09:26,540 --> 00:09:28,304
但这样做是不可行的
But it's ridiculous to build such a thing,
161
00:09:28,530 --> 00:09:31,700
因为在远没到百万数量级的时候
because long before the millionth stage,
162
00:09:31,710 --> 00:09:34,112
这种组合方法打从头产生的热噪声
the thermal noise in those components way at the beginning
163
00:09:34,120 --> 00:09:36,352
会慢慢增强 并使得我们的幸苦付之一炬
is going to get amplified and make the whole thing meaningless.
164
00:09:38,650 --> 00:09:42,670
计算机科学处理的是理想化组件
Computer science deals with idealized components.
165
00:09:43,670 --> 00:09:47,184
我们对将要结合在一起的
We know as much as we want about these little program
166
00:09:47,200 --> 00:09:49,110
程序和数据了如指掌
and data pieces that we're fitting things together.
167
00:09:51,456 --> 00:09:52,752
我们不需要去关心公差
We don't have to worry about tolerance.
168
00:09:52,760 --> 00:09:56,540
也就是说 在构建大系统时
And that means that, in building a large program,
169
00:09:57,680 --> 00:09:59,580
在我理想和现实之间
there's not all that much difference
170
00:09:59,900 --> 00:10:03,730
并不没有太大的不同
between what I can build and what I can imagine,
171
00:10:05,088 --> 00:10:07,152
因为这些部分都是抽象单元
because the parts are these abstract entities
172
00:10:07,184 --> 00:10:09,872
可以随心所欲的组合
that I know as much as I want.
173
00:10:09,888 --> 00:10:11,940
可以据目前所知而自由构建
I know about them as precisely as I'd like.
174
00:10:13,008 --> 00:10:15,050
就是与其它的工程不同之处
So as opposed to other kinds of engineering,
175
00:10:15,210 --> 00:10:16,976
(在其它的工程中)对你所构建系统的约束
where the constraints on what you can build
176
00:10:16,990 --> 00:10:18,450
来自于物理系统以及
are the constraints of physical systems,
177
00:10:18,490 --> 00:10:20,576
物理定律 噪声 近似值等
the constraints of physics and noise and approximation,
178
00:10:20,760 --> 00:10:25,152
而建立大型软件系统时所施加的约束
the constraints imposed in building large software systems
179
00:10:25,190 --> 00:10:27,130
就是对我们大脑的限制
are the limitations of our own minds.
180
00:10:28,670 --> 00:10:29,536
从这个角度来看
So in that sense,
181
00:10:29,550 --> 00:10:33,220
计算机科学就像是工程中的一种抽象形式
computer science is like an abstract form of engineering.
182
00:10:33,350 --> 00:10:35,280
在这种工程中 我们忽略
It's the kind of engineering where you ignore
183
00:10:35,310 --> 00:10:37,570
现实所施加的约束
the constraints that are imposed by reality.
184
00:10:41,520 --> 00:10:45,700
那么 这其中有哪些技术呢
Well, what are some of these techniques?
185
00:10:45,830 --> 00:10:47,940
计算机科学中并没有特别的技术
They're not special to computer science.
186
00:10:49,940 --> 00:10:52,100
第一个技术是在很多工程中都使用的
First technique, which is used in all of engineering,
187
00:10:52,910 --> 00:10:58,464
被称为“黑盒抽象”的方法
is a kind of abstraction called black-box abstraction.
188
00:11:07,264 --> 00:11:12,130
即将一些东西组合并封装起来
Take something and build a box about it.
189
00:11:13,920 --> 00:11:19,648
以之前我们提到的求取平方根的方法为例
Let's see, for example, if we looked at that square root method,
190
00:11:22,190 --> 00:11:28,080
我将这些操作视为一个“盒子”
I might want to take that and build a box.
191
00:11:29,440 --> 00:11:37,072
也就是说 为了找到X的平方根
That sort of says, to find the square root of X.
192
00:11:38,416 --> 00:11:40,820
或许会有一系列的复杂规则
And that might be a whole complicated set of rules.
193
00:11:42,192 --> 00:11:46,240
我们将规则封装 输入数据即可获得结果
And that might end up being a kind of thing where I can put in,
194
00:11:46,368 --> 00:11:49,610
比如说 输入36 然后说36的平方根是多少呢
say, 36 and say, what's the square root of 36?
195
00:11:49,808 --> 00:11:51,010
则给出结果 6
And out comes 6.
196
00:11:53,440 --> 00:11:55,776
重点是
And the important thing is that
197
00:11:55,790 --> 00:11:59,584
通过这样的设计
I'd like to design that so that
198
00:11:59,612 --> 00:12:03,633
可以方便他人的使用
if George comes along and would like to compute,
199
00:12:04,656 --> 00:12:08,928
例如Goerge想计算A的平方根加上B的平方根
say, the square root of A plus the square root of B,
200
00:12:10,896 --> 00:12:13,936
他无需了解“盒子”内部的构成
he can take this thing and use it as a module
201
00:12:13,984 --> 00:12:15,296
而直接可以以模块的形式使用它
without having to look inside
202
00:12:15,328 --> 00:12:16,864
也可以利用它去构建新的“盒子”
and build something that looks like this,
203
00:12:18,000 --> 00:12:23,750
例如构建一个 A和B以及一个平方根和或者另一个平方根盒子
like an A and a B and a square root box and another square root box
204
00:12:24,080 --> 00:12:33,420
然后将这些结果加在一起并输出答案
and then something that adds that would put out the answer.
205
00:12:33,510 --> 00:12:37,700
如你所见 就我想实现的功能的层面来看
And you can see, just from the fact that I want to do that,
206
00:12:38,470 --> 00:12:39,970
对于George来说
is from George's point of view,
207
00:12:40,060 --> 00:12:42,650
盒子内部是什么样并不重要
the internals of what's in here should not be important.
208
00:12:43,740 --> 00:12:46,800
例如 以下这些说法都没什么问题
So for instance, it shouldn't matter that, when I wrote this,
209
00:12:46,820 --> 00:12:49,984
我说求X的平方根
I said I want to find the square root of X.
210
00:12:50,160 --> 00:12:51,820
也可以说计算Y的平方根
I could have said the square root of Y,
211
00:12:52,272 --> 00:12:55,170
或者其它任何数的平方根
or the square root of A, or anything at all
212
00:12:56,256 --> 00:13:01,904
黑盒抽象的基本规则是
That's the fundamental notion of putting something in a box
213
00:13:03,088 --> 00:13:05,990
将处理过程放入盒子里以隐藏细节
using black-box abstraction to suppress detail.
214
00:13:07,152 --> 00:13:10,540
这样做的原因则是你可以脱身去构建更大的盒子
And the reason for that is you want to go off and build bigger boxes.
215
00:13:11,600 --> 00:13:14,128
现在 除了隐藏细节外
Now, there's another reason for doing black-box abstraction
216
00:13:14,140 --> 00:13:17,968
使用黑盒抽象还有另外一个原因
other than you want to suppress detail for building bigger boxes.
217
00:13:18,030 --> 00:13:24,576
有的时候 你想要用你的方法去完成一件事
Sometimes you want to say that your way of doing something,
218
00:13:24,590 --> 00:13:26,430
你的方法
your how-to method,
219
00:13:27,990 --> 00:13:30,340
就是一个通法的具体实例
is an instance of a more general thing,
220
00:13:30,710 --> 00:13:34,120
同时 你也希望你的表述方式能够具有普遍性
and you'd like your language to be able to express that generality.
221
00:13:35,120 --> 00:13:37,488
我们接着用实例来说明
Let me show you another example
222
00:13:37,520 --> 00:13:38,416
继续刚才关于平方根的讨论
sticking with square roots.
223
00:13:38,448 --> 00:13:41,712
让我们回过头再来看看
Let's go back and take another look at that slide
224
00:13:41,744 --> 00:13:43,300
求平方根的算法
with the square root algorithm on it.
225
00:13:43,712 --> 00:13:45,170
想一想之前是怎么说的
Remember what that says.
226
00:13:45,344 --> 00:13:49,376
为了求解 首先要作出猜测
That says, in order to do something, I make a guess,
227
00:13:50,176 --> 00:13:54,390
然后基于这个猜测 做出持续不断的改进
and I improve that guess, and I sort of keep improving that guess.
228
00:13:55,216 --> 00:13:59,690
因此就存在一个找到某个到结果的通用方法
So there's the general strategy of, I'm looking for something,
229
00:14:00,704 --> 00:14:03,550
就是持续不断地改进结果
and the way I find it is that I keep improving it.
230
00:14:03,712 --> 00:14:09,800
求取不动点的方法有很多
Now, that's a particular case of another kind of strategy
231
00:14:10,528 --> 00:14:12,780
这种方法只是其中的一个特例
for finding a fixed point of something.
232
00:14:14,128 --> 00:14:16,140
每个函数都有一个不动点
So you have a fixed point of a function.
233
00:14:16,688 --> 00:14:25,580
函数的不动点是一个值
A fixed point of a function is something, is a value.
234
00:14:25,680 --> 00:14:31,340
F的不动点Y满足F(Y)=Y
A fixed point of a function F is a value Y, such that F of Y equals Y.
235
00:14:32,528 --> 00:14:40,448
首先要做是做出一个猜测
And the way I might do that is start with a guess.
236
00:14:41,552 --> 00:14:45,408
在迭代函数F时不会改变的东西则是我们所求的结果
And then if I want something that doesn't change when I keep applying F,
237
00:14:45,510 --> 00:14:49,008
我会不断迭代函数F直到结果不会有很大改变
is I'll keep applying F over and over until that result doesn't change very much.
238
00:14:49,600 --> 00:14:51,480
这就是一个通法
So there's a general strategy.
239
00:14:51,792 --> 00:14:55,728
因此 为了计算X的平方根
And then, for example, to compute the square root of X,
240
00:14:55,792 --> 00:15:03,000
我可以试着找到Y与X/Y的平均值函数的不动点
I can try and find a fixed point of the function which takes Y to the average of X/Y.
241
00:15:03,104 --> 00:15:07,072
因为如果我真有一个等于X平方根的Y
And the idea that is that if I really had Y equal to the square root of X,
242
00:15:07,568 --> 00:15:11,350
那么Y和X/Y应为同一值
then Y and X/Y would be the same value.
243
00:15:11,552 --> 00:15:13,450
它们俩都是X的平方根
They'd both be the square root of X,
244
00:15:14,416 --> 00:15:18,400
因为X除根号X得根号X
because X over the square root of X is the square root of X.
245
00:15:18,640 --> 00:15:21,390
如果平均值Y等于X的平方根
And so the average if Y were equal to the square of X,
246
00:15:21,808 --> 00:15:24,760
那么这个平均值就不会改变
then the average wouldn't change.
247
00:15:25,536 --> 00:15:28,480
因此X的平方根即是某一特定函数的不动点
So the square root of X is a fixed point of that particular function.
248
00:15:29,648 --> 00:15:33,408
现在 我将要描述
Now, what I'd like to have, I'd like to express
249
00:15:33,536 --> 00:15:35,970
寻找不动点的通法
the general strategy for finding fixed points.
250
00:15:36,128 --> 00:15:39,680
我所希望做的就是
So what I might imagine doing, is to find,
251
00:15:40,576 --> 00:15:46,000
用我自己的语言定义一个可以获得不动点的“盒子”
is to be able to use my language to define a box that says "fixed point,"
252
00:15:49,136 --> 00:15:51,740
正如我可以定义一个输出平方根的盒子一样
just like I could make a box that says "square root."
253
00:15:51,760 --> 00:15:54,736
我想要用自己的语言来表述
And I'd like to be able to express this in my language.
254
00:15:55,632 --> 00:16:00,928
因此 对于这种“怎么做”的指令性知识
So I'd like to express not only the imperative how-to knowledge
255
00:16:00,976 --> 00:16:02,768
我不仅是想表达具体应该如何求平方根
of a particular thing like square root,
256
00:16:03,136 --> 00:16:05,152
我也希望能够表述更加通用问题
but I'd like to be able to express the imperative knowledge
257
00:16:05,216 --> 00:16:07,820
例如 怎么求取不动点
of how to do a general thing like how to find fixed point.
258
00:16:09,376 --> 00:16:11,808
让我们再回过头来看看之前的幻灯片
And in fact, let's go back and look at that slide again.
259
00:16:14,576 --> 00:16:22,832
不但如何去求取一个不动点
See, not only is this a piece of imperative knowledge,
260
00:16:22,880 --> 00:16:24,870
是一种指令性知识
how to find a fixed point,
261
00:16:25,808 --> 00:16:26,944
在这下面 这里
but over here on the bottom,
262
00:16:26,976 --> 00:16:29,870
这儿还有另一种指令性知识 说的是
there's another piece of imperative knowledge which says,
263
00:16:29,968 --> 00:16:35,400
计算平方根的一种方法就是应用找不动点的方法
one way to compute square root is to apply this general fixed point method.
264
00:16:35,728 --> 00:16:38,440
如果 也想要表述这种指令性知识
So I'd like to also be able to express that imperative knowledge.
265
00:16:39,296 --> 00:16:40,256
那结果会是什么样呢?
What would that look like?
266
00:16:40,288 --> 00:16:44,450
这个不动点盒子可能会是这样
That would say, this fixed point box is such that
267
00:16:45,310 --> 00:16:57,760
如果我输入一个函数 该函数从Y映射到Y和X/Y的平均值
if I input to it the function that takes Y to the average of Y and X/Y,
268
00:16:59,328 --> 00:17:05,780
然后我们将会得到求不动点的盒子就是求平方根的一个方法
then what should come out of that fixed point box is a method for finding square roots.
269
00:17:08,464 --> 00:17:09,792
因此在这些我们构建的盒子中
So in these boxes we're building,
270
00:17:09,824 --> 00:17:14,624
输入和输出都不局限于数字
we're not only building boxes that you input numbers and output numbers,
271
00:17:15,952 --> 00:17:18,090
我们将要构建能够
we're going to be building in boxes that,
272
00:17:18,220 --> 00:17:20,896
找到平方根计算方法的盒子
in effect, compute methods like finding square root.
273
00:17:21,776 --> 00:17:25,408
我输入的是一个函数
And my take is their inputs functions,
274
00:17:26,048 --> 00:17:28,840
比如Y映射到Y和X/Y的平均值的函数
like Y goes to the average of Y and X/Y.
275
00:17:29,264 --> 00:17:31,040
我们之所以采用这种方式是希望
The reason we want to do that,
276
00:17:31,760 --> 00:17:35,152
输入是一个过程 输出也是一个过程
the reason this is a procedure, will end up being a procedure,
277
00:17:35,184 --> 00:17:38,160
如我们所见 一个过程输出了另一个过程
as we'll see, whose value is another procedure,
278
00:17:38,864 --> 00:17:40,650
之所以这样做是因为
the reason we want to do that is because
279
00:17:41,072 --> 00:17:45,820
我们将通过程序来讨论指令性知识
procedures are going to be our ways of talking about imperative knowledge.
280
00:17:47,552 --> 00:17:49,488
这种处理方式很强大
And the way to make that very powerful is
281
00:17:49,488 --> 00:17:51,680
我们将可以基于此来讨论其它类型的知识
to be able to talk about other kinds of knowledge.
282
00:17:52,976 --> 00:17:56,070
实际上 我们讨论的是一种生成过程的过程
So here is a procedure that, in effect, talks about another procedure,
283
00:17:56,656 --> 00:17:59,890
一种生成通法的通法
a general strategy that itself talks about general strategies.
284
00:18:03,120 --> 00:18:07,790
那么 我们将主要讨论三个主题的内容
Well, our first topic in this course--
285
00:18:07,808 --> 00:18:09,248
而首个主题则是
there'll be three major topics--
286
00:18:09,296 --> 00:18:10,496
黑盒抽象
will be black-box abstraction.
287
00:18:10,528 --> 00:18:12,864
让我们稍稍深入一点
Let's look at that in a little bit more detail.
288
00:18:14,672 --> 00:18:23,590
我们将讨论
What we're going to do is we will start out talking about
289
00:18:23,632 --> 00:18:26,270
Lisp是如何通过基本对象建立起来的
how Lisp is built up out of primitive objects.
290
00:18:26,912 --> 00:18:28,750
以及Lisp的构成
What does the language supply with us?
291
00:18:29,040 --> 00:18:33,136
接下来 将会涉及到一些基本过程和基础数据
And we'll see that there are primitive procedures and primitive data.
292
00:18:35,712 --> 00:18:36,592
然后我们将会看到
Then we're going to see,
293
00:18:36,608 --> 00:18:38,320
我们如何使用这些基本对象
how do you take those primitives and
294
00:18:38,368 --> 00:18:40,310
并把它们组合起来构建更复杂的东西
combine them to make more complicated things,
295
00:18:41,008 --> 00:18:42,470
及相应的组合方法
means of combination?
296
00:18:42,752 --> 00:18:45,850
后续将讨论各种进行组合的方法以及
And what we'll see is that there are ways of putting things together,
297
00:18:46,000 --> 00:18:50,032
如何用基本过程来构建更复杂的过程
putting primitive procedures together to make more complicated procedures.
298
00:18:50,512 --> 00:18:53,980
同时 我们也将看到如何将基本数据组合成复合数据
And we'll see how to put primitive data together to make compound data.
299
00:18:55,760 --> 00:18:58,896
然后我们将会介绍如何对复合数据
Then we'll say, well, having made those compounds things,
300
00:18:59,344 --> 00:19:00,848
如何将它们抽象出来
how do you abstract them?
301
00:19:02,464 --> 00:19:04,528
如何用黑盒对它们进行封装
How do you put those black boxes around them
302
00:19:04,592 --> 00:19:07,280
使得你可以将它们作为组件用于更复杂的东西
so you can use them as components in more complex things?
303
00:19:07,712 --> 00:19:10,480
我们会发现这些都是通过定义程序
And we'll see that's done by defining procedures and
304
00:19:11,072 --> 00:19:14,340
以及一种处理复合数据的数据抽象技术完成的
a technique for dealing with compound data called data abstraction.
305
00:19:15,168 --> 00:19:16,910
最重要的是
And then, what's maybe the most important thing,
306
00:19:17,472 --> 00:19:21,040
我们可以从中了解到专家是如何工作的
is going from just the rules to how does an expert work?
307
00:19:21,168 --> 00:19:26,672
对于找不动点的方法来讲
How do you express common patterns of doing things, like saying, well,
308
00:19:26,704 --> 00:19:28,192
找平方根的方式是它的一个特例
there's a general method of fixed point and
309
00:19:28,240 --> 00:19:30,420
你如何表述完成工作中所存在的通用模式呢?
square root is a particular case of that?
310
00:19:31,456 --> 00:19:33,968
我们将会使用
And we're going to use--
311
00:19:34,144 --> 00:19:35,184
之前已经提到过的
I've already hinted at it--
312
00:19:35,216 --> 00:19:36,850
某种叫做高阶过程的东西
something called higher-order procedures,
313
00:19:36,896 --> 00:19:41,600
也就是说 它的输入、输出和它本身都是过程
namely procedures whose inputs and outputs are themselves procedures.
314
00:19:42,512 --> 00:19:44,416
我们将会看到一些有趣的东西
And then we'll also see something very interesting.
315
00:19:44,416 --> 00:19:48,040
随着学习的深入 将会越发抽象
We'll see, as we go further and further on and become more abstract,
316
00:19:48,352 --> 00:19:49,860
那么将会发现
there'll be very--
317
00:19:49,980 --> 00:19:53,168
我们认为是数据和我们认为是过程之间的
well, the line between what we consider to be data and
318
00:19:53,184 --> 00:19:57,350
分界线将变得模糊到难以置信的程度
what we consider to be procedures is going to blur at an incredible rate.
319
00:20:02,448 --> 00:20:06,670
这便是我们的第一个主题 黑盒抽象
Well, that's our first subject, black-box abstraction.
320
00:20:06,672 --> 00:20:08,170
让我们来看看第二个主题
Let's look at the second topic.
321
00:20:10,656 --> 00:20:13,430
这样说吧
I can introduce it like this.
322
00:20:13,440 --> 00:20:17,640
假设我想表达某个想法
See, suppose I want to express the idea--
323
00:20:18,976 --> 00:20:22,064
请注意 我们讨论的是想法
remember, we're talking about ideas--
324
00:20:22,464 --> 00:20:25,088
比如说
suppose I want to express the idea that
325
00:20:25,968 --> 00:20:34,672
我想将某个元素与另两个元素之和相乘
I can take something and multiply it by the sum of two other things.
326
00:20:35,648 --> 00:20:37,480
举例来说
So for example, I might say,
327
00:20:37,664 --> 00:20:41,070
我用1和3(之和)乘2 得8
if I had 1 and 3 and multiply that by 2, I get 8.
328
00:20:41,584 --> 00:20:44,660
但我这里想讨论的是关于线性组合的基本想法
But I'm talking about the general idea of what's called linear combination,
329
00:20:44,992 --> 00:20:47,530
是说你可以将两个元素的和乘以另一个元素
that you can add two things and multiply them by something else.
330
00:20:48,832 --> 00:20:50,560
在数集内思考这个问题是很容易的
It's very easy when I think about it for numbers,
331
00:20:50,608 --> 00:20:54,960
但假设我想将这个想法应用于
but suppose I also want to use that same idea to think about,
332
00:20:55,632 --> 00:20:58,130
对两向量a1和a2相加
I could add two vectors, a1 and a2,
333
00:20:59,440 --> 00:21:02,816
乘以某一因子x然后得到另一向量
and then scale them by some factor x and get another vector.
334
00:21:02,880 --> 00:21:09,300
我甚至可以说 若a1和a2皆为多项式
Or I might say, I want to think about a1 and a2 as being polynomials,
335
00:21:10,620 --> 00:21:13,456
我想对这两个多项式求和
and I might want to add those two polynomials and
336
00:21:13,472 --> 00:21:16,416
然后乘以2得到一个多项式
then multiply them by 2 to get a more complicated one.
337
00:21:19,710 --> 00:21:23,380
同理 a1或a2也可以是电信号
Or a1 and a2 might be electrical signals,
338
00:21:24,110 --> 00:21:27,328
我想将二个信号加和
and I might want to think about summing those two electrical signals and
339
00:21:27,360 --> 00:21:29,824
并将结果放入一个放大器
then putting the whole thing through an amplifier,
340
00:21:29,824 --> 00:21:29,830
用一个类似于2的因子乘以它们
multiplying it by some factor of 2 or something.
并将结果放入一个放大器
then putting the whole thing through an amplifier,
341
00:21:29,830 --> 00:21:32,580
用一个类似于2的因子乘以它们
multiplying it by some factor of 2 or something.
342
00:21:33,376 --> 00:21:36,480
这种想法的基本点是 我希望用一个通用记号表示它们
The idea is I want to think about the general notion of that.
343
00:21:37,872 --> 00:21:44,976
假如我们的语言可以很好的表述这类想法
Now, if our language is going to be good language for expressing those kind of general ideas,
344
00:21:46,624 --> 00:21:48,864
如果真可以这样的话
if I really, really can do that,
345
00:21:50,208 --> 00:21:51,648
我将会以这样的方式表述
I'd like to be able to say
346
00:21:54,544 --> 00:21:59,960
用x乘以a1和a2的和
I'm going to multiply by x the sum of a1 and a2,
347
00:22:02,352 --> 00:22:04,624
更进一步 我希望做更抽象更基本的表述
and I'd like that to express the general idea of
348
00:22:05,584 --> 00:22:08,784
使其可以适应各个不同类型的a1和a2
all different kinds of things that a1 and a2 could be.
349
00:22:09,584 --> 00:22:11,136
现在回过头来想想 似乎有点问题
Now, if you think about that, there's a problem,
350
00:22:11,136 --> 00:22:15,728
毕竟 对两个数字和两个多项式进行加和运算
because after all, the actual primitive operations
351
00:22:15,760 --> 00:22:17,888
所用的基本操作
that go on in the machine are obviously going to be different
352
00:22:17,936 --> 00:22:22,530
在机器内部显然是不同的
if I'm adding two numbers than if I'm adding two polynomials,
353
00:22:22,848 --> 00:22:27,040
对两个电信号或声波加和也有同样的问题
or if I'm adding the representation of two electrical signals or wave forms.
354
00:22:27,440 --> 00:22:32,080
无论怎样 对不同类型的元素进行求和运算
Somewhere, there has to be the knowledge of the kinds of various things
355
00:22:32,420 --> 00:22:33,808
总是需要使用不同的方法
that you can add and the ways of adding them.
356
00:22:36,640 --> 00:22:38,192
现在 为了构建这样一个系统
Now, to construct such a system,
357
00:22:38,336 --> 00:22:40,224
我们将如何使用这些知识呢?
the question is, where do I put that knowledge?
358
00:22:40,752 --> 00:22:43,968
如何在各种方法中进行选择?
How do I think about the different kinds of choices I have?
359
00:22:44,112 --> 00:22:47,970
而如果明天George又想出了一种新类型的对象
And if tomorrow George comes up with a new kind of object
360
00:22:48,000 --> 00:22:49,872
并将它用于加和以及乘积
that might be added and multiplied,
361
00:22:50,560 --> 00:22:52,870
我又该如何把这个新类型引入到系统中
how do I add George's new object to the system
362
00:22:53,072 --> 00:22:55,230
而且能够做到不把已有的系统弄得一团糟?
without screwing up everything that was already there?
363
00:22:57,360 --> 00:23:00,096
这便是我们的第二大主题
Well, that's going to be the second big topic,
364
00:23:00,128 --> 00:23:02,710
控制复杂度的方法
the way of controlling that kind of complexity.
365
00:23:03,392 --> 00:23:07,980
我们实现的方法是按照约定来实现相应的接口
And the way you do that is by establishing conventional interfaces,
366
00:23:16,992 --> 00:23:19,760
并以此将各部分组合起来
agreed upon ways of plugging things together.
367
00:23:19,808 --> 00:23:21,590
就如同电气工程中
Just like in electrical engineering,
368
00:23:22,496 --> 00:23:24,944
人们为连接器规定标准阻抗
people have standard impedances for connectors,
369
00:23:25,712 --> 00:23:28,176
如果用符合这个标准的东西来构建系统
and then you know if you build something with one of those standard impedances,
370
00:23:28,224 --> 00:23:29,952
你就知道你可以把各个部件组合在一起
you can plug it together with something else.
371
00:23:32,336 --> 00:23:35,230
这就是我们将要讨论的第二个主题:约定接口
So that's going to be our second large topic, conventional interfaces.
372
00:23:35,280 --> 00:23:40,496
如我之前提到的
What we're going to see is, first, we're going to talk about the problem of generic operations,
373
00:23:40,528 --> 00:23:41,776
接下来我们将讨论通用操作中的问题
which is the one I alluded to,
374
00:23:42,144 --> 00:23:46,832
例如对各种不同类型数据进行均适用的加法操作
things like "plus" that have to work with all different kinds of data.
375
00:23:52,160 --> 00:23:54,128
随后则会讨论通用操作
So we talk about generic operations.
376
00:23:54,160 --> 00:23:56,544
然后我们将讨论大型架构问题
Then we're going to talk about really large-scale structures.
377
00:23:57,872 --> 00:24:00,380
如果通过对现实世界的复杂系统建模
How do you put together very large programs
378
00:24:00,576 --> 00:24:04,440
来构建大型程序
that model the kinds of complex systems in the real world that you'd like to model?
379
00:24:05,088 --> 00:24:06,080
我们将看到 在构建这样的系统时
And what we're going to see is that
380
00:24:06,128 --> 00:24:11,360
有两种非常重要的方法
there are two very important metaphors for putting together such systems.
381
00:24:11,408 --> 00:24:13,456
其一是面向对象编程
One is called object-oriented programming,
382
00:24:13,648 --> 00:24:18,496
在这种模式中 你把你的系统想象成一个社区
where you sort of think of your system as a kind of society
383
00:24:18,928 --> 00:24:21,910
社区中的各个部分都是通过相互间传递消息联系起来的
full of little things that interact by sending information between them.
384
00:24:22,992 --> 00:24:27,360
其二是关于聚集的操作 称作“流”
And then the second one is operations on aggregates, called streams,
385
00:24:27,536 --> 00:24:31,056
使用这种方式构建大型系统
where you think of a large system put together kind of
386
00:24:31,056 --> 00:24:34,840
类似于电气工程师构造大型电气系统
like a signal processing engineer puts together a large electrical system.
387
00:24:38,480 --> 00:24:40,048
这就是我们的第二个话题
That's going to be our second topic.
388
00:24:42,928 --> 00:24:45,488
现在 我们将要讨论第三个话题
Now, the third thing we're going to come to,
389
00:24:45,504 --> 00:24:49,250
控制复杂度的第三个技术
the third basic technique for controlling complexity,
390
00:24:49,296 --> 00:24:50,496
便是定义新的语言
is making new languages.
391
00:24:51,248 --> 00:24:54,976
因为有时 当你有点受不了设计的复杂度时
Because sometimes, when you're sort of overwhelmed by the complexity of a design,
392
00:24:55,024 --> 00:24:59,240
你可以通过定义一门新的语言来控制系统复杂度
the way that you control that complexity is to pick a new design language.
393
00:25:00,960 --> 00:25:05,152
新语言的设计意图是为了强调系统的某个方面
And the purpose of the new design language will be to highlight different aspects of the system.
394
00:25:05,344 --> 00:25:08,912
它一方面隐藏了部分细节 另一方面则但强调一些其他的细节
It will suppress some kinds of details and emphasize other kinds of details.
395
00:25:12,544 --> 00:25:15,488
这部分将是课程中最神奇的部分
This is going to be the most magical part of the course.
396
00:25:15,584 --> 00:25:20,750
我们将开始于构建新的计算机语言
We're going to start out by actually looking at the technology for building new computer languages.
397
00:25:21,376 --> 00:25:25,850
实际上我们首先要完成的工作已经内建于Lisp之中了
The first thing we're going to do is actually build in Lisp.
398
00:25:28,784 --> 00:25:33,570
我们将展现如何用Lisp来解释Lisp
We're going to express in Lisp the process of interpreting Lisp itself.
399
00:25:33,840 --> 00:25:36,496
这是一个非常类似于自循环的过程
And that's going to be a very sort of self-circular thing.
400
00:25:36,510 --> 00:25:39,472
这与(Lisp中)一个神奇的符号有关
There's a little mystical symbol that has to do with that.
401
00:25:40,528 --> 00:25:45,936
解释Lisp的步骤是
The process of interpreting Lisp is sort of a giant wheel of two processes,
402
00:25:46,128 --> 00:25:47,264
应用和求值——这两大步骤的轮转
apply and eval,
403
00:25:47,440 --> 00:25:50,420
这两者不断地互相交替进行
which sort of constantly reduce expressions to each other.
404
00:25:52,096 --> 00:25:53,792
接下来 我们将看到其余神奇的东西
Then we're going to see all sorts of other magical things.
405
00:25:53,808 --> 00:25:56,400
譬如另一种魔法符号
Here's another magical symbol.
406
00:25:56,672 --> 00:26:01,070
一种叫做Y运算符的东西
This is sort of the Y operator,
407
00:26:01,100 --> 00:26:06,000
某种意义上 它在过程式语言中用于 表达无限
which is, in some sense, the expression of infinity inside our procedural language.
408
00:26:06,064 --> 00:26:06,992
我们也会谈论到它
We'll take a look at that.
409
00:26:07,952 --> 00:26:13,280
总之 这部分课程被称作“元语言抽象”
In any case, this section of the course is called Metalinguistic Abstraction,
410
00:26:15,728 --> 00:26:25,780
主要讨论如何构建一门新语言
abstracting by talking about how you construct new languages.
411
00:26:29,776 --> 00:26:35,264
如我所言 我们将从了解解释的过程开始
As I said, we're going to start out by looking at the process of interpretation.
412
00:26:35,296 --> 00:26:41,670
随后则一起讨论应用-求值循环和构建Lisp
We're going to look at this apply-eval loop, and build Lisp.
413
00:26:41,712 --> 00:26:43,720
你将发现这种方法具有相当的普遍性
Then, just to show you that this is very general,
414
00:26:43,920 --> 00:26:47,810
我们将用同样的技术去构建一门全完不同的语言
we're going to use exactly the same technology to build a very different kind of language,
415
00:26:48,080 --> 00:26:49,860
一种所谓的逻辑编程语言
a so-called logic programming language,
416
00:26:50,080 --> 00:26:54,380
一种无关具有输入和输出的过程
where you don't really talk about procedures at all that have inputs and outputs.
417
00:26:54,416 --> 00:26:56,800
而仅关注元素之间关系的语言
What you do is talk about relations between things.
418
00:26:56,864 --> 00:27:03,470
最终 我们将讨论如何将这些东西
And then finally, we're going to talk about how you implement these things very concretely
419
00:27:03,504 --> 00:27:05,152
实实在在的实现在简单的机器上
on the very simplest kind of machines.
420
00:27:05,200 --> 00:27:07,940
比如说这个
We'll see something like this.
421
00:27:08,688 --> 00:27:11,690
如图所示的芯片
This is a picture of a chip,
422
00:27:11,712 --> 00:27:17,024
就是我们在硬件部分谈及的Lisp解释器
which is the Lisp interpreter that we will be talking about then in hardware.
423
00:27:20,432 --> 00:27:23,340
这三大主题就是本课的提纲
Well, there's an outline of the course, three big topics.
424
00:27:24,432 --> 00:27:28,960
黑盒抽象 约定接口 元语言抽象
Black-box abstraction, conventional interfaces, metalinguistic abstraction.
425
00:27:31,136 --> 00:27:33,120
好 先休息一会儿 然后正式开始
Now, let's take a break now and then we'll get started.
426
00:27:51,744 --> 00:28:02,976
[音乐]
[JESU, JOY OF MAN'S DESIRING]
427
00:28:03,472 --> 00:28:06,390
现在让我们正式开始学习Lisp
Let's actually start in learning Lisp now.
428
00:28:07,616 --> 00:28:10,304
事实上 我们将开始学习一些非常重要的内容
Actually, we'll start out by learning something much more important,
429
00:28:10,352 --> 00:28:13,888
在这门课程中最重要的 不是Lisp本身
maybe the very most important thing in this course, which is not Lisp,
430
00:28:13,936 --> 00:28:17,960
而是一种的通用框架体系
in particular, of course, but rather a general framework
431
00:28:18,176 --> 00:28:21,440
我们用它来组织我之前提到的语言
for thinking about languages that I already alluded to.
432
00:28:21,671 --> 00:28:24,650
当有人要向你展示一门新语言
When somebody tells you they're going to show you a language,
433
00:28:24,688 --> 00:28:25,712
你应该问他
what you should say is,
434
00:28:25,744 --> 00:28:32,420
(构成语言的)基本元素有哪些?
what I'd like you to tell me is what are the primitive elements?
435
00:28:37,056 --> 00:28:38,330
这门语言使用哪些基本元素?
What does the language come with?
436
00:28:38,512 --> 00:28:43,088
你是如何将这些元素组合在一起的?
Then, what are the ways you put those together?
437
00:28:43,232 --> 00:28:46,976
组合的方法是什么?
What are the means of combination?
438
00:28:49,728 --> 00:28:53,730
允许你将这些基本元素整合在一起
What are the things that allow you to take these primitive elements
439
00:28:53,920 --> 00:28:56,064
以构建更大的对象的又是什么?
and build bigger things out of them?
440
00:28:57,568 --> 00:28:59,168
把东西构建在一起的方法是什么?
What are the ways of putting things together?
441
00:29:00,944 --> 00:29:05,248
以及 抽象的方法是什么?
And then, what are the means of abstraction?
442
00:29:07,904 --> 00:29:16,400
我们如何利用这些元素并把它们封装成盒子?
How do we take those complicated things and draw those boxes around them?
443
00:29:16,432 --> 00:29:19,216
我们如何为它们命名使得我们可以
How do we name them so that we can now use them
444
00:29:19,232 --> 00:29:23,408
把它们当作基本元素来用于构建更复杂的东西?
as if they were primitive elements in making still more complex things?
445
00:29:23,440 --> 00:29:25,216
等等 等等 等等
And so on, and so on, and so on.
446
00:29:26,448 --> 00:29:27,632
因此 当有人告诉你
So when someone says to you, gee,
447
00:29:27,648 --> 00:29:29,104
嘿 我发明了一种新的计算机语言
I have a great new computer language,
448
00:29:30,416 --> 00:29:34,256
你不应该问 用你的语言编写求逆矩阵需要多少代码
you don't say, how many characters does it take to invert a matrix?
449
00:29:35,280 --> 00:29:36,432
这是风马牛不相及的
It's irrelevant.
450
00:29:36,944 --> 00:29:41,850
如果该语言没有内建了矩阵或者类似的东西
What you say is, if the language did not come with matrices built in
451
00:29:41,888 --> 00:29:42,928
那你就应该问他
or with something else built in,
452
00:29:42,928 --> 00:29:45,584
应该如何构建矩阵?
how could I then build that thing?
453
00:29:45,600 --> 00:29:48,020
如何通过组合来构建?
What are the means of combination which would allow me to do that?
454
00:29:48,176 --> 00:29:50,260
如何对其进行抽象
And then, what are the means of abstraction
455
00:29:51,232 --> 00:29:53,760
把它作为基本元素
which allow me then to use those as elements
456
00:29:53,776 --> 00:29:56,070
来构建更复杂的东西?
in making more complicated things yet?
457
00:29:58,304 --> 00:30:04,160
我们将了解到Lisp的一些基本数据和基本过程
Well, we're going to see that Lisp has some primitive data and some primitive procedures.
458
00:30:04,800 --> 00:30:07,056
好吧 这次是真的开始了
In fact, let's really start.
459
00:30:07,104 --> 00:30:14,448
这里有一个Lisp的基本数据 数字3
And here's a piece of primitive data in Lisp, number 3.
460
00:30:15,824 --> 00:30:19,420
事实上 如果打破沙锅问到底的话 这不是数字3
Actually, if I'm being very pedantic, that's not the number 3.
461
00:30:19,488 --> 00:30:25,120
这只是一个符号 用以代表柏拉图观念下的数字3的
That's some symbol that represents Plato's concept of the number 3.
462
00:30:26,224 --> 00:30:28,480
这又是另一个
And here's another.
463
00:30:30,032 --> 00:30:35,616
这个是Lisp中又一个基本数据 17.4
Here's some more primitive data in Lisp, 17.4.
464
00:30:35,632 --> 00:30:38,976
又或者说 代表17.4
Or actually, some representation of 17.4.
465
00:30:40,544 --> 00:30:44,032
这儿还有一个5
And here's another one, 5.
466
00:30:46,416 --> 00:30:51,760
然后这儿又有一个内建于Lisp的基本对象“+”
Here's another primitive object that's built in Lisp, addition.
467
00:30:51,808 --> 00:30:55,232
如果又要继续深究的话
Actually, to use the same kind of pedantic--
468
00:30:55,264 --> 00:31:00,020
这只是一个名字 代表对元素进行加和的基本方法而已
this is a name for the primitive method of adding things.
469
00:31:00,080 --> 00:31:02,080
就像这个是柏拉图式的3
Just like this is a name for Plato's number 3,
470
00:31:02,160 --> 00:31:08,870
这也只是一个代表柏拉图观念下的将某些元素加和起来
this is a name for Plato's concept of how you add things.
471
00:31:09,872 --> 00:31:11,530
这些都是基本元素
So those are some primitive elements.
472
00:31:11,696 --> 00:31:13,310
我可以将它们放在一起
I can put them together.
473
00:31:13,696 --> 00:31:17,840
我可以说 3加17.4加5的和是多少
I can say, gee, what's the sum of 3 and 17.4 and 5?
474
00:31:18,240 --> 00:31:20,864
这等同于说
And the way I do that is to say,
475
00:31:20,880 --> 00:31:27,264
让我们把求和运算符应用于这三个数
let's apply the sum operator to these three numbers.
476
00:31:27,296 --> 00:31:30,700
我可以得到什么呢 是8 是17 还是25.4
And I should get, what? 8, 17. 25.4.
477
00:31:33,984 --> 00:31:37,600
因此 我可以问Lisp这个的值是多少
So I should be able to ask Lisp what the value of this is,
478
00:31:38,496 --> 00:31:40,320
(表达式)返回25.4
and it will return 25.4.
479
00:31:43,136 --> 00:31:44,384
介绍一些术语吧
Let's introduce some names.
480
00:31:44,432 --> 00:31:51,024
我所写的这些东西就叫做组合式
This thing that I typed is called a combination.
481
00:31:56,432 --> 00:32:01,490
通常 一个组合式是由运算符
And a combination consists, in general, of applying an operator--
482
00:32:02,944 --> 00:32:04,272
这些就是运算符
so this is an operator--
483
00:32:09,264 --> 00:32:11,600
和应用该运算符的运算对象组成
to some operands.
484
00:32:12,800 --> 00:32:14,096
这些是运算对象
These are the operands.
485
00:32:21,440 --> 00:32:23,340
当然 我可以完成更复杂的事
And of course, I can make more complex things.
486
00:32:23,376 --> 00:32:28,110
我可以使之更复杂是因为 这些运算对象
The reason I can get complexity out of this is because the operands themselves,
487
00:32:29,072 --> 00:32:30,640
通常来说 也可以是组合式
in general, can be combinations.
488
00:32:30,704 --> 00:32:44,020
比如 3加上5乘以6乘以8乘以2的积的和是多少
So for instance, I could say, what is the sum of 3 and the product of 5 and 6 and 8 and 2?
489
00:32:45,216 --> 00:32:51,712
而我应该得到 我算一下 30 40 43
And I should get-- let's see-- 30, 40, 43.
490
00:32:52,288 --> 00:32:54,368
因此Lisp会返回这个表达式的值是43
So Lisp should tell me that that's 43.
491
00:32:56,112 --> 00:33:02,352
后续我们将看到构造组合式是组合的基本需求
Forming combinations is the basic needs of combination that we'll be looking at.
492
00:33:04,208 --> 00:33:08,770
你所看到的这些语法
And then, well, you see some syntax here.
493
00:33:10,112 --> 00:33:12,592
就是Lisp用的所谓的前缀表示法
Lisp uses what's called prefix notation,
494
00:33:15,776 --> 00:33:24,760
意即操作符在操作数的左端
which means that the operator is written to the left of the operands.
495
00:33:25,024 --> 00:33:26,032
这只是个约定
It's just a convention.
496
00:33:27,216 --> 00:33:29,320
注意 这些都被括起来了
And notice, it's fully parenthesized.
497
00:33:29,632 --> 00:33:31,872
这些括号使得它们区别开来
And the parentheses make it completely unambiguous.
498
00:33:31,872 --> 00:33:36,544
因此只要看看这个 我就可以知道这个是运算符
So by looking at this, I can see that there's the operator,
499
00:33:36,560 --> 00:33:40,540
以及这有1个 2个 3个 4个运算对象
and there are 1, 2, 3, 4 operands.
500
00:33:41,936 --> 00:33:47,520
而且我也可以发现第二个运算对象是个组合式
And I can see that the second operand here is itself some combination
501
00:33:48,432 --> 00:33:51,100
该组合式有一个运算符和两个运算对象
that has one operator and two operands.
502
00:33:51,984 --> 00:33:53,824
Lisp中的括号 有点或者非常不同于
Parentheses in Lisp are a little bit,
503
00:33:54,160 --> 00:33:57,260
通常数学中的括号
or are very unlike parentheses in conventional mathematics.
504
00:33:57,328 --> 00:33:59,664
数学中 我们常将其用于分组
In mathematics, we sort of use them to mean grouping,
505
00:34:00,768 --> 00:34:03,300
如果有时你忘了闭合括号 但其他人能理解你的意图
and it sort of doesn't hurt if sometimes you leave out parentheses
506
00:34:03,328 --> 00:34:05,110
这也无关紧要
if people understand that that's a group.
507
00:34:05,312 --> 00:34:08,064
通常的 你多加了括号也无所谓
And in general, it doesn't hurt if you put in extra parentheses,
508
00:34:08,416 --> 00:34:10,496
因为这样只会使得分组更加明确
because that maybe makes the grouping more distinct.
509
00:34:10,512 --> 00:34:11,328
Lisp可不像这样
Lisp is not like that.
510
00:34:12,672 --> 00:34:14,928
Lisp中你既不能不闭合括号
In Lisp, you cannot leave out parentheses,
511
00:34:15,936 --> 00:34:18,112
亦不能添加多余的括号
and you cannot put in extra parentheses,
512
00:34:18,880 --> 00:34:20,832
因为加括号总是意味着
because putting in parentheses always means,
513
00:34:20,928 --> 00:34:26,600
确切的来说 所括之物是一个组合式
exactly and precisely, this is a combination which has meaning,
514
00:34:26,640 --> 00:34:28,368
表示将运算符应用于运算对象
applying operators to operands.
515
00:34:28,592 --> 00:34:32,176
如果我不闭合这个括号
And if I left this out, if I left those parentheses out,
516
00:34:32,208 --> 00:34:33,510
这个就变成其它的意思了
it would mean something else.
517
00:34:34,960 --> 00:34:36,800
事实上 我们可以这么来理解这个问题
In fact, the way to think about this,
518
00:34:36,960 --> 00:34:41,200
把我写的这些东西想作一个树
is really what I'm doing when I write something like this is writing a tree.
519
00:34:41,920 --> 00:34:46,850
这个组合式实际上是一个树 树具有一个“+”
So this combination is a tree that has a plus and
520
00:34:46,928 --> 00:34:54,016
以及 一个3和一些其它的东西和一个8 还有一个2
then a 3 and then a something else and an 8 and a 2.
521
00:34:54,032 --> 00:34:55,904
而这里的其它的东西
And then this something else here is
522
00:34:55,904 --> 00:35:02,770
它本身是一个有一个“*”一个5和一个6的子树
itself a little subtree that has a star and a 5 and a 6.
523
00:35:03,504 --> 00:35:05,088
我们可以这样认为
And the way to think of that is, really,
524
00:35:05,104 --> 00:35:08,550
我们只是在构建这些树而已
what's going on are we're writing these trees,
525
00:35:08,768 --> 00:35:14,656
括号只是将这种二维结构写作线性字符串
and parentheses are just a way to write this two-dimensional structure
526
00:35:15,344 --> 00:35:16,896
的一种方法罢了
as a linear character string.
527
00:35:18,784 --> 00:35:23,360
因为至少在Lisp发明时 人们还在用电传打字机或者打孔卡
Because at least when Lisp first started and people had teletypes or punch cards or whatever,
528
00:35:23,728 --> 00:35:25,150
这种记法方便多了
this was more convenient.
529
00:35:25,520 --> 00:35:30,070
如果Lisp是在当下被发明的 语法可能会像树那样
Maybe if Lisp started today, the syntax of Lisp would look like that.
530
00:35:31,312 --> 00:35:34,620
那么 让我们看看在计算机里面它究竟是什么样
Well, let's look at what that actually looks like on the computer.
531
00:35:35,840 --> 00:35:38,928
这里有个Lisp解释套件
Here I have a Lisp interaction set up.
532
00:35:38,960 --> 00:35:39,984
这是个编辑器
There's a editor.
533
00:35:40,688 --> 00:35:44,410
我将要在上方写一些表达式并让Lisp对其求值
And on the top, I'm going to type some values and ask Lisp what they are.
534
00:35:44,672 --> 00:35:46,300
比如 我可以问Lisp
So for instance, I can say to Lisp,
535
00:35:46,384 --> 00:35:48,080
这个符号的值是多少
what's the value of that symbol?
536
00:35:48,992 --> 00:35:50,050
我键入3
That's 3.
537
00:35:50,128 --> 00:35:51,750
然后叫Lisp对其求值
And I ask Lisp to evaluate it.
538
00:35:51,872 --> 00:35:54,320
然后你就会看到Lisp在下面返回了一些信息
And there you see Lisp has returned on the bottom,
539
00:35:54,944 --> 00:35:56,390
这个值就是3
and said, oh yeah, that's 3.
540
00:35:57,136 --> 00:36:04,510
我也可以问 3加上4加上8的和是多少
Or I can say, what's the sum of 3 and 4 and 8?
541
00:36:06,000 --> 00:36:07,600
键入这个组合式
What's that combination?
542
00:36:08,480 --> 00:36:10,210
让Lisp对其求值
And ask Lisp to evaluate it.
543
00:36:14,048 --> 00:36:15,232
返回15
That's 15.
544
00:36:16,128 --> 00:36:18,352
我可以键入一些更复杂的东西
Or I can type in something more complicated.
545
00:36:18,800 --> 00:36:33,690
将3乘以7加19.5的和的乘积求和得多少
I can say, what's the sum of the product of 3 and the sum of 7 and 19.5?
546
00:36:34,768 --> 00:36:37,552
你会发现Lisp内建了一些功能
And you'll notice here that Lisp has something built in
547
00:36:37,568 --> 00:36:39,312
帮你跟踪这些括号
that helps me keep track of all these parentheses.
548
00:36:39,328 --> 00:36:41,680
看我键入下一个右圆括号
Watch as I type the next closed parentheses,
549
00:36:41,760 --> 00:36:44,560
用于闭合以“*”开头的那个组合式
which is going to close the combination starting with the star.
550
00:36:45,072 --> 00:36:46,850
开头的那个左括号会闪一下
The opening one will flash.
551
00:36:47,312 --> 00:36:49,240
我把这些括号擦去 再示范一次
Here, I'll rub those out and do it again.
552
00:36:49,696 --> 00:36:52,250
键入右括号 闭合了“+”组合式
Type close, and you see that closes the plus.
553
00:36:53,136 --> 00:36:55,968
再键入右括号 闭合了“*”组合式
Close again, that closes the star.
554
00:36:57,456 --> 00:37:00,310
现在我又回到了加 我将它们与4相加
Now I'm back to the sum, and maybe I'm going to add that all to 4.
555
00:37:01,216 --> 00:37:02,240
闭合了“+”组合式
That closes the plus.
556
00:37:02,288 --> 00:37:06,624
现在我补全了组合式 然后我问Lisp它们的值是多少
Now I have a complete combination, and I can ask Lisp for the value of that.
557
00:37:06,816 --> 00:37:11,216
这种内建于各种Lisp系统的
That kind of paren balancing is something that's built into
558
00:37:11,312 --> 00:37:12,840
括号匹配工具帮你跟进(括号匹配)
a lot of Lisp systems to help you keep track,
559
00:37:12,912 --> 00:37:16,100
因为手工闭合这些括号太辛苦了
because it is kind of hard just by hand doing all these parentheses.
560
00:37:16,368 --> 00:37:20,752
这又是另外一种保持括号跟进的约定
There's another kind of convention for keeping track of parentheses.
561
00:37:20,800 --> 00:37:23,232
我另外写一个复杂的组合式
Let me write another complicated combination.
562
00:37:24,320 --> 00:37:33,552
将3和5的积与某个元素求和
Let's take the sum of the product of 3 and 5 and add that to something.
563
00:37:33,584 --> 00:37:34,784
现在我将要缩进
And now what I'm going to do is
564
00:37:34,832 --> 00:37:39,408
使得这些运算对象都是垂直书写的
I'm going to indent so that the operands are written vertically.
565
00:37:39,856 --> 00:37:45,200
将这些加上47乘以
Which the sum of that and the product of 47 and--
566
00:37:46,576 --> 00:37:54,144
恩…… 47乘以20和6.8的差
let's say the product of 47 with a difference of 20 and 6.8.
567
00:37:54,176 --> 00:37:56,640
意即从20中减去6.8
That means subtract 6.8 from 20.
568
00:37:58,528 --> 00:37:59,744
然后 这个括号闭合了
And then you see the parentheses close.
569
00:37:59,776 --> 00:38:03,020
闭合“-” 闭合“*”
Close the minus. Close the star.
570
00:38:03,312 --> 00:38:04,976
现在 我们再写一个运算符
And now let's get another operator.
571
00:38:04,992 --> 00:38:09,040
Lisp编辑器自动缩进到正确的位置
You see the Lisp editor here is indenting to the right position automatically
572
00:38:09,952 --> 00:38:11,056
来帮助我保持跟进
to help me keep track.
573
00:38:12,160 --> 00:38:13,648
我再示范一次
I'll do that again.
574
00:38:13,680 --> 00:38:15,440
这样就又闭合了最后一个括号
I'll close that last parentheses again.
575
00:38:15,808 --> 00:38:17,260
它匹配了这个“+”(的括号)
You see it balances the plus.
576
00:38:19,952 --> 00:38:22,190
现在我想问 这个的值是多少
Now I can say, what's the value of that?
577
00:38:23,424 --> 00:38:28,832
因此 这两件事 缩进到正确的位置
So those two things, indenting to the right level,
578
00:38:28,864 --> 00:38:30,410
也就是所谓的美观的输出
which is called pretty printing,
579
00:38:31,104 --> 00:38:33,136
以及闭合提示
and flashing parentheses,
580
00:38:33,440 --> 00:38:37,280
是许多Lisp系统所内建用于帮你保持跟进的工具
are two things that a lot of Lisp systems have built in to help you keep track.
581
00:38:37,312 --> 00:38:38,560
你应该学习如何使用它们
And you should learn how to use them.
582
00:38:41,072 --> 00:38:42,720
好 这些都是基本的内容
Ok, those are the primitives.
583
00:38:44,288 --> 00:38:45,860
这就是一种组合的方法
There's a means of combination.
584
00:38:45,888 --> 00:38:47,488
现在让我们来看看抽象的方法
Now let's go up to the means of abstraction.
585
00:38:48,992 --> 00:38:53,390
我希望我能够写一些像这样的组合式
I'd like to be able to take the idea that I do some combination like this,
586
00:38:53,408 --> 00:38:55,320
将它抽象化并给它命名
and abstract it and give it a simple name,
587
00:38:55,360 --> 00:38:56,810
使得我可以将其作为一个(我们语言的)元素
so I can use that as an element.
588
00:38:56,864 --> 00:38:59,472
在Lisp中 我可以用“define”来实现
And I do that in Lisp with "define."
589
00:39:00,720 --> 00:39:01,980
比如说
So I can say, for example,
590
00:39:02,288 --> 00:39:14,608
定义A为5乘以5
define A to be the product of 5 and 5.
591
00:39:17,952 --> 00:39:21,904
现在我可以问Lisp
And now I could say, for example, to Lisp,
592
00:39:21,936 --> 00:39:25,568
A和A的乘积是多少
what is the product of A and A?
593
00:39:26,736 --> 00:39:29,360
这个是25所以这个就是625
And this should be 25, and this should be 625.
594
00:39:31,520 --> 00:39:35,560
但更重要的则是 我现在可以使用A
And then, crucial thing, I can now use A--
595
00:39:35,760 --> 00:39:37,470
我已经在这个组合式里面用过了
here I've used it in a combination--
596
00:39:37,968 --> 00:39:43,104
但我也可以在更复杂的组合式里面使用它
but I could use that in other more complicated things that I name in turn.
597
00:39:43,136 --> 00:39:50,480
我也可以说 定义B为
So I could say, define B to be the sum of,
598
00:39:50,528 --> 00:39:57,008
A与5乘以A的积的和
we'll say, A and the product of 5 and A.
599
00:39:58,992 --> 00:40:00,272
闭合“+”
And then close the plus.
600
00:40:03,008 --> 00:40:05,408
让我们来看看它在计算机中是怎样的吧
Let's take a look at that on the computer and see how that looks.
601
00:40:06,832 --> 00:40:10,230
我就像黑板上写的那样键入就可以了
So I'll just type what I wrote on the board.
602
00:40:10,384 --> 00:40:21,280
我告诉Lisp
I could say, define A to be the product of 5 and 5.
603
00:40:23,296 --> 00:40:24,930
定义A为5乘以5的积
And I'll tell that to Lisp.
604
00:40:25,072 --> 00:40:28,490
注意Lisp在下方回应了一个A
And notice what Lisp responded there with was an A in the bottom.
605
00:40:28,640 --> 00:40:30,930
通常来说 你如果在Lisp中键入了一个定义
In general, when you type in a definition in Lisp,
606
00:40:31,056 --> 00:40:34,570
它返回被定义的符号
it responds with the symbol being defined.
607
00:40:35,184 --> 00:40:39,216
现在我问Lisp A乘以A的积是多少
Now I could say to Lisp, what is the product of A and A?
608
00:40:42,368 --> 00:40:43,888
Lisp返回625
And it says that's 625.
609
00:40:45,600 --> 00:40:59,890
我也可以定义B为A加上5乘以A的积的和
I can define B to be the sum of A and the product of 5 and A.
610
00:41:00,032 --> 00:41:05,250
闭合“*” 闭合“+” 闭合“define”
Close a paren closes the star. Close the plus. Close the "define."
611
00:41:07,184 --> 00:41:09,920
Lisp在下方正常返回B
Lisp says, OK, B, there on the bottom.
612
00:41:10,592 --> 00:41:12,790
现在我可以问Lisp B的值是多少
And now I can say to Lisp, what's the value of B?
613
00:41:16,736 --> 00:41:18,432
我也可以问一些更复杂的事
And I can say something more complicated,
614
00:41:18,480 --> 00:41:26,240
比如A加上B除以5的商的和是多少
like what's the sum of A and the quotient of B and 5?
615
00:41:26,288 --> 00:41:29,808
这个“/”是另一个基本运算符 代表除
That slash is divide, another primitive operator.
616
00:41:29,936 --> 00:41:32,330
我让B除以5 并加在A上
I've divided B by 5, added it to A.
617
00:41:33,200 --> 00:41:34,784
Lisp正常返回55
Lisp says, OK, that's 55.
618
00:41:36,120 --> 00:41:37,472
就像这样
So there's what it looks like.
619
00:41:39,376 --> 00:41:42,950
这是定义东西的基本方法
There's the basic means of defining something.
620
00:41:42,992 --> 00:41:48,570
这是最简单的命名方法 但并不是很强大
It's the simplest kind of naming, but it's not really very powerful.
621
00:41:49,616 --> 00:41:51,152
注意我们讨论的是通用方法
See, what I'd really like to name--
622
00:41:51,392 --> 00:41:52,928
因此我真正想定义的是
remember, we're talking about general methods--
623
00:41:53,120 --> 00:41:57,232
一种通用方法 可以
I'd like to name, oh, the general idea that, for example,
624
00:41:57,664 --> 00:42:17,088
得到 5乘5 6乘6 1001乘1001 1001.7乘1001.7
I could multiply 5 by 5, or 6 by 6, or 1,001 by 1,001, 1,001.7 by 1,001.7.
625
00:42:17,312 --> 00:42:23,712
我想给一个数与其自身相乘这种想法一个名字
I'd like to be able to name the general idea of multiplying something by itself.
626
00:42:28,032 --> 00:42:29,664
你应该知道 这叫做平方
Well, you know what that is. That's called squaring.
627
00:42:31,248 --> 00:42:35,184
而在Lisp中我应该这样实现
And the way I can do that in Lisp is I can say,
628
00:42:37,520 --> 00:42:55,808
定义 square某个叫x的东西 为 将x乘以x自己
define to square something x, multiply x by itself.
629
00:42:57,424 --> 00:43:00,672
定义完毕后 我可以问Lisp
And then having done that, I could say to Lisp,
630
00:43:00,672 --> 00:43:05,040
比如 10的平方是多少
for example, what's the square of 10?
631
00:43:06,224 --> 00:43:07,424
Lisp返回100
And Lisp will say 100.
632
00:43:10,256 --> 00:43:13,790
让我们深入讨论一下
So now let's actually look at that a little more closely.
633
00:43:14,848 --> 00:43:16,430
这儿是square的定义
Right, there's the definition of square.
634
00:43:17,056 --> 00:43:22,100
square某个元素 即是将该元素进行自乘
To square something, multiply it by itself.
635
00:43:23,248 --> 00:43:24,896
这里的x
You see this x here.
636
00:43:25,840 --> 00:43:27,360
应该算是一种代词
That x is kind of a pronoun,
637
00:43:27,424 --> 00:43:29,080
指代了我要做平方的元素
which is the something that I'm going to square.
638
00:43:31,040 --> 00:43:36,960
实际上我将其乘以x 即是乘以它自己
And what I do with it is I multiply x, I multiply it by itself.
639
00:43:41,776 --> 00:43:47,820
这些就是定义一个过程的记法
OK. So there's the notation for defining a procedure.
640
00:43:47,840 --> 00:43:49,840
这样说可能把你搞糊涂了
Actually, this is a little bit confusing,
641
00:43:50,368 --> 00:43:53,520
因为这就像我在用square一样
because this is sort of how I might use square.
642
00:43:53,552 --> 00:43:56,352
但如果我说x的平方根或者10的平方根
And I say square root of x or square root of 10,
643
00:43:57,104 --> 00:44:00,360
并没有说清楚我对什么做了定义
but it's not making it very clear that I'm actually naming something.
644
00:44:02,656 --> 00:44:04,464
所以让我换个方式来进行定义
So let me write this definition in another way
645
00:44:05,296 --> 00:44:07,760
这样可以清楚的看到定义的具体内容
that makes it a little bit more clear that I'm naming something.
646
00:44:08,096 --> 00:44:28,944
我定义“square”为“(lambda (x) (* x x))”
I'll say, "define" square to be lambda of x times xx.
647
00:44:36,112 --> 00:44:41,600
这里 我定义square就像我某命名为A一样
Here, I'm naming something square, just like over here, I'm naming something A.
648
00:44:42,784 --> 00:44:44,272
我定义square
The thing that I'm naming square--
649
00:44:44,304 --> 00:44:47,940
这里 我把这个组合式的值命名为A
here, the thing I named A was the value of this combination.
650
00:44:48,848 --> 00:44:51,968
在这里 我把这个东西命名为square
Here, the thing that I'm naming square is this thing
651
00:44:51,984 --> 00:44:52,992
以lambda开头
that begins with lambda,
652
00:44:53,008 --> 00:44:56,320
lambda在Lisp中用以构建一个过程
and lambda is Lisp's way of saying make a procedure.
653
00:44:59,792 --> 00:45:02,464
请仔细看一下幻灯片上的内容
Let's look at that more closely on the slide.
654
00:45:03,820 --> 00:45:05,360
这个定义读作
The way I read that definition is to say,
655
00:45:05,408 --> 00:45:09,880
将square定义为
I define square to be make a procedure--
656
00:45:12,336 --> 00:45:13,520
一个由lambda构造的
that's what the lambda is--
657
00:45:13,616 --> 00:45:17,040
一个有带有参数x的过程
make a procedure with an argument named x.
658
00:45:18,816 --> 00:45:23,648
而该过程返回将x自乘的结果
And what it does is return the results of multiplying x by itself.
659
00:45:24,528 --> 00:45:32,672
一般来讲 这是最佳的定义方式
Now, in general, we're going to be using this top form of defining,
660
00:45:32,960 --> 00:45:34,752
因为这个更加方便一点
just because it's a little bit more convenient.
661
00:45:34,752 --> 00:45:34,768
但是也别忘了它实质上也是这个
But don't lose sight of the fact that it's really this.
因为这个更加方便一点
just because it's a little bit more convenient.
662
00:45:34,768 --> 00:45:38,224
但是也别忘了它实质上也是这个
But don't lose sight of the fact that it's really this.
663
00:45:38,416 --> 00:45:40,960
事实上 就Lisp解释器而言
In fact, as far as the Lisp interpreter's concerned,
664
00:45:41,168 --> 00:45:45,104
这两种方法没有区别
there's no difference between typing this to it and typing this to it.
665
00:45:46,064 --> 00:45:52,848
换句话说 这只是一种语法糖
And there's a word for that, sort of syntactic sugar.
666
00:45:53,968 --> 00:45:55,350
语法糖的意思就是
What syntactic sugar means,
667
00:45:55,904 --> 00:46:00,384
这种形式输入更方便一些
it's having somewhat more convenient surface forms for typing something.
668
00:46:00,672 --> 00:46:05,664
这只是这下面的有lambda的表达式的语法糖而已
So this is just really syntactic sugar for this underlying Greek thing with the lambda.
669
00:46:06,864 --> 00:46:10,176
你应该记住
And the reason you should remember that is don't forget that,
670
00:46:10,352 --> 00:46:13,420
当我这样写的时候 其实是在对某个东西进行命名
when I write something like this, I'm really naming something.
671
00:46:14,016 --> 00:46:15,776
我将其命名为square
I'm naming something square,
672
00:46:15,792 --> 00:46:19,456
square代表一个构建好的过程
and the something that I'm naming square is a procedure that's getting constructed.
673
00:46:20,752 --> 00:46:23,456
让我们看看在计算机里面又是 怎样的吧
Well, let's look at that on the computer, too.
674
00:46:24,336 --> 00:46:35,504
定义“(square x)”为x乘以x的积
So I'll come and I'll say, define square of x to be times xx.
675
00:46:49,200 --> 00:46:51,872
将它送入Lisp
Now I'll tell Lisp that.
676
00:46:53,040 --> 00:46:53,472
返回square
It says "square."
677
00:46:53,488 --> 00:46:55,840
现在 我已经将某个东西命名为square了
See, I've named something "square."
678
00:46:56,000 --> 00:47:02,430
完毕后 我就可以问Lisp 1001的平方是多少
Now, having done that, I can ask Lisp for, what's the square of 1,001?
679
00:47:04,816 --> 00:47:17,248
或者更通常的来说 我可以问 5加上7的和的平方是多少
Or in general, I could say, what's the square of the sum of 5 and 7?
680
00:47:22,368 --> 00:47:24,500
12的平方是144
The square of 12's 144.
681
00:47:24,624 --> 00:47:28,416
在某些组合式中我亦可把square当作一个元素
Or I can use square itself as an element in some combination.
682
00:47:28,432 --> 00:47:37,056
3的平方加上4的平方的和是多少
I can say, what's the sum of the square of 3 and the square of 4?
683
00:47:42,080 --> 00:47:43,648
9加上16得25
9 and 16 is 25.
684
00:47:44,464 --> 00:47:50,096
我可以将square作为元素用于更复杂的式子
Or I can use square as an element in some much more complicated thing.
685
00:47:50,144 --> 00:48:00,064
比如 1001的平方点的平方的平方是多少
I can say, what's the square of, the sqare of, the square of 1,001?
686
00:48:07,440 --> 00:48:10,180
这就是1001点的平方的平方的平方
And there's the square of the square of the square of 1,001.
687
00:48:10,752 --> 00:48:15,008
我也可以问Lisp square本身是什么
Or I can say to Lisp, what is square itself?
688
00:48:15,232 --> 00:48:16,710
它的值是是什么
What's the value of that?
689
00:48:16,992 --> 00:48:21,690
Lisp用一种约定的方法告诉我这是一个过程
And Lisp returns some conventional way of telling me that that's a procedure.
690
00:48:21,824 --> 00:48:23,536
它返回 复合过程square
It says, "compound procedure square."
691
00:48:23,808 --> 00:48:27,470
记住 square的值是一个过程
Remember, the value of square is this procedure,
692
00:48:28,704 --> 00:48:30,448
而那些用星号和括号的记法
and the thing with the stars and the brackets
693
00:48:30,656 --> 00:48:34,330
只是Lisp用来描述这个过程的约定
are just Lisp's conventional way of describing that.
694
00:48:35,664 --> 00:48:40,880
让我们再看两个关于define的例子
Let's look at two more examples of defining.
695
00:48:44,464 --> 00:48:46,464
这有两个过程
Here are two more procedures.
696
00:48:46,912 --> 00:48:52,390
定义x和y的平均值为x加上y的和除以2的商
I can define the average of x and y to be the sum of x and y divided by 2.
697
00:48:54,224 --> 00:49:01,040
以及定义好平方和平均值后 我可以定义均方
Or having had average and mean square, having had average and square,
698
00:49:01,200 --> 00:49:04,260
我可以用它们来讨论某元素的均方
I can use that to talk about the mean square of something,
699
00:49:04,464 --> 00:49:08,810
即x的平方与y的平方的平均值
which is the average of the square of x and the square of y.
700
00:49:10,528 --> 00:49:13,184
当定义好它们后 我可以问
So for example, having done that, I could say,
701
00:49:13,216 --> 00:49:24,432
2和3的均方是多少
what's the mean square of 2 and 3?
702
00:49:24,784 --> 00:49:29,790
我将会得到 4和9的平均值 即6.5
And I should get the average of 4 and 9, which is 6.5.
703
00:49:32,400 --> 00:49:36,192
关键点在于 定义了square后
The key thing here is that, having defined square,
704
00:49:36,192 --> 00:49:38,224
我可以把它当作一个基本元素来使用
I can use it as if it were primitive.
705
00:49:40,960 --> 00:49:42,624
因此在这里
So if we look here on the slide,
706
00:49:44,208 --> 00:49:45,296
我在讨论均方的时候
if I look at mean square,
707
00:49:46,848 --> 00:49:52,112
从这点来说 定义均方的人没有必要知道
the person defining mean square doesn't have to know, at this point,
708
00:49:52,160 --> 00:49:55,312
究竟square是由语言内建支持
whether square was something built into the language
709
00:49:56,496 --> 00:49:58,480
还是自定义的过程
or whether it was a procedure that was defined.
710
00:49:59,280 --> 00:50:00,832
这是Lisp的关键之一
And that's a key thing in Lisp,
711
00:50:01,850 --> 00:50:07,072
你无法准确区别
that you do not make arbitrary distinctions between things
712
00:50:07,088 --> 00:50:11,370
哪些是语言的基本对象 哪些是语言的内建支持
that happen to be primitive in the language and things that happen to be built in.
713
00:50:12,384 --> 00:50:14,288
用户使用时则无需关心这些
A person using that shouldn't even have to know.
714
00:50:14,480 --> 00:50:18,064
你自己构建的东西看起来就像是语言自带的基本对象
So the things you construct get used with all the power and flexibility
715
00:50:18,064 --> 00:50:19,088
具有同样的能力和灵活性
as if they were primitives.
716
00:50:19,120 --> 00:50:22,128
大家可以在课后上机做做测试
In fact, you can drive that home by looking on the computer one more time.
717
00:50:24,304 --> 00:50:25,856
我们接下来讨论一下“+”吧
We talked about plus.
718
00:50:26,272 --> 00:50:29,648
好的 让我们在计算机中看看
And in fact, if I come here on the computer screen and say,
719
00:50:29,664 --> 00:50:31,888
“+”的值是什么
what is the value of plus?
720
00:50:33,952 --> 00:50:36,752
注意Lisp在下面的输出
Notice what Lisp types out. On the bottom there, it typed out,
721
00:50:36,800 --> 00:50:38,368
复合过程“+”
"compound procedure plus."
722
00:50:39,440 --> 00:50:41,840
因为在此系统中
Because, in this system,
723
00:50:41,888 --> 00:50:45,040
“+”运算符是一个复合过程
it turns out that the addition operator is itself a compound procedure.
724
00:50:45,520 --> 00:50:47,520
但如果我不输入进去做下测试 你永远不会知道
And if I didn't just type that in, you'd never know that,
725
00:50:47,616 --> 00:50:49,232
所以这没什么不同
and it wouldn't make any difference anyway.
726
00:50:49,392 --> 00:50:50,064
我们并不关心这些
We don't care.
727
00:50:50,112 --> 00:50:52,940
它比我们日常处理的问题更加抽象一些
It's below the level of the abstraction that we're dealing with.
728
00:50:53,728 --> 00:50:58,660
其关键点在于你无法分辨出
So the key thing is you cannot tell, should not be able to tell, in general,
729
00:50:58,720 --> 00:51:03,370
内建元素与复合元素之间的不同
the difference between things that are built in and things that are compound.
730
00:51:03,392 --> 00:51:03,936
为什么会这样呢?
Why is that?
731
00:51:03,936 --> 00:51:07,620
因为复合元素经过了一次抽象封装 (以致于无法分辨)
Because the things that are compound have an abstraction wrapper wrapped around them.
732
00:51:08,608 --> 00:51:11,168
我们已经介绍了Lisp的大多数元素了
We've seen almost all the elements of Lisp now.
733
00:51:12,224 --> 00:51:14,080
还有一个需要进行讨论的
There's only one more we have to look at,
734
00:51:14,128 --> 00:51:16,080
就是如何进行分情况分析
and that is how to make a case analysis.
735
00:51:16,144 --> 00:51:17,250
举个例子
Let me show you what I mean.
736
00:51:18,512 --> 00:51:23,632
让我们考虑绝对值函数的数学定义
We might want to think about the mathematical definition of the absolute value functions.
737
00:51:23,664 --> 00:51:29,580
我或许会说x的绝对值这样是一个函数
I might say the absolute value of x is the function
738
00:51:29,712 --> 00:51:36,790
若x小于0 则为-x
which has the property that it's negative of x. For x less than 0,
739
00:51:37,472 --> 00:51:40,680
若x等于0 则为0
it's 0 for x equal to 0.
740
00:51:42,192 --> 00:51:46,170
若x大于0 则就是x
And it's x for x greater than 0.
741
00:51:48,704 --> 00:51:51,456
而Lisp则有一套分情况分析方法
And Lisp has a way of making case analyses.
742
00:51:51,664 --> 00:51:53,408
以绝对值定义为例 我给大家说明一下
Let me define for you absolute value.
743
00:51:55,104 --> 00:52:01,960
定义绝对值为 x是有多种情况的
Say define the absolute value of x is conditional.
744
00:52:02,576 --> 00:52:05,220
这就是分情况分析
This means case analysis, COND.
745
00:52:08,784 --> 00:52:18,640
如果x小于0 则结果为-x
If x is less than 0, the answer is negate x.
746
00:52:22,544 --> 00:52:24,430
我这里写的是一个子句
What I've written here is a clause.
747
00:52:24,544 --> 00:52:35,090
这整个是一个由两部分组成的条件表达式
This whole thing is a conditional clause, and it has two parts.
748
00:52:35,904 --> 00:52:44,250
这个部分叫做谓词或者条件
This part here is a predicate or a condition.
749
00:52:44,384 --> 00:52:45,456
这就是一种情况(条件)
That's a condition.
750
00:52:45,664 --> 00:52:47,840
用以表达条件的东西叫做谓词
And the condition is expressed by something called a predicate,
751
00:52:47,888 --> 00:52:50,600
Lisp中的谓词是一种
and a predicate in Lisp is some sort of thing
752
00:52:50,928 --> 00:52:52,420
可以返回true或者false的东西
that returns either true or false.
753
00:52:53,088 --> 00:52:55,680
比如说“小于”是Lisp中的一个基本过程
And you see Lisp has a primitive procedure, less-than,
754
00:52:56,848 --> 00:52:58,630
它返回true或者false
that tests whether something is true or false.
755
00:53:00,090 --> 00:53:05,872
子句其余部分为一个动作或者需要做的事
And the other part of a clause is an action or a thing to do,
756
00:53:06,480 --> 00:53:07,696
本例中为true
in the case where that's true.
757
00:53:07,728 --> 00:53:09,360
在这里 我则是取x的相反数
And here, what I'm doing is negating x.
758
00:53:09,632 --> 00:53:13,960
有趣的是 Lisp中减运算符符与相反数运算符相同
The negation operator, the minus sign in Lisp is a little bit funny.
759
00:53:14,112 --> 00:53:17,980
如果有两个及两个以上的参数
If there's two or more arguments,
760
00:53:18,130 --> 00:53:22,048
正如我们看到的 假设刚好有两个参数 就从第一个中减去第二个
if there's two arguments it subtracts the second one from the first, and we saw that.
761
00:53:22,080 --> 00:53:23,680
如果只有一个参数 则取其相反数
And if there's one argument, it negates it.
762
00:53:24,688 --> 00:53:27,420
这与前面相符合
So this corresponds to that.
763
00:53:27,424 --> 00:53:29,240
这又是一个COND子句
And then there's another COND clause.
764
00:53:30,192 --> 00:53:35,424
这是说 在x等于0的时候 结果为0
It says, in the case where x is equal to 0, the answer is 0.
765
00:53:37,504 --> 00:53:44,300
在x大于0的时候 结果为x
And in the case where x is greater than 0, the answer is x.
766
00:53:44,880 --> 00:53:48,930
闭合子句 闭合COND 闭合define
Close that clause. Close the COND. Close the definition.
767
00:53:49,120 --> 00:53:50,848
这就是绝对值的定义
And there's the definition of absolute value.
768
00:53:50,864 --> 00:53:53,216
你会发现分情况分析
And you see it's the case analysis that looks very much
769
00:53:53,216 --> 00:53:55,590
与数学中所用的非常相似
like the case analysis you use in mathematics.
770
00:53:57,696 --> 00:54:02,624
当然还有一些不常用的受限的分情况分析方法
There's a somewhat different way of writing a restricted case analysis.
771
00:54:02,624 --> 00:54:05,792
很多时候 你在进行分情况分析时只有一种情况
Often, you have a case analysis where you only have one case,
772
00:54:06,480 --> 00:54:07,620
你首先进行测试
where you test something,
773
00:54:07,888 --> 00:54:10,300
然后根据返回的为true或false来决定如何处理
and then depending on whether it's true or false, you do something.
774
00:54:10,560 --> 00:54:15,450
这是另外一种定义绝对值的方法
And here's another definition of absolute value
775
00:54:15,552 --> 00:54:16,740
但看起来是几乎一样的
which looks almost the same,
776
00:54:17,216 --> 00:54:22,112
像这样 如果x小于0 结果则为x的相反数
which says, if x is less than 0, the result is negate x.
777
00:54:23,960 --> 00:54:25,520
否则 结果即为x
Otherwise, the answer is x.
778
00:54:25,600 --> 00:54:26,800
我们将会大量的使用“if”
And we'll be using "if" a lot.
779
00:54:26,848 --> 00:54:28,688
再次声明
But again, the thing to remember is that
780
00:54:28,688 --> 00:54:32,256
你们在这里看到的绝对值形式
this form of absolute value that you're looking at here,
781
00:54:33,856 --> 00:54:36,530
和我在黑板上写的那种
and then this one over here that I wrote on the board,
782
00:54:37,072 --> 00:54:38,352
本质上是一样的
are essentially the same.
783
00:54:38,640 --> 00:54:41,810
而“if”和“COND”则是——
And "if" and COND are-- well, whichever way you like it.
784
00:54:41,856 --> 00:54:44,000
你可以把“COND”当做“if”的语法糖
You can think of COND as syntactic sugar for "if",
785
00:54:44,544 --> 00:54:46,912
或者“if”是“COND”的语法糖
or you can think of "if" as syntactic sugar for COND,
786
00:54:46,944 --> 00:54:48,200
这没什么区别
and it doesn't make any difference.
787
00:54:48,768 --> 00:54:50,900
Lisp系统的设计者会从中会选择一个
The person implementing a Lisp system will pick one
788
00:54:50,944 --> 00:54:52,528
然后依照这个来实现另外一个
and implement the other in terms of that.
789
00:54:52,704 --> 00:54:54,224
你首先实现哪一个都无所谓
And it doesn't matter which one you pick.
790
00:55:01,824 --> 00:55:04,910
让我们停下来 解决几点疑问
Why don't we break now, and then take some questions.
791
00:55:05,248 --> 00:55:09,632
为什么我有时用define时
How come sometimes when I write define,
792
00:55:10,640 --> 00:55:14,300
我在这里使用了一个左括号
I put an open paren here and say,
793
00:55:14,368 --> 00:55:16,000
输入 define (XXX
define open paren something or other,
794
00:55:16,416 --> 00:55:20,368
而有时我这样写时却没加左括号
and sometimes when I write this, I don't put an open paren?
795
00:55:21,616 --> 00:55:26,784
是因为你所见的
The answer is, this particular form of "define",
796
00:55:26,816 --> 00:55:28,960
这种“define”表达式
where you say define some expression,
797
00:55:29,024 --> 00:55:31,680
对于定义过程来讲是非常特殊
is this very special thing for defining procedures.
798
00:55:33,168 --> 00:55:39,760
再次强调 这实际上是说我定义这个叫square的符号为这个
But again, what it really means is I'm defining this symbol, square, to be that.
799
00:55:41,008 --> 00:55:45,536
你所知道的则是 你先写一个“define”
So the way you should think about it is what "define" does is you write "define",
800
00:55:46,704 --> 00:55:49,616
然后你再写一个符号 没有左括号
and the second thing you write is the symbol here-- no open paren--
801
00:55:49,728 --> 00:55:51,040
这是你将要定义的符号
the symbol you're defining
802
00:55:51,632 --> 00:55:53,250
这又是你要将其定义为什么
and what you're defining it to be.
803
00:55:54,208 --> 00:55:57,104
就像这儿和这儿
That's like here and like here.
804
00:55:57,168 --> 00:55:59,840
这是“define”的基本使用方法
That's sort of the basic way you use "define."
805
00:56:00,672 --> 00:56:03,200
然而 这种特殊的语法技巧
And then, there's this special syntactic trick
806
00:56:03,840 --> 00:56:06,592
使得你可以定义像这样的过程
which allows you to define procedures that look like this.
807
00:56:07,728 --> 00:56:11,040
因此区别就在于你是否定义了一个过程
So the difference is, it's whether or not you're defining a procedure.
808
00:56:12,464 --> 00:56:37,152
[音乐]
[JESU, JOY OF MAN'S DESIRING]
809
00:56:37,600 --> 00:56:41,536
信不信由你 你们已经学了足够多的Lisp的知识了
Well, believe it or not, you actually now know enough Lisp
810
00:56:42,336 --> 00:56:44,976
现在你基本上可以编写
to write essentially any numerical procedure
811
00:56:45,808 --> 00:56:49,184
FORTRAN、Basic或者其它语言中一样的
that you'd write in a language like FORTRAN or Basic or whatever,
812
00:56:49,216 --> 00:56:50,560
数值计算过程了
or, essentially, any other language.
813
00:56:51,600 --> 00:56:54,310
或许你会说 这不可能
And you're probably saying, that's not believable,
814
00:56:54,368 --> 00:56:56,208
因为你知道这些语言有
because you know that these languages have things
815
00:56:56,208 --> 00:56:59,770
像“for”语句和“do-until-while”语句的东西
like "for statements", and "do until while" or something.
816
00:57:00,544 --> 00:57:04,144
实际上这些我们一点也用不着
But we don't really need any of that.
817
00:57:04,608 --> 00:57:06,680
本课中我们一点也不会使用这些东西
In fact, we're not going to use any of that in this course.
818
00:57:07,808 --> 00:57:09,712
我给你们来个下马威
Let me show you.
819
00:57:09,808 --> 00:57:13,168
回过头来看看平方根
Again, looking back at square root,
820
00:57:13,200 --> 00:57:18,580
让我们看看亚历山大的Heron提出的平方根算法
let's go back to this square root algorithm of Heron of Alexandria.
821
00:57:18,640 --> 00:57:19,520
想想它是怎么说的
Remember what that said.
822
00:57:19,616 --> 00:57:23,220
算法说 为了找到X的平方根的近似值
It said, to find an approximation to the square root of X,
823
00:57:24,624 --> 00:57:25,712
你做出猜测
you make a guess,
824
00:57:27,008 --> 00:57:31,430
然后通过取guess和X/guess的平均数来改进猜测
you improve that guess by averaging the guess and X over the guess.
825
00:57:32,496 --> 00:57:35,616
你不断改进猜测 直到这个猜测足够好
You keep improving that until the guess is good enough.
826
00:57:36,272 --> 00:57:37,984
我已经提到过这种想法
I already alluded to the idea.
827
00:57:38,112 --> 00:57:41,792
这种想法是说 如果你最初采用的猜测
The idea is that, if the initial guess that you took
828
00:57:42,592 --> 00:57:46,460
真真切切的等于X的平方根
was actually equal to the square root of X,
829
00:57:46,704 --> 00:57:49,616
那么G就会等于X/G
then G here would be equal to X/G.
830
00:57:52,448 --> 00:57:54,880
如果你算出平方根 对其取平均数并不会改变它
So if you hit the square root, averaging them wouldn't change it.
831
00:57:55,248 --> 00:57:59,170
如果你所采用的G比X的平方根大
If the G that you picked was larger than the square root of X,
832
00:57:59,936 --> 00:58:02,490
那么X/G就会比X的平方根小
then X/G will be smaller than the square root of X,
833
00:58:02,768 --> 00:58:04,928
因此当你取G与X/G的平均值时
so that when you average G and X/G,
834
00:58:05,184 --> 00:58:07,120
就得到了两者之间的某数
you get something in between.
835
00:58:08,512 --> 00:58:12,500
同理 若你采用的G过小 答案则会过大
So if you pick a G that's too small, your answer will be too large.
836
00:58:12,672 --> 00:58:14,368
如果你采用了一个太大的G
If you pick a G that's too large,
837
00:58:15,872 --> 00:58:17,616
如果你的G比X的平方根还要大的话
if your G is larger than the square root of X
838
00:58:17,632 --> 00:58:19,904
X/G就会比X的平方根还要小
and X/G will be smaller than the square root of X.
839
00:58:20,784 --> 00:58:23,200
因此取平均值使得你总可以得到两者间的某数
So averaging always gives you something in between.
840
00:58:24,080 --> 00:58:27,680
这不是毫无意义的 它表明
And then, it's not quite trivial, but it's possible to show that,
841
00:58:27,728 --> 00:58:31,310
事实上 如果G只差X的平方根一点的话
in fact, if G misses the square root of X by a little bit,
842
00:58:31,360 --> 00:58:37,540
G和X/G的平均值就会慢慢的向X的平方根靠近
the average of G and X/G will actually keep getting closer to the square root of X.
843
00:58:37,584 --> 00:58:38,544
只要你不断的这样做
So if you keep doing this enough,
844
00:58:38,976 --> 00:58:40,736
最终就可以不断地靠近
you'll eventually get as close as you want.
845
00:58:41,264 --> 00:58:42,400
另外一个事实则是
And then there's another fact,
846
00:58:42,576 --> 00:58:47,200
你总可以使用1作为一个初始猜测值来开始计算
that you can always start out this process by using 1 as an initial guess.
847
00:58:48,784 --> 00:58:50,900
它总是朝X的平方根聚拢
And it'll always converge to the square root of X.
848
00:58:51,792 --> 00:58:56,320
这就是亚历山大的Heron的连续求平均值法
So that's this method of successive averaging due to Heron of Alexandria.
849
00:58:56,368 --> 00:58:58,760
让我们在Lisp中实现
Let's write it in Lisp.
850
00:59:00,120 --> 00:59:02,160
中心思想是
Well, the central idea is,
851
00:59:02,208 --> 00:59:06,740
尝试将guess作为X的平方根的一个猜想意味着什么
what does it mean to try a guess for the square root of X?
852
00:59:07,856 --> 00:59:08,928
我来编码
Let's write that.
853
00:59:09,344 --> 00:59:24,576
定义(try guess x)
So we'll say, define to try a guess for the square root of X,
854
00:59:26,000 --> 00:59:27,790
我们该如何做 我们会说
what do we do? We'll say,
855
00:59:27,840 --> 00:59:44,816
如果猜测精确到可以作为X的平方根
if the guess is good enough to be a guess for the square root of X,
856
00:59:46,096 --> 00:59:49,070
那么我们就可以将这个猜测作为答案
then, as an answer, we'll take the guess.
857
00:59:51,168 --> 00:59:56,560
否则 我们就会尝试改进猜测
Otherwise, we will try the improved guess.
858
00:59:57,744 --> 01:00:03,792
我们将通过改进这个猜测来作为X的平方根
We'll improve that guess for the square root of X,
859
01:00:04,816 --> 01:00:08,880
并尝试是否为X平方根
and we'll try that as a guess for the square root of X.
860
01:00:08,912 --> 01:00:12,512
闭合try 闭合if 闭合define
Close the "try." Close the "if." Close the "define."
861
01:00:12,864 --> 01:00:14,368
这就是我们如何尝试一个猜测
So that's how we try a guess.
862
01:00:15,408 --> 01:00:17,150
然后 这个过程的下一步是说
And then, the next part of the process said,
863
01:00:17,280 --> 01:00:21,450
为了计算平方根
in order to compute square roots, we'll say,
864
01:00:21,488 --> 01:00:29,728
定义计算X的平方根为
define to compute the square root of X,
865
01:00:30,352 --> 01:00:35,344
从1作为X的平方根的一个猜测开始尝试
we will try 1 as a guess for the square root of X.
866
01:00:36,976 --> 01:00:39,140
我们必须定义一些其它的东西
Well, we have to define a couple more things.
867
01:00:39,632 --> 01:00:42,912
我们必须说明 一个猜测如何才叫“足够好”
We have to say, how is a guess good enough?
868
01:00:43,392 --> 01:00:44,848
我们又该如何改进这个猜测
And how do we improve a guess?
869
01:00:45,408 --> 01:00:46,656
那么让我们来看看
So let's look at that.
870
01:00:46,944 --> 01:00:53,792
而改进一个X的平方根的一个猜测的算法则是
The algorithm to improve a guess for the square root of X,
871
01:00:54,192 --> 01:00:56,736
取平均数
we average-- that was the algorithm--
872
01:00:56,736 --> 01:01:01,712
我们取guess和X/guess的平均数
we average the guess with the quotient of dividing X by the guess.
873
01:01:02,544 --> 01:01:04,128
这就是我们如何改进一个猜测
That's how we improve a guess.
874
01:01:05,408 --> 01:01:08,352
为了确定一个猜测是否足够精确 我们需要做一下规定
And to tell whether a guess is good enough, well, we have to decide something.
875
01:01:08,416 --> 01:01:10,912
假设这个是X的平方根的一个猜测
This is supposed to be a guess for the square root of X,
876
01:01:10,928 --> 01:01:13,584
你可能做的一件事就是
so one possible thing you can do is say,
877
01:01:13,616 --> 01:01:15,620
当你采用这个猜测并将其平方
when you take that guess and square it,
878
01:01:16,192 --> 01:01:17,968
你会得到一个非常接近于X的数
do you get something very close to X?
879
01:01:18,144 --> 01:01:20,650
而表达这个想法的一种方式是
So one way to say that is to say,
880
01:01:20,672 --> 01:01:23,860
我们用X减去guess的平方
I square the guess, subtract X from that,
881
01:01:24,704 --> 01:01:26,700
并且确认所得结果的绝对值是否
and see if the absolute value of that
882
01:01:26,752 --> 01:01:31,600
比一个由你规定的很小的数还要小
whole thing is less than some small number, which depends on my purposes.
883
01:01:34,256 --> 01:01:40,970
因此 我们就有了计算X的平方根的一整套过程
So there's a complete procedure for how to compute the square root of X.
884
01:01:41,024 --> 01:01:43,088
我们再来深入观察一下这个结构
Let's look at the structure of that a little bit.
885
01:01:47,392 --> 01:01:48,672
我搞定了整件事
I have the whole thing.
886
01:01:48,700 --> 01:01:54,992
我有一个用于计算X的平方根的记号
I have the notion of how to compute a square root.
887
01:01:55,088 --> 01:01:56,432
这是一种模块
That's some kind of module.
888
01:01:56,608 --> 01:01:58,016
也是一种黑盒
That's some kind of black box.
889
01:01:58,272 --> 01:02:07,570
它的定义依赖于如何尝试将一个猜测值作为X的平方根
It's defined in terms of how to try a guess for the square root of X.
890
01:02:08,864 --> 01:02:13,650
定义try是用来
"Try" is defined in terms of, well,
891
01:02:14,160 --> 01:02:17,584
确认某数是否足够精确以及如何去改进该数
telling whether something is good enough and telling how to improve something.
892
01:02:18,288 --> 01:02:19,232
这是good-enogh?
So good enough.
893
01:02:19,440 --> 01:02:28,400
try的定义依赖于good-enough?和improve
"Try" is defined in terms of "good enough" and "improve".
894
01:02:30,512 --> 01:02:32,110
让我们来看看我填入了些什么
And let's see what else I fill in.
895
01:02:32,264 --> 01:02:33,844
如果我向下拓展这棵树
Well, I'll go down this tree.
896
01:02:34,288 --> 01:02:38,048
good-enough?的定义依赖于abs和square
"Good enough" was defined in terms of absolute value, and square.
897
01:02:40,528 --> 01:02:43,680
而improve的定义依赖于averaging
And improve was defined in terms of something called averaging
898
01:02:44,720 --> 01:02:46,256
而其它的都是一些基本运算符
and then some other primitive operator.
899
01:02:46,272 --> 01:02:48,432
平方根的定义依赖于try
Square root's defined in terms of "try".
900
01:02:48,432 --> 01:02:52,864
try的定义依赖于good-enough?和improve
"Try" is defined in terms of "good enough" and "improve",
901
01:02:53,568 --> 01:02:54,944
甚至依赖于try本身
but also "try" itself.
902
01:02:55,136 --> 01:03:00,416
因此try也按照它如何应用于自身而进行定义
So "try" is also defined in terms of how to try itself.
903
01:03:02,304 --> 01:03:04,272
额 这可能会使你有点糊涂
Well, that may give you some problems.
904
01:03:04,272 --> 01:03:07,712
你的高中几何老师或许告诉过你
Your high school geometry teacher probably told you
905
01:03:08,224 --> 01:03:12,128
用一个东西自己去定义自己是很不对的
that it's naughty to try and define things in terms of themselves,
906
01:03:12,432 --> 01:03:13,472
因为这根本行不通
because it doesn't make sense.
907
01:03:13,472 --> 01:03:14,272
这(种说法)是错的
But that's false.
908
01:03:15,584 --> 01:03:19,232
有时候用一个东西自己来定义自己非常有意义
Sometimes it makes perfect sense to define things in terms of themselves.
909
01:03:19,712 --> 01:03:23,930
我们来看看这个例子
And this is the case. And we can look at that.
910
01:03:23,936 --> 01:03:26,448
假设我问Lisp:2的平方根是多少
We could write down what this means, and say,
911
01:03:26,464 --> 01:03:29,888
我们可以写出它究竟是什么意思
suppose I asked Lisp what the square root of 2 is.
912
01:03:32,208 --> 01:03:34,220
2的平方根是什么意思
What's the square root of 2 mean?
913
01:03:35,344 --> 01:03:43,168
意思就是我将用1作为2的平方根的一个猜测
Well, that means I try 1 as a guess for the square root of 2.
914
01:03:46,528 --> 01:03:50,470
然后我考虑 对于2的平方根来说 1是一个足够好的猜测么
Now I look. I say, gee, is 1 a good enough guess for the square root of 2?
915
01:03:51,200 --> 01:03:53,240
这取决于good-enough?是如何判断的
And that depends on the test that "good enough" does.
916
01:03:54,160 --> 01:03:56,112
本例中 good-enough?会说
And in this case, "good enough" will say,
917
01:03:56,208 --> 01:03:58,600
不 对于2的平方根来说 1不是一个足够好的猜测
no, 1 is not a good enough guess for the square root of 2.
918
01:03:59,344 --> 01:04:07,770
因此我会继续说 我试试一个改进值
So that will reduce to saying, I have to try an improved--
919
01:04:08,192 --> 01:04:12,180
改进猜测值1
improve 1 as a guess for the square root of 2,
920
01:04:14,704 --> 01:04:17,010
然后将其作为2的平方根的一个猜测
and try that as a guess for the square root of 2.
921
01:04:18,688 --> 01:04:21,620
改进猜测值1用作2的平方根
Improving 1 as a guess for the square root of 2
922
01:04:21,648 --> 01:04:24,630
也就是说我取1和2/1的平均值
means I average 1 and 2 divided by 1.
923
01:04:26,656 --> 01:04:28,656
因此我们将取平均数
So this is going to be average.
924
01:04:29,136 --> 01:04:38,990
这段代码将会取1和2/1的平均数
This piece here will be the average of 1 and the quotient of 2 by 1.
925
01:04:40,384 --> 01:04:42,300
那么这段代码
That's this piece here.
926
01:04:43,408 --> 01:04:46,270
我算算 结果是1.5
And I'm gonna try... And this is 1.5.
927
01:04:48,624 --> 01:04:53,952
因此这个(sqrt 2)归约到(try 1 2)
So this square root of 2 reduces to trying 1 for the square root of 2,
928
01:04:54,112 --> 01:05:04,380
然后归约到(try 1.5 2)
which reduces to trying 1.5 as a guess for the square root of 2.
929
01:05:05,584 --> 01:05:07,616
因此这行得通
So that makes sense.
930
01:05:07,664 --> 01:05:09,072
让我们看下剩下的步骤
Let's look at the rest of the process.
931
01:05:09,280 --> 01:05:14,550
如果我尝试1.5 则会归约到
If I try 1.5, that reduces.
932
01:05:14,560 --> 01:05:18,608
1.5作为2的平方根的猜测 并不是足够好
1.5 turns out to be not good enough as a guess for the square root of 2.
933
01:05:19,776 --> 01:05:21,552
然后又归约到
So that reduces to trying the average of
934
01:05:21,568 --> 01:05:25,720
(try (average 1.5 (/ 2 1.5)))
1.5 and 2 divided by 1.5 as a guess for the square root of 2.
935
01:05:27,840 --> 01:05:29,920
平均值是1.333
That average turns out to be 1.333.
936
01:05:30,736 --> 01:05:34,790
然后整个事又归约到(try 1.3333 2)
So this whole thing reduces to trying 1.333 as a guess for the square root of 2.
937
01:05:34,832 --> 01:05:35,616
如此进行下去
And then so on.
938
01:05:37,568 --> 01:05:41,216
然后又归约到(good-enough? 1.4)或者其它的
That reduces to another called a "good enough", 1.4 something or other.
939
01:05:41,280 --> 01:05:44,020
然后这个(步骤)会持续进行到
And then it keeps going until the process finally stops
940
01:05:44,400 --> 01:05:47,472
good-enough?认为足够好了才停止
with something that "good enough" thinks is good enough, which,
941
01:05:47,520 --> 01:05:50,832
本例中 是1.4242或者其它的东西
in this case, is 1.4142 something or other.
942
01:05:52,064 --> 01:05:55,600
因此这个这个过程运行得非常完美
So the process makes perfect sense.
943
01:05:59,488 --> 01:06:02,656
这种定义方法叫做“递归定义”
This, by the way, is called a recursive definition.
944
01:06:13,952 --> 01:06:20,510
进行递归定义将会给你带来无穷威力
And the ability to make recursive definitions is a source of incredible power.
945
01:06:21,504 --> 01:06:22,608
之前我已提到过
And as you can already see I've hinted at,
946
01:06:22,640 --> 01:06:26,768
递归定义可以在不增加任何负担的前提下
it's the thing that effectively allows you to do these infinite computations
947
01:06:26,800 --> 01:06:28,380
仅仅通过调用过程 在达到条件之前
that go on until something is true,
948
01:06:29,280 --> 01:06:33,216
完成无限次的计算
without having any other constricts other than the ability to call a procedure.
949
01:06:35,520 --> 01:06:37,020
还有一点要说明的
Well, let's see, there's one more thing.
950
01:06:37,264 --> 01:06:43,760
我再在这里给你们演示另外一种平方根的定义方法
Let me show you a variant of this definition of square root here on the slide.
951
01:06:43,984 --> 01:06:47,712
这两种方法看起来像是一样的
Here's sort of the same thing.
952
01:06:47,952 --> 01:06:51,040
在这儿 我把improve、good-enough?、try的定义
What I've done here is packaged the definitions of
953
01:06:51,072 --> 01:06:55,712
全都封装在了sqrt里面
"improve" and "good enough" and "try" inside "square root".
954
01:06:56,304 --> 01:07:00,544
因此实际上 我们构建了一个平方根盒子
So, in effect, what I've done is I've built a square root box.
955
01:07:01,360 --> 01:07:08,080
我构建了一个其它人可以使用的平方根盒子
So I've built a box that's the square root procedure that someone can use.
956
01:07:08,128 --> 01:07:11,024
它们输入36 然后(盒子)输出6
They might put in 36 and get out 6.
957
01:07:11,360 --> 01:07:13,380
但是 盒子里面封装的过程
And then, packaged inside this box
958
01:07:13,712 --> 01:07:23,400
就是try、good-enough?和improve的定义
are the definitions of "try" and "good enough" and "improve."
959
01:07:26,336 --> 01:07:27,904
它们都隐藏在盒子里面
So they're hidden inside this box.
960
01:07:27,952 --> 01:07:30,310
这样做是因为
And the reason for doing that is that,
961
01:07:30,736 --> 01:07:32,400
如果有人正在使用这个平方根
if someone's using this square root,
962
01:07:32,768 --> 01:07:34,288
如果George正在使用这个平方根
if George is using this square root,
963
01:07:34,304 --> 01:07:36,910
George并不会关心
George probably doesn't care very much that,
964
01:07:37,840 --> 01:07:39,584
当我在实现平方根时
when I implemented square root,
965
01:07:39,760 --> 01:07:44,000
我定义了盒子内的那些try、good-enough?和improve过程
I had things inside there called "try" and "good enough" and "improve".
966
01:07:45,952 --> 01:07:48,880
事实上 Harry可能会实现一个也具有
And in fact, Harry might have a cube root procedure
967
01:07:48,928 --> 01:07:50,512
try、good-enough?和improve的立方根盒子
that has "try" and "good enough" and "improve".
968
01:07:50,992 --> 01:07:52,896
因此 为了不让整个系统变得混乱
And in order to not get the whole system confused,
969
01:07:52,912 --> 01:07:57,216
Harry最好把这些内部过程封装在它的立方根过程里
it'd be good for Harry to package his internal procedures inside his cube root procedure.
970
01:07:57,952 --> 01:07:59,616
这个叫做块结构
Well, this is called block structure,
971
01:07:59,872 --> 01:08:08,510
这是把东西打包到定义内部的一种方法
this particular way of packaging internals inside of a definition.
972
01:08:09,520 --> 01:08:12,512
让我们回过头来再看看
And let's go back and look at the slide again.
973
01:08:12,672 --> 01:08:18,128
这种过程的定义读作 定义“sqrt”为
The way to read this kind of procedure is to say, to define "square root",
974
01:08:19,424 --> 01:08:21,392
那么 在其内部
well, inside that definition,
975
01:08:21,680 --> 01:08:25,040
我们已有improve的定义
I'll have the definition of an "improve" and
976
01:08:25,110 --> 01:08:28,432
我们已有good-enough?和try的定义
the definition of "good enough" and the definition of "try."
977
01:08:29,280 --> 01:08:31,930
以及这些定义的实体
And then, subject to those definitions,
978
01:08:32,032 --> 01:08:34,624
我求平方根的定义实体是从1开始尝试
the way I do square root is to try 1.
979
01:08:35,630 --> 01:08:38,880
注意这里 我不必将X当做参数传递
And notice here, I don't have to say 1 as a guess for the square root of X,
980
01:08:39,424 --> 01:08:41,872
因为它们都在平方根内部
because since it's all inside the square root,
981
01:08:42,391 --> 01:08:44,201
它相当于已知这个X了
it sort of has this X known.
982
01:08:53,616 --> 01:08:55,920
我来总结下
Let me summarize.
983
01:08:56,048 --> 01:08:59,040
我们从表述指令性知识
We started out with the idea that
984
01:08:59,060 --> 01:09:02,736
开始学习
what we're going to be doing is expressing imperative knowledge.
985
01:09:04,544 --> 01:09:09,296
这张幻灯片总结了一些关于Lisp的知识
And in fact, here's a slide that summarizes the way we looked at Lisp.
986
01:09:09,296 --> 01:09:14,670
我们从基本元素如“+”和“*”开始
We started out by looking at some primitive elements in addition and multiplication,
987
01:09:15,408 --> 01:09:19,056
一些用于测试某物小于或等于的谓词
some predicates for testing whether something is less-than or something's equal.
988
01:09:19,072 --> 01:09:22,544
事实上 我们正在使用的系统掩盖了很多细节
And in fact, we saw really sneakily in the system we're actually using,
989
01:09:22,576 --> 01:09:25,408
这些并不是系统的基本元素 但这无所谓
these aren't actually primitives, but it doesn't matter.
990
01:09:26,176 --> 01:09:28,144
重要的是我们会把它们当作是基本元素
What matters is we're going to use them as if they're primitives.
991
01:09:28,160 --> 01:09:29,360
我们不会去研究系统的内部
We're not going to look inside.
992
01:09:29,840 --> 01:09:32,700
我们也有一些基本数据和一些数
We also have some primitive data and some numbers.
993
01:09:34,176 --> 01:09:37,216
我们学习了合成的手段 组合的手段
We saw some means of composition, means of combination,
994
01:09:37,290 --> 01:09:40,928
用运算符和运算对象合成函数
the basic one being composing functions and
995
01:09:40,960 --> 01:09:43,312
和构建组合式的基本方法
building combinations with operators and operands.
996
01:09:44,368 --> 01:09:47,980
还有一些像是“COND”、“if”和“define”的东西
And there were some other things, like COND and "if" and "define".
997
01:09:50,848 --> 01:09:53,248
具体来说 关于“define”的重点则是
But the main thing about "define," in particular,
998
01:09:53,424 --> 01:09:55,264
它是一种进行抽象的方法
was that it was the means of abstraction.
999
01:09:55,280 --> 01:09:57,250
它是我们为某物命名的方法
It was the way that we name things.
1000
01:09:57,340 --> 01:09:59,856
我们之前提到过 从这里也可以看出来
You can also see from this slide not only where we've been,
1001
01:10:01,120 --> 01:10:05,830
有时候 我们需要研究如何通过组合基本数据来得到复合数据
At some point, we'll have to talk about how you combine primitive data to get compound data,
1002
01:10:06,112 --> 01:10:11,584
以及如何抽象数据 使得你可以在一个更大的环境中
and how you abstract data so you can use large globs of data
1003
01:10:11,616 --> 01:10:12,624
将其当作基本数据使用
as if they were primitive.
1004
01:10:13,456 --> 01:10:15,424
这也是我们的目的所在
So that's where we're going.
1005
01:10:15,936 --> 01:10:21,600
在我们讨论这个问题之前 下节课我们首先将会讨论
But before we do that, for the next couple of lectures we're going to be talking about,
1006
01:10:22,816 --> 01:10:26,310
我们编写的过程与机器内部
first of all, how it is that you make a link
1007
01:10:26,432 --> 01:10:30,320
进程之间的联系
between these procedures we write and the processes that happen in the machine.
1008
01:10:31,696 --> 01:10:35,530
接着 我们将跳出小规模的计算问题
And then, how it is that you start using the power of Lisp
1009
01:10:35,936 --> 01:10:39,328
来学习如何发挥Lisp的威力
to talk not only about these individual little computations,
1010
01:10:39,637 --> 01:10:43,701
来解决更加通用的计算问题
but about general conventional methods of doing things.
1011
01:10:44,368 --> 01:10:45,720
好了 大家还有什么问题么
OK, are there any questions?
1012
01:10:46,304 --> 01:10:51,820
学生:在定义A时 如果我们用一个括号将A括起来
AUDIENCE: Yes. If we defined A using parentheses instead of as we did,
1013
01:10:51,872 --> 01:10:53,050
会与不使用括号不同么?
what would be the difference?
1014
01:10:53,152 --> 01:10:56,432
教授:如果我这样写
PROFESSOR: If I wrote this, if I wrote that,
1015
01:10:57,088 --> 01:11:01,680
我则会是定义一个过程并命名为A
what I would be doing is defining a procedure named A.
1016
01:11:02,768 --> 01:11:06,400
本例中 这个过程没有参数
In this case, a procedure of no arguments, which,
1017
01:11:06,400 --> 01:11:09,160
而当我运行它 则会返回5乘以5
when I ran it, would give me back 5 times 5.
1018
01:11:10,624 --> 01:11:11,840
学生:它们俩完成了相同的事
AUDIENCE: Right. I mean, you come up with the same thing,
1019
01:11:11,872 --> 01:11:13,470
但本质上是否相同?
except for you really got a different--
1020
01:11:13,600 --> 01:11:16,180
教授:好 的确会有不同 之前的那一个
PROFESSOR: Right. And the difference would be, in the old one--
1021
01:11:16,576 --> 01:11:17,904
我还是在这里写清楚一点吧
Let me be a little bit clearer here.
1022
01:11:18,688 --> 01:11:22,992
我们还是把这个叫做A
Let's call this A, like here.
1023
01:11:23,680 --> 01:11:27,312
作为对比 我们假装这里有一个
And pretend here, just for contrast, I wrote,
1024
01:11:27,344 --> 01:11:37,110
我定义D为5乘以5
define D to be the product of 5 and 5.
1025
01:11:39,776 --> 01:11:41,120
这两者的区别则是
And the difference between those,
1026
01:11:41,510 --> 01:11:43,792
让我们看看它们在Lisp解释器中是怎样的
let's think about interactions with the Lisp interpreter.
1027
01:11:45,296 --> 01:11:48,680
我在Lisp中键入A 返回25
I could type in A and Lisp would return 25.
1028
01:11:52,384 --> 01:11:57,360
如果我仅仅键入D
I could type in D, if I just typed in D,
1029
01:11:58,048 --> 01:12:05,104
Lisp返回复合过程D
Lisp would return compound procedure D,
1030
01:12:06,672 --> 01:12:08,680
因为D就是一个过程
because that's what it is. It's a procedure.
1031
01:12:09,248 --> 01:12:12,144
我可以运行D 我可以问运行D的结果是什么
I could run D. I could say, what's the value of running D?
1032
01:12:12,144 --> 01:12:14,780
这是一个没有运算数的组合式
Here is a combination with no operands.
1033
01:12:16,000 --> 01:12:18,620
我考虑到它没有运算数 所以我在D后面没有键入任何东西
I see there are no operands. I didn't put any after D.
1034
01:12:18,944 --> 01:12:20,890
Lisp则会说结果是25
And it would say, oh, that's 25.
1035
01:12:22,560 --> 01:12:29,072
我再说周全一点 如果我键入 A的运行结果是多少
Or I could say, just for completeness, if I typed in, what's the value of running A?
1036
01:12:29,090 --> 01:12:30,120
只能得到一个错误
I get an error.
1037
01:12:31,344 --> 01:12:34,848
跟这里的错误一样
The error would be the same one as over there.
1038
01:12:34,880 --> 01:12:40,060
这个错误是因为 A的值——25
It'd be the error would say, sorry, 25, which is the value of A,
1039
01:12:40,112 --> 01:12:42,790
并不是我可以应用于某物的运算符
is not an operator that I can apply to something.
1040
01:12:43,392 --> 01:12:48,432
MIT OpenCourseWare
http://ocw.mit.edu
1041
01:12:48,688 --> 01:12:54,416
本项目主页
https://github.com/FoOTOo/Learning-SICP
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。