ClojureDocs

Nav

Namespaces

*ns*

clojure.core

Available since 1.0
    A clojure.lang.Namespace object representing the current namespace.
    3 Examples
    user=> *ns*
    #<Namespace user>
    user=> (ns foo.bar)
    nil
    
    foo.bar=> *ns*
    #<Namespace foo.bar>
    ;; 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
    See Also
    No see-alsos for clojure.core/*ns*
    2 Notes
      By , created 13.8 years ago

      A trap I fell into was that ns seems to get assigned to clojure.core when run as a "gen-class" compiled class.

      By , created 7.8 years ago, updated 7.8 years ago

      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.)