letrec在双括号方案?

时间:2015-02-11 22:29:14

标签: scheme

我无法理解ribbon01代码,与括号混淆。有人可以向我解释一下,我是计划新手

(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。

2 个答案:

答案 0 :(得分:3)

注意(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之外。

答案 1 :(得分:2)

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

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

现在,letrec中唯一的变量是di,它是一个参数的过程。然后在letrec 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一样被应用。没有什么不同。