【问题标题】:Scheme: when are expressions in let evaluated?方案:什么时候评估 let 中的表达式?
【发布时间】:2013-11-24 01:55:42
【问题描述】:

在“经验丰富的计划者”的第 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))(depth* (cdr l)) 被评估并传递给(lambda (x1 ... xn) b ...) 表示的lambda。但这意味着l 可能为空的列表将在(null? l) 1) 中的空检查完成之前传递给carcdr

【问题讨论】:

    标签: scheme let


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

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

      在使用let 时,会评估每个expression ...。表达式以未指定的顺序计算。

      在您的情况下,ad 涉及 depth* 的表达式将在正文之前进行评估。因此,正如您得出的结论,当调用 carcdr 时,l 可能是 '()

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-02
        • 2020-10-01
        相关资源
        最近更新 更多