3

在“The Seasoned Schemer”的第 66 页上,它说这(let ...)是 的缩写:

(let ((x1 a1) ... (xn an)) b ...) = ((lambda (x1 ... xn) b ...) a1 ... an)

例如在第 70 页上使用它:

(define depth*
  (lambda (l)
    (let ((a (add1 (depth* (car l))))
          (d (depth* (cdr l))))
      (cond
        ((null? l) 1)
        ((atom? (car l)) d)
        (else (cond
                ((> d a) d)
                (else a)))))))

但是上面的定义lambda会暗示(add1 (depth* (car l))and(depth* (cdr l))被评估并传递给由(lambda (x1 ... xn) b ...). 但这意味着l可能为空的 list 将在 null 签入完成之前car传递给它们。cdr(null? l) 1)

4

2 回答 2

3

你说得对,(car l)并且(cdr l)会在测试 if is null 之前被执行,因此如果 if is lIndeed 会引发错误。继续阅读本书,在接下来的两页中对此进行了解释,并显示了正确的版本。lnulldepth*

于 2013-11-12T03:36:23.017 回答
0

let语法关键字接受以下形式(忽略'named-let'):

(define-syntax let
  (syntax-rules ()
    ((let ((identifier expression) ...) body ...)
     ;; ...)))

在使用的地方,let每个都expression ...被评估。表达式以未指定的顺序进行评估。

a在您的情况下,用于和d涉及的表达式depth* 在正文之前进行评估。因此,正如您已经得出的结论,可能l'()何时被调用。carcdr

于 2013-11-12T05:20:53.840 回答