Ok, this might be hard to keep up, but nothing ventured …

Rich Hickey is going to be coming to Northampton on March 20th to talk about clojure. In preparation for that, I am going to blog every day in March about clojure — then, hopefully we can post the results of his talk.

If you don’t have clojure yet — go get it. Start here to learn basic clojure syntax (there is also a download link). Clojure is trivial to get running and you definitely want to play with it a little to understand the rest of this. The quick description of clojure is that it’s a dialect of Lisp that runs on the JVM. It has support for immutable and persistent data-structures and a concurrent programming model.

Today I’m going to start with some of the work I did to learn clojure through translating SICP lectures. In the first lecture, the first interesting program starts at 56:20 in this video:

Starting there presumes you know some basic Lisp syntax. This is the program he eventually writes to calculate the square root (in Scheme):

(define (improve guess x)

(average guess (/ x guess)))

(define (good-enough? guess x)

(< (abs (- (square guess) x)) .001))

(define (try guess x)

(if (good-enough? guess x)

guess

(try (improve guess x) x)))

(define (sqrt x) (try 1 x))

I have left out implementations for square and average here. This code and the algorithm is explained in the video. Here it is in clojure (I defined average and square — you could just use Java, but I am trying to keep it all in clojure for now)

(defn sum ([] 0)

([x] x)

([x & more] (+ x (apply sum more) )))

(defn average

([] 0)

([x] x)

([x & more]

(/ (+ x (apply sum more)) (+ 1 (count more)))))

(defn abs [x] (if (< x 0) (- x) x)) (defn square [x] (* x x))

(defn improve [guess x]

(average guess (/ x guess)))

(defn good-enough? [guess x]

(< (abs (- (square guess) x)) 0.001))
(defn try-sqrt [guess x]

(if (good-enough? guess x)

guess

(try-sqrt (improve guess x) x)))

(defn sqrt [x] (try-sqrt 1 x))

(prn (sqrt 9))

If you take this and put it in a file named sqrt.clj, you can run it like this (after downloading clojure):

java -cp clojure.jar clojure.lang.Script sqrt.clj

And it will print out:

65537/21845

Explanation of the differences between the two examples:

- clojure uses defn to define functions and puts arguments in []
- sum and average implementations show how clojure can overload on arity (number of arguments)
- try is reserved for exception handling, so I renamed the try function to try-sqrt
- the answer is in clojure’s rational number format, since all of the computation was adding and averaging integers and rationals, the result is a rational number and clojure preserves that.

Tomorrow, I’ll improve this so to make it more generic. A lot of what I used in this can is explained in the clojure Functional Programming support page.