1
votes

As some of you know I am implementing Shen in Clojure. Since Shen has a dual namespace and all symbols evaluate to themselves I need a Clojure macro, which binds the symbol to itself and the value to a postfixed symbol.

Now also symbols like *language* have to be bound. But when I use the following macro with *language* as a parameter I get 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#))

Can someone tell me why this is not working?

2

2 Answers

4
votes

The use of reader macros is wrong here. You have to use with-meta. I'm also not sure why you need the intern call.

(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#)))

Shameless self-promotion: with-meta and the reader.

1
votes

What you receive is a WARNING due to the convention in Clojure < 1.3 for which vars named with "earmuffs", i.e. with leading and trailing starts, where dynamically rebindable.

Since Clojure 1.3 this is no longer the case, and the Reader throws that warning to, well, warn you that things might not be as you expect. It shouldn't break you code though, as WARNINGs are not errors.