一〇年五月二十六日由一个序言谈起

“我认为,在计算机科学中保持计算中的趣味性是特别重要的事情。这一学科在起步时饱含着趣味性。当然,那些付钱的客户们时常觉得受了骗。一段时间之后,我们开始严肃地看待他们的抱怨。我们开始感觉到,自己真的像是负起成功地、无差错地,完美地使用这些机器的责任。我不认为我们可以做到这些。我认为我们的责任是去拓展这一领域,将其发展到新的方向,并在自己的家里保持趣味性。我希望计算机科学的领域绝不要丧失其趣味意识,最重要的是,我希望我们不要变成传道士,不要认为你是兜售圣经的人,世界上这种人已经足够多了。你所知道有关计算的东西,其他人也都能学到。绝不要以为似乎成功计算的钥匙就掌握在你的手里。你所掌握的,也是我认为并希望的,也就是智慧:那种看到这一机器比你第一次站在它面前时能做得更多的能力,这样你才能将它向前推进。“–Alan J. Perlis

偶然在 TP 书架上看到了《计算机程序的构造和解释》。然后看到了这个很像题词一样的东西。

“传教士”一个词很有意味,这趣味并非来自传教士本身,而是”想做一名传教士“背后的动机。在这个越来越不关注个体的社会中,为标榜而传教恐怕是最大的动机了吧。”传教士“一词我听得不多,第一次是在看 Linux 与 Windows 大战的时候看到的,人们提到 Linux 的传教士;第二次是在学习 Emacs 的时候看到的,指的是 Emacs 的信徒。宣扬 Linux 的蠢事情我也干过,但现在干得少了:)至于 Emacs,我就从来没宣扬过,因为学习曲线太曲折了,估计我的同学不愿意上这种当。花很多时间为了用 Emacs 来学习 Emacs,特别是 Windows 用户,实在有点亏:)我在默默忍受了一段 Emacs的痛苦学习后,现在好多了。

另外一个词是“推进”,看到这个词,我先想到了方向。计算机学科的迷人处应该在于提高效率了吧,比如 MIT 讲“算法导论”那“老头儿”说他喜欢 skating,喜欢速度带来的快感,速度即效率嘛。一直以来学的的东西,无论是 Vi、Emacs、还是各种语言,那是他人的智慧,我们利用一下,产生了新的“智慧”。于是有了各种配置文件,一代又一代的人从( autoload ....)开始学起,以便创造出更高效的工具,我在有一点上似乎忘记了一个重点–高效工具的目的何在,若没有目的,去提高效率的意义又何在。这样看来,对 Emacs各种功能的扩充(上网,听音乐)却显得略有多余了,也就是反对 Emacs 的人所提到的 Emacs 不符合‘K.I.S.S.‘精神。

在上 Linux 课的时候,老师说 MIT 的计算机系第一门计算机语言课是讲授 Lisp 语言。我还查到了卡内基梅隆的计算机语言课直接讲授 java,国内除 C 之外没有例外了吧。Eric 说如果想做黑客,他建议从 Python 开始学起,C 的确很强大,但不适合入门学习,很多底层的东西是要靠自己去实现的。但讲了 C 之后有个好处,好比英语考试,直接朝着 GRE 的目标去的话,现在也不至于在痛苦地背单词了(笑)。

在网上无意中看到了有人对《计算机程序的构造和解释》做出的评价,大意是,按照自己的十几年的编程经验,这本书对他的启发大大出乎他的意料。我刚开始看这本书,内容的确有些出乎意料。因为这本书不仅和程序有关,还和计算有关,还没有讲到循环的时候已经涉及到牛顿迭代法了。我一度把“在计算机科学中保持计算中的趣味性是特别重要的事情”看成了“在计算机科学中保持计算机的趣味性是特别重要的事情”。因为我每接触一门语言,必然只从语法,构成讲起,然后把语言介绍完之后就结束了。而《计算机程序的构造和解释》不是以语言为目标,而是能力。

首先,我们希望建立起一种看法:一个计算机语言并不仅仅是让计算机去执行操作的一种方式,更重要的,它是一种表述有关方法学的思想的新颖的形式化媒介。因此,程序必须写得能够供人们阅读,偶尔地去供计算机执行。其次,我们相信,在这一层次的课程里,最基本的材料并不是特定程序设计语言的语法,不是有效计算某种功能的巧妙算法,也不是算法的数学分析或者计算的本质基础,而是一些能够用于控制大型软件系统的智力复杂性的技术。

我们的目标是,使完成了这一科目的学生能对程序设计的风格要素和审美观有一种很好的感觉。他们应该掌握了控制大型系统中的复杂性的主要技术。他们应该能够去读 50 页长的程序,只要该程序是以一种值得模仿的形式写出来的。他们应该知道在什么时候哪些东西不需要去读,哪些东西不需要去理解。他们应该很有把握地去修改一个程序,同时又能保持原来作者的精神和风格。

我开始慢慢觉得,计算机科学与技术专业,除了那些迷人的技术,更多的应该是和数字打交道的科学,只有这样才能真正地做到“你所掌握的,也是我认为并希望的,也就是智慧:那种看到这一机器比你第一次站在它面前时能做得更多的能力,这样你才能将它向前推进。”在现在这个阶段,无论是学习什么语言,应该是以改进思维模式为目标,而不应该简单地以项目需要来决定学还是不学。
为了求 a + abs(b),我们可以在 C 中用两个if来做到,下面的代码用了不一样的方式

(define (a-plus-abs-b a b)
((if (> b 0) + -) a b))

思维的不一致性就是这样体现的。

我曾经想过要多多的学习计算机语言,想了解各种语言的特性。但当我真正想要用这些语言来实践的时候,却不知道可以用它来做什么。学习语言没有问题,有人提出应该给自己定个每年学习一种语言的计划,我看是合适的,但要清楚学习语言的目的,不为学语言而学习,应该以改变思维,培养能力为目标来学习。这里的能力应该如作者所言:

他们应该能够去读 50 页长的程序,只要该程序是以一种值得模仿的形式写出来的。他们应该知道在什么时候哪些东西不需要去读,哪些东西不需要去理解。他们应该很有把握地去修改一个程序,同时又能保持原来作者的精神和风格。

这样一种能力是难得的,就从我的学习过程来看,我的同龄人中鲜有这样的能力。