My impression is that there are two reasons. 1) In doing so, you are more likely to avoid any name clashes and/or accidental overshadowing. 2) Such practices give greater transparency about the ultimate source of the functions and variables used in the code. The first one is pretty practical, and Chiron's answer provides a great demonstration.
The second one is more subtle, but if you are using a lot of libraries, it can be pretty important. Let's say you do:
(ns your-namespace
(:use [library-one]
[library-two]
[library-three]
[library-four]
[library-five]))
And then somewhere, later in your code, you invoke:
(important-function some-arg some-other-arg)
If important-function
is defined in, for example, library-three
, then you (or whoever is trying to make sense of your code) have to go digging through each of those libraries' code to figure out what it does--because there's nothing to indicate which library is its source! Well, actually, if you have a REPL available, you should be able to figure it out by doing:
your-namespace> `important-function
> library-three/important-function
But that kind of hidden information is probably not the best thing to inflict on other people (including your future self) who may wish to understand your code. On the other hand, :require
d libraries always come with a prefix. So instead, your code would look like:
(ns your-namespace
(:require [library-one]
[library-two]
[library-three]
[library-four]
[library-five]))
...
(library-three/important-function some arg some-other-arg)
Which makes it very clear where important-function
is defined. Note that this should be equivalent to specifying :refer :all
. Although :refer :all
could indicate to others that you considered specifically which vars to reference, and made a conscious decision to include all of them from that library.
If you are not worried about name clashing...well you probably should be. But if you still aren't, and you want to be clear about vars' sources, then you could always do :use
with :only
. For example:
(ns your-namespace
(:use [library-one :only []]
[library-two :only []]
[library-three :only [important-function]]
[library-four :only []]
[library-five :only []]))
...
(important-function some arg some-other-arg)
Obviously, if you are :use
ing libraries with blank :only
vectors, than you might as well not :use
them in the first place, I just wanted to unify with the previous examples. And doing :require
may seem verbose, but you can always shorten it by aliasing with :as
. Fragment example:
(ns your-namespace
(:require [library-three :as L3]))
(L3/important-function some-arg some-other-arg)
See also, this SO question, and this guide about libraries and namespaces in Clojure.