clojure的语法报价如何工作? [英] How does clojure's syntax-quote work?
问题描述
clojure中的各种特殊字符是
Various special characters in clojure are abbreviations for things
(quote(ab))
的缩写'(ab)
,您可以通过评估:
user> ''(a b)
(quote (a b))
缩写,这是一个好主意。
This seems to be syntax as abbreviation, which strikes me as a fine idea.
但语法 - 引号,`,似乎特别。我不能认为是等价的
But the syntax-quote, ` , seems special. I can't think what would be equivalent to
`(a b)
我会猜到(syntax-quote(ab))
,但它不工作,如果我只是猜错了,我找不到真正的名字。
I would have guessed something like (syntax-quote (a b))
, but it doesn't work, and if I've just guessed wrong, I can't find out what it's really called.
user> '`(a b)
(clojure.core/seq (clojure.core/concat (clojure.core/list (quote user/a)) (clojure.core/list (quote user/b))))
有点神秘。
有趣的是,syntax-quote中使用的特殊语法的工作方式与我预期的一样:
Interestingly, the special syntax used in the syntax-quote does work as I expected:
user> '~a
(clojure.core/unquote a)
user> '~@a
(clojure.core/unquote-splicing a)
user> '~'a
(clojure.core/unquote (quote a))
这一个:
user> 'a#
a#
我原以为会生产类似 (unquote(gensyma))
我意识到我在这里有点虚弱,代码。如果没有人喜欢解释发生了什么或提供参考,任何人都可以给我一个提示,如何找到相关的代码和寻找什么。
I do realise that I'm being a bit feeble here, and should just go and read the code. If no-one fancies explaining what's going on or giving a reference, can anyone give me a hint about how to find the relevant code and what to look for?
推荐答案
我不认为有引用
函数的语法引用。
I don't think there's a syntax-quote equivalent of the quote
function.
Clojure读取器(目前)是用Java编写的。 Clojure源中的 SyntaxQuoteReader
类在 src / jvm / clojure / lang / LispReader.java
我想读。它似乎相当复杂。你可以看到它建立列表(seq(concat ...))
那里。
The Clojure reader is (currently) written in Java. The SyntaxQuoteReader
class in src/jvm/clojure/lang/LispReader.java
in the Clojure source is probably what you'll want to read. It seems rather complex. You can see it building lists like (seq (concat ...))
there.
ret = RT.list(SEQ, RT.cons(CONCAT, sqExpandList(seq)));
读者通常不会返回直接的Clojure代码,土地立即。例如'[1 2 3]
不会生成Clojure代码(vector 1 2 3)
。也许它可以以某种方式工作,但它不。读者只需创建并返回向量对象本身。
It's common for the reader not to return straightforward Clojure code, but rather do the right thing in Java-land immediately. For example '[1 2 3]
doesn't yield the Clojure code (vector 1 2 3)
. Maybe it could work that way somehow, but it doesn't. The reader just creates and returns the vector object itself.
同样, SyntaxQuoteReader
在Java中立即执行一些魔法来解析符号命名空间并创建gensyms本身,复杂的和复杂的Clojure代码,做正确的事情,但不一定容易为人阅读。无论是这样,因为它必须是,或者因为它更容易做这种方式在Java,或性能或一些其他原因,我不知道。同样,我不知道 quasiquote
是否可以作为一个纯宏/特殊形式存在于Clojure中,而不是,或者它根本不存在。我不明白为什么它不能。
Likewise, the SyntaxQuoteReader
does some magic in Java immediately to resolve symbol namespaces and create gensyms itself and it returns some mangled and complicated-looking Clojure code that does the right thing, but isn't necessarily easy for a human to read. Whether it's like this because it has to be, or because it's easier to do it this way in Java, or for performance or some other reason, I don't know. Likewise I don't know if quasiquote
could exist as a plain macro/special form in Clojure and doesn't, or if it couldn't exist at all. I don't see why it couldn't though.
WrappingReader
'
(plain old quote
)。你可以看到它只是包装任何你传递它在一个列表包含符号 quote
加上你的参数。它简单得多。注意,这个类还处理 @
,所以'@ foo
会返回 )
。
WrappingReader
in the same file is the class that handles '
(plain old quote
). You can see that it just wraps whatever you pass it in a list containing the symbol quote
plus your argument. It's much simpler. Note that this class also handles @
, so that '@foo
does return (deref foo)
.
This thread might shed some more light.
一个概念证明 quasiquote
宏。注意,这个代码依赖和滥用Clojure内部在一个可怕的方式。请不要使用此项。
Here's a proof-of-concept quasiquote
macro. Note that this code is relying upon and abusing Clojure internals in a horrible way. Please don't use this for anything.
user> (defmacro quasiquote [x]
(let [m (.getDeclaredMethod clojure.lang.LispReader$SyntaxQuoteReader
"syntaxQuote"
(into-array [Object]))]
(.setAccessible m true)
(.invoke m nil (into-array [x]))))
#'user/quasiquote
user> (let [x 123] `(x 'x ~x))
(user/x (quote user/x) 123)
user> (let [x 123] (quasiquote (x 'x ~x)))
(user/x (quote user/x) 123)
这篇关于clojure的语法报价如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!