《计算机程序的构造和解释》(sicp) chap-2.1

第二章第一节 数据抽象引导

  现在到了数学抽象中最关键的一步,让我们忘记这些符号所表示的对象,不应该在这里停步,有许多操作可以应用于这些符号,而根本不必考虑它们到底代表什么东西。

  程序本质是对现实的模拟,在遇到复杂的现实情况时,简单的数据类型将不能再满足我们对程序实现的需要。我们需要复杂的复合数据来满足各种各样的程序设计。

  来举一个简单的例子,现在需要定义一个过程,接受a,b,x,y四个参数,返回ax + by的值。根据过程我们能够很轻松的定义出来函数。linear-combination

(define (linear-combination a b x y)
    (+ (* a b) (* b y))
)

  此时存在问题,linear-combination函数只能适配正常简单数字数据结构的入参,当入参为有理数,复数,甚至多项式的时候,这个函数就不能运行了。我们需要做的,就是在命令式的+*上面做一层函数抽象,能够让linear-combination函数适配各种复杂的数据结构,达到ax + by的目的。函数修改如下:

(define (linear-combination a b x y)
    (add (mul a b) (mul b y))
)

  此时的addmul不是简单的+*,而是针对不同的数据结构进行不同的抽象的操作,这就是这一章的核心思想,如何在复杂的数据结构之中建立适当的抽象屏障,来设计出合健壮的程序。

  在第一节数据抽象导引中,将用有理数作为例子,通过实现一系列的有理数的操作,来学习如何在程序中建立合适的抽象屏障

2.1数据抽象导引

  数据抽象的基本思想就是构造出一段程序,在使用时就像你在操作这复合数据一样。

  我们来看有理数的例子。我们需要定义一个变量来存放有理数,再定义一个make-rat的函数能够生成一个有理数,之后通过numer来获取有理数的分子,denom来获取有理数的分母。就像这样:

;; 定义 1/2
(define rational (make-rat 1 2))
;; 拿出分子1
(numer rational)
;; 拿出分母2
(denom rational)

  实际上在scheme中,程序自带一种名为序对的数据结构,能够像粘合一样,把两个数绑定在一起。使用(cons a b)来把a和b粘合到一起,carcdr来取出第一项和第二项。

(define x (cons 1 2))
(display x) ;; (1 . 2)
(car x) ;; 1
(cdr x) ;; 2

  利用序对我们可以非常简单的写出来make-ratnumerdenom。我们还能定义一个打印有理数的方法display-rat

(define (make-rat a b)
    (cons a b)
)
(define (numer rational) (car rational))
(define (denom rational) (cdr rational))
(define (display-rat rational)
  (newline)
  (display (numer rational))
  (display "/")
  (display (denom rational))
)

  现在我们可以的结合有理数的例子简单领悟一下抽象屏障的概念。

-  使用有理数的程序 -
-  操作有理数的方法(如display-rat) - 
-  有理数本身的数据结构(make-rat) -
-  作为序对的有理数(cons car cdr) - 

  作为有理数程序的使用者,我们无需关心有理数的数据组织结构,只需要使用生成有理数的make-rat,以及相应提供的操作有理数的方法,来去实现我们程序所需要的。就像JS当中的数组和对象,我们使用字面量或者构造函数生成数组对象,再使用数组对象prototype上面的各种方法来操作这些数据结构来实现我们的程序,而不用去关心这些底层的内容。
  现在我们来关心一下底层cons方法以及对应的car,cdr的实现。

(define (cons x y)
    (define (dispatch m)
        (cond ((= m 0) x)
              ((= m 1) y)
              (else (error "Argument not 0 or 1 -- cons"))
        )
    )
    dispatch
)

  这里我们定义cons函数,它返回一个名为dispatch的函数过程。dispatch接受一个参数,当参数为0时返回x,参数为1时返回y。现在我们就可以轻松的定义出来carcdr

;; cons函数返回的为dispatch,即这里cons-num就是dispatch
;; 我们只需要在取数内部取出即可
(define (car cons-num) (cons-num 0))
(define (cdr cons-num) (cons-num 1))

  按照这个逻辑思路,你可以定义出关联三个数的cons-three,关联四个数的cons-four。正如这章开头所说的,复杂数据本质是过程的高级抽象。
  最后来看课后的习题2.4来组合一下思路,使用代还模型证明一种新的cons方法可用,并根据car实现cdr

(define (cons x y)
    (lambda (m) (m x y))
)
(define (car z)
    (z (lambda (p q) p))
)

  这里的cons方法同样返回一个lambda过程,这个lambda接受一个函数,接受后直接传入xy参数并执行。那么我们来代换一下car

;; z其实就是cons返回的lambda
(car (lambda (m) (m x y)))

  那么car中执行执行这个函数,并传入了新的一个lambda方法(lambda (p q) p)。即直接把m代换为(lambda (p q) p)

;; m为(lambda (p q) p)
(lambda (x y) x)

  所以根据这个逻辑cdr的实现很简单。

(define (car z)
    (z (lambda (p q) q))
)

  这本书习题真的是多到和正文内容一样多了,工作又忙,读起来的速度是真的非常慢。但是总的来说还是有所值的。本章节阐述了核心思想,符合数据结构本质上都是一段程序过程。我们在做复合数据结构设计的时候,要有抽象屏障的概念,提供制造复合数据的方法以及各种使用复合数据的方法让调用的人不用去关心底层的内容,

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

推荐阅读更多精彩内容