Thursday, October 27, 2011

Evolution of a recursive function in Clojure

This was my first foray into Clojure programming and I thought I'd share it for fun.

Note that these are not good examples of idiomatic Clojure coding style, but more of an introduction to functional programming using Clojure.

Here is the basic definition for the function of a square, which takes x as a variable:

(defn square [x] (* x x))

call the function like this and this is the result you get
=> (square 4)
16

(defn addone [a] (inc a))
here are a couple renditions I went through of refactoring the sum of squares function and making it more generic this is not idiomatic clojure code, but the easiest to understand
(defn sumsquare [a b]
  (if (> a b)
    0
    (+ (* a a) (sumsquare (+ a 1) b))))

now we take the squaring (* a a) out of the code and replace it with a function that can be passed in
(defn sum [fn a b] 
  (if (> a b)
    0
    (+ (fn a) (sum fn (+ a 1) b)))) 

and here we replace the explicit increment (+ a 1) with a passed in function
(defn sum2 [func incr a b]
  (if (> a b)
    0
    (+ (func a) (sum2 func incr (incr a) b))))

with help from the Google Clojure newsgroup here is a more idiomatic example
(defn sum3 [func incr a b]
  (if (> a b)
    0
    (reduce + (map func (take-while #(<= % b) (iterate incr a))))))

and yet another even more idiomatic example, using an anonymous function and the invocation of its arguments (see the let post for more on this)
(defn sum4 [func incr a b]
  (loop [accum 0
         x a]
    (if (> x b)
      accum
      (recur (+ (func x) accum) (incr x)))))

No comments:

Post a Comment