的行为quote在R6RS附录A.3中指定。对于'1,相关规则是6sqv:
(存储 ( sf 1 ...) S 1 [ 'sqv 1 ]) → (存储 ( sf 1 ...) S 1 [ sqv 1 ])
是时候打破这个了。
“S → T”表示法定义了评估术语的一个步骤,其中“S”评估为“T”。
由于store和非终结符在左侧和右侧看起来相同,因此您无需了解它们即可了解如何评估。如果您需要某些东西,请将其视为“存储环境”,并将其视为名称和值对;表示标识符与 value 相关联,并且在评估 term 时与之相关联。sf1 '1storesfn(store ((x 1) (y 2)) S)x1y2S
如果你不熟悉这个符号,它指的是一个有一个“洞”(一个里面有 a 的词)填充的术语。有两个相关的语法元素:带有孔的术语 ( ) 和带有由值填充的孔的术语 ( )。孔有点(但只有一点)像未命名的变量。一个重要的区别是一个术语只允许一个洞。孔可能最好用例子来解释。以下是:S[e][]eS[]S[e]S[]
请注意,只有在子项在语法上有效时才会出现空洞;[] 2)不是一个有洞的术语。S[0]将是一个0代入洞中的术语:
当为孔指定值时,该术语S[]也称为“上下文”。这来自 term-with-holes 的主要用途之一:匹配包含给定值的任何术语。是任何包含有效子术语的术语,因此出现的上下文也是如此。简而言之,它是包含引用的任何术语的替代。S[e]eS[]eS1['sqv1]
请注意,第二个术语为引用术语提供了两种不同的上下文:(list [] 'a "foo"), (list 'bar [] "foo"). 这表明您不应该过多地将漏洞视为未命名的变量。
如果您想知道为什么使用上下文术语和孔,它们是递归定义的替代方案。如果没有上下文,→ 必须在术语结构上递归定义(Scheme 的语法定义了结构)。lambda 演算中的替换是结构递归的一个示例,您可能在 Scheme 中定义的任何树处理函数也是如此(尽管 Scheme 语法与用于定义 → 和 lambda 演算替换的语法完全不同)。
(define (tree-depth tree)
(if (pair? tree)
(max (tree-depth (car tree))
(tree-depth (cdr tree)))
1
) )
接下来,让我们检查一下 的含义sqv,它是“自引用值”的缩写。这是附录 A.2 中给出的Scheme 语法的非终结符。
平方::= n | #t | #f
n ::= [数字]
sqv只是一个数字或布尔值。
总之,6sqv评估规则意味着引用的数字或布尔值评估为数字或布尔值;报价被简单地丢弃。
这对您的作业意味着您无法区分普通函数1和'1普通函数之间的区别,因为在调用函数之前会评估子项。你需要一个宏。
为什么要经历这一切只是为了说“'1评估为1”?首先,回答“为什么”比回答“什么”更重要。此外,它有望帮助您超越问题,学习一点如何阅读 Scheme 的形式语义,让您体验计算理论概念并引发更多问题。