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 and 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
clojure.string which contains some useful functions like
Let’s try to use
split to break up the first line of a CSV file:
Whoops! We forgot to actually tell Clojure that we’re going to be using that namespace. There are a few namespaces (
clojure.set, etc.) that get auto-required into the
user namespace when the repl starts up, but
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
namespace/var-name 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 require a
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
string.clj 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
clojure.string 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:
require 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
:as, 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
clojure.string 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 with
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 with the
As you’d expect, the code gets loaded again with the
:reload flag. 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, but
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
require already, and you’ll rarely have a need to use
refer directly, so let’s stick to the syntax of
This is pretty heavy handed. We’ve just blown away the definitions of
clojure.core, 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, like this:
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
split comes from the
clojure.string namespace, with no need to
grep the 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
use example (shadowing the
clojure.core functions), but it’s still not obvious at a glance where
split comes from. I prefer
:only 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
:only, 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
:as, 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 purposes as
require, if we supply an empty list to the
:only 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 there 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 is 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
import 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 example for
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
deftypes. 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 reincarnated as
:use, the first element of a list within the
ns macro body.
The same goes for
require → :require and
import → :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 the same
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
import are 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!