Я не думаю, что есть синтаксическая кавычка, эквивалентная функции quote
.
Читатель Clojure (в настоящее время) написан на Java.Класс SyntaxQuoteReader
в src/jvm/clojure/lang/LispReader.java
в исходном коде Clojure - это, вероятно, то, что вы захотите прочитать.Это кажется довольно сложным.Вы можете видеть, что там создаются списки типа (seq (concat ...))
.
ret = RT.list(SEQ, RT.cons(CONCAT, sqExpandList(seq)));
Для читателя характерно не возвращать простой код Clojure, а сразу же делать правильные вещи в Java-земле.Например, '[1 2 3]
не дает код Clojure (vector 1 2 3)
.Может быть, это может так или иначе работать, но это не так.Читатель просто создает и возвращает сам векторный объект.
Точно так же SyntaxQuoteReader
немедленно выполняет магию в Java для разрешения пространств имен символов и создания самих gensyms, а также возвращает искаженный и сложный код Clojure, который делает правильные вещи, но не всегда легкоЧеловек, чтобы читать.Так ли это, потому что так должно быть, или потому, что так проще делать в Java, или по производительности, или по какой-то другой причине, я не знаю.Кроме того, я не знаю, может ли quasiquote
существовать в Clojure как простая макро / специальная форма и не существует, или вообще не может существовать.Хотя я не понимаю, почему это не удалось.
WrappingReader
в том же файле - класс, который обрабатывает '
(обычный старый quote
).Вы можете видеть, что он просто переносит все, что вы передаете, в список, содержащий символ quote
плюс ваш аргумент.Это намного проще.Обратите внимание, что этот класс также обрабатывает @
, поэтому '@foo
возвращает (deref foo)
.
Этот поток может пролить немного света.
Редактировать
Вот макрос проверки концепции 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)