Clojure:^:宏中的动态?

时间:2012-03-05 10:27:00

标签: dynamic macros clojure

有些人知道我在Clojure中实施Shen。 由于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 个答案:

答案 0 :(得分:4)

这里使用读者宏是错误的。您必须使用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#)))

无耻的自我推销:with-meta and the reader

答案 1 :(得分:1)

由于Clojure中的惯例,您收到的是WARNING< 1.3以“earmuffs”命名的变量,即具有前导和尾随开始的变量,可动态重新绑定。

由于Clojure 1.3不再是这种情况,并且读者会发出警告,警告你事情可能不像你期望的那样。它不应该破坏你的代码,因为WARNING不是错误。