我试图使用拟引用生成列表(1 unquote 2)
。我试过了:
`(1 unquote 2)
然而,在Racket, MIT Scheme和Chez Scheme中,我得到一个虚线列表:'(1 . 2)
。
所以我试了这个:
`(1 'unquote 2)
然而,我得到(1 'unquote 2)
。
我终于用这种方法得到了我想要的列表:
`(1 unquote 2 ,((lambda (x) x) 'unquote) 2) ; Returns: '(1 unquote 2)
当unquote
是准引用列表中的倒数第二个元素时,为什么我从准引用列表中获得点列表?
实际上,它并不总是产生一个点列表。例如:
`(1 unquote (list 2 3 4)) ; Returns: '(1 2 3 4)
请解释在准引号列表中倒数第二个元素反引号的奇怪行为。
(a b c)
是(a . (b . (c . ())))
的缩写。
所以(quasiquote (1 unquote 2))
实际上是(quasiquote (1 . (unquote 2)))
,也就是'(1 . 2)
。
(或者如果你想完全展开它,(quasiquote (1 unquote 2))
就是(quasiquote . ((1 . (unquote . (2 . ()))) . ()))
)
同理,(quasiquote (1 unquote (list 2 3 4)))
实际上是(quasiquote (1 . (unquote (list 2 3 4))))
=(quasiquote (1 . (2 3 4)))
='(1 2 3 4)
。
'(1 unquote 2)
的一种更简单的方法是:
`(1 ,'unquote 2)
根据R5RS,
如果任何符号
quasiquote
,unquote
或unquote-splicing
出现在
你的位置不是"如上所述";-格式必须为(unquote expression ...)
。
在R6RS中已升级为语法违例。
[写答案而不是注释,因为在注释中不可能正确格式化反引号。Lisp/Scheme仍然比markdown处理得更好;-)]
正如其他人(特别是Sorawee)所解释的那样,unquote
(又名,
)是一个特殊的名称,在quasiquote
d列表(又名反打号)中被特殊对待。为了防止其特殊含义,一个简单的解决方法是确保特殊名称不以文本形式出现。请注意,unquote
在quote
中没有特殊的含义(与quasiquote
中相比)。
因此,这将在Scheme的所有变体中工作:
(define unquote-sym 'unquote) ; `unquote` is inside `quote`, so it's a mere symbol here
`(1 ,unquote-sym 2) ; '(1 unquote 2)