Как работает синтаксическая цитата clojure? - PullRequest
29 голосов
/ 14 сентября 2010

Различные специальные символы в 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))))

Немного загадочно.

Предположительно, читатель делает что-то особенное, может быть, потому, что ему нужно знать пространства имен?

Интересно,специальный синтаксис, используемый в синтаксической кавычке, работает так, как я ожидал:

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"))

Я понимаю, что я немного ослаб, и мне нужно просто пойти и прочитать код.Если никто не любит объяснять, что происходит или дает ссылку, может кто-нибудь подсказать мне, как найти соответствующий код и что искать?

Ответы [ 3 ]

33 голосов
/ 14 сентября 2010

Я не думаю, что есть синтаксическая кавычка, эквивалентная функции 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)
3 голосов
/ 13 марта 2011

hiredman реализовал полностью основанную на clojure версию синтаксическая цитата . Не для слабонервных, но хорошее доказательство концепции.

3 голосов
/ 14 сентября 2010

Кажется, вы хорошо разбираетесь в синтаксисе макросов, поэтому я не могу добавить слишком много.

есть немного освещения на форумах по программированию clojure .и вы можете по своему усмотрению прочитать код здесь проверить строку 352

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...