variables - 创建本地绑定(bind)的 'let' 或 'letrec' 和 'define' 之间有什么区别?

标签 variables scope scheme letrec

我不明白两者之间有什么区别(对于人为的例子感到抱歉):

(define average
  (lambda (elems)

   (define length
     (lambda (xs)
      (if (null? xs)
          0
          (+ 1 (length (cdr xs))))))

   (define sum
     (lambda (xs)
      (if (null? xs)
          0
          (+ (car xs) (sum (cdr xs))))))

   (define total (sum elems))

   (define count (length elems))

   (/ total count)))


(define average
  (lambda (elems)
   (letrec ((length
              (lambda (xs)
               (if (null? xs)
                   0
                   (+ 1 (length (cdr xs))))))

            (sum
              (lambda (xs)
               (if (null? xs)
                   0
                   (+ (car xs) (sum (cdr xs))))))

            (total (sum elems))

            (count (length elems)))

     (/ total count))))

据我所知,它们都创建了一个新的作用域,并在该作用域中创建了 4 个局部变量,它们相互引用并引用自身,并评估并返回一个主体。

我在这里遗漏了什么,或者是letrec作用域 define 的同义词年代?

我知道这可能取决于实现;我试图了解 Lisps 的基础知识。

最佳答案

你说得对,define 之间有相似之处。和 letrec您的代码的版本。然而,魔鬼在细节中。在 R5RS 中,internal define has letrec semantics .在 R6RS 中,internal define has letrec* semantics .

有什么不同?您的代码实际上只是突出了这种差异。正如哲豪的回答所提到的,您对 total 的定义和 count在同一个letrec作为 lengthsum不正确:lengthsum不保证在您评估 (length elems) 的值时受到约束和 (sum elems) ,因为这些变量的绑定(bind)不保证是从左到右的。
letrec*类似于 letrec ,但有从左到右的保证。因此,如果您更改了 letrecletrec* ,会好的。

现在,回到我最初的评论:因为 R5RS 的内部 define使用 letrec语义,甚至你的define代码的版本在 R5RS 实现下是不正确的,但在 R6RS 实现下是可以的,它有 letrec*语义。

关于variables - 创建本地绑定(bind)的 'let' 或 'letrec' 和 'define' 之间有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11463232/

相关文章:

java - 可以将具有推断类型的局部变量重新分配给不同的类型吗?

MySQL 变量从 SUM() 获取 NULL

c++ - 编译错误 : 'this' cannot be implicitly captured in this context

javascript - 如何在 Rails 应用程序上有效地限定 javascript set css 的范围?

Scheme:define 和 let 与 continuation 一起使用时有什么区别

bash - 如何激活 FULL $var 完成

bash - 如何使用 shell 脚本变量作为 sed 的参数?

ExtJS 按钮处理程序不起作用

Scheme-Wrong type to apply #f error in code for checking a prime number

scheme - 如何从 Scheme 中的递归调用正确返回值?