gpt4 book ai didi

clojure - Clojure 的语法引用是如何工作的?

转载 作者:行者123 更新时间:2023-12-03 00:58:37 26 4
gpt4 key购买 nike

clojure中的各种特殊字符都是事物的缩写

(quote (a b))'(a b)

相同

通过评估您可以看到:

user> ''(a b)
(quote (a b))

这似乎是语法缩写,这对我来说是个好主意。

但是语法引号 ` 看起来很特殊。我想不出什么相当于

`(a b)

我会猜测类似 (syntax-quote (a b)) 的内容,但它不起作用,如果我猜错了,我无法找出它到底是什么已调用。

user> '`(a b)
(clojure.core/seq (clojure.core/concat (clojure.core/list (quote user/a)) (clojure.core/list (quote user/b))))

有点神秘。

大概读者正在做一些特殊的事情,也许是因为它需要知道 namespace ?

有趣的是,语法引用中使用的特殊语法确实按照我的预期工作:

user> '~a
(clojure.core/unquote a)
user> '~@a
(clojure.core/unquote-splicing a)
user> '~'a
(clojure.core/unquote (quote a))

除了这个:

user> 'a#
a#

我本以为会产生类似 (unquote (gensym "a"))

我确实意识到我在这里有点软弱,应该去阅读代码。如果没有人愿意解释发生了什么或提供引用,任何人都可以给我一个关于如何找到相关代码以及要寻找什么的提示吗?

最佳答案

我认为没有与 quote 函数等效的语法引用。

Clojure 阅读器(当前)是用 Java 编写的。 Clojure 源代码中的 src/jvm/clojure/lang/LispReader.java 中的 SyntaxQuoteReader 类可能就是您想要阅读的内容。看起来比较复杂。您可以看到它在那里构建类似 (seq (concat ...)) 的列表。

                ret = RT.list(SEQ, RT.cons(CONCAT, sqExpandList(seq)));

读者通常不会返回简单的 Clojure 代码,而是立即在 Java 领域执行正确的操作。例如,'[1 2 3] 不会生成 Clojure 代码 (vector 1 2 3)。也许它可以以某种方式工作,但事实并非如此。读者只需创建并返回向量对象本身。

同样,SyntaxQuoteReader 在 Java 中立即执行一些魔法来解析符号 namespace 并创建 gensyms 本身,它返回一些损坏且看起来复杂的 Clojure 代码,这些代码做了正确的事情,但不一定易于人类阅读。我不知道是因为必须如此,还是因为在 Java 中这样做更容易,或者出于性能或其他原因。同样,我不知道 quasiquote 是否可以作为 Clojure 中的普通宏/特殊形式存在,或者是否根本不存在。我不明白为什么它不能。

同一文件中的

WrappingReader 是处理 ' 的类(普通的旧 quote)。您可以看到它只是将您传递给它的任何内容包装在包含符号 quote 和您的参数的列表中。简单多了。请注意,此类还处理 @,因此 '@foo 确实返回 (deref foo)

This thread可能会带来更多启发。

编辑

这是一个概念验证quasiquote 宏。请注意,这段代码以一种可怕的方式依赖和滥用 Clojure 内部结构。请不要将其用于任何用途。

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 - Clojure 的语法引用是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3704372/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com