在quququoted点对中取消引用项目

时间:2012-12-10 22:17:39

标签: scheme

我开始尝试学习Scheme评估的内部结构,而quasiquotation,unquoting,evaluation and cons-cells的一个方面令我感到困惑。如果你能就这个问题推荐任何好的参考资料,我将非常感激。

R7RS草案在第4.2.8节中有关于准规范的例子。

`(( foo ,(- 10 3)) ,@(cdr '(c)) . ,(car '(cons)))

(这也是R4RS规范,所以这不是新事物。)

根据规范,这应评估为:

((foo 7) . cons)

我在理解原因时遇到了一些麻烦。在我看来,。从内部列表的开头删除unquote,这意味着它不会被评估为过程。

这是一个表达同样问题的简单表达式:

`(foo . ,(car '(bar)))

使用与上面相同的逻辑,这应评估为:

(foo . bar)

事实上它确实在我试过的Scheme系统上进行了评估。

然而,根据我的理解,它不应该评估,所以我想找出我出错的地方。

我对Scheme评估的理解是(OK,简化),如果它是open-bracket之后的第一个关键字,则以列表的其余部分作为参数调用该过程。

我对规范的理解是','完全等同于将下一个表达式包装在'(非引用'过程中。

我对点符号的理解是,为了一般显示的目的,你删除点和左括号(和匹配的右括号),如下所述:

  

In general, the rule for printing a pair is as follows: use the dot notation always, but if the dot is immediately followed by an open parenthesis, then remove the dot, the open parenthesis, and the matching close parenthesis.

所以:

`(foo . ,(car '(bar)))

同样可以渲染为:

(quasiquote (foo unquote (car (quote (bar)))))

(事实上,这就是jsScheme在日志窗口中呈现输入的方式。)

然而,在评估时:

(quasiquote (foo unquote (car (quote (bar)))))

为什么'unquote'被评估(作为一个程序?),不引用和评估(car ...)列表?当然它应该被视为一个带引号的符号,因为它不是在一个开头括号之后?

我可以想到一些可能的答案 - 'unquote'不是常规程序,'unquote'是在常规评估过程之外进行评估的,有一种不同的方式来指示一个被调用的程序而不是一个'('后跟程序的符号 - 但我不确定哪个是正确的,或者如何挖掘更多信息。

我见过的大多数方案实现都是使用宏而不是与评估器使用相同的语言来处理它,而且我很难搞清楚应该发生什么。有人可以解释,或者向我展示关于这个主题的任何好的参考资料吗?

1 个答案:

答案 0 :(得分:1)

你是正确的,因为涉及到宏:特别是quasiquote是一个宏,unquoteunquote-splicing是文字。这些都不是程序,所以正常的评估规则不适用。

因此,尽管(quasiquote (foo bar baz unquote x))不是第一个语法元素,但可以为unquote提供所需的特殊处理。