识别嵌套引号并在方案中取消引用它

时间:2014-11-23 14:00:34

标签: scheme racket

我试图创建一个特殊的折叠功能。

我有关于引号的问题,尤其是嵌套的引号。似乎它们有时会作为列表的开头插入,有时候作为引用。

说我有下一个代码:

'(x '(a b c))

然后:

(car '(x '(a b c)))

将返回:x。虽然:

(cadr '(x '(a b c)))

将返回:'(a b c)。  这是什么意思?这是一个清单吗?如果是这样,为什么:

(caadr '(x '(a b c)))

返回:引用。这句话的含义是什么? 有什么方法可以识别这些列表吗?如果是这样,有没有办法取消引用它们?

1 个答案:

答案 0 :(得分:3)

当我们评估引用的表达式时,请记住此表达式:'x只是简写:(quote x)。例如:

'(x '(a b c))

相当于:

(quote (x (quote (a b c))))

现在这个表达式也将返回一个带引号的表达式,该表达式恰好以另一个引用的表达式开头:

(cadr (quote (x (quote (a b c)))))
                ---------------
=> ''(a b c)

这在下一个示例中更明显,我们最终检索'quote符号本身:

(caadr (quote (x (quote (a b c)))))
                  -----
=> 'quote

对于问题的最后部分:如果您想将最里面的列表解释为列表而不是引用的表达式,那么根本不要引用它:

(cadr '(x (a b c)))
=> '(a b c)

当然,我们也可以将第二个quoteeval留在最里面的列表中,但这很麻烦,potentially evil

(define-namespace-anchor a)
(define ns (namespace-anchor->namespace a))

(eval (cadr '(x '(a b c))) ns)
=> '(a b c)

或者我们可以使用quasiquoting and unquoting

(cadr `(x ,'(a b c)))
=> '(a b c)