difference between use and require
Can anyone explain the difference between use
and require
, both when used directly and as :use
and :require
in the ns
macro?
Solution 1:
require
loads libs (that aren't already loaded), use
does the same plus it refers to their namespaces with clojure.core/refer
(so you also get the possibility of using :exclude
etc like with clojure.core/refer
). Both are recommended for use in ns
rather than directly.
Solution 2:
It's idiomatic to include external functions with require
and refer
. You avoid namespace conflicts, you only include functions you actually use/need, and you explicitly declare each function's location:
(ns project.core
(:require [ring.middleware.reload :refer [wrap-reload]]))
I do not have to invoke this function by prefixing it with its namespace:
(wrap-reload) ; works
If you don't use refer
you'll need to prefix it with the namespace:
(ring.middleware.reload/wrap-reload) ; works if you don't use refer in your require
If you choose use
instead, (pretty much) always use only
:
(ns project.core
(:use [ring.middleware.reload :only [wrap-reload]]))
Otherwise you're including everything, making it both an unnecessarily large operation and very confusing for other programmers to find where the functions live.
Also, I highly recommend this blog as a resource for learning more about Clojure namespaces.
Solution 3:
Use sure does make it easier by not requiring you to spell out the namespace every time you want to call a function though it can also make a mess of things by creating namespace conflicts. A good middle ground between "use" and "require" is to only 'use' the functions from a namespace that you actually use.
for instance:
(use '[clojure-contrib.duck-streams :only (writer reader)])or even better, specify it at the top of the file in the namespace definition:
(ns com.me.project (:use [clojure.contrib.test-is :only (deftest is run-tests)]))
Solution 4:
As has been mentioned the big difference is that with (require 'foo)
, you then refer to names in the lib's namespace like so: (foo/bar ...)
if you do (use 'foo)
then they are now in your current namespace (whatever that may be and provided there are no conflicts) and you can call them like (bar ...)
.