Clojure — разница между ' (апостроф) и ` (обратная кавычка)

Я новичок в Clojure и не уверен, что полностью понимаю разницу между апострофом и обратной кавычкой в ​​Clojure.

(def x 5)

;; Question 1
(+ x x)  ;; evaluates to 10
'(+ x x) ;; evaluates to (+ x x)
`(+ x x) ;; evaluates to (clojure.core/+ user/x user/x)

;; Question 2
`(~+ ~x ~x) ;; evaluates to (#<core$_PLUS_ clojure.core$_PLUS_@32ee28a9> 5 5)
  1. Поправьте меня, если я ошибаюсь, но мне кажется, что апостроф не позволяет всем символам (т.е. + и x) разрешаться в их соответствующие var, тогда как обратная кавычка позволяет символам разрешаться в их var (но не оценивает значения внутри вара). Это точно?
  2. Что именно здесь делает символ без кавычек (~)? Он оценивает var до его фактического значения (т.е. символ + для функционального объекта и символ x для числового объекта)? Если бы вы могли объяснить это с точки зрения фаз READ-COMPILE-EVAL Clojure, это тоже было бы полезно.

person wmock    schedule 23.07.2013    source источник


Ответы (2)


Когда вы цитируете коллекцию с помощью ', имя символа будет заключено в кавычки точно так, как вы его вводите.

'(+ x x) 
=> (+ x x)
(map namespace *1)
=> (nil nil nil)
'(bingo/+ lara/y user/z)
=> (bingo/+ lara/y user/z)
(map namespace *1)
=> ("bingo" "lara" "user")

Когда вы цитируете коллекцию с обратной кавычкой, она пытается найти пространство имен каждого символа. Если он не может найти его, он использует текущее пространство имен. Если вы укажете пространство имен, оно будет работать так же, как ' с полным пространством имен.

`(+ x x)
= > (clojure.core/+ user/x user/x)
(map namespace *1)
=> ("clojure.core" "user" "user")

Когда вы используете ~ внутри `, форма просто не будет заключена в кавычки. Это полезно для создания макросов, где макрос использует символы из пространства имен, в котором он определен, а также символы из пространства имен, в котором он используется.

 `(+ ~'x x)
 => (clojure.core/+ x user/x)
 `(+ ~x x)
 => (clojure.core/+ 3 user/x)

Наконец, вы можете снять с кавычек целую коллекцию склейок, содержащихся в кавычках.

 `(+ ~@`(x x))
 => (clojure.core/+ user/x user/x)

Обратите внимание, что оба xes могли быть переданы как список символов, соответствующих пространству имен, и были бы объединены в другой список. Вы не можете использовать ~ или ~@ вне коллекции с обратной кавычкой.

person Leon Grapenthin    schedule 23.07.2013
comment
Хороший ответ. Здесь есть отличный пост в блоге, если вы хотите копнуть глубже: blog.8thlight.com/colin-jones/2012/05/22/ - person Daniel Szmulewicz; 16.03.2016
comment
Посмотрите все эти примеры вживую с KLIPSE app.klipse.tech/ - person viebel; 28.04.2016

Backquote — это синтаксическая цитата в терминах Clojure, см. ее описание на странице http://clojure.org/reader.

Во время чтения `(~+ ~x ~x) расширяется до формы, которая генерирует список, который может ссылаться на лексическое окружение. Затем компилятор компилирует этот код. Давайте посмотрим, во что расширяется `(~+ ~x ~x), поставив перед ним кавычки:

user=> '`(~+ ~x ~x)
(clojure.core/seq (clojure.core/concat (clojure.core/list +) (clojure.core/list x) (clojure.core/list x)))

Если вы просто вставите эту форму в текстовый редактор вместо `(~+ ~x ~x), будет создан список с функцией + и двумя крестиками. Таким образом, `(~+ ~x ~x) расширяется до кода Clojure, который создает список определенной структуры.

Backquote — это своего рода язык шаблонов для данных Clojure (списков, массивов и т. д.).

person monoid    schedule 23.07.2013
comment
Что на самом деле означает синтаксическая цитата? - person wmock; 23.07.2013
comment
Это просто слово в документации Clojure. См. также stackoverflow.com/questions/3704372/ - person monoid; 23.07.2013
comment
это означает кавычки, но сначала разрешив символы: '+ означает просто '+', тогда как '+ означает 'clojure.core/+', но если вы сказали (def + rest), то '+ становится 'user/+' - так что это то, что символ разрешает в окружающей среде - person Hendekagon; 23.07.2013
comment
Проблема уценки: в этом ответе есть по крайней мере одна неэкранированная обратная галочка, вызывающая проблемы. - person Paul Bissex; 05.05.2015