Hi all,
I have a problem with a var that I want to be dynamically scoped. In my
DSL, I state types using symbols like 'localities.Locality, and at some
point some function resolves these types in some Java lib.
For convenience, I wanted to add a macro that binds simple names to
qualified names, so that you can use the simple name in the body of the
macro:
(with-schema-imports [localities.Locality]
(code-using 'Locality ...))
This is my code:
--8<---------------cut here---------------start------------->8---
(def
^{:dynamic true ;; should be needed with only Clojure 1.3
:doc "A dynamically scoped map from simple names to qualified names."}
*schema-imports* (hash-map))
(defn- keyval
"Given a qualified name qn as string, symbol, or keyword, returns a vector of
the form [Bar foo.baz.Bar]."
[qn]
(let [qstr (name qn)
sn (subs qstr (inc (.lastIndexOf qstr ".")))]
[sn qstr]))
(defmacro with-schema-imports
"Executes body with schema elems (given as vector of symbol, keywords, or
strings) imported and thus referrable by their simple name in body and its
dynamic scope."
[elems & body]
(let [keyvals (mapcat keyval elems)]
`(binding [*schema-imports* (assoc *schema-imports* ~@keyvals)]
~@body)))
--8<---------------cut here---------------end--------------->8---
But when I write something like that
--8<---------------cut here---------------start------------->8---
(with-schema-imports [localities.Locality]
(println *schema-imports*)
(vseq (rg) :cls 'Locality))
--8<---------------cut here---------------end--------------->8---
the println prints {Locality localities.Locality}, which is correct.
However, my resolving function errors because there is no class
Locality. In the error message, I also print the value of
*schema-imports*, and in fact, it is {}.
So it seems that my *schema-imports* var has only lexical scope, but
why?
The macroexpansion looks good to me:
--8<---------------cut here---------------start------------->8---
(clojure.core/binding [funql.core/*schema-imports*
(clojure.core/assoc
funql.core/*schema-imports*
"Locality" "localities.Locality")]
(println *schema-imports*)
(vseq (rg) :cls (quote Locality)))
--8<---------------cut here---------------end--------------->8---
Bye,
Tassilo
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en