#clojure
#clojure
Вопрос:
В чем смысловая разница между var и quote в Clojure? Например, (var a)
и (quote a)
.
На официальном сайте есть приведенные ниже документы, но в чем разница между объектом var и значением символа? Я в замешательстве.
(символ var) Символ должен преобразовываться в var, и возвращается сам объект Var (не его значение)
Комментарии:
1. Подумайте также о добавлении определения для
quote
. Это должно иметь смысл.
Ответ №1:
(quote a)
возвращает символ (clojure.lang.Символ) — он эффективно выполняет то же самое, что 'a
. Стоит прочитать немного больше о Clojure Reader, чтобы узнать немного больше о символах. Пример:
(quote a)
=> a
(var a)
возвращает var (clojure.lang.Var), представленный символом a в текущем пространстве имен. Вы получите сообщение об ошибке, если a не определено в текущем пространстве имен. Пример:
(var a)
=> #<CompilerException java.lang.RuntimeException: Unable to resolve var: a in this context, compiling:(NO_SOURCE_PATH:1)>
(def a 1)
(var a)
=> #'user/a
Это техническое определение, но за ним стоит интуиция: символ — это имя, которое можно использовать для поиска var в заданном пространстве имен. Сам var является своего рода ссылкой, которая может содержать любое значение Clojure. Итак, символ идентифицирует var, который содержит значение.
Ответ №2:
Рассмотрим это:
; #'x a reader short-cut for (var x), and 'x is a short-cut for (quote x)
(def x)
(binding [x 1] (var-set #'x 2) (list (var x) (quote x) x))
Который оценивается примерно так (добавлены комментарии)
(
#'sandbox177857/x ; the variable itself - was passed to var-set
x ; the symbol x. same as 'x
2 ; last value in #'x
)
set!
примет (среди прочего) Var или символ, который преобразуется в глобальное имя ( var-set
примет только Var). Причина, по которой (var-set x ...)
это не сработало бы, заключается в том, что это привело бы к передаче значения x (а не переменной с именем x).
Надеюсь, это помогло. Удачного кодирования.
Комментарии:
1. Спасибо за ответ. Кажется, что объект Var является непосредственным слоем между именем символа и его значением, верно?
2. @Thomson Это способ «поговорить» о переменной с заданным именем. В C это не требуется:
x = x 1;
Первый x является l-значением и не вычисляется. Таким образом, переменные в Clojure могут быть более мощными, потому что их можно передавать примерно как сами значения; C потребовал бы управления указателем. Кроме того, поскольку Var отделен от имени областью видимости, его можно передавать через разные лексические области, которые могут иметь свою собственную переменную «x», но Var всегда остается самим собой.3. Кроме того, я не могу запустить ваш пример программы напрямую, чтобы проверить результат. Я получил «Систему исключений CompilerException. Исключение: Не удалось разрешить var: x в этом контексте». Но если я добавлю a (def x 3) перед образцом, это также сгенерирует исключение.
4. @pst, спасибо. Вы это исправили? Я все еще не могу запустить его с помощью простого копирования и вставки. Все еще получено «Исключение InvalidOperationException не может динамически привязать нединамический var: user / x»
5. @Thomson : верно, Var — это уровень косвенности. Это конструкция для управления состоянием, как и ссылки, агенты, атомы. Итак, var — это поле, в котором можно задать значение. Отличительным свойством vars является способность динамически привязывать к ним новое значение для каждого потока («из коробки» с clojure <=1.2, после объявления его как динамического с помощью метаданных boolean: dynamic, начиная с предстоящего clojure 1.3), что предоставляет Clojure «динамическую область видимости» (в отличие от «лексической области видимости», с помощью которой замыкания фиксируют значения).