Clojure’s method of assigning a symbol to the result of an expression will look a bit alien to those us used to imperative languages like Java. In Java, to assign a value to a variable, we say something like **x = 42;**, but in Clojure doing something like this is a bit more involved.

Clojure provides the **let** statement for assignment. The syntax of **let** is:

(let [vector of name-value pairs] (expression))

The vector of name-value pairs is the list of assignments that **let** is to make, and the expression can be any Clojure expression. A simple example will show how this works.

(defn let-test [number] (let [x number y (* x x)] (println "x = " x ". y = " y)))

Here we define a function called **let-test** which takes one argument, **number**. Then we have a **let** statement. Its vector contains two name-value pairs. The first pair assigns **number** to the symbol **x**, and the second pair assigns **(* x x)** (that is, x squared) to the symbol **y**. Finally, we use **println** to print out the values of **x** and **y**. If we test this from the REPL, we get

user=> (let-test 42) x = 42 . y = 1764 nil

It is important to realize that the assignments that take place within a **let** have a scope that is restricted to the **let** statement. For example, if we had placed the **println** statement outside the **let**, we would get a compilation error, since **x** and **y** are undefined outside the **let**. In this respect, **let** is not equivalent to the simple assignment statements in Java, where an assignment’s scope lasts from the line in which it is made to the end of the function (assuming it is not superseded by another assignment statement).

The **let** statement can be used to make code more readable and understandable, even if it does make code a bit longer. As an example of a more extended use of **let**, consider the algorithm for calculating the date of Easter, given the year. Various algorithms exist, some of which give the date in the Gregorian calendar (the one commonly used in the West today) and others in the Julian calendar. We’ll have a look at one of the Gregorian algorithms (the ‘anonymous Gregorian algorithm’ given here). The algorithm uses only arithmetic, but is quite complicated, although it would be easy enough to code it in Java from the version given in the Wikipedia article. In Clojure, we’ll use **let** to make the assignments to each of the variables given in the algorithm, then print out the date of Easter at the end. The result is as follows.

(ns glenn.rowe.Easter (:require clojure.contrib.math) ) (use 'clojure.contrib.math) (defn easter [year] (let [a (rem year 19) b (floor (/ year 100)) c (rem year 100) d (floor (/ b 4)) e (rem b 4) f (floor (/ (+ b 8) 25)) g (floor (/ (+ (- b f) 1) 3)) h (rem (+ (- (- (+ (* 19 a) b) d) g) 15) 30) i (floor (/ c 4)) k (rem c 4) L (rem (- (- (+ (+ 32 (* 2 e)) (* 2 i)) h) k) 7) m (floor (/ (+ (+ a (* 11 h)) (* 22 L)) 451)) month (floor (/ (+ (- (+ h L) (* 7 m)) 114) 31)) day (+ (rem (+ (- (+ h L) (* 7 m)) 114) 31) 1)] (println day "/" month "/" year)))

This code introduces the Clojure math library, so it’s useful to see how it is referenced. In the **ns** statement at the start, we’ve added a **require** clause, stating that the **clojure.contrib.math** library is needed for this program. The **clojure.contrib** library is a standard part of Clojure, so it will have been installed when you installed Clojure, and should be available.

On line 4, the **use** statement tells the program that functions in **clojure.contrib.math** are to be used in the code, so we can call these functions just by using their bare name. In fact, the only such function we need is the **floor** function, which returns the largest integer less than or equal to its single argument. (There is a built-in function called **quot** which will perform integer division and discard the remainder, so we could have said **(quot year 100)** instead of **(floor (/ year 100))** without using the math library, but I wanted to see how to call functions in the math library.)

The rest of the code is a fairly straightforward translation of the algorithm into Clojure arithmetic functions. The **rem** function on line 7 is Clojure’s modulus function: **(rem x y)** returns the remainder when integer **x** is divided by integer **y** (it’s equivalent to the **%** operator in Java). The **rem** function is part of the Clojure core, so the math library isn’t needed for it.

You can see that **let** allows a whole series of symbols to be assigned in pairs, by stating the symbol and then the expression whose return value is to be assigned to that symbol. Again, remember that the **println** statement at the end must be *inside* the **let** statement. (American readers will probably want to reverse the ‘day’ and ‘month’ bits of the output.)

## Comments

One of the toughest things I’ve found transitioning to Clojure is you have to create data scoping hierarchy. For example, if you read data in from a spreadsheet, the Clojure let form allows you to create a binding, and then functions process that data within the let’s scope. I remember transitioning from C to C++ a long time ago, and functional programming transition will be even tougher.

## Trackbacks

[…] the use of the quot function, which calculates the integer quotient, discarding any remainder. Recall that variables defined within a let have a scope that is restricted to the […]

[…] that can be applied to each binding. The first is :let, which works in much the same way as the regular let statement. It can be used to define symbols for later use within the for. For example, suppose we wanted to […]