I recently started learning Clojure and I'm having a bit of difficulty wrapping my head around namespaces. As the creator of Clojure said, newcomers often struggle to get the concept right. I don't clearly understand the difference between (use ...) and (require ...). For example playing around in the REPL if I say (use 'clojure.contrib.str-utils2) I get warnings about functions in clojure.core namespace being replaced by the ones in clojure.contrib.str-utils2, but that doesn't happen when I use (require 'clojure.contrib.str-utils2). I'm not sure that I will always want to replace what's in clojure.core, so can someone point some best practices for importing external stuff and managing namespaces in Clojure?
Oh and also, when should I use :use and :require? Only inside (ns ....)?
Thanks in advance.
The answer lies in the docstrings:
user> (doc use)
-------------------------
clojure.core/use
([& args])
Like 'require, but also refers to each lib's namespace using
clojure.core/refer. Use :use in the ns macro in preference to calling
this directly.
'use accepts additional options in libspecs: :exclude, :only, :rename.
The arguments and semantics for :exclude, :only, and :rename are the same
as those documented for clojure.core/refer.
nil
And the long one for require:
user> (doc require)
-------------------------
clojure.core/require
([& args])
Loads libs, skipping any that are already loaded. Each argument is
either a libspec that identifies a lib, a prefix list that identifies
multiple libs whose names share a common prefix, or a flag that modifies
how all the identified libs are loaded. Use :require in the ns macro
in preference to calling this directly.
Libs
A 'lib' is a named set of resources in classpath whose contents define a
library of Clojure code. Lib names are symbols and each lib is associated
with a Clojure namespace and a Java package that share its name. A lib's
name also locates its root directory within classpath using Java's
package name to classpath-relative path mapping. All resources in a lib
should be contained in the directory structure under its root directory.
All definitions a lib makes should be in its associated namespace.
'require loads a lib by loading its root resource. The root resource path
is derived from the lib name in the following manner:
Consider a lib named by the symbol 'x.y.z; it has the root directory
<classpath>/x/y/, and its root resource is <classpath>/x/y/z.clj. The root
resource should contain code to create the lib's namespace (usually by using
the ns macro) and load any additional lib resources.
Libspecs
A libspec is a lib name or a vector containing a lib name followed by
options expressed as sequential keywords and arguments.
Recognized options: :as
:as takes a symbol as its argument and makes that symbol an alias to the
lib's namespace in the current namespace.
Prefix Lists
It's common for Clojure code to depend on several libs whose names have
the same prefix. When specifying libs, prefix lists can be used to reduce
repetition. A prefix list contains the shared prefix followed by libspecs
with the shared prefix removed from the lib names. After removing the
prefix, the names that remain must not contain any periods.
Flags
A flag is a keyword.
Recognized flags: :reload, :reload-all, :verbose
:reload forces loading of all the identified libs even if they are
already loaded
:reload-all implies :reload and also forces loading of all libs that the
identified libs directly or indirectly load via require or use
:verbose triggers printing information about each load, alias, and refer
Example:
The following would load the libraries clojure.zip and clojure.set
abbreviated as 's'.
(require '(clojure zip [set :as s]))
nil
They both do the same thing, but use goes the extra step and creates mappings for the stuff in the require'd namespace in the current namespace. That way, rather than doing some.namespace/name you're just referring to it as name. While this is convenient sometimes, it's better to use require or select the individual vars that you want rather than pull in the entire namespace. Otherwise, you could have issues with shadowing (where one var is preferred over another of the same name).
If you don't want to use require, but you know what vars you want out of the namespace, you can do this:
(ns whatever
(:use [some.namespace :only [vars you want]]))
If you don't know which vars you're going to need, or if you need a lot, it's better to use require. Even when you require, you don't always have to type the totally qualified name. You can do this:
(ns whatever
(:require [some.namespace :as sn]))
and then you can use vars from some.namespace like this: (sn/somefunction arg1 arg2)
And to answer your last question: try to only use :require and :use inside of (ns ...). It's much cleaner this way. Don't use and require outside of (ns ..) unless you have a pretty good reason for it.
Related
For an embedded DSL I'd like to remove all the core functions and require the ones I need one by one.
Is it possible and how?
You can use the :refer-clojure directive in your ns declaration to specify only the core functions you need:
(ns my-namespace
(:refer-clojure :only [defn]))
I have namespace with debug utilities that are used only in development. I'd like to make them accessible in all namespaces without qualifier (same as symbols from clojure.core).
Let's say my project structure is as follows:
dbg_utils.clj:
(ns project.dbg-utils)
(defmacro dbg ...)
db.clj
(ns project.db)
(defn create-entity [...]
...)
After I'd like to fire up REPL and type something like this:
> (require 'project.db)
> (require 'project.dbg-utils)
> (globalize-symbol 'project.dbg-utils/dbg)
And after use dbg macro without qualifier:
(ns project.db) ;; no require of project.dbg-utils
(defn create-entity [...]
(dbg ...) ;; and no qualifier here
...)
Is anything like globalize-symbol (or close to this) available?
Leiningen provides the :injections feature and the :user profile for that.
This article shares some pointers on how to do that. It basically works by adding the debugging functions you want to clojure.core and since all public vars from this namespace are always included when using the ns macro (unless you specify otherwise), you will have them available in all your namespaces.
I've read this thread, but it seems like there are no load and load-file in ClojureScript. Is it possible to separate a single namespace over multiple files?
The reason I want to do that is because I'm using Om and I want to separate components into different files. I can do it using separate namespaces, but then I will have to write the same requires in the beginning of each file and also the only way to call those components in the main file is like that:
(:require [some-project.sidebar :as sidebar])
...
(om/build sidebar/sidebar app-state)
i.e. I have to specify namespace before each component's name, which doesn't look pretty. Any ideas on how to improve it? I'm new to Clojure and ClojureScript, so maybe I'm missing something obvious?
There are a few things to note here
You can use :refer in your :require to import unqualified vars into a namespace. This is ok if there are a few, but can quickly get unwieldy if you tried to do it for everything.
Clojure applications are often structured in a tree like fashion where a main namespace requires sub namespaces, and so on, so you won't necessarily be importing the same namespaces into every namespace.
Even if it was possible to split a namespace across multiple files, it wouldn't be idiomatic Clojure. One file = one namespace is the norm.
If you wanted, you can def vars from one namespace into another to make one 'master' namespace to use in your other namespaces.
If you want to minimise the number of imports you have to do, make fewer namespaces and make them bigger.
I'm working on a Clojure application that needs to be able to read Clojure code from the shell command line. The application has a -main function that reads a string passed on the command line containing a single Clojure form, and passes this string to the Clojure function load-string, which parses the string and executes the code. This runs successfully using both lein run and using an uberjar.
I've found that the code passed at the command line can include fully-qualified namespace names if the namespaces were required at the top of the file containing -main. For example, if the source file begins with
(ns popco.core.popco
(:require [popco.core.reporters :as rpt]))
then the string I pass on the command line can reference my function ticker by popco.core.reporters/ticker. However, I can't use the alias rpt. If I refer to ticker by rpt/ticker, I get an exception: java.lang.RuntimeException: No such namespace: rpt.
I'm guessing that this is because the aliases are only available at compile time, and only one compile time. Since the time at which load-file compiles the string of code is after the time at which compilation of the source file has been completed, rpt is no longer available as an alias.
A solution that allows me to use namespace aliases is to duplicate the requires at the top of the file (which I want for use when running in the repl) within -main. However, there are several namespaces that I might need to include, and duplicating code is undesirable, of course.
Is there another solution? Some way to make aliases defined once, available both when runnning in the repl and when running code from the command line?
(EDIT: The analysis in terms of time of compilation above can't quite be correct--or maybe I don't understand Clojure compilation. (Well, in fact I don't understand Clojure compilation!) The solution mentioned in two paragraphs above works using a require statement in the original source code inside -main, not only with a string passed to load-file. So that require is getting compiled when -main is compiled, I suppose, which would be during the same pass as the top of the source file, I assume. Yet somehow code inside -main is in scope of the alias from the top of the file if the code was typed into the definition of -main, but not if it's brought in via load-file. Yet what's brought in via load-file is in the scope of the alias when (require '[popco.core.reporters :as rpt]) is literally in the source code for -main. Why?)
The alias function, which is the mechanism require uses to create namespace aliases via the :as key, mutates the current namespace. That is, the namespace that is current at the time alias runs.
This is why require embedded into your definition of -main creates the alias in the way you expect: it is mutating your runtime namespace to include the given alias. Emphatically, this does not necessarily alter the popco.core.popco namespace! In fact, that is unlikely to be the working namespace at runtime, when -main is invoked (it would be at compile time, and thus would, as in the ns macro, mutate the ns being defined).
The key here is to realize that the ns at runtime is not always the ns which defined your -main function, and if you want to mutate the evaluation environment at runtime, you need to either switch to the namespace you are mutating, or mutate the namespace you are in.
Can anyone explain the difference between use and require, both when used directly and as :use and :require in the ns macro?
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.
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.
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)]))
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 ...).