A classical book is people often talked about, but never read.
这是西西弗书店里的一个标语,原文记不清楚了,感觉放在这里很应景。标题中的SICP
是英文 The Structure and Interpretation of Computer Programs
的缩写,amazon.com
用户对该书的评分成两极分化的态势。这本书很奇特,仿佛调味品中的芥末,喜欢的人爱到不行,不爱的人闻一下都会难受。
这本书从出版至今近33
个年头。在国外很流行,然而在国内却非常的小众。这本书经常出没在各种编程书籍的推荐单中,也有很多人好奇,到底有多少中国学生认真读完了它,应该非常非常少吧。对于scheme
的语法,很多人都不习惯。lisp
系的(
,)
让很多熟悉了C
系语法的人感到很别扭。下面举两个例子:
sicp ex1.3 scheme
版本
(define (sum-square-largest x y z)
(cond ((and (<= x y) (<= x z))
(+ (* y y) (* z z)))
(else
(sum-square-largest y z x))))
sicp ex1.3 java
版本
long sumSquareLargest(int x, int y, int z) {
if (x <= y && x <= z) {
return y * y + z * z;
}
return sumSquareLargest(y, z, x);
}
这两段代码实现同样的功能,只是为了对比一下二者语法上的不同。相比较而言java
版本显得“可读性”更好。我想这是很多人放弃学习lisp
系语言最冠冕堂皇的理由了。
scheme
代码看多了写多了会慢慢的喜欢上这种优雅的表示方式。这是无法与外人道哉的一种美。书中代码还有一些非常好的编码约定, 对于谓词变量以?
结尾,比如good-enough?
言下之意该变量(值)或者方法(返回值)应该为true
或者false
。对于"赋值型"的函数则以!
结尾,一个大大的️,因为改变程序的"状态“意味着side effect
会陡然增加控制程序行为的复杂性,对于这类的函数需要给予足够的重视。对于选择函数car
,cdr
这类函数都是一种无副作用“轻量”的操作。写程序过程中,给变量命名绝对是一门艺术,scheme
的命名约定方式,提供了一个良好的规范。对于用户自定义的操作如果都遵循这种方式,将会大大提高代码的可维护性,甚至可以通过代码静态扫描的方式找出那些有赋值动作选择函数。其实在实际生产过程中已经遇到好多次这样的案例,服务名称看起来是个读接口,但是内部实现却违反了接口的约定,具有副作用,久而久之这类的服务早晚会让服务使用方踩坑。这是读sicp
的体验之一。
现在很多编程语言都是基于图灵可计算理论以及冯诺依曼体系结构模型设计出来,和图灵的可计算模型相等价的另一套模型则是阿隆索.邱奇的lambda
演算。相较于图灵机lambda
演算则要简单、优雅至极,下面是lambda 演算形式化
表述:
<expr> ::= <identifier>
<expr> ::=(λ<identifier> .<expr>)
<expr> ::=(<expr> <expr>)
是的,就这么简单的三条规则,就完全可以和图灵机媲美。在读完sicp
之后,你会感到无比的震惊。虽然本书的作者没有将这部分内容作为主线来介绍,但是无形之中已经将lambda
演算的神奇之处展露无遗。有些是在书本的正文中介绍,有些则是通过习题的方式介绍给读者。比如,如何用lambda
来实现邱奇数,如何实现其算数运算;如何从lambda
来实现分支判断;如何实现基本的cons
,car
,cdr
等等。放眼望去,除了lambda
算子之外一切皆是语法糖。当然,读完第四章你还会看到令人拍案叫绝的Y combinator
。
人脑理解迭代,神脑理解递归。
这句话是看完Y combinator
的深刻感受。这是读sicp
读出的体验二。
其实sicp
贯穿全书的理念应该是教会读者控制程序复杂性的手段——抽象:过程的抽象,数据的抽象,语言的抽象。MIT
两位天才级的作者,用众多合适的实例,巧妙的将这一手段展现的淋漓尽致。大神Peter Norvig
在amazon.com
的书评 很好的说明了一切 。如此大规模集中式的抽象训练没有任何书籍能够与之媲美,这才是编程语言设计最好的书籍。这是第三个感受,这也应该是任何读者都会有的感受!
如此优秀的一本书,大多数读者上止于第三章,后面的内容就很少再去读了,实在是可惜。设计实现一门编程语言应该是任何一个有技术追求的程序员的梦想,而第四、五章就是教你如何实现一门新的编程语言的解释器。如何扩展扩充修改原有的scheme
解释器,如何让你的新语言具备OO
功能,如何实现逻辑式编程语言,如何实现具备惰性求值的解释器等等。甚至你可以实现自己的GC
, 顺便说一句,GC
的引入还得要归功于lisp
这门古老的编程语言。当然,最后的两章的内容比真正的“编译技术”要简单一些,毕竟这不是一本介绍编译技术的书籍。作者引入的所有例子都是为了更好的让读者理解程序设计的本质是什么,如何更好的控制系统的客观复杂性。这是一本教你造汽车的书籍,而不是教你开车的书籍。
youtube
上有两位作者1986
年给某公司员工培训的视频,视频也非常的有意思,在视频里作者还不时的讽刺一下那个年代的"人工智能"浪潮,其实就是简单的规则模式匹配而已。历史又不断的在重演,人工智能这个话题每隔一段时间都要被推到一个新高度,然后又冷下来。对“停机问题”的深刻理解,以及计算本质的理解,会让你倾向于相信:机器永远不会有智能。那些重复的机械的劳动最终必定会被机器取代,对于创造性的脑力工作者,比如程序员,机器将永远都取代不了。
阅读sicp
有哪些困难?
- 时间。如果是在校生,至少也要花一学期的课余时间。如果是已工作了,有可能这辈子都读不完。
- 编程思维。99%的程序员平时使用的基本上都是命令式的编程语言,到函数式编程思维方式需要转变。
- 内容比较难,这是客观的事实。确实比较难。
sicp
有什么缺点吗?有!它会让你在精神满足感之余,有一种孤独感。