Imperative programmers frequently complain that one of the things that makes functional languages hard to learn is their lack of loops. Clojure actually does provide quite a few methods for doing iteration. We’ll have a look at some of them here.

Suppose we want to print out a table of squares of certain numbers. In Clojure, we can provide these numbers in a list, as in **‘(1 3 5 8 19)** (remember the quote at the start is needed to stop Clojure interpreting the list as a function). To an imperative programmer, the way to do this is to set up a loop over each element in the list, calculating the square of each number. How can we do the equivalent in Clojure?

We can use the **doseq** macro. The code is

(defn squares-table [numlist] (doseq [num numlist] (println (str "Square of " num " = " (* num num)))))

The function **squares-table** takes a list as an argument. The **doseq** macro takes two arguments. The first, **num** here, is undefined before **doseq** is run. It is assigned each element of **numlist** in turn, and for each element, the form or forms (you can put any number of forms after the argument list) are executed. In this case, we just print out a string giving the square of **num**.

We could call this function in the REPL with

**(squares-table ‘(1 3 5 8 19))**

and we get the result:

Square of 1 = 1

Square of 3 = 9

Square of 5 = 25

Square of 8 = 64

Square of 19 = 361

nil

The ‘nil’ at the end is just the return value of **squares-table**.

Another iteration macro is **dotimes**. A variant of our squares-calculating program looks like this:

(defn squares-times [maxnum] (dotimes [num maxnum] (println (str "Square of " num " = " (* num num)))))

This time, **squares-times** takes a single argument, **maxnum**, not a list. The **dotimes** macro takes two arguments. The first, **num** here, is undefined at the start. It takes on each integer value from 0 up to **maxnum – 1**. For each value of **num**, the body of the **dotimes** is run, so in this case, we’ll get a table of squares from 0 up to **maxnum – 1**. Incidentally, **maxnum** can also be a character, in which case it is interpreted as that character’s ASCII code. So if we made the call **(square-times \A)**, we’d get a table of squares from 0 up to 64, since ‘A’ has ASCII code 65. The backslash before the A is needed, since otherwise, Clojure will interpret A as a symbol, not a bare character.

Although the **doseq** and **dotimes** macros look quite powerful, they have one limitation which results in them not being used as much as you might think. The problem is that they both return only ‘nil’, so they don’t produce any data that can be used in subsequent functions. You might think that this is no big deal, since a ‘for’ loop in an imperative language doesn’t return anything either, but you can, of course define other data structures such as arrays that are constructed within a ‘for’ loop and are then used in subsequent code.

Clojure provides several other macros and functions that do return useful data, usually in the form of a list, and these macros are used much more than **doseq** and **dotimes**. One powerful function is **map**.

In its simplest form, **map** takes two arguments. The first is a *unary* function (that is, a function that takes a single argument), and the second is a list. **map** iterates through the list and applies the function to each item in the list in turn. The results are returned as a new list.

For example, suppose we wanted to create a list of all the squares of numbers within a given range. The following code does this.

(defn square [num] (* num num)) (defn squares-map [minnum maxnum] (map square (range minnum (inc maxnum))))

First, we define a simple unary function **square** which squares its argument. Then we define **squares-map** which takes two arguments. Then we call **map** to create the list of squares. The first argument to **map** is our **square** function that we’ve just defined. The second argument must be a list. We’ve used the **range** function (part of Clojure). When given two integer arguments, range returns a list starting with the first argument and ending with one less than the last argument. Since we want the final value **maxnum** to be included in our answer, we apply the **inc** function to add 1 to **maxnum** before sending it to **range**.

**map** will thus apply **square** to each number from **minnum** to **maxnum** and return the result as a list. For example, if we call **(squares-map 3 9)** we get back **(9 16 25 36 49 64 81)**. Clearly the Clojure code for doing this is a lot shorter than in, say, Java. (OK, so a lot of work is being done for you by the people who wrote **map** and **range** and so on, but these functions are part of the Clojure language, rather than being optional add-ons, so you can rely on any installation of Clojure having them.)

Note, by the way, that this example shows a function **square** being passed as a parameter to another function **map**. This shows that functions are just data that can be passed around like any other kind of data; this is something that many imperative languages don’t let you do.

**map** is actually a lot more powerful than this simple example showed. In its more general form, it takes a function that takes any number of arguments, followed by the same number of lists of data. It will then pick off the first element from each list and pass these as arguments to the function, then it will pick out the second element from each list and pass those as arguments, and so on until it comes to the end of the shortest list, at which point it will stop and ignore all remaining data in other lists.

For example, suppose we had two lists of numbers and wanted to calculate a number that is the square of an element in the first list added to the square of the corresponding number in the second list. We can do this as follows.

(defn sum-squares [x y] (+ (square x) (square y))) (defn add-squares [nums1 nums2] (map sum-squares nums1 nums2))

We first define a function **sum-squares** that takes two arguments and returns the sum of their squares (using the **square** function from earlier). Then we define **add-squares** that takes two lists, **num1** and **num2**. We call map, giving it the **sum-squares** function and the two lists. For example, if we called **(add-squares ‘(1 3 5 7) ‘(2 4 6))** we get back **(5 25 61)**. This is because 1*1 + 2*2 = 5, 3*3 + 4*4 = 25 and 5*5 + 6*6 = 61. The final 7 in the first list is ignored since there is nothing in the second list to match it with.

Finally, we’ll have a look at the **filter** function. **filter** iterates through a list and tests each list element against a predicate function (a function that returns true or false). If an element is ‘true’ according to the predicate, it is included in a new list, otherwise it is excluded. The return from **filter** is a list of all elements from the original list that pass the predicate test.

For example, suppose we wanted a list of all the odd squares within a given range. We could do that using **filter** as follows.

(defn is-odd? [num] (= (rem num 2) 1)) (defn odd-squares [minnum maxnum] (let [numlist (range minnum (inc maxnum)) squares (map square numlist)] (filter is-odd? squares)))

Our predicate function **is-odd?** tests if a single number is odd by calculating its remainder when divided by 2. The **odd-squares** function uses the **map** from our earlier function to calculate the list of squares within a given range, and then **filter** is applied to this list. We’ve used a **let** to make the code more readable. We could have written the whole thing on one line like this:

(defn is-odd? [num] (= (rem num 2) 1)) (defn odd-squares [minnum maxnum] (filter is-odd? (map square (range minnum (inc maxnum)))))

However, deciphering this code requires a fair bit of backwards thinking, so it’s not very human-readable. (Actually, we could have included the definition of **is-odd?** within that single line as well, as an anonymous function, but more on that when we consider ways of creating functions.)

Testing this function, we call** (odd-squares 3 16)** and get back **(9 25 49 81 121 169 225)**.

Hopefully these little examples have illustrated the power and brevity of a lot of Clojure code.

## Comments

I have not seen as clear a reason why doseq and other do forms are not always useful, especially when you need to return something other than nil. Thanks.

## Trackbacks

[…] second list uses filter, which we saw earlier, to find all the numbers in denoms that divide n evenly (that is, with zero remainder). Recall […]