SCIP读书笔记(一)

    不得不说SCIP(Structure and Interpretation of Computer Programs)是我至今以来看过的让我最受益的一本教材了。它开启了我程序设计世界里的另一扇门,我有时会惊叹:原来程序可以这样写!这里我将自己的读书心得分享给大家,既然是读书心得,不到之处,还请大家指正。
    书中所有的例子都采用Scheme语言编写,因此我这里涉及到代码的地方也会使用Scheme。初次看Scheme语句的时候你可能会十分别扭,但是当你逐步深入学习时,你会发现Scheme语言的强大之处。我这里不会去评论各种编程语言的好坏,存在即是理由,不管是历史造就了一门语言,或是某个产品推动了一门语言的发展。每种语言都有自己的优点与缺点,在特定的场景下使用适当的语言,才能充分发挥程序的作用。就像生活中有各种各样的刀一样,有削铅笔的刀,有切菜的刀,有砍骨头的刀...每种刀只有在特定的场景下才能充分展示其作用,你不可能拿砍骨头的刀去削铅笔,反之,你也不会拿削铅笔的刀去砍骨头。语言就是一门工具,我们说学习一门语言,无外乎学习这门语言的语法规则,这是一件十分简单的事,我们可以在几个小时内就熟悉,但是我们其实更应该学习的是分析和解决问题的能力。写代码就是为了解决现实生活中的一些问题,遇到一个问题我们以什么方式能够高效优雅地解决,这才是一个程序员能力的体现。引用书中的一个比喻,我觉得十分恰当:学习一门语言就像学习下棋,语言的语法就像下棋的规则,就像象棋里的马走日,象飞田...每个人都能够快速的上手,但是要称为下棋的高手,光懂这些规则是远远不够的,还需要学习比如开局,战术,策略...因此作为程序员,我们更应该追求后者,提高自己分析和解决问题的能力,而不是炫耀学了多少种语言。好了,扯了很多不相关的东西,下面正式步入正题。
在这一篇中,我们主要熟悉Scheme的语法和一些基本概念。

1. 什么是程序设计语言?

书的开篇就提出了一个问题:什么是程序设计语言?程序设计语言需要具备什么特性?

程序设计语言就是一种指示机器去执行任务的方法,另外一方面,程序设计语言需要提供给其使用者一种表达其思想的方法。

上面是我翻译的,原文是这样的:

A powerful programming language is more than just a means for instructing a computer to perform tasks. The language also serves as a framework within which we organize our ideas about processes.

从这里我们可以看出,程序设计语言其实充当着翻译官的作用,它连接着程序员和机器,将程序员的思想翻译给机器执行。仔细想想,好像是这么一回事。强大的程序设计语言都具备以下三种机制:

  • 元表达式:程序设计语言中的最简单的实体
  • 组合方式:通过组合方式将简单的实体组合成更加复杂的元素
  • 抽象能力:组合的元素能够被命名并作为一个整体来使用

所谓的元表达式就是程序中最简单的元素,主要包括两种:数字和元操作符+,-,*,/。元操作符和数字可以进行组合,例如在Scheme语言中你可以这样写:

(+ 1 2 3 4) -> 10
(* 2 3 5) -> 30

这样表示方法叫前缀表达式,语法规则是

(操作符 操作数 操作数 ...)

这样表示法相比于我们熟悉的中缀表达式的一个最大的好处是一个表达式可以有任意多个操作数而不会产生歧义,就像上面的例子。前缀表达式的另一个优势在于表达式的嵌套,例如:

(+ (* 2 3) (- 10 3)) -> 13

(注:要运行这些例子,需要下载一个Scheme解释器,例如MIT的scheme解释器)

    关于组合方式这一块,我们可以回顾下C语言和Java语言。在C语言中我们可以使用结构体struct和联合体union来简单的元素组合成复杂的元素;在Java语言中,我们使用类class来组合各种简单的元素,相比于结构体struct,class中还可以定义方法(当然,结构体中也可以定义函数指针变量来实现等价的效果),因此Java语言的组合方式更多一点。在Scheme语言里提供的组合方式叫做pair,我们可以使用box-and-pointer的表示方法来表示一个pair。在box-and-pointer中,每个实体都表示为一个box和指向该box的一个pointer,元表达式的box中就存放着与之对应的内容,而pair可以看做是两个连在一起的box和指向这两个box的pointer。一图胜千言:

box-and-pointer表示法

一个pair可以使用Scheme提供的cons函数来创建,如:

(cons 1 2) 就构建了上图中的pair

就像结构体struct中可以嵌套结构体,class中可以定义class一样,这里的cons中也可以嵌套cons,例如:

(cons 1 (cons 2 (cons 3 (cons 4 nil))))

用图形表示一下:


cons实现链表效果

是不是像某个数据结构:链表?(表达式中nil可以和我们熟悉的null做类比)这种嵌套(闭包特性:若某种操作的结果仍然可以用该操作处理,那么我们说这个操作有闭包特性,例如这里的cons)十分强大,能够表达各种各样的数据结构,这个后续还会详细介绍。
抽象能力这块其实是程序员需要重点关注的地方,看待一个问题的时候,我们应该尽可能地从更高层次上去抽象出问题的本质并找到合适的解决方案。在程序设计语言中的抽象能力主要体现在一个实体可以被命名,通过名字来引用某个实体。

    从元表达式、组合方式、抽象能力这三点我们可以总结一下:程序设计其实和搭积木很类似,我们有一个个简单的积木(元表达式),可以通过胶水或其他方式将一些简单的积木绑在一起(组合方式)得到组合的积木,最后我们用组合的积木(抽象能力)构建成最终的形状。反过来,我们要解决某个具体的问题,我们需要用抽象的能力将问题分解成一个个子问题,这些子问题能够更加简单的方式解决,当子问题解决后,我们将子问题的解组成原始问题的解。

2.Scheme基本语法

学习一门语言,当然最开始的就是学习其语法。这里主要简单的讲下基本语法,有兴趣的同学可以看书深入了解。

  • 变量与函数的定义
    定义变量使用(define 变量名 变量值) 如 (define PI 3.14)
    定义函数使用(define (函数名 形式参数列表) 函数体) 如 (define (sum a b) (+ a b))
  • 条件语句与预言

所谓的预言就是一个布尔表达式,有真和假两种情况,也就是我们常用的逻辑表达式:

逻辑与 (and <e1> <e2> ... <en>) 当<e1>, <e2> ... <en>都为真时为真,有短路规则.
逻辑或 (or <e1> <e2> ... <en>) 当<e1>, <e2> ... <en>任意一个为真时为真,有短路规则
逻辑非 (not <e>) <e>为真时表达式为假,<e>为假时表达式为真

条件语句的语法是:

(cond (<p1> <e1>)
       (<p2> <e2>)
        ...
        (<pn> <en>))

类似于我们熟悉预言里的switch语句,其执行顺序为若p1预言为真,那么就执行e1,同时e1表达式的结果将作为条件语句的结果返回。若p1为假,那么就判断p2预言,以此类推。条件语句还有一种,就是我们常用的if语句,其在Scheme里的语法为:

(if 预言 预言为真执行的语句 预言为假执行的语句) 例如 (if (> x 0) (+ x 1) (- x 1))

if语句是一种条件受限的cond语句,它只有两种情况。也就是说所有的if语句可以转换为cond语句,反之则不能。
    Scheme的基本语法就这么多,你或许会问,怎么没有循环表达式?这也是我当时的困惑,在Scheme中使用递归来代替了循环表达式,详细在后文中讲述。现在应该了解了Scheme的基本语法了,可以尝试用Scheme实现下书中的例子求某个数x的平方根。有疑问?请留言。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,076评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,658评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,732评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,493评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,591评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,598评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,601评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,348评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,797评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,114评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,278评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,953评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,585评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,202评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,180评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,139评论 2 352

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,647评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,012评论 25 707
  • 知的定义 荀子给“知”下了一个准定义: “凡以知,人之性也;可以知,物之理也。”(《解蔽》) 这个知不是所谓知识,...
    徐红钢阅读 1,393评论 0 0
  • 飒飒西风里,清癯处士衣。 空有攀云志,恨无上天梯。 柴油不解意,盐米告罄急。 庶几箪瓢满,诗酒乐忘机。
    aaab0cd9403b阅读 168评论 0 0
  • 暗恋能教会我们, 如何好好去爱下一个人, 有点甜蜜,有点苦涩。
    驴子lv阅读 131评论 0 0