终于敲完了两本书的所有示例代码,整个过程还是蛮特别的。
写在前面
看这两本书纯粹是因为之前读了《黑客与画家》,对作者屡次提及的Lisp感到好奇,想要了解下,然后在common lisp和scheme中毫不犹豫选择了后者,仅仅因为它看起来小而巧,而选择这两本scheme书,也是Google到的缘分,现在看来,觉得特别幸运,遇见了这样特别的书。
书中多处致敬了多位在数学和计算机领域作出贡献的人,还顺带调侃了下《动物庄园》里面的名句,令人捧腹。而往往在你看不懂代码,一头雾水,烦躁不安时,作者又时不时整一两句有关食物的调皮话,让人一下子又觉得没那么难懂了。
如果所有的编程书都能用这种方式去写,那该多有趣,可惜能把复杂的东西用这样特别的方式呈现出来,对于作者本人的要求着实不低。
这里简单屡屡两本书的大致内容以及遇到的问题。
《the little schemer》4th
全书10章,入门级,从最基本的概念说起,难度比较大的是chapter09,有关Y-combinator的推导,虽然我目前不是很清楚,Y-combinator到底有怎样特别的用途,但是整个的推导过程并不难,耐着性子跟着作者的思路走就好,而且等你完成这个推导过程后,你会发现读《the seasoned schemer》chapter 16时,Y-bang 已经不再让你感到困惑。
最后一章chapter 10算是初级版本的scheme解释器,好比手把手教你写一个用scheme解释scheme语法的工具。说它是初级版本,是因为在《the seasoned schemer》chapter 20 中,作者对这块的代码重构了,加入了letcc, set!等,算是终极版本。
这本书遇到的问题不多,主要是在chapter 6 。
chapter 6 shadow部分,章节最末尾针对(())
, (() ())
, (() () ())
类列表定义了函数:+,lat?, 但这两个函数是无效的,执行时,无法输出结果,也许这正是章节标题 shadow的含义。
《the seasoned schemer》
全书10章,是《the little schemer》的进阶版。
个人觉得这本书相对有些难度的是chapter16和chapter19。
chapter 16中引入了Y-bang,并定义了一个函数biz用来告诉你它与 Y-combinator其实并不一样,但是具体为何不同,需要自行推导。嗯,你都能推导出Y-combinator了,这个自然也难不倒你,带着肥宅水上路吧!
chapter 19 中你会看到一个不一样的continuation,真的是很special的一个continuation。反正我自个儿是刷了两三遍才get到two-in-a-raw* 为什么可以那样定义,看完这章的时候,还想着整理点continuation的用法记录下来,结果看完wiki上有关call-with-current-continuation 举出的示例代码后,深深觉得自己水平太低,对yin-yang puzzle那块更是懵逼的一塌糊涂,先埋个坑吧,期待日后也能写一写阴阳谜题。
chapter 20 呼应着《the little schemer》chapter 10,完善了原先的代码,如果你一路走下来对每一章都理解的七七八八,这一章看下来会觉得没啥难度,看完不要忘记奖励自己甜点啊。
这本书遇到的问题主要在chapter13 和 chapter14。
chapter 13 hop skip jump 部分,书中直接使用的letcc,在mit-scheme中无法使用, 报错:Unbound variable: letcc,因为它没有定义这种缩写形式,建议练习时,遇到letcc的地方,都改用(call-with-current-continuation (lambda ....))
. 或者你也可以这样
(define call/cc call-with-current-continuation)
使用 call/cc 来代替,这样也算是某种简化了。
chapter 14 let there be games 部分,章节末尾出现了try, 但是那段代码无法正常执行,没有Google到解决方法,书中给出的try解释也让人有点懵逼,至少我觉得 a 中应该出现 x。不过对该章节印象还蛮深刻的,作者不断的改进函数leftmost,算是结结实实体验了一把Refactoring scheme version。
chapter 20 中,在使用 let 去重定义*const 时出现了重复代码,可能作者急着去party而忘记删除了😂。这个不算问题,算找茬😄。
结语
自然是强烈推荐这两本书,第一次发现原来编程书可以写得这么有意思。