我正在阅读这本书 - 计划编程语言,第4版。在练习中,有一个表达式((car (list + - * /)) 2 3)
。以下是我相信表达式将被评估的步骤。如果我的理解是正确的,请告诉我。
(list + - * /)
被评估为过程列表:(+ - * /)
。 (我了解list
始终会生成“正确的列表”,有人请说明使用list
和cons
之间的一些区别吗?)(car (+ - * /))
被计算为符号+
,其符合过程。 (我真的不明白如何评估(car (+ - * /))
,在REPL提示符下输入(car (+ - * /))
会产生错误。)(+ 2 3)
的评估结果为5
。如果我能得到其他/深入解释,我想。
答案 0 :(得分:2)
+
时,您会得到一些像#<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
。 错误。您的评估表达式(list + - * /)
与(#<primitive-procedure-+> #<...> #<...> #<...>)
类似。已评估变量的列表,您现在可以看到它们的可视化表示形式。在其上执行car
会为您提供第一个对象#<primitive-procedure-+>
,它是您在评估全局变量+
时获得的相同。此步骤中不涉及符号。由于裸符号是变量,因此上一步不涉及符号。 'test
成为符号,而test
成为变量指向的任何内容。按名称的所有过程只是在应用之前评估的变量。这是Scheme中的默认行为。
由于对象与值+
相同,因此在评估后,它会将其余的操作数添加到中。因为它们都是数字,所以传递给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
答案 1 :(得分:1)