A clojure.lang.Namespace object representing the current namespace.
;; A (rare) trap which can happen is attempting to dynamically call `in-ns`, due to how ;; `*ns*` is really an instance of `clojure.lang.Var` with a root binding. user=> (ns my.namespace) nil my.namespace=> *ns* #<Namespace my.namespace> ;; This will *only* work in the REPL (or REPL-like environments)!! ;; Tools like Boot and Lein may or may not provide this (read the manual/code) my.namespace=> (defn swap-ns! [ns-name] (in-ns ns-name)) #'my.namespace/swap-ns! my.namespace=> (swap-ns! 'other.ns) #namespace[other.ns] ;; Later, at runtime... ;; Throws IllegalStateException("Can't change/establish root binding of: *ns* with set") ;; Remember, *ns* is a root var and in-ns calls set!, which only works after ;; someone somewhere calls the binding macro (or Java equivalent) (defn -main [& args] (println *ns*) (swap-ns! 'arbitrary-namespace)) ;; prints #namespace[clojure.core] and then will crash
clojure.core/*ns*
A trap I fell into was that ns seems to get assigned to clojure.core when run as a "gen-class" compiled class.
To clarify the above point, see my example above. Although within Lein/Boot/REPL/Compiler contexts, *ns*
is thread-local due to the use of the binding
machinery, and so in-ns
works in those situtations, *ns*
has a root of clojure.core
. That means that, at runtime, you cannot call in-ns
within functions until you've first called binding
. (This could be relevant for e.g. eval
calls.)