Now that we know how to create our functions we need to understand how Clojure organizes and accesses it, this way is called namespaces.
Every good wizard has a lot of books on his bookshelf, with different magics to use in a lot of situations. Imagine a Clojure namespace as being one of your books, and each function or variable (defined with def
) is written on it, when you need to use your function, you just search for it in this book and use it!

If you enter in your REPL, you’ll be in a “default” namespace called user
, everything that you define here, we’ll be associated with this namespace.
user => (def author-name "otavio")
#'user/author-name
You may have already noticed that when we defined author-name
it returned #'user/author-name
, it means that you defined an author-name
in the user namespace.
To create a new namespace and switch to it, you only need to type ns
and a name to it, it will create (if not exists), and you can’t access values defined in other namespace directly anymore. Just like a blank book, waiting to be written.
user => (ns my-new-ns)
nil
my-new-ns => author-name
Syntax error compiling at (REPL:1:1).
Unable to resolve symbol: author-name in this context

If you want, you can access any variable or function defined in other namespace, just typing its “full address” namespace + name.
my-new-ns => user/author-name
"otavio"
Switch between namespaces is easy, just use in-ns
and pass the namespace name preceded by quote. After it, you can access the defined values of this namespace directly again.
any-ns=> (in-ns 'user)
#object[clojure.lang.Namespace 0x56317ffa "user"]
user=> author-name
"otavio"
You can always see in which namespace are you, just typing *ns
* (but you can just see in your REPL too.)
Reading other books
Sometimes you as a wizard will want to read books written by other wizards, to not lose your precious time reinventing the wheel creating already existent magics.
Most languages are shipped with a lot of code that you must need, things like string operations, basic http logic, and much more. All this code is available for you, in the form of namespaces, and to use it is simple!

Every time that you create a new namespace using ns
in your REPL, it will be automatically loaded on it, and you can just start using it, but this is not true while trying to access namespaces packaged in files (which will be important in the future when we start to work with multiple files in large projects).
Let’s use as an example the namespace clojure.string
which contains functions to deal with common string operations, we want to use capitalize
function from it! The first step is to make our REPL aware of the namespace that you want to use using the require
function, passing as an argument the namespace that we want to load in our REPL, after this all functions and symbols globally defined in this namespace are available to us, just use them using its ‘full address’ namespace + name
.
user => (require 'clojure.string)
nil
user => (clojure.string/capitalize "hello clojure")
"Hello lojure"
But write clojure.string
every time isn’t productive, so we can use the :as
keyword to create an alias to use this namespace.
user => (require '[clojure.string :as str])
nil
user => (str/capitalize "hello clojure")
"Hello clojure"
This required namespace will be available only on current namespace, if you change to other namespace, it will no longer be available.
Better now, ya? This is the Clojurist way of using external namespaces from other namespace (including libraries as we’ll see in the future).
If you want, you can also enter in the string namespaces and use functions directly, but I really don’t know why you may want to do it:
user => (require 'clojure.string)
nil
user => (in-ns 'clojure.string)
nil
clojure.string => (capitalize "hello clojure")
"Hello clojure"
Conclusions
Learn how to use namespaces is important! We did not learn how to pack namespace in files yet, but we will in the future! This knowledge is important, it will help while developing using our REPL, and in the future post talking about files.
Next steps
On the next post of this series, we’ll still talking about functions, with just a short trick to make our functions better and readable!
Final thought
If you have any questions that I can help you with, please ask! Send an email (otaviopvaladares at gmail.com), pm me on my Twitter, or comment on this post!
The mindset in clojure is that you can navigate namespaces as you would directories, so you set the curr dir with in-ns, list available symbols in there with ns-map etc. https://clojure.org/reference/namespaces#_related_functions
LikeLike
Very interesting! I’ll write more about this mindset in a future post talking about Clojure’s development environment, it will help a lot! Thanks for your feedback
LikeLike