我已经开始尝试学习 Scheme 评估的内容,而 quasiquotation、unquoting、evaluation 和 cons-cells 的一个方面让我感到困惑。如果您能推荐有关该主题的任何好的参考资料,我将不胜感激。
R7RS 草案在关于准引用的第 4.2.8 节中有这个例子。
`(( foo ,(- 10 3)) ,@(cdr '(c)) . ,(car '(cons)))
(它也在 R4RS 规范中,所以这不是新事物。)
根据规范,这应该评估为:
((foo 7) . cons)
我很难理解为什么。在我看来,. 从内部列表的开头删除取消引用,这意味着它不会被评估为一个过程。
这是一个演示相同问题的更简单的表达式:
`(foo . ,(car '(bar)))
使用与上述相同的逻辑,这应该评估为:
(foo . bar)
事实上,它确实在我尝试过的 Scheme 系统上进行了评估。
但是,据我了解,它不应该评估为那个,所以我想找出我哪里出错了。
我对方案评估的理解是(好的,简化的)如果它是左括号之后的第一个关键字,则使用列表的其余部分作为参数调用该过程。
我对规范的理解是 ',' 完全等同于将下一个表达式包装在 '(unquote' 过程中。
我对点符号的理解是,出于一般显示目的,您删除了点和左括号(以及匹配的右括号),如下所述:
所以:
`(foo . ,(car '(bar)))
同样可以呈现为:
(quasiquote (foo unquote (car (quote (bar)))))
(事实上,这就是jsScheme在其日志窗口中呈现输入的方式。)
但是,在评估这一点时:
(quasiquote (foo unquote (car (quote (bar)))))
为什么要评估“取消引用”(作为程序?),取消引用和评估(汽车...)列表?当然它应该被视为一个带引号的符号,因为它不在左括号之后?
我可以想到许多可能的答案 - 'unquote' 不是常规程序,'unquote' 是在常规评估过程之外评估的,除了 '('后面是程序的符号 - 但我不确定哪个是正确的,或者如何挖掘更多信息。
我见过的大多数方案实现都使用宏而不是使用与评估器相同的语言来处理这个问题,而且我很难弄清楚应该发生什么。有人可以解释一下,或者给我看关于这个主题的任何好的参考资料吗?