Whenever I’m showing a newcomer to Clojure how to bring in code from other namespaces, I find myself apologizing that it’s a bit complex and confusing.
Now, I won’t spend time moaning about the current state of namespaces (see
this Clojure mailing list discussion
the design discussion around namespaces in the Clojure Confluence
), but I thought it might be helpful to give an overview of the various calls you
can make to require a Clojure
Let’s start a Clojure repl, where we’ll outline
the baseline commands to pull in libs. If you don’t know how,
download Clojure and use
these instructions to get a REPL
up and running. If you already have the jar, just fire up a repl using
java -jar clojure-VERSION-HERE.jar.
Later, we’ll see the
ns macro, which is much more idiomatic, and that’s what
you’ll use in real Clojure projects. However, since
import are what you’ll often use in the repl, and because those
are used behind the scenes, we’ll start there.
The baseline: require
Let’s say we want to use some of Clojure’s built-in string operations. In the current
version of Clojure (1.2), there’s a library called
contains some useful functions like
Let’s try to use
split to break up the first line of a
Whoops! We forgot to actually tell Clojure that we’re going to be using that namespace.
There are a few namespaces (
that get auto-required into the
user namespace when the repl starts up,
clojure.string isn’t one of them. So let’s tell the repl that we’re
going to be using
Great, so that worked. Let’s take a moment to examine this, the most basic syntax for
pulling in other Clojure code.
require is just a Clojure function that
takes a few different types of arguments.
First, we could pass a single quoted symbol, and
require will make the
namespace named by that symbol available with the full
syntax in later code. We can also pass multiple quoted symbols:
Keep in mind that I’m starting a fresh repl for each of these examples, to
demonstrate what happens the first time you load a
lib. In general, if you
lib a second time, nothing will happen.
There’s a way around that (mainly for interactive development), as we’ll see later on, but for now, just start up a new repl as you’re trying these out.
It’s worth noting here that the name of the
lib itself parallels the directory structure,
so in order to require
clojure.string, you’d need a directory named
clojure relative to your classpath, and a file called
within that directory.
That particular case is already true within the Clojure
jar, but it’s
something to keep in mind as you write your own Clojure code and have need to require it
outside of the namespace where it lives.
There’s also a way to alias namespaces when you require them, such that you could
refer to a
string namespace rather than a
namespace, and you’d get the same result:
The strange looking quoted vector is a shorthand to avoid having to quote every individual symbol within the vector. You could type:
The same concepts apply to using requiring multiple namespaces:
will take an arbitrary number of libspecs, such as the quoted symbol
and vector we’ve just seen. You can also mix and match symbols with vectors:
One last way to use
require simplifies things when a prefix is the
same in several libraries you want to load:
clojure is the prefix for both of the libraries we want, so
we only need to type
test are just libspecs in these situations, so you can use the
:as option here as well:
At this point, the variation between list and vector notation (parentheses and square brackets, respectively) may be driving you a bit bonkers.
Never fear, the main thing to remember here is that a libspec should be either
a quoted symbol or vector. So whenever you want to use something like
that thing (the libspec) should be a vector.
It’s become somewhat idiomatic to use lists for many other places we’ll see later, but often that isn’t actually enforced by the language, and there are in fact situations where either vectors or lists might make more sense than the other from a semantic perspective.
Phil Hagelberg has some thought-provoking advice on this matter. Just stick with the syntax you see here and in the Clojure documentation, remembering that you must use vectors for libspecs, and you’ll be fine.
If you’re interested, you can see more details about what happens under the covers
by appending a
:verbose flag to the end of the argument list to
require (note that the
:verbose flag is outside
the libspec vector that pulls in
As you can see,
clojure.core/load does the low level loading, then we
switch back to the
user namespace (loading
made it the current namespace for a brief, shining moment), and finally we create
an alias in the
user namespace so that we can refer to
clojure.string as simply
You’ll see significantly more complex output from this if you do something similar
clojure.test, as it requires other libraries itself:
That might have seemed intimidating at the start of the article, but you’re likely now at a point now where you can guess the things that are being required under the covers.
Finally, I promised an example of reloading code from a particular namespace for interactive development, so here’s how it works:
Nothing happens the second time, as you can see. However, we can change that
As you’d expect, the code gets loaded again with the
reload-all flag works similarly, but it will also make sure that
all dependencies of the namespace in question are also reloaded.
Now don’t get overwhelmed yet. This is a lot of information for one function,
require is quite similar to other code-including functions
and macros, so you’ll see the same patterns again.
Using other namespaces’ code as though it’s yours: use
Update (4/18/2012): As of the 1.4.0 release, there's no longer a good
reason to use
require :refer instead. From the
Clojure 1.4.0 changelog: "
require can now take a
:refer takes a list of symbols to refer from the namespace or
:all to bring in all public vars."
Sometimes, including any namespace information at all seems too verbose
(unit tests for a namespace are a good example). In these cases, we want
to refer to
vars as though they were ours, and that’s where
use comes in.
Use actually uses two other functions to do the bulk of its work:
refer. We’ve covered
already, and you’ll rarely have a need to use
so let’s stick to the syntax of
This is pretty heavy handed. We’ve just blown away the definitions of
so if we wanted to use those again, we’d have to fully qualify those
functions (something like
In addition, this kind of wholesale inclusion of
vars into our current
namespace can make it difficult do decipher where the definitions live.
It’s not something we want to do very often—maybe in the case of a unit test.
It would be much better to limit the
vars being referred to a named subset,
It still works, but now we’re very clear about what we want. Anyone peeking into
this code for the first time will know immediately that
clojure.string namespace, with no need to
whole project for the function definition.
Note that the libspecs here are strikingly similar to what we used for
require! We have a new option,
:only, where we used
:as before, and that option is associated with a list rather than a
symbol, but it’s easy to see that they’re really the same sort of data structure.
There are other options with
use as well:
This eliminates one of the problems with the first
clojure.core functions), but it’s still not obvious
at a glance where
split comes from. I prefer
in most situations.
I’ve seen a quote come across my Twitter stream, attributed to Stuart Halloway
(also discussed in the context of Fortran),
that recommends: “Only use
use with :only.” With rare exceptions,
I think that advice is pretty sound.
There’s one more available option,
:rename, that lets us specify a map
of vars to rename in the context of the current namespace:
The most common of these options in the wild is certainly
but knowing that all of these are available will prepare you for that moment
when they’re exactly what you need.
It’s also worth pointing out here that you can also use
in the same way that we did with
require, to provide a shorter
alias for a namespace:
So it turns out that we could use
use for exactly the same
require, if we supply an empty list to the
option. I don’t recommend that use, as
require itself is more idiomatic,
but it’s there!
Working with Java and deftypes/defrecords: import
In terms of syntax,
import is much simpler than either
use as t’here are no options to specify various behaviors.
In general, you can think of
import as the way you get ahold of
Java code. The specifics are only a bit more complex. Let’s take a look.
As long as the Java class you want it on the classpath, you can already refer to it using the fully qualified name:
If you’re at all familiar with Java already, you already know that
can be used in a way similar to
use, so that you can just talk about a
Date in your code, rather than specifying the packages every time as
You’re probably already wondering if you can use a libspec instead of a plain
old symbol! It’s actually not a libspec in this case, but you can indeed get
some different behavior here by using a quoted list, similarly to the shared prefix
So here we’re specifying a package as the first element of the vector, and the classes from that package that we want to import as the remaining elements.
You actually don’t need a vector here (a list would do just fine), but it seems more symmetrical to the other functions to use a vector, so that’s what I prefer here. I haven’t seen a strong trend emerge here, but particular projects generally stick to one or the other.
It’s very important to note here that
import actually applies to any
classes you need to get ahold of, including Clojure
Pretend you have a namespace
stuff which contains a
One important detail here is that the initial
require is necessary—without
it, you’ll get a
Defypes work identically, though their
printed representation will of course vary. You can use the same vector notation as with Java
classes, but here you’d specify a namespace rather than a Java package as the first element
of the vector.
This difference in code loading requirements between
deftypes/defrecords and other
Clojure code may be surprising at first (it was to me, anyway), but the capitalization (along with
several semantic differences) is a good hint that something different needs to happen.
And once you’ve
required the Clojure namespace, you can refer to
deftypes by their fully qualified names (e.g.
stuff.BigWidget), in a
similar way that you could with Java classes.
Bringing it all together: ns
import are the basis for all
of your expeditions into other people’s code in Clojure, you won’t often be using them
directly in your actual Clojure projects.
It’s far more idiomatic to use the
ns macro, which pulls all of these together.
The most basic use of
ns gives just the namespace for the code that comes
afterwards—you’ll see at least this much in just about every Clojure file you come across:
Because we have so much background already, let’s jump right into a much more complex
There’s a lot here to look at, but take heart! Our trusty old
use has been
:use, the first element of a list within the
The same goes for
require → :require and
→ :import. The other syntax change to get used to is that we no longer
need to quote any of our libspecs—that’s done internally. If you know
much about how writing Clojure macros works, it’ll make a good bit of sense.
You can take any of our previous examples and plug them into the
ns macro with
only these small changes. Multiple
:import forms are okay here:
But it’s more often the case that you’d eliminate the duplication there by rolling those into
Another point of style: unless you’re using the prefix form as in
(clojure template walk)
from the first
ns example above, you generally want to stick to one namespace per
line, and left align the libspecs.
Once you’ve made these small syntax leaps, you’ve got all the knowledge you’ll need to use
Clojure libs. Remember that you should prefer
ns in any non-repl
code that you write—the basic
just the building blocks.
Libs can be among the most confusing areas of Clojure, but with a little effort and practice, they start to make a lot more sense. I hope this has been helpful—happy requiring!