-
Notifications
You must be signed in to change notification settings - Fork 0
/
up2020-zh-2.tex
500 lines (459 loc) · 40.5 KB
/
up2020-zh-2.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
\newpart
\section{Hilbert 第 24 问题:数学中的极简主义}\label{sec:hilbert}
1900 年,David Hilbert 发表了一个包含 23 道未解数学难题的清单,这些将被称为
“Hilbert 问题”的难题影响了整个 20 世纪的数学家,而且仍在产生重要影响;2000 年,
有人在 Hilbert 的笔记中发现了一个因故被排除在原先清单之外的附加问题,而我们就
从这个第 24 问题\cupercite{wiki:hilbert}开始本部分的内容。Hilbert 第 24 问题
本质上寻求的是对数学证明简洁性的形式化标准,以及论证给定证明是相应定理最简证明
的方法;由此我们已经可以注意到在数学中同样存在对简洁性的追求,而这种追求其实也
存在于其他伟大数学家身上,例如 Paul Erdős 经常提起“THE BOOK”\footnote{其在现实
世界中的一个“近似”,《Proofs from THE BOOK》\cupercite{wiki:thebook},在 1998
年被献给 Paul Erdős,后者在此书编写过程中提出许多建议,但在其出版之前就逝世
了。},一本假想的上帝用来保存最简证明的书,并且在 1985 年的一场讲座中说到:
\begin{quoting}
You don't have to believe in God, but you should believe in THE BOOK.
\end{quoting}
对简洁性的追求似乎也并不是大师们的专利,因为 Edsger W.\ Dijkstra 曾经说过:
\begin{quoting}
How do we convince people that in programming simplicity and clarity --
in short: what mathematicians call ``elegance'' -- are not a dispensable
luxury, but a crucial matter that decides between success and failure?
\end{quoting}
由此可见数学家在某种意义上比程序员更加极简主义,而我们将在第
\ref{sec:science} 节中见到极简主义在数学中的一种极端体现。
在 Hilbert 关于第 24 问题的笔记中,他试图将一族特定的证明归约为一族主要由
特定类型元素组成的序列,并通过序列的长度来判断简洁性;从程序语言的角度,这不难
推广\footnote{这种对应关系可以通过\stress{Gödel 数}\cupercite{wiki:godelnum}来
形式化,后者将不同的程序映射到不同的整数,而这种操作也可以应用到证明上,因此每个
证明在形式上都等价于一个程序。但这种关系不能反过来,因为证明必须在有限步内结束,
而程序则不必这样;不过因为算法也须要在有限步内结束,每个算法在形式上都等价于
一个证明。}:证明(类似于程序)毕竟是基于公理(类似于基本操作),因此通过将
所涉及定理的证明(类似于库函数的实现)嵌入的方式,我们可以将一个证明归约
为对公理的一系列应用,于是就能计数了。考虑到这种对应关系,我们可以像
重构程序一样\stress{“重构”证明和命题}来让它们更加简短、清晰,例如
\begin{quoting}
对矩约束下的离散概率测度,具有 (*) 式形式的概率测度只要存在,则必唯一且
必为最大熵分布;而最大熵分布只要存在,则必然有 (*) 式的形式,因而也必唯一。
\end{quoting}
可以重构为
\begin{quoting}
对矩约束下的离散概率测度,存在最大熵分布当且仅当存在
具有 (*) 式形式的概率测度,此时两者必等同且唯一。
\end{quoting}
沿用这一思路,我们应该可以构造 Hilbert 所想的对简洁性的形式化标准,但关于论证
证明最简性的那一部分怎么办呢?我的猜想是应该存在无法论证为最简的证明,这里我用
将在第 \ref{sec:kolmogorov} 节进一步讨论的 Kolmogorov 复杂度来说明这一猜想。
为了论证一个证明的最简性,我们很可能须要寻找可行证明的复杂度下界,这一下界似乎
和 Kolmogorov 复杂度紧密相连;然而即使忽略后者的不可计算性,Chaitin 不完全定理
也证明存在一个复杂度上界,我们无法论证一个证明的复杂度不低于此上界。那么如果
被证明定理的复杂度已经超过这一上界,我们该怎么办呢?此时连可行证明的
最低复杂度都无法论证,这就 Hilbert 所追求的方法而言显然不妙。
\section{Boltzmann 公式:公理还是定理?}\label{sec:boltzmann}
当年在我参加我后来被录取那家单位的考研面试时,一位面试老师问了我“Boltzmann
公式 $S = k_\mathrm{B} \ln\varOmega$ 在统计物理中是公理还是定理?”的问题。
从当时各位老师的反应来看,我的回答“都可以”让他们颇为惊讶,于是我解释了
我想表达的意思是一组命题可以基于多组互相可替代的基础公理,而一个命题
可以在一些基础之上是公理,同时在另一些基础之上又是定理。也许是这一
完整回答仍然出乎那些老师(主要是物理学家)预料的缘故,他们没有再
追问;但上述问题显然不应到此为止,而我将在本节深入考察这一问题。
在我的回答之后可以立刻追问的一个问题是“那么哪种方案好?”,因为\stress{各组
基础公理并不一样好},尽管它们可以“rebase”到彼此之上:例如我们可以在一组公理中
加入一个已知的定理,由此产生的公理组显然和之前的公理组具有相同的相容性,只是
前者有额外的冗余性。此外,即使在多个互相等价的极小公理组中,有些也可能不便
使用\footnote{出于对函数式编程的好奇,我在还是博士生的时候参加了一次具有很强
科普性质的关于范畴论的报告,其中报告人提到了一些数学家把数学从集合论 rebase
到范畴论的努力。尽管这种努力在学术上可能很有趣,我对其在实际应用中的重要性感到
怀疑:从我极其粗浅的了解来看,对基本数学概念的范畴论形式化似乎比其集合论类似物
要更加复杂,因此根据本节的模型来看,前者似乎并不比后者优越。}:打个比方,尽管
存在许多 Turing 等价的计算模型,计算机科学家在一般性的讨论中最常用的仍然只是
Turing 机、lambda 演算以及其它少数几种模型,而不是元胞自动机乃至 \verb|sed|。
我用一种我称为“\stress{推导图}”的基于图的模型来分析后一问题,这一模型以命题为
节点、以推导为边,因此它和依赖图很相关但又有明显的区别:第一,经常有“等价”的可以
互相推导的命题,所以推导图中一般有环,而非像依赖图那样无环(参考下图左边 3 个微分
中值定理之间的关系);第二,一个命题常常可以用多种方式证明,所以推导图中须要有
析取节点(也就是“虚节点”,例如下图右边的“$7 \times 6 = 42$”节点);第三,一些
证明比其它的证明更复杂,所以推导图中的边是带权的。有了这一模型,我们就可以
通过从各公理组张成全图时的总路径权重来比较这些公理组,而这种总权重
正好和生成所有命题过程的复杂程度这一直观概念相联系。
\colskipa\begin{multicols}{2}
\begin{wquoting}
\begin{tikzpicture}[thm/.style = {
align = center, font = \linespread{1}\selectfont
}, shorten <= 0.1em, shorten >= 0.1em]
\tikzmath{\dista = 2.5\baselineskip;}
\node (rolle) at (\dista, 4\baselineskip)
[thm, anchor = north] {Rolle 定理};
\node (lagrange) at (0, 0)
[thm, anchor = south] {Lagrange\\中值定理};
\node (cauchy) at (2 * \dista, 0)
[thm, anchor = south] {Cauchy\\中值定理};
\draw [<-] (rolle) -- (lagrange); \draw [->] (rolle) -- (cauchy);
\draw [->, transform canvas = {xshift = -0.5em}] (rolle) -- (lagrange);
\draw [<-, transform canvas = {xshift = 0.5em}] (rolle) -- (cauchy);
\draw [->] (cauchy) -- (lagrange);
\end{tikzpicture}
\end{wquoting}
\begin{wquoting}
\begin{tikzpicture}[
prop/.style = {draw, circle, minimum size = 0.25em, inner sep = 0},
typ/.style = {draw, rectangle, inner sep = 0, font = \scshape}
]
\newcommand*{\mm}{\ensuremath{\!\times\!}}
\newcommand*{\pp}{\ensuremath{\!+\!}}
\newcommand*{\ee}{\ensuremath{\!=\!}}
\tikzmath{
\unit = \baselineskip; \dista = 5 * \unit;
\lena = 1.08 * \unit; \lenb = 0.96 * \unit;
\lenc = \dista - 2 * \lena; \distb = 0.5 * \dista;
}
\foreach \i/\t in {%
0/{$6\mm6\ee36$},1/{$36\pp6\ee42$},2/{$7\mm5\ee35$},3/{$35\pp7\ee42$}%
} {
\node (p\i) at (0, -\i * \unit) [prop] {};
\node at (0, -\i * \unit) [anchor = east] {\t};
}
\node (p4) at (\dista, -1.5 * \unit) [prop] {};
\node (p5) at (\distb, -0.5 * \unit) [prop] {};
\node (p6) at (\distb, -2.5 * \unit) [prop] {};
\node at (\dista, -1.5 * \unit) [anchor = west] {$7 \mm 6 \ee 42$};
\foreach \j/\a/\b/\c/\t in {%
0/0/{1/4}/0.5/{\&},1/0/{1/4}/2.5/{\&},2/1/{3/4}/1.5/or%
} {
\node (t\j) at ({(\a + 1/2) * \lena + \b * \lenc}, - \c * \unit)
[typ, minimum width = \lena, minimum height = \lenb] {\t};
}
\foreach \i/\j in {0/0,1/0,2/1,3/1,5/2,6/2} \draw [->] (p\i) -- (t\j);
\foreach \i/\j in {4/2,5/0,6/1} \draw (p\i) -- (t\j);
\end{tikzpicture}
\end{wquoting}
\end{multicols}\colskipb
推导图在实际的定量应用中用处多半不大,主要原因是此时涉及的形式化系统是无穷的,
但推导图作为一个概念仍然具有很强的指导意义,而我们将在本部分中多次涉及这一概念。
例如推导图有助于解释第 \ref{sec:user} 节中的知识重要性判据:通过掌握具有较强
普适性(联系到图中其它许多部分)和有用性(简化复杂的推导)的概念,我们将能明显
更高效地理解所学的内容。在结束本节之前,我们先暂时回到 Boltamann 公式的问题:
我猜测这一公式在几乎所有合理的极小公理组之上应该都会是定理,只要熵 $S$
在统计物理中还是一个导出概念而非原始概念。
\section{Kolmogorov 复杂度和信息组织}\label{sec:kolmogorov}
在之前各节中,我们已经多次初步涉及在特定场景中复杂度下界的问题:例如在
考虑如何论证给定公理的某一证明的简洁性(见第 \ref{sec:hilbert} 节)时,我
考察了可行证明最小复杂度的概念;早在讨论内聚(见第 \ref{sec:coupling} 节)
时,我把它定义成子模块间本质性的耦合,这也和某种不可避免的复杂度相关联。
在考虑客体的本质复杂度时,人们经常使用 \stress{Kolmogorov 复杂度}%
\cupercite{wiki:kolmogorov},而我们将在本节对这一概念进行进一步考察。
从本质上看,一个客体(通常编码为字符串)的 Kolmogorov 复杂度是可以产生它的
计算机程序的最小长度,其值对所用程序语言只有很弱的依赖性:两个语言所对应
复杂度的值之差具有一个只和这对语言相关、和字符串无关的上界。Kolmogorov
复杂度是一个\stress{不可计算}的函数,换言之我们可以证明根本无法编写一个
能对所有输入计算其值的程序;此外 Chaitin 不完全定理表明可证明的复杂度
下界值存在一个上界,这一上界只取决于证明所使用的语言和证明所用的
公理系统,所以我们甚至无法证明一个字符串比这一上界更复杂。
你一定会好奇,既然 Kolmogorov 有这么“不好”的性质,那它还有多大意义?据我所知,%
Kolmogorov 的确极少用于对复杂度的实际度量,而主要是用来证明各种不可能性,例如
特定函数的不可计算性。然而这也意味着一件事:从上文很容易注意到信息压缩\footnote%
{顺便提到,Hutter 奖\cupercite{wiki:hutter}(实质是对文本形式的人类知识进行无
损压缩的竞赛)在信息压缩、信息组织和人工智能这几个领域之间架起了桥梁。}的极限
正是 Kolmogorov 复杂度,因此这一复杂度的不可计算性及其下界在多数情况下的不可
证明性说明对信息压缩的研究将永远不会有一个正式的终结。类似的结论在其它研究领域
中也存在,它们被总结为“full employment theorem\cupercite{wiki:employ}”;在一个
有些哲学意味的层面上看,虽然那些“不好”的性质表明了这些领域中可用形式化理论的
局限性,但是它们同时也表明\stress{人的努力并不会轻易地被计算机程序取代}。
有必要注意,Kolmogorov 复杂度所度量的是已知客体的本质复杂度,而不能轻易扩展到对
多个可能但未知的客体,例如一个定理的所有可行证明之间的比较。此外,Kolmogorov
复杂度在和信息压缩紧密相关但不那么形式化的领域,例如图书馆学中的\stress{信息
组织}领域中适用性更差;我认为广义的信息组织正是编程对系统复杂度的极小化在现实
世界中的对应物,所以它必须或多或少地符合极简主义。当然,正如推导图模型一样,
尽管 Kolmogorov 复杂度并不能定量地应用于实际问题(并不完全如此,我们
将在第 \ref{sec:ockham} 节中看到其一些间接应用),它在概念上
仍然具有指导意义,因其本质是\stress{描述复杂度}。
\section{科学技术中的极简主义}\label{sec:science}
到目前为止,本部分中主要讨论的是数学和假想的公理化物理中的极简主义,但极简主义也
可以在其它的科学技术领域,特别是那些\stress{复杂度会带来可观的有形成本}的领域中
观察到,这些成本既包含经济成本也包括脑力成本。就此而言,传统的工程领域是一个不错
的例子,因为其中复杂度的经济成本在技术进步的背景下仍然明显:只要一个工程项目的
预算有些紧张,如果完成同一任务的简单方法没有其它严重的代价,那么它一般会优先于
复杂方法被考虑。例如 Jon Bentley 在《编程珠玑》\footnote{其在《ACM 通讯》
上的同名专栏正是最初讨论词频排序问题(见第 \ref{sec:shell} 节)
的地方。}中写到\cupercite{bentley1999}:
\begin{quoting}
General Chuck Yeager (the first person to fly faster than
sound) praised an airplane's engine system with the words
``simple, few parts, easy to maintain, very strong''.
\end{quoting}
极简主义显然也是理论物理学家的一种追求,例如《人月神话》的
作者 Fred Brooks 在《没有银弹》\cupercite{brooks1987}中写到:
\begin{quoting}
Einstein repeatedly argued that there must be simplified
explanations of nature, because God is not capricious or
arbitrary. No such faith comforts the software engineer.
\end{quoting}
这一态度让我们回想起 Plan~9 中系统调用的精简化(见第 \ref{sec:plan9} 节),而
类似的态度在理论物理中的其它著名人物,例如 Issac Newton(注意其《自然哲学的数学
原理》)、James Clerk Maxwell(注意其方程组)等等身上也很明显。我们也可以注意到
以优雅推导的形式体现的极简主义,这和对需求的优雅实现相对应:我的一位学力学的朋友
曾经提到,在不少流体动力学教材花费大量(有时一两章)篇幅分析重力波\footnote%
{注意不是广义相对论中的引力波。}的背景之下,Lev Landau 和 Evgeny Lifshitz
的《理论物理学教程》只用长约 10 页的一节就将其解释清楚,
而这 10 页中还有好几页是习题及其解答。
从一小组规则中推出系统性理论的传统当然可以追溯到更早,而人们通常将 Euclid
的《几何原本》看作最早采取这一做法的最重要资料之一;几何学成为西方教育中一个
不可或缺部分的原因几乎无可争议地就是《几何原本》,但此书在代数上有一个问题:其中
所有的代数命题和推导都是以句子而非公式写成的,这或许是因为当时的数字符号系统太
难用。20 世纪,Bourbaki 数学学派\footnote{他们用于表示警告的弯道符号直接启发了
Donald Knuth 使用“\textdbend”。}在用基于集合论的纯公理化方法构建数学基础的过程中
采用了完全相反的做法:他们的著作的确具有极其深远的影响和非常积极的意义,但其内容
风格极为简练、抽象,少有解释性的评注、只有最少量的例子,而且几乎没有图像、完全
不谈实际应用。这虽然并不影响 Bourbaki 著作在逻辑上的正确性,但是也为试图理解
其内容的读者制造了困难;第 \ref{sec:cognitive} 节会深入分析这一问题,
这里我只希望在结束本节之前再额外讨论一个可能值得考虑的问题。
在讨论当前所用数学基础万一被证明不相容可能造成的结果时\cupercite{gaillard2010}%
\footnote{如果你好奇为什么居然会有这样的问题,注意 \stress{Gödel 不完全定理}%
\cupercite{wiki:godelthm}(事实上是其中的第二定理)论证了这些数学基础不能自证其
相容性,所以这一理论问题是有一定根据的。},有人指出多数学者完全可以找个替代的
数学基础,然后继续自己的日常工作;毕竟集合论诞生于 1870 年代,晚于其它许多
领域,而且许多结果的集合论表述不过是用另一种数学语言重新陈述已有结果:例如
V.~I.\ Arnold 在 1963--1964 年不借助公理化的手段向中学生讲授了群论的内容,并
能在半年内讲到一般五次方程根式解不存在性的一个拓扑学证明\cupercite{arnold1998,
alekseev2004}\footnote{顺便提到,Dan Friedman 的好几部著作,例如《The Little
Schemer》和《The Little Prover》,也达成了类似的目标。}。类似的现象在物理学
中也存在,例如量子力学的现象学结论对实际底层原理的相对独立性,以及宏观
热力学结论对底层统计物理原理的相对独立性;这些现象证明了形式化系统和
半形式化系统中\stress{抽象层之间相对分离}的存在性,就像软件系统中的
类似构造一样:从推导图的角度看,通过加入更加原始公理的方式,我们
可以将一个推导图中的公理转换为另一推导图中的定理,而此时虽然会
出现对现有命题的新证明途径,但是整个图的总体结构不会有太大的改变。
\section{科学和非科学理论中的极简主义}\label{sec:ockham}
在本部分中,我已经提到几种理论,它们中的每一种基于一组极小的基本假设,这些
假设在形式化之后便成为公理;在上节,我提到这样的传统和 Euclid 的《几何原本》
有着密切的联系,但并未把这一传统限制在科学技术领域,因为它其实也被许多哲学家
乃至一些神学家贯彻。一个介于这些领域之间的重要例子是 Pierre-Simon Laplace
在被 Napoleon Bonaparte 问起其五卷巨著《天体力学》中为何没有提及上帝时的
回答:“我不需要这一假设”。这一传统被总结为称作 \stress{Ockham 剃刀}%
\cupercite{wiki:ockham}的原则,通常表述为“若无必要,勿增实体”;有必要
指出,Ockham 剃刀是在多个理论都和已有观测吻合且做出同样的预测时用于在
它们之中进行选择的原则,它并不意味着最简的理论在所有情形下都最有可能正确。
现已存在多种利用和概率论相关的形式化手段来从数学上论证 Ockham 剃刀的尝试,例如
关于最小信息长度\cupercite{wiki:mml}(MML)和最小描述长度\cupercite{wiki:mdl}%
(MDL)的理论;MML 和 MDL 都是受到第 \ref{sec:kolmogorov} 节所讨论 Kolmogorov
复杂度启发的产物,但和 Kolmogorov 复杂度不同的是 MML 和 MDL 可以用于统计模型
的实际挑选。MML 和 MDL 方法之间有比较微妙的区别,但两者大体思路相近:以某种
方法表示一个模型,并把它和观测数据被这一模型编码之后的表示连接起来,而我们
可以证明\stress{具有最短联合表示的模型最有可能是正确模型}。由此可见 MML 和
MDL 在数学上和信息压缩有着很强的关联,这使它们和 Kolmogorov 复杂度相联系;
而如果我们将已有观测看作数据,将理论看作模型,那么从上述结果可知能高效解释
观测数据的最简模型就是最好的模型,这的确和 Ockham 剃刀原则吻合。上述结果
也很容易使我们联想到在减少系统总复杂度这一意义上的 Unix 哲学,如果我们
把希望实现的应用看成数据,并把支持这些应用所需接口的实现看成模型的话。
\section{文学和艺术中的极简主义审美}\label{sec:art}
追求简洁在文学和艺术领域也是一种重要的审美观,而本节将主要从文学方面入手,简要
地考察这种审美观。声名显赫的美式英语格式手册《英文写作指南》在 2011 年被《时代》
杂志评为 1923 年以来影响力最大的 100 部英文书籍之一,其作者 William Strunk
Jr.\ 格外强调“\stress{omit needless words!}”,并在书中对写作风格提出了以下的
建议\footnote{董桥将这段 63 个单词的箴言译为 63 个汉字\cupercite{dongqiao1999}:
“铿然有力之文必简洁。一句之中无赘字,一段之中无赘句,犹如丹青无冗枝,机器无
废件。此说不求作者下笔句句精短,摒弃细节,概而述之;但求字字有着落耳。”}:
\begin{quoting}
Vigorous writing is concise. A sentence should contain no
unnecessary words, a paragraph no unnecessary sentences, for the
same reason that a drawing should have no unnecessary lines and
a machine no unnecessary parts. This requires not that the writer
make all his sentences short, or that he avoid all details and
treat his subject only in outline, but that every word tell.
\end{quoting}
《英文写作指南》并不只针对文学作品,因此其反映的其实是所有英语写作中的一种
共同审美,而类似的审美至少早在约 5 世纪的中国就已存在。南北朝时期刘勰的
《文心雕龙》是我国首部系统性的文学批评著作,此书也将所有文体的作品都当作文学
作品来分析。李敖在《中国名著精华全集》中把《文心雕龙》全书重点总结成两点:
\begin{quoting}
一个是反对不切实用的浮靡文风,一个是主张实用的“摛文必在纬军国”之落实文风。
\end{quoting}
而我国《文心雕龙》学会首任秘书长牟世金这样评价此书的基本观点%
\cupercite{moushijin1995}\footnote{同一资料中也指出,《文心雕龙》
是作者对当时浮夸文风所产生反应的产物,而事实上本文档又何尝不是呢?}:
\begin{quoting}
要有充实的内容和巧丽的形式相结合,这就是文学创作的金科玉律,这就是
刘勰评论文学的最高准则。这一基本观点,是贯彻于《文心雕龙》全书的。
\end{quoting}
在对文学作品的评价中,“堆砌辞藻”“华而不实”“空洞无物”等等从来就不是褒义词,由此
可见上述审美观在中外文学界的确是得到充分认可的;从反面来看,可以印证这种认可的
还有中西文艺界对使用微小细节表达丰富内涵的描绘手法,例如在绘画中用寥寥数笔表现
其中人物动态或情感手法的普遍赞赏。又例如中国文学提倡“炼字”、讲究“诗眼”,以下诗句
\begin{quoting}
鸟宿池边树,僧敲月下门。
\end{quoting}
被世人传诵的原因就在于其中“敲”字既营造了敲门声打破夜晚寂静的氛围,又
(相对于“推”字而言)暗示了门外是访问的客人而非归家的主人。我相信类似的
例子在不同的文明中普遍存在,而且其中反映的审美观在很大程度上并不是从
其他文明中传播过来的;正如十进制数在多种文明中的互相独立产生很可能是
因为人类有10 个手指(“digit”)一样,\stress{极简主义审美能在大相径庭的
各种文明中不约而同地产生应该有其深层原因},而我将在下节探讨这一原因。
\section{从认知的视角看待极简主义}\label{sec:cognitive}
在第 \ref{sec:intro} 节,我问到“追求简洁只有审美意义了吗?”,而读到这里时你
应该已经知道并非如此,因为我们有充分的现实理由去追求简洁。在第 \ref{sec:art}
节,我提到极简主义审美在多种文明中的互相独立产生应当归结于某种深层原因;事实上,
我认为这一审美有其认知根源,后者和那些现实原因存在紧密的联系,而和具体的文明
无关。在本节中,我将讨论极简主义的认知本源,并且考察其一些表面“例外”;经过这些
分析之后,我们就能进入后两节,也是本部分最后两节的内容。我将本节的论证建立在%
\stress{多数(如果不是所有)道德和审美都源于现实生活中的实际需求}这一基本假设
之上。为什么我们讨厌在有很多人等待时插队的人?因为这种行为牺牲许多人的时间精力
来换取少数几人的利益,而且刺激人们以一种拥挤的方式等待,后者降低总吞吐量且可能
造成安全隐患。为什么设计师讨厌 Comic Sans?因为这种字体在开启抗锯齿的条件下
(这是当今的绝对主流)具有不佳的易读性\cupercite{kadavy2019};这可能有些微妙,
但如果考虑到在你初学写字时老师几乎会本能地制止潦草的书写,这一理由会显得更自然。
Paul Graham 提到,数学家和好的程序员在工作时会将整个问题置于脑海中,以充分探索其
涉及的各方面,因此简洁性在求解问题的过程中自然有其重要性\cupercite{graham2007};
他也提到,在通常的办公室环境中工作的普通程序员很少进入状态,将其正在处理的程序
充分载入脑中。考虑到后一类程序员仍然可以生产质量平庸的程序,这些程序或多或少达到
指定的目标,但数学家却常常无福享受这种宽松待遇,这或许能为第 \ref{sec:boltzmann}
节中数学家显得比程序员更极简主义的现象提供一种解释。我进一步认为在求解问题时将其
置于脑海中的要求不是数学家和程序员专有的,因为\stress{人不擅长于多任务}:借用
计算机科学中的术语,我们可以说人类思维中“上下文切换”有很大的开销,所以为了避免
上下文切换、达成优良的性能,被求解问题的所有相关子问题都须要载入脑中。有了简洁
但强大的工具,我们就能让许多子问题更好理解,从而提升我们能载入脑中的问题规模,
而我相信这就是我们欣赏这些工具的认知根源。 V.~I.\ Arnold 这样回忆他在被教到
看起来无关的数学概念之间存在的本质关联时的本能反应\cupercite{arnold1998}:
\begin{quoting}
\emph{[... a more impressive example, omitted here for the sake of
brevity ...]} Jacobi noted the most fascinating property of mathematics,
that in it one and the same function controls both the presentations of
an integer as a sum of four squares and the real movement of a pendulum.
These discoveries of connections between heterogeneous mathematical objects
can be compared with the discovery of the connection between electricity
and magnetism in physics or with the discovery of the similarity in
the geology of the east coast of America and the west coast of Africa.
\end{quoting}
类似地,我在了解到 Aboriginal Linux 的起源\cupercite{landley2017}时也非常震惊:
\begin{quoting}
The original motivation of Aboriginal Linux was that back around
2002 Knoppix was the only Linux distro paying attention to the
desktop, and Knoppix's 700 megabyte live CD included the same
100 megabytes of packages Linux From Scratch built, which
provided a roughly equivalent command line experience as the
1.7 megabytes tomsrtbt which was based on busybox and uClibc.
\end{quoting}
V.~I.\ Arnold 的评论本意是要和 Bourbaki 学派(见第 \ref{sec:science} 节)的
作风对照,而你多半会好奇,既然简洁性是这么好的属性,为什么未受训练的读者会在
阅读 Bourbaki 式的数学书时感到困难呢?我的答案建立在第 \ref{sec:mcilroy} 节对人
和机器之间区别分析的基础之上,这一分析在深层次上表明了人和机器分别擅长于完成抽象
和直观的任务。此外,为了充分理解所学的内容,人还需要涉及其各个不同方面的反复刺激
(这或许也能帮助解释为什么人类长于直觉),而我猜想这可能是为了更好识别重要知识
(如之前借助推导图讨论的一样)进行自然适应的产物。这些都告诉我们,虽然形式化
系统只需要命题和推导的抽象表示,人还需要评注、例子、图像和实际应用才能充分
理解它们;正因如此,\stress{形式化的抽象和非形式化的图像是互补的,它们
对我们具有同等的重要性}:例如考虑微积分中极限的 $\epsilon$-$\delta$
定义及其非形式化版本,“通过使输入充分逼近指定值,输出可以
任意逼近极限”,后者顺便也揭示了极限的拓扑学本质。
在本节末尾还有一个问题须要考虑:我在上文中提到,数学家通常无权像程序员那样生产
“差不多过得去”的结论,但这是为什么呢?因为数学家一般须要严格证明其结论,或者至少
在其强烈怀疑后者为真的前提下提出猜想;相比之下,程序员把软件看成工程项目的产品,
并且因其在本质上的复杂性经常愿意牺牲可证明的正确性以换取更低的开发和维护成本%
\footnote{\label{fn:formal}事实上,\stress{形式化验证}在硬件产业中使用相当广泛
(可能是因为对硬件的要求相对固定),但在软件中仍然极少大规模应用。一个著名的
例子是 seL4 微内核\cupercite{wiki:sel4}的形式化证明,它比 seL4 本身的代码大一个
数量级,而后者本身已经很小而且拥有良好的设计。}。因此在形式化证明成本过高时,
我们不得不依赖我们自己的推理,但正如 Tony Hoare 所说\cupercite{hoare1981}:
\begin{quoting}
There are two ways of constructing a software design: one way is to make
it so simple that there are obviously no deficiencies, and the other way
is to make it so complicated that there are no obvious deficiencies.
\end{quoting}
由此可知尽管机器只用知道程序所对应的可执行指令,人还须要设法保证\stress{程序的
正确性};不管保证正确性的手段是形式化证明还是人工推理,对程序内部机理的清晰理解
都是必需的。所以在评估软件系统时,我们不仅须要度量其尺寸,而且须要考察系统中的
内聚和耦合,而这正是我在第 \ref{sec:complex} 节中强调“认知复杂度”一词的原因。
\section{Unix 哲学在社会中推广的限度}\label{sec:society}
正如我们在本部分已经看到的,除了编程中的 Unix 哲学之外,极简主义在科学技术、
哲学和文学艺术中也有其重要性;这并非偶然,因为极简主义根植于人类认知之中,
这本身很可能是源于人类进行多任务时的巨大开销。由此而来的一个自然的问题是
“Unix 哲学是否能应用于社会?”,因为社会在许多方面类似于机器,因而或多或少地
可以从 Unix 的角度分析。把社会看成机器的一个重要理由是因为分工使社会可以
在概念上被划分为相互作用的群体,其中每个群体执行一组不同的任务,而每个群体
又可以被分为执行不同子任务的子群体。沿用这一思路,我们可以粗略地将社会比作
由相互作用的模块组成的系统,于是 Unix 哲学看来可以在其中找到应用。
考虑到这一背景,设法促成不同社会群体之间(以及类似地在同一群体之内的子群体之间)
的\stress{适度分工}当然是有利的;而极端细化的社会分工似乎也成为一种有些诱人的
设想,在这样的分工下每个人只做一件极其微小且良定义的工作。然而正如 Charlie
Chaplin 的杰作《摩登时代》中生动表现的一样,让人们像没有思维的机器一样工作其实
是违反人类本性的,这样做对社会的坏处远大于好处。我相信这是社会为何常常不像
Unix 那样工作的一个本质原因,它可以用上节中讨论的人类对多样刺激的需求来解释:
如果你整天做的都是某种机械、单调的工作,你满脑子想的都会是这种工作,这会让你的
思维越来越疏远于其它人类行为。由此可见,虽然生产极简主义的产品是好事,但是也
有必要\stress{尊重人的本性},鼓励人们经常尝试一点在思维上有挑战性的不同的
东西;从另一方面来看,多样的刺激也能增强人的创造力,并由此增强整个社会的活力。
正如之前强调的,人类并不能完全比作机器,因为人需要多样的刺激;类似地,社会群体也
不能完全比作计算机系统中的模块,其中一个主要的原因是\stress{社会群体一旦形成就会
追逐自身的利益},而不像软硬件模块那样只是机械地工作。例如正像 Laurent Bercot 等
人注意到\cupercite{ska:systemd}的一样,公司会自然地倾向于生产质量平庸的软件,而
Paul Graham 将其归结于\cupercite{graham2007}公司希望每个开发者是可替代的;这一
趋势(即使只是一种无意识的效果)在依赖贩卖服务以获利的开源公司中注定更为严重,
因为生产难以独立维护的软件更加有利可图,而我强烈怀疑这是催生 systemd 闹剧(见第
\ref{sec:foss} 节)的因素之一。由此可知,社会群体之间的相互作用并不完全是合作
的,因此正如 Unix 式高安全系统\cupercite{djb:qmailsec}中的模块那样,社会群体
间的互信应该有一定的限度,所以在这一方面 Unix 和社会达成了某种殊途同归的效果。
\section{极简主义对个人工作、生活的启发}\label{sec:worklife}
我在第 \ref{sec:user} 节中提到高效学习 Unix 的本质,以及如何实现这种高效学习;
在读完本部分中前面各节之后,你应该已经知道这些并不是 Unix 独有,而是所有学习
过程中共通的原理。既然如此,Unix 在学习过程中扮演的真正角色是什么呢?我认为
Unix 哲学会自然地促成极简主义的习惯,后者正是高效学习的关键;在本节中,我将
讨论如何更好地培养这种习惯,以及这种习惯会为并不出众的人带来怎样的实际收益。
正如之前所述,高效学习的实质在于降低学习过程的总复杂度,而我们对此已经有了一个
概念模型——推导图(见第 \ref{sec:boltzmann} 节);利用这一模型,我们分析了第
\ref{sec:user} 节中的知识重要性判据,而我在这里要对这一分析进行一些补充。我们
知道和死记硬背\footnote{有时我们不得不死记硬背,此时我们可以考虑使用抽认卡程序,
后者常常可以极大提升记忆效率。Mnemosyne 和 Anki 是两个开源的抽认卡程序,但遗憾
的是两者都比较臃肿。}相比,记忆重点并根据需求从它们推出其它知识点通常是更好的
选择;这意味着我们可以把推导图“压缩”成那些普适且有用的概念,并从这些概念游走到
需要的部分。然而必须强调的是\stress{我们记住的不仅是重要概念},而且有对它们和
其它概念之间关系的粗略印象,而这种印象通常是(如果不总是)基于先有知识的:例如在
学习乘法表时,掌握加减法会很有用,因为后者帮助学习者将不熟悉的结果关联到熟悉的
结果(如 $7 \times 6 = 7 \times 7 - 7 = 49 - 7 = 42$)。因此为了能高效学习,上述
印象最好是基于某种扎根于我们脑海中的知识,而我相信后者可以简单地称为直觉:如第
\ref{sec:cognitive} 节中分析的一样,为了充分理解某种客体,我们需要多样的刺激,
而直觉(例如自然数及其基本运算)正是先有刺激的产物,它可以帮助我们降低学习所需
刺激的量;这也支持了同一节中非形式化图像和形式化抽象一样重要的论断。
由上可知为了高效学习,我们不但要关注重要的概念,而且要尝试寻找它们和我们已经
熟悉的概念之间的联系;就后者而言我们可以从主动\stress{寻找概念之间的相似性}%
开始,例如“\verb|fork()|/\verb|exec()| 像原型模式”“12 个音符间的音程就像钟表上
12 个小时之间的时差”。通过这样的做法,我们能使用先有知识来极小化我们须要记忆的
信息量,从而实现所谓“把书读薄了”的效果;此外,在发现概念之间的新联系时,对旧
概念的理解也会被加深,而正如第 \ref{sec:devel} 节所述,对相关主题的深刻理解
往往是优雅发明的关键。从概念模型的层面上看,在发现不同推导图在结构上的相似性
之后,每个图中的推导经常可以为发现其它图中之前被忽视的推导提供无价的启发;
在这一方面,跳动的宏观液滴和被量子力学支配的微观粒子之间的类比,以及我国
钟万勰院士关于经典动力学和结构力学在计算方面类比的工作是两个很好的例子。
于是我们已经考察了多个推导图之间的关联,并考虑了先有知识可以怎样帮助我们
掌握新概念;正如上文所述,\stress{新知识也有助于我们从新的角度考虑先有概念}:
换言之,“温故而知新”,这正是我们应该培养回顾旧知识习惯的原因,同时也是我在第
\ref{sec:devel} 节中提到我们应该经常考虑重构的原因。既然再次提到了习惯的问题,
我认为现在是时候指出直觉和习惯都是重复刺激的产物,它们的区别在于前者主要关注
“某物是什么”(例如柠檬是酸的),而后者主要关注“怎样做某事”(例如怎样使用某种
餐具)。\stress{好的直觉会给人很丰厚的回报,但它经常需要一定量的训练才能获得}:
例如一个在有机化学上经过足够训练的人可以立刻察觉 \parencite{zxhxy2018}\footnote%
{这显然不是其原始来源,但我的确没能找到原始来源;据我所知,这一合成路线至少可以
追溯到 2014 年,当时我在看到这一路线之后把它的最后一步画在了一件 T 恤衫上。}%
中“囧烷”(经过“环猫烯”)合成路线的优雅,但这种训练即使对在最优秀老师指导之下
的最聪明学生也并非易事。类似的结论对习惯也成立,这也为我们提了个醒:如第
\ref{sec:society} 节所述,我们应当尊重人的本性,但同时纵容自己保持从长远
上看弊大于利的习惯也是不明智的;打个比方,虽然慵懒的坐姿可能感觉更舒服,
但是它一般会导致近视、驼背和鸡胸,而我可以证实这三者都是不健康的。
在本部分的末尾,我希望在给出最后的观点之前考虑一个古典音乐的例子:“多数
音乐家同意 J.~S.\ Bach 是西方音乐史上最伟大的作曲家,而 L.\ van Beethoven
和 W.~A.\ Mozart 争夺第二的位置”这种说法应该不会显得过于不公,然而同时几乎没有
人会对 Mozart 的天赋明显高于 Bach 这一点有争议,这是为什么呢\footnote{类似的比较
或许也可以在 Albert Einstein 和 John von Neumann 之间进行,虽然对两者伟大程度的
判断将比对 Bach 和 Mozart 的判断更有争议得多。}?我认为答案已经蕴含在我一位同学
注意到的现象之中:“Mozart 总有新的乐思,而 Bach 不断探索已有乐思中新的可能”;
或许正是因为这一原因,Bach 作品中的元素经常被称为许多后世音乐风格的原型,这些
风格最晚在 20 世纪才产生。我想用这个例子表达的观点是\stress{尽管“天才”可以轻松
地深入思考,他们也往往缺乏努力思考和回顾旧想法的动机}:因为有太多足够有意义
的问题供他们求解,但这同时也留下一些重要但未能考察的的死角。在编程中,这些死角
中一个极为重要的部分是软件系统的简化,这一工作即使普通程序员也常常能做,只要
后者有足够的决心;在实践中,这种简化对我们普通程序员的意义反而更大,所以我认为
我们应该比“天才”更有动力去做这一工作。此外如上文所述,极简主义的习惯让我们专注
于问题的本质,这会自然地引起深入思考,并因此常常可以提供深刻的眼光,后者正是
解决难题的关键。有时伟大的程序员和我们之间的区别正是这样的眼光,这或许也为第
\ref{sec:user} 节中 Dennis Ritchie 的名言提供了另一种解释——通过贯彻极简主义,
即使并不出众的程序员也可以成为“天才”;出于这一原因,我以下面的引言结束本部分:
\begin{quoting}
Common sense is instinct, and enough of it is genius.
\end{quoting}