方案表达式评估

标签 scheme lisp

我正在阅读《Scheme 编程语言》第四版这本书。在练习中,有一个表达式 ((car (list + - */)) 2 3)。以下是我认为将评估表达式的步骤。请告诉我我的理解是否正确。

  1. 表达式(list + - */) 被计算为过程列表:(+ - */)。 (我知道 list 总是产生一个“正确的列表”,有人可以说明一下使用 listcons 之间的一些区别吗?)<
  2. 表达式(car (+ - */)) 被计算为符号+,该符号计算为一个过程。 (我不太明白 (car (+ - */)) 是如何计算的,在 REPL 提示符处输入 (car (+ - */)) 会产生一个错误)。
  3. 表达式 (+ 2 3) 的计算结果为 5

我希望我能得到一些其他/深入的解释。

最佳答案

  1. 是的!但是,这些过程没有文字表示,因此当您评估 + 时你会得到一些疯狂的文本表示,例如 #<primitive-procedure-+>复制它并将其粘贴到 repl 中不会返回相同的对象。与列表相同。当您评估(list 1 2 3)时你得到(1 2 3)但你不能只写 (1 2 3)因为它会认为应该调用 1作为带有两个参数的过程。 (list 1 2 3)使(cons 1 (cons 2 (cons 3 '())))嵌套对链。那最后cdr()这就是它的正确之处。因此,允许 list 的原语做这件事是 cons
  2. 错了。您有一个计算表达式 (list + - * /)类似 (#<primitive-procedure-+> #<...> #<...> #<...>) 。评估变量的列表,您现在可以看到它们的视觉表示。做car它给你第一个对象 #<primitive-procedure-+>这与评估全局变量 + 时得到的相同 。此步骤不涉及任何符号。上一步也不涉及符号,因为裸符号是变量。 'test成为符号,而 test变成变量所指向的任何内容。所有按名称命名的过程都只是在应用之前评估的变量。这是Scheme 中的默认行为。

  3. 由于该对象与值 + 相同它会将其余操作数求值后添加到一起。由于它们都是数字,因此传递给 apply 的参数保持不变,但如果您有像 (+ (* 3 3) (* 4 4)) 这样的表达式那么操作数如 (* 3 3)需要进行评估,其结果就是所应用的。

您可以应用替换规则。这不是Scheme解释器所做的,但是任何变量都可以被它拥有的值替换,每个表达式都可以被它的结果替换,只要你不改变任何东西:

((car (list + - * /)) (- 5 2) (/ 4 2)) ; == (car (list + - * /)) evaluates to the same value as the variable +
(+ (- 5 2) (/ 4 2)) ; == (- 5 2) evaluates to 3, (/4 2) evaluates to  2
(+ 3 2)             ; == (+ 3 2) evaluates to 5
; ==> 5 (the result)

注意我替换了(car (list + - * /))变量 +而不是一个符号。它们都是相同的:(eq? (car (list + - * /)) +) ; ==> #t

关于方案表达式评估,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43613269/

相关文章:

javascript - 除了 First Class Functions 和 Lexical Scoping,JavaScript 与 Scheme 实现有什么共同之处?

recursion - 替换列表中每个出现的元素,仅当它跟在指定元素之后时

list - 将元素 append 到方案中的现有列表

emacs - 为什么 slime 的 "package"和劣等的 lisp 不一样?

list - 反转 LISP 中列表的前 n 个元素

programming-languages - 为什么是高阶程序?

scheme - 阴阳拼图是如何工作的?

Clojure:确定函数是否存在

ruby-on-rails - 支持复杂嵌套形式的框架 ala Rails 的 accepts_nested_attributes_for?

macros - 从 Quicklisp 包内的宏调用函数