夜裏睡不着看起了 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…