Clojure: ^: динамический в макросах? - PullRequest
1 голос
/ 05 марта 2012

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

Теперь и символы типа *language* должны быть связаны. Но когда я использую следующий макрос с *language* в качестве параметра, я получаю Warning: *language* not declared dynamic and thus is not dynamically rebindable, but its name suggests otherwise. Please either indicate ^:dynamic *language* or change the name.

(defmacro set [x y] 
  `(let [y# ~y]
    (def ^:dynamic ~x '~x)
    (intern *ns* (symbol (str (name ~x) "__varPoF__")))
    (def ^:dynamic ~(symbol (str (name x) "__varPoF__")) y#)
    y#))

Может кто-нибудь сказать мне, почему это не работает?

Ответы [ 2 ]

4 голосов
/ 05 марта 2012

Использование макросов читателя здесь неправильно. Вы должны использовать with-meta. Я также не уверен, зачем вам звонить intern.

(defmacro set
  [x y]
  (let [dynamic {:dynamic true}]
    `(let [y# ~y]
       (def ~(vary-meta x merge dynamic) '~x)
       (def ~(vary-meta (symbol (str (name x) "__varPoF__")) merge dynamic) y#)
       y#)))

Бесстыдная самореклама: с мета и ридером .

1 голос
/ 05 марта 2012

То, что вы получаете, является WARNING из-за соглашения в Clojure <1.3, для которого переменные названы "наушниками", то есть с начальным и конечным запусками, где динамически перебираются. </p>

С Clojure 1.3 это уже не так, и Читатель выдает это предупреждение, чтобы предупредить вас, что все может быть не так, как вы ожидаете. Это не должно нарушать ваш код, так как WARNING s не являются ошибками.

...