Clojure: Namespace
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:
:exclude list-of-symbols
:only list-of-symbols
:rename map-of-fromsymbol-tosymbol
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:
- • Arguments are never quoted.
- • function name are keyword. i.e.
(:require …)
instead of(require …)
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