Clojure: Namespace

By Xah Lee. Date: . Last updated: .

This page is WORK IN PROGRESS.

At anytime, you are in a namespace.

current namespace is in the object *ns*.

*ns* is a predefined variable. Its value is a clojure.lang.Namespace object representing the current namespace.

clojure.core/*ns*

;; find current namespace
(pr *ns*) ; #<Namespace user>
;; this means, current namespace is “user”

;; the #<…> usually presents a Clojure object. todo

At REPL, you can see your current namespace in output. Example

(def xx 3) ; #'user/xxx
;; the current namespace is “user”

call functions in other namespace

To refer to symbols in other namespace, you can use fully qualified name. For example, clojure.core/list

;; load pretty print package
(require 'clojure.pprint)

(clojure.pprint/pprint [3 [7 8] {:h "b"} 5])

(pr [3 [7 8] {:h "b"} 5])

switch namespace

use in-ns to switch namespace.

(in-ns name) → switch to namespace name, create it if doesn't already exist. clojure.core/in-ns

;; print current namespace
(pr *ns*) ; #<Namespace user>

;; switch to or create a namespace called “myspace”
(in-ns 'myspace)

;; print current namespace
(clojure.core/pr clojure.core/*ns*) ; #<Namespace myspace>

;; once you switch namespace, clojure.core functions needs to be fully qualified

refer

You can use refer to kinda “import” the symbols from a different namespace to the current.

(refer 'namespace) → “import” symbols in namespace current namespace.

;; todo. this is error
(refer 'clojure.test)

(is 1 1)

Usage: (refer ns-sym & ‹filters›)

(clojure.core/refer 'clojure.core)
(clojure.core/refer 'clojure.core :rename {'map 'core-map, 'set 'core-set})

refers to all public vars of ns, subject to filters. filters can include at most one each of:

For each public interned var in the namespace named by the symbol, adds a mapping from the name of the var to the var to the current namespace. Throws an exception if name is already mapped to something else in the current namespace. Filters can be used to select a subset, via inclusion or exclusion, or to provide a mapping to a symbol different from the var's name, in order to prevent clashes. Use 「:use」 in the ns macro in preference to calling this directly.

clojure.core/refer

alias

another way to refer to name in other namespace is by alias

Usage: (alias alias namespace-sym)

Add an alias in the current namespace to another namespace. Arguments are two symbols: the alias to be used, and the symbolic name of the target namespace. Use :as in the ns macro in preference to calling this directly.

(alias 'set 'clojure.set)
(set/union #{1 3 5} #{2 3 4}) ; #{1 2 3 4 5}

clojure.core/alias

use

clojure.core/use

Usage: (use & args)

Like 'require, but also refers to each lib's namespace using clojure.core/refer. Use :use in the ns macro in preference to calling this directly.

'use accepts additional options in libspecs: :exclude, :only, :rename. The arguments and semantics for :exclude, :only, and :rename are the same as those documented for clojure.core/refer.

import

Usage: (import & import-symbols-or-lists)

import-list ⇒ (package-symbol class-name-symbols*)

For each name in class-name-symbols, adds a mapping from name to the class named by package.name to the current namespace. Use :import in the ns macro in preference to calling this directly.

clojure.core/import

load

(load paths)

Loads Clojure code from resources in classpath. A path is interpreted as classpath-relative if it begins with a slash or relative to the root directory for the current namespace otherwise.

(load "/a/b/c")

will try to load file "/a/b/c.clj" or "/a/b/c.class" on Java classpath.

(load "a/b/c")

will try to load file "a/b/c.clj" or "a/b/c.class" relative to the file of current namespace.

clojure.core/load

load-file

use load-file to load a file.

(load-file "../xx/some.clj" )

(load-file file_path) → evaluate all code in a file. clojure.core/load-file

normally you don't need to call load, but require or use

(use 'org.danlarkin.json)
(use 'clojure.xml)

“use takes all public functions from the namespace and includes them in the current namespace. The result is as though those functions were written in the current namespace.”


require

clojure.core/require

(require '(org.danlarkin [json :as json-lib]))
(require '(clojure [xml :as xml-core]))

“require makes functions available to the current namespace, as use does, but doesn't include them the same way. They must be referred to using the full namespace name or the aliased namespace using the as clause”

(require 'a.b.c)

will load "a/b/c.clj" or “.class”, and check if namespace is loaded, else throw exception. If the namespace is alreadys loaded, then don't load.

(require '[x.y.ou :as h])

This loads the namespace x,y.ou and aliases it as h in the current namespace.

(require 'ee.hh.one 'ee.hh.two 'ee.hh.three) is same as (require '(ee.hh one two three))

(require '(ee.hh one [two :as duo]))

clojure.core/gen-class

ns optional args takes the same form as refer, load, require, use, import , with two differences:

public vs private namespace

defn-creates private function. private function can only be called from the namespace they are defined in

clojure.core/defn-

to install a new clojur lib, put the jar file some directory such as lib, and make sure classpath includes that directory.


reload and reload-all

use reload to reload a lib, because you might have edited the lib's code.

(use 'org.currylogic.damages.http.expenses :reload)
(require '(org.currylogic.damages.http [expenses :as exp]) :reload)

“:reload can be replaced with :reload-all to reload all libraries that are used either directly or indirectly by the specified library.”


Usage: (create-ns sym)

Create a new namespace named by the symbol if one doesn't already exist, returns it or the already-existing namespace of the same name.

clojure.core/create-ns

Usage: (in-ns name)

Sets *ns* to the namespace named by the symbol, creating it if needed.

clojure.core/in-ns

Usage: (all-ns)

Returns a sequence of all namespaces.

clojure.core/all-ns

Usage: (find-ns sym)

Returns the namespace named by the symbol or nil if it doesn't exist.

clojure.core/find-ns

Usage: (ns-interns ns)

Returns a map of the intern mappings for the namespace.

clojure.core/ns-interns

Usage: (ns-publics ns)

Returns a map of the public intern mappings for the namespace.

clojure.core/ns-publics

Usage: (ns-resolve ns sym) (ns-resolve ns env sym)

Returns the var or Class to which a symbol will be resolved in the namespace (unless found in the environment), else nil. Note that if the symbol is fully qualified, the var/Class to which it resolves need not be present in the namespace.

clojure.core/ns-resolve

Usage: (resolve sym) (resolve env sym)

same as (ns-resolve *ns* symbol) or (ns-resolve *ns* &env symbol)

clojure.core/resolve

Usage: (ns-refers ns)

Returns a map of the refer mappings for the namespace.

clojure.core/ns-refers


Use ns to switch namespace

(ns myspace)

fully qualified name can be used. That is, it includes the namespace. For example, user/x

you can not define a new name in a different namespace, even with fully qualified name.

;; switch to namespace myspace
;; and import the names from clojure.test
(ns myspace (:use clojure.test))
;; switch to namespace myspace
;; load the names from clojure.test, but don't import it
(ns myspace (:require clojure.test))
(ns myspace (:require [clojure.test :as abc]))

clojure.core/ns

clojure.core/in-ns