clojure的语法报价如何工作? [英] How does clojure's syntax-quote work?

查看:102
本文介绍了clojure的语法报价如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆