Namespaces are mappings from simple (unqualified) symbols to Vars and/or Classes. Vars can be interned in a namespace, using def or any of its variants, in which case they have a simple symbol for a name and a reference to their containing namespace, and the namespace maps that symbol to the same var. A namespace can also contain mappings from symbols to vars interned in other namespaces by using refer or use, or from symbols to Class objects by using import. Note that namespaces are first-class, they can be enumerated etc. Namespaces are also dynamic, they can be created, removed and modified at runtime, at the Repl etc.

The best way to set up a new namespace at the top of a Clojure source file is to use the ns macro. By default this will create a new namespace that contains mappings for the classnames in java.lang plus clojure.lang.Compiler, and the functions in clojure.core.

At the Repl it’s best to use in-ns, in which case the new namespace will contain mappings only for the classnames in java.lang. In order to access the names from the clojure.core namespace you must execute (clojure.core/refer 'clojure.core). The user namespace at the Repl has already done this.

The current namespace, *ns* can and should be set only with a call to in-ns or the ns macro, both of which create the namespace if it doesn’t exist.

Creating and switching to a namespace: in-ns ns create-ns
Adding to a namespace: alias def import intern refer
Finding what namespaces exist: all-ns find-ns
Examining a namespace: ns-name ns-aliases ns-imports ns-interns ns-map ns-publics ns-refers
Getting a namespace from a symbol: resolve ns-resolve namespace
Removing things: ns-unalias ns-unmap remove-ns

More information