夜里睡不着看起了 SICP,这里是第二章《构造数据抽象》的笔记。html
(cons x y) 表示一个序对,记为 z。
(car z) 能够获取 z 的第一个元素 x。
(cdr z) 能够获取 z 的第二个元素 y。
复制代码
cons(读做控死)、car(读做卡) 和 cdr(读做酷得儿)数组
翻译成 JS 风格的伪代码就是bash
z = cons x y
car z // 值为 x
cdr z // 值为 y
复制代码
有没有可能 cons、car 和 cdr 实际上是三个过程(也就是函数)呢?数据结构
只要 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" m))))
despatch)
(define (car z) (z 0))
(define (cdr z) (z 1))
复制代码
翻译成 JS 大概是这样的:函数
function cons(x, y){
// 直接返回一个函数
return function dispatch(m){
if(m===0){return x}
if(m===1){return y}
throw new Error('argument not 0 or 1 -- cons' + m)
}
}
function car(z){
return z(0)
}
function cdr(z){
return z(1)
}
复制代码
这里使人惊奇的地方就在于 cons 直接返回了一个函数,并无返回一个数组之类的玩意。post
不过这只是一种模拟,语言内部并非这样实现的。这种程序设计风格叫作「消息传递」。ui
还能够这样定义 cons、car、cdrspa
(define (cons x y)
(lambda (m) (m x y)))
(define (car z)
(z (lambda (a b) a)))
(define (cdr z)
(z (lambda (a b) b))
复制代码
翻译成 JS 是这样翻译
cons = (x, y)=> {
return (m) => m(x, y)
}
car = z => {
return z((a, b) => a)
}
cdr = z => {
return z((a, b) => b)
}
复制代码
写成这样还挺烧脑的。
上面的知识点说明其实能够抛弃复合数据结构,全用函数就好了。
可是若是我告诉你,连数字均可以不须要呢?(假设只考虑非负整数,并且这种语言容许咱们对函数进行任何操做)
0 用一个函数来表示
zero = f => x => x // 这里的 f 看起来没有意义,要到下面才能理解
复制代码
加1操做用另外一个函数来表示
add1 = n => f => x => f(n(f)(x))
复制代码
一、2 的表示方法见习题答案。
zero= f => x => x
one = f => x => f(x)
two = f => x => f(f(x))
复制代码
这样定义了以后,能够证实
add1(zero) 获得的函数跟 one 是如出一辙的(但不是同一个函数);
add1(one) 获得的函数跟 two 是如出一辙的(但不是同一个函数);
虽然我不知道这样作有什么意义,不过仍是很震撼的。
通常来讲,某种组合数据对象的操做知足闭包性质是指:经过它组合起数据对象获得的结果自己还能够经过一样的操做再进行组合。
换句话说:组合式的成员自己还能够是组合式的。
好比
(const (cons 1 2)
(cons 3 4))
复制代码
cons 组合 一、2 获得的数据,还能够做为 cons 的元素,因此说 cons 知足闭包性质。
(cons 1
(cons 2 (
cons 3 (
cons 4 nil))))
复制代码
经过 cons 的这种性质,很容易用 cons 表示一个链表。
这种语法能够简化为
(list 1 2 3 4)
复制代码
注意 (list 1 2 3 4) 是一个函数调用,其返回值为(1 2 3 4)。假设 one-to-four = (list 1 2 3 4)
(define one-to-four (list 1 2 3 4))
复制代码
car one-to-four 就是获取表头,cdr one-to-four 就是获取表头以外的节点。
咱们能够用 cons 来在链表中插入节点
(cons 10 one-to-four)
复制代码
结果为(10 1 2 3 4)。
还挺有意思的。
未完待续……
第三章的笔记:juejin.im/post/5c04de…