Clojure Programming/FAQ

How do I declare a variable?
As a functional language, Clojure discourages the use of variables in the classic sense of a place that holds a mutable value. If it takes more thought initially to construct solutions that don't need variables, please try to expend the effort - it will repay you many times over. e.g.:

Can be written without variables in Clojure as Clojure does support variables but you should read about them fully before using them to understand their semantics. If you are really stuck and want a quick solution, you can use def: But this is not recommended and is only suggested as a workaround until you can more fully explore Clojure.

Clojure also supports variable as a name for an immutable value - meaning you can't change it later. These are created by binding the value to a name, and always have a lexical scope over which the name can be used. Function parameters are one such example, and should be familiar from other languages.

There are a number of clojure constructs that also create temporary bindings (some of them more than once). The simplest is let:

How can I loop through something and produce a result collection of a different size?
Suppose I need to process the lines of a text file, and every now and then (based on the line contents) create an object and add it to a list of results. (e.g. a simple parsing of a text file). For example maybe every 5 or 6 lines there is a blank line and I use that to create an object based on the previous lines. Because the number of lines is different I can't use map or anything functional, so it seems. Is with-local-vars required, or is there some more elegant way?

The following code searches through a set of lines and returns matching lines. The def lines simply gives us a collection to work with. The for statement iterates through the "lines" and assigns each entry to "line". For each line, the :when clause is called. If that returns true, then the body of the for is executed, in this case, simply return line. The results are put into a sequence, same as the map function but only containing the matching elements. The filter function accomplishes a similar thing

Create a Clojure library
With Leiningen, to create a library, foo:

With the default project.clj:

Note by Leiningen's terminology, "foo" is name of the artifact, "0.1.0-SNAPSHOT" is the version number.

Go to the root directory of the newly created project, foo. Implement functions. Install the library.

The above worked with Leiningen 2.4.2.

Use the library
Set up the project, try-foo

Customize the project.clj file, to express dependency to the library foo

then open a repl connected to the project,

The library should be ready for use.

Why doesn't contains? do what I expect on vectors and lists
Sequential lookup is not an important operation. Clojure includes sets and maps, and if you are going to be looking things up you should be using them. contains? maps to java.util.Set.contains. The fact that java.util.Collection also has contains is, IMO, a mistake, as you really can't write code to an interface with dramatically varying performance characteristics. So, lookups in sets and maps take priority and get the best name - contains? People write naive programs that do linear lookups with contains in other languages, and get correspondingly bad n-squared performance - that's not an argument for encouraging that in Clojure. If they get an explanation of why it's a bad idea, and how to use sets and maps, that's fine.

Why are some lazy sequences a little eager? (chunked sequences)
You might have noticed something a little unexpected when using side-effects with some lazy sequences:

See De-chunkifying sequences in Clojure

How do I fetch web pages and make HTTP requests?
For the simple case of GETing a document into a string you can simply pass a URL to clojure.contrib.duck-streams/slurp*:

For more advanced usage, including other request types like POST you may find the clojure-http-client library useful. Finally you can of course use (.openConnection) on a Java URL object directly.

How can I lookup what methods a Java object contains
You can use the clojure-contrib "show":

Or if you don't want to use "clojure.contrib" then the following should do some of the work:

Is Clojure object-oriented?
Clojure is not object-oriented (at least in the traditional sense). One of the core premises of Clojure is that conflating state and identity in the traditional OO way is a bad idea, particularly in the face of concurrency. On state and identity and Rich Hickey's Are we there yet? talk explain some of the thinking behind this.

Also see Stuart Halloway's Rifle-Oriented Programming article which explains some of Clojure's answers to the concerns of object-oriented programming.

Of course, just because the language doesn't encourage it doesn't mean it is impossible to write object-oriented code in Clojure—it may be necessary to some extent to inter-operate with Java code. However, traditional OO-style programming is non-idiomatic in Clojure and not encouraged.

I've installed paredit.el but it doesn't work for curly braces! {}
Make sure you're using paredit version 22 (beta)

Where does swank-clojure (SLIME) look for Clojure's jars?
When you start it with M-x slime, it will add all jars under check ~/.clojure and ~/.swank-clojure to your classpath. You will need at least clojure.jar, clojure-contrib.jar and swank-clojure.jar. You can download pre-built Clojure and Contrib jars from build.clojure.org and swank-clojure.jar from Clojars.

When you use M-x swank-clojure-project and specify a directory swank-clojure will add the following entries to the classpath:


 * src/
 * classes/
 * lib/*.jar

You will need to manually add the clojure, contrib and swank-clojure jar versions you wish to use to the lib directory or use a dependency fetching tool such as Leiningen or Maven.

Slime hangs with the message: Polling "/tmp/slime.####".. (Abort with `M-x slime-abort-connection'.)
You're probably missing swank-clojure.jar. See the previous question.

What versions of Java are supported?
Clojure currently targets Java 5 (and later versions).

What versions of Java have been tested?
Clojure 1.0 and 1.1 are both routinely used by many people on various versions of:

It is also known to run on:
 * Sun's JRE 1.5.0 and 1.6.0
 * OpenJDK 1.5.0 and 1.6.0
 * IBM J9


 * JamVM with Classpath