I went to write a context macro so that I could define functions in another namespace. After the obligatory googling, I found "with-ns":
http://richhickey.github.io/clojure-contrib/with-ns-api.html Clicking through to look at the source, I was surprised to see that "eval" was being wrapped around each form in the body of "binding". I thought, "surely forms within the body of a binding expression are evaluated in a context of the bindings?!": user> (ns blah) nil blah> (in-ns 'user) #<Namespace user> user> (binding [*ns* (the-ns 'blah)] *ns*) #<Namespace blah> Okay, no surprise there. Yet, to my surprise: user> (binding [*ns* (the-ns 'blah)] (defn foo [])) #'user/foo user> (binding [*ns* (the-ns 'blah)] (eval '(defn foo []))) #'blah/foo The extra eval is necessary after all. But wait, what does the one without eval expand into? user> (clojure.walk/macroexpand-all '(binding [*ns* (the-ns 'blah)] (defn foo []))) (let* [] (clojure.core/push-thread-bindings (clojure.core/hash-map #'*ns* (the-ns 'blah))) (try (def foo (fn* ([]))) (finally (clojure.core/pop-thread-bindings)))) Huh. Alright, let's remind ourselves of what "def" means: user> (doc def) ------------------------- def (def symbol doc-string? init?) Special Form Creates and interns a global var with the name of symbol *in the current namespace (*ns*) *or locates such a var if it already exists. If init is supplied, it is evaluated, and the root binding of the var is set to the resulting value. If init is not supplied, the root binding of the var is unaffected. Please see http://clojure.org/special_forms#def Now my confusion: isn't binding *ns* exactly how one sets the "current namespace"? It seems like "def" is not behaving as advertised. I looked briefly at jvm.clojure.lang.Compiler.DefExpr, but I wasn't able to figure out why the symbol and namespace resolution going on in that class didn't consult thread-bindings (by design?). Assuming this isn't a bug, what's the rationale for the current behavior? -- 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 --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.