SICP

背景

SICP 全称 Structure and Interpretation of Computer Programs,翻译过来叫《计算机程序的构造和解释》。我看的是英文版,所以下面都用 SICP 缩写(后面解释为什么要看英文版)。

最初看 SICP 我是拒绝的,因为这书太厚,而且感觉没啥用。带着这种想法,看了八十多页就放弃了。

那为什么这次又开始看 SICP 了呢?很简单,无聊了……我发现无聊的时候真的很适合看这种深奥的东西,虐一虐自己的大脑。

好的,那么在一个无聊的周五,我打开了 SICP,就这样学起来了。

我的所有习题解答全部放在 GitHub 上,仅供参考,仅供参考,仅供参考。

第一道题

就这样学啊学……学啊学……

(我写了的)最后一道题

今天下午,终于看完了全书,因此写篇文章,说说我是怎么刷的。对我来说算是个纪念+总结,如果对大家也有帮助那就更好了。

看完全书

SICP 好处都有啥?

一千个人心中有一千个 SICP

网上能搜到太多太多答案,不过这里我要写的,是我自己亲自看完学完之后的体会。

两个字总结 SICP:内功

看过小说的都知道,什么刀法剑法往往都不重要,重要的是内功,是修炼方法。在编程界,SICP 毫无疑问是一本顶级内功。

这本书教你的并不是“函数命名要有意义”、“不要编写超过一屏的函数”、“如何安装和配置 Xcode”、“如何编写年轻人的第一个 Hello World”,学完这本书后,还是原来的 PM,还是原来的需求,还是原来不换行的大括号,这些都不会变。

变的是你的思维方式。

SICP 要教你的不是那些细枝末节的东西,而是把你拉到一个极高的视角,一边分解程序,一边教你如何正确的构建和编写程序。具体来说,SCIP 教你如何熟练运用抽象以及程序如何运行

有些同学看到这里可能要说了,抽象不就是封装函数吗?不就是隐藏实现吗?程序不就是解释或者编译运行吗?

其实这样说也没错,但是要真正理解和掌握这些东西需要大量的训练。知道掌握是两个截然不同的概念,在这个时代我们知道的太多,掌握的太少。

说完了好处,也要聊聊坏处。

SICP 的最大缺点就是长得太丑

什么叫长得丑?打开书随便一翻就是各种数学公式、加法器、数理逻辑,还没看就吓跑一批人。

不过这其实是纸老虎,为什么呢?咱们下一节继续说。

SICP 怎么学?

作为长者,我有必要告诉你们一点学习的经验

首先,不要慌

很多人会被 SICP 的各种公式吓跑,但是在我学习的过程中发现,这些东西都是纸老虎!

一个非常简单的道理:作者的目的是教你一些知识,而不是为了难住你。这是“SICP 第一定律”,在学习过程中一定要牢记这句话。

据我自己统计,SICP 里面涉及到的知识有:

  • 向量
  • 矩阵
  • 各种数学公式(求平方根、立方根、导数、不动点、微积分……)
  • 数字电路
  • 数理逻辑
  • 机器语言
  • 并发
  • 解释器
  • 编译器

在学习的过程中,经常是上一页还在实现微积分,下一页就开始讲电路;上一页还在解数理逻辑,下一页就开始写编译器,内容跨度之大令人发指。

但是大家不要慌,先默念十遍第一定律,然后往下看。

这些东西其实都是给你举例子,真正的目的是教你编程思想。只不过呢,SICP 是 MIT 的教材,MIT 里众神云集,给他们写的教材自然也不能太简单。

普通的教材举例子会说:

1
小明有三个苹果,小张有四个苹果,俩人一共几个苹果?

SICP 会说:

1
x = 3, y = 4, x + y = ?

说白了,无论是电路还是公式,你就当它们是小明小红,照着要求去实现就行。

然后,不要停

先来个错误示范:

小明想看 SICP,下载电子书,发现一共 883 页。小明想两个月看完,打开计算器做一个简单的除法再取个整,每天看 15 页。小明一想,15 页这不是轻松搞定嘛!哪怕一页看五分钟,也就一个多小时,更何况一页不可能看五分钟。

于是小明开心的去看了。

两周后,小明放弃,游戏结束。

问题出在哪里?

在学 SICP 的过程中,我收获了一个重要的经验,那就是:一鼓作气

看起来完美的计划为什么总是失败?不是你计划得不好,不是你除法用得不溜,而是因为战线拖的太长。

生活中有太多无法预料的事情,公司加班、感冒发烧、朋友聚餐、外包、技术大会、租房、跳槽……你的计划只考虑了理想情况,但凡有点物理知识的同学就知道,真实世界中不存在理想情况,小车的空气阻力不可能为零。

战线长的第二个问题就是低效。每天 15 页,看似分摊了任务,无形之中增加了很多上下文切换和环境初始化的开销。每天你都需要先回忆之前的内容,然后继续看。如果题目用到了之前的知识(这在 SICP 中很常见),你不得不返回去继续阅读。这反过来又增加了失败的概率。

因此,不要再浪费时间做无用的计划,从现在开始,一鼓作气,用尽一切时间去学!

我可以说说我是怎么学的。

每天早晨到公司吃完早点是九点,我会从九点一直学到下午六点半下班。吃饭和公司需求会占用一段时间,不过通常来说白天在公司我会用七个小时学习(总不可能一年到头加班吧!难道你不用等设计师出图?不用等产品扯皮?)。晚上回家之后我还会在睡觉前学习一个小时,这样算下来我一天会学习至少八个小时。

这种状态我持续了两周。

也就是说,这两周时间从早晨睁眼到晚上睡觉,绝大部分时间我都在看书和做题,让 SICP 占用所有缓存。

为什么能坚持下来?很简单,坚持不下来的时候,再努力一下就好了。中间有几次我也觉得很烦躁,不过睡一觉起来,还是坐在电脑前面继续看书做题。我这人脾气不好,说了要看完,就是要看完,就是和自己较劲。

总结下来,我的 SICP 学习经验就是:首先理解作者思路,把一切看做纸老虎,然后坚持到底。

如何开始?

开发一个项目,至少有 50% 时间在配置环境

如果你看到了这里,并且决定开始学习 SICP,下面是一个简单的 setup 步骤:

  1. 下载 英文版 SICP (为什么是英文版,看下一节 FAQ),这并不是盗版,是 Lytha Ayth 基于官方公开的 HTML 制作的 PDF 版
  2. 参考 这个回答 安装 MIT-Scheme。Scheme 是 Lisp 的一种方言,也是 SICP 使用的语言。MIT-Scheme 是 MIT 实现的 Scheme 解释器,和 MIT 教材 SICP 更配哦
  3. 打开一个你最喜欢的编辑器(我用的 Sublime Text 3),编写一段 Scheme 代码并保存成 test,可以没有后缀名
  4. 打开命令行,输入 scheme < test,即可执行程序

现在你已经准备好了一切,JUST READ THAT FUCKING BOOK!

FAQ

当我沉默著的时候,我觉得充实;我将开口,同时感到空虚

为什么要读英文版?

如果经常读技术书籍,你会发现一个问题:英文比中文好读得多。

举几个例子,scope 这个单词,翻译过来叫“作用域”;adder 翻译过来叫“加法器”;higher-order 叫“高阶”。

当然这些翻译没什么错,但是对读者来说,这种陌生的术语理解起来反而比英语还难。

所以我现在给自己定了一个规矩,尽量读英文书,体会原文的意思。我建议大家也这样做,你会发现,英文版的 SICP 比中文版好读多了。

有些题我不会怎么办?

简单,跳过它。

学习的目的不是做对所有题,而是学到你本来不会的知识。SICP 里面有不少难度很大的题,有些我自己也没有做出来,所以不要太在意题。

当然,首先你要尽力去做,然后在万不得已的情况下跳过。

你的答案正确吗?

仅供参考。

我做了大概 90% 的题,有些实在太难或者太复杂就没有做。不过 SICP 到后面就开始意识流了,很多程序也都只是为了理解思想,所以真的仅供参考。

能运行的程序一般都是对的,有些题只是要求补充片段,没法独立运行,我也就没法验证了。

我还有其他问题

尽管问,知无不言言无不尽。

你可以直接在文章下面评论,或者去微博找我@梁杰_numbbbbb,也可以给我发邮件:lj925184928@gmail.com

最后

SICP 真的是一本好书,一本不可多得的内功心法,一定要读,一定要读,一定要读。

关于我

这一部分是最不重要的,因此放在最后。

如果你真的读到了这里,想必对这个喋喋不休的家伙有些兴趣。

我是梁杰,90 后,职业前端,业余 iOS,业余 Python,翻译过多本书。如果你想了解更多信息,可以访问以下链接:

  • 我的博客,最近才开始重建,内容不多,不过绝对有趣
  • GitHub,或许你点开就会发现“哦原来是你!”