Theory: Namespaces

A namespace in Clojure is used to manage the logical separation of code, usually along features of the application. A namespace limits the scope of functions and names of data structures to a specific namespace.

The names bound to function definitions using the defn function can be used elsewhere in the namespace just by using the name. The same goes for any values bound to a name using the def function.

Clojure order of evaluation

The code in a Clojure namespace is evaluated only once and from top to bottom. To call a named function or data structure, it must have its definition evaluated first.

To use a function outside the namespace, you need to use its namespace and its name, for example clojure.string/reverse

Include another namespace in the REPL

The require function will provide access functions and names from specific namespaces and an alias for the namespace can also be specified with the :as directive.

A function from that namespace can then be used by prefixing its name with the alias specified in the require expression.

Here is an example of including the clojure.string namespace and calling its reverse function

(require '[clojure.string :as string])

(string/reverse "RedRum")

Including another namespace in source code

Instead of the require function, add the :require keyword in the namespace definition, ns.

(ns todo-list.core
 (:require '[clojure.string :as string))

(string/reverse "RedRum")

If a funciton will be used many times in the namespace, you can :refer a function so you can call it just by name, as if it had been defined in the current namespace.

(ns todo-list.core
 (:require '[clojure.string :refer [reverse]))

(reverse "RedRum")

If you are using most functions from another namespace, you could :refer :all. However, use this sparingly as it could lead to functions over-riding each other.

(ns todo-list.core
 (:require '[clojure.string :refer :all))

Dependency conflicts - avoid the use function

The use function and :use within an ns definition are seen as a bad practice and should be avoided.

The use function includes all the functions as if they had been written in the including a great many unused functions into the namespace. It will also pull in all the other namespace functions that each namespace included.

As Clojure is typically composed of many libraries, its prudent to only include the specific things you need from another namespace. This also helps reduce conflicts when including multiple libraries in your project.

Namespaces outside the project

To use a namespace from a library that is not part of the project, you also need to include it as a dependency. We saw in add ring dependency how to add a library as a :dependency in the Leiningen project.clj file.

results matching ""

    No results matching ""