在SICP中使用lambda进行cons/car/cdr定义

Pen*_*ino 14 lambda scheme sicp racket

当我在SICP中遇到以下'替代'定义的缺点和汽车时,我才开始觉得我对球拍和方案中lambda的使用有一个模糊的理解

(define (cons x y)
   (lambda (m) (m x y)))

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

(define (cdr z)
  (z (lambda (p q) q)))
Run Code Online (Sandbox Code Playgroud)

对于我的生活,我无法解析它们.

任何人都能解释如何以对全新手有意义的方式解析或扩展这些吗?

Ósc*_*pez 23

这是一种表示数据的有趣方式:作为函数.请注意,这个定义cons返回a 关闭参数 并在lambda其中捕获它们的值.另请注意,返回的lambda接收函数作为参数:xy m

;creates a closure that "remembers' 2 values
(define (cons x y)    (lambda (m) (m x y)))
;recieves a cons holding 2 values, returning the 0th value
(define (car z)       (z (lambda (p q) p)))
;recieves a cons holding 2 values, returning the 1st value
(define (cdr z)       (z (lambda (p q) q)))
Run Code Online (Sandbox Code Playgroud)

在上面的代码中z是一个闭包,就像cons在程序的主体中创建的那样,我们将另一个 lambda作为参数传递给它,还记得m吗?就是这样!它期待的功能.

了解上述情况,可以很容易地看到carcdr工作; 让我们分析一下car,cdr解释器如何一步一步地评估:

; lets say we started with a closure `cons`, passed in to `car`
(car (cons 1 2))

; the definition of `cons` is substituted in to `(cons 1 2)` resulting in:
(car (lambda (m) (m 1 2)))

; substitute `car` with its definition
((lambda (m) (m 1 2)) (lambda (p q) p))

; replace `m` with the passed parameter
((lambda (p q) p) 1 2)

; bind 1 to `p` and 2 to `q`, return p
1
Run Code Online (Sandbox Code Playgroud)

总结一下:cons创建一个闭包,"记住"两个值,car 接收该闭包并将其传递给充当第0个值的选择器的函数,并cdr充当第1个值的选择器.这里要理解的关键点是lambda作为一个 闭包.这有多酷?我们只需要函数来存储和检索任意数据!

的嵌套组合物carcdr定义多达4个深在大多数的Lisp.例:

(define caddr (lambda (x) (car (cdr (cdr x)))))
Run Code Online (Sandbox Code Playgroud)

  • 在这两种情况下都有潜伏的功能,等待好好问:) (4认同)