My Profile Photo

wlnirvana


Youth is not a time of life, it is a state of mind.


SICP

我学计算机基本上都是自学。网上搜索、顺藤摸瓜,对各种看起来貌似高大上的资料、技术都很感兴趣,于是东一榔头西一棒槌地学了不少东西。但学着学着逐渐发现,由于计算机技术的应用范围极其广泛,与计算机科学相关的知识之多简直超乎想象。比如说最近几年云计算、人工智能很火,一个相关院系、企业要是没点这类项目恐怕都不好意思说自己是搞计算机的了。往前推一段时间,社交网络流行过一阵,貌似也有不少人在折腾。要是再追溯到卡片打孔的上古时代,大学教的基本上都是逻辑、数值分析这些。面对这些纷繁复杂的资料,非科班出身的我时常感到困惑:这些真的都是计算机科学吗?怎么感觉相互之间没什么关系?或者说,有没有一套计算机科学的核心体系来把他们串联起来呢?直到读了这本SICP,我才感觉稍稍摸到了点门路。

SICP成书于80年代的MIT,至今已经30余年了。和许多计算机书籍随着指令集、编程语言等版本更新必须重新改写不同,本书30年来只出过两版。书名翻译过来叫做计算机程序的构造与解释,提纲挈领,很好地对应了书的内容。书的前三章讲了一个好的计算机程序的结构应该是什么样的,即过程抽象和数据抽象。分析完如何写一个好的计算机程序,最后两章转而介绍拿到一个程序之后,计算机是如何解释(亦即运行)它的。

这样粗浅地听下来,似乎这本书无非是教了一门编程语言、一点编译器的知识罢了。这种评价并不算错,却忽略了SICP最为可贵的特点:它所侧重的,不是某种特定的知识,而是所有这些知识背后共有的思想。换言之,尽管SICP没有C++、Java、Python等语言的相关介绍,那些关于好的程序结构的知识却可以被运用到这些所有语言当中去;尽管SICP是通过自己设计的一台机器来介绍程序的解释和运行,但学会了其中的原理,x86也好SPARC也好,稍加变通和探索,全部可以玩转。可堪对比的是另一部同样非常精彩的计算机入门教科书CSAPP。读完CSAPP,我们大体会对x86、C语言、gcc、gdb有不错的了解,会使用breakpoint等各种功能。但读完SICP,你也许不会C、gdb的语法,却对编译、breakpoint的原理有了根本性的认识,懂得为什么需要编译、如何实现编译和breakpoint。至于是想基于C还是C++来实现,已经变成一个纯粹的技术细节了。这大概也是我为什么觉得摸到了计算机科学的体系的原因:SICP努力让读者关注隐藏在技术细节背后的想法和直觉,而非纷繁复杂的表象。

当然,如果只是讲思想,SICP恐怕得当作哲学书来看了。本书能成为计算机科学的经典,另一大原因就是其完善的例子和作业,使得读者能够亲自编程实现那些想法,感受其作用。例如本书第二章,一步步地从有理数到复数,再到多项式,实现了一个运算模块。而在这个过程中,由于利用数据抽象的思想做了统一的接口,最后实现的运算模块可以轻松处理各种类型的数据。再比如四、五两章介绍程序的解释,从基于Scheme的元解释器,到语法分析和执行分离的解释器,再到基于汇编指令的解释和编译,逐层递进,给出了所有代码,帮助读者很好地理解何为解释、如何解释。很多程序员喜欢引用一句话:talk is cheap, show me the code。而这些例题正很好地将那些思想从空谈落实为了程序。

此外,作为计算机科学的入门书籍(但绝不只是入门,老程序员依然可以从这本书中学到很多东西),SICP内容的丰富性是很多其他同类书籍所不具有的。除了结构、解释这两大主题,SICP还介绍了大量的其他知识,让读者真切地感受到程序设计的威力。例如符号求导、多项式运算,都完全是基于符号进行的,有点像WolframAlpha;第三章实现了一个约束系统,可以进行多个方向的运算;第四章还介绍了类似prolog的逻辑编程。这些与我们熟悉的过程式的、面向对象的编程都极为不同,丰富了读者的眼界。我读SICP的时候,屡次为这些不同的模型击节赞叹,只觉得原来编程竟还可以做这么多好玩的事情,人类的智慧真是无穷无尽!

最后,回到本文最初的那个问题:计算机科学的核心是什么?坦白讲,尽管SICP给了我一些模糊的感觉,我却仍然没有一个清晰的答案。当然,这个问题是开放的、仁者见仁的。而随着计算机理论和应用的不断发展,这门学科的内涵想必还会不断变化。但我觉得,起码现在市面上的很多书籍、很多高校的课程安排,并不是以一种最合理的方式进行的。例如我在IC上的体系结构课程、CSAPP书等,都花了不小的篇幅来介绍二补码等数据表示。在我看来,二补码当然不失其工程上的巧妙,但充其量只是一种trick,不能算得上计算机科学,不应该浓墨重彩地介绍。更别提上升沿下降沿、曼彻斯特码等等,都该完全归入EE而非CS。有些人可能会说,EE和CS本身就是密不可分的两个专业。没错,但他们在事实上的纠缠不清,并不代表二者就应该混为一谈。曾经这个世界上也没有物理、化学等等,只有一个大一统的哲学,但随着人类知识的细化,这些学科不也是逐渐分开了吗?我希望有朝一日,能有一本(套)更为清晰的书,能够厘清EE、CS乃至较为上层的AI等学科之间的关系,帮助读者建立一个对这些学科的宏观把握。如果一直没人写,那我就动笔啦:)

comments powered by Disqus