letrec 在带有双括号的方案中?

letrec in scheme with double brackets?

我无法理解 ribbon01 代码,与括号混淆。有人可以给我解释一下吗我是 scheme

的新手
(define ribbon01
  (lambda (lat)
    ((letrec
         ((di (lambda (lat)
                (display lat))))
       di) (cdr lat))))

(define ribbon02
  (lambda (lat)
    (letrec (( di (lambda (lat)
                  (display lat))))
    (di (cdr lat)))))

ribbon02很容易理解,letrec中有2条语句,di的声明,di的调用。

注意 (1) 中的双括号和 (2) 中的返回值:

(define ribbon01
  (lambda (lat)
    ((letrec ; (1)
         ((di (lambda (lat)
                (display lat))))
       di)   ; (2)
     (cdr lat))))

发生的事情是我们在 (2) 中返回 di 然后我们在 (1) 中 应用 它作为参数传递 (cdr lat) -请记住,一对 () 应用 作为函数传递的值,在这种情况下,该值是 di。和ribbon02一样,只不过ribbon01里面的函数应用发生在外面letrec.

将表达式括在额外括号中的唯一原因是,如果您想将其作为过程应用。

(define ribbon01
  (lambda (lat)
    ((letrec ((di (lambda (lat)
                    (display lat))))
       di)
     (cdr lat))))

现在 letrec 中唯一的变量是 di,它是一个单参数过程。然后在letrec的body中对di求值,这样整个letrec的结果就是一个程序。由于 di 未在 lambda 内部使用,我们可以使用 lambda 形式简化整个 letrec

(define ribbon01
  (lambda (lat)
    ((lambda (lat) (display lat)) (cdr lat))))

现在 lambda 只使用一个参数并因此提供 display。我们也可以替换它:

(define ribbon01
  (lambda (lat)
    (display (cdr lat))))

因此,如果您想象您评估 (ribbon01 '(1 2 3 4)),您就会知道 cdr 等于 (2 3 4),这就是显示的内容。

ribbon02 不会返回计算过程然后调用它,而是从 letrec 中应用它。使用 letrec 可能是一种更常见的方法,但结果是一样的。再次将 di 替换为它代表的内容:

(define ribbon02
  (lambda (lat)
    ((lambda (lat) (display lat)) (cdr lat))))

您会发现您与 ribbon01 处于同一位置,并且可以从那里进行相同的缩减。

因此,如果您有一个表达式 e 并在其两边加上括号 (e something),您就知道表达式 e 需要计算为一个过程,而某些东西将成为它的一个参数.

它与 (+ 1 2) 没有什么不同,因为 + 也是一个成为过程的表达式,并且由于它周围有额外的括号,所以它的应用方式与您的 letrec 一样.完全没有什么不同。