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 clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to