In Clojure use
loads a lib and in addition refers to the lib's namespace.
load
does not change the current namespace.
Then what is the purpose of the in-ns
command that is implicitly called when a lib is loaded with use
?
user=> (use 'project.core :verbose)
(clojure.core/load "/project/core")
(clojure.core/in-ns 'user)
(clojure.core/refer 'project.core)
In other words, isn't (clojure.core/in-ns 'user)
in the previous example unnecessary?
It doesn't actually call in-ns
– it only prints this line when "loading verbosely" (that is, if you pass in :verbose
as an option to use
) so that you know which namespace the referring takes place in. It would also do that if you called require
with :as
to make clear which namespace the alias would be created in:
user=> (require '[clojure.set :as set] :verbose)
(clojure.core/load "/clojure/set")
(clojure.core/in-ns 'user)
(clojure.core/alias 'set 'clojure.set)
This is useful when the initial load causes more namespaces to be loaded recursively. For example, here's the output of (require '[clojure.core.rrb-vector :as fv] :verbose)
(arguably the refer
lines could use the explanatory in-ns
line treatment as well):
(clojure.core/load "/clojure/core/rrb_vector")
(clojure.core/load "/clojure/core/rrb_vector/protocols")
(clojure.core/refer 'clojure.core.rrb-vector.protocols :refer '[slicev splicev])
(clojure.core/load "/clojure/core/rrb_vector/nodes")
(clojure.core/refer 'clojure.core.rrb-vector.nodes :refer '[ams object-am object-nm primitive-nm empty-pv-node empty-gvec-node])
(clojure.core/load "/clojure/core/rrb_vector/rrbt")
(clojure.core/refer 'clojure.core.rrb-vector.protocols :refer '[PSliceableVector slicev PSpliceableVector splicev])
(clojure.core/refer 'clojure.core.rrb-vector.nodes :refer '[ranges overflow? last-range regular-ranges first-child last-child remove-leftmost-child replace-leftmost-child replace-rightmost-child fold-tail new-path index-of-nil object-am object-nm primitive-nm])
(clojure.core/load "/clojure/core/rrb_vector/transients")
(clojure.core/refer 'clojure.core.rrb-vector.nodes :refer '[ranges last-range])
(clojure.core/refer 'clojure.core.rrb-vector.transients :refer '[transient-helper])
(clojure.core/load "/clojure/core/rrb_vector/fork_join")
(clojure.core/load "/clojure/core/reducers")
(clojure.core/in-ns 'clojure.core.reducers)
(clojure.core/alias 'walk 'clojure.walk)
(clojure.core/in-ns 'clojure.core.rrb-vector.fork-join)
(clojure.core/alias 'r 'clojure.core.reducers)
(clojure.core/in-ns 'clojure.core.rrb-vector.rrbt)
(clojure.core/alias 'fj 'clojure.core.rrb-vector.fork-join)
(clojure.core/refer 'clojure.core.protocols :refer '[IKVReduce])
(clojure.core/in-ns 'clojure.core.rrb-vector.rrbt)
(clojure.core/alias 'r 'clojure.core.reducers)
(clojure.core/refer 'clojure.core.reducers :refer '[CollFold coll-fold])
(clojure.core/refer 'clojure.core.rrb-vector.rrbt :refer '[as-rrbt])
(clojure.core/load "/clojure/core/rrb_vector/interop")
(clojure.core/refer 'clojure.core.rrb-vector.protocols :refer '[PSliceableVector slicev PSpliceableVector splicev])
(clojure.core/refer 'clojure.core.rrb-vector.rrbt :refer '[as-rrbt])
(clojure.core/in-ns 'user)
(clojure.core/alias 'fv 'clojure.core.rrb-vector)
Here's the relevant fragment of the source of clojure.core/load-lib
(which is where the printout comes from):
;; as of Clojure 1.6.0
(when (and need-ns *loading-verbosely*)
(printf "(clojure.core/in-ns '%s)\n" (ns-name *ns*)))
(when as
(when *loading-verbosely*
(printf "(clojure.core/alias '%s '%s)\n" as lib))
(alias as lib))
need-ns
is a local whose value is (or as use)
– that is, truthy if an :as
alias was specified or the load was caused by a use
.
Say (source clojure.core/load-lib)
at the REPL if you'd like to examine the entire function.