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 ...).