Creating Objects in Clojure
May 26, 2010
If you have a Java background and can't imagine life without objects, don't worry! Using closures, it's easy to build the kind of `objects' which you are familiar with in Java.
Let's create a simple `student' class with fields `name' and `age' and two methods - `set' and `get'.
(defn student  (let [name (atom nil) age (atom nil) set (fn [n a] (do (reset! name n) (reset! age a))) get (fn  [@name @age])] (fn [m] (cond (= m :set) set (= m :get) get))))
Now, let's create a student and try to set/get the fields:
(def s1 (student)) ; think of s1 as our student `object' ((s1 :set) "foo" 34) ; call the `set' function ((s1 :get)) ; returns ["foo" 34]
The logic is simple - the `student' function defines four local variables `name', `age', 'set' and `get' of which `set' and `get' are themselves functions. The body of the let is a function which accepts one parameter and depending on the value of that parameter (either :set or :get) returns one of the functions `set' or `get'.
The key to understanding the code fragment given above is to realize that `s1' is a function - this function, when called with parameter :set, yields yet another function to which we can pass a name and an age. The same function, when called with parameter :get yields a function which when invoked returns the values of the atoms `name' and `age'.
Object oriented programming does not end with creating objects - we need stuff like inheritance, polymorphism etc. Clojure can do all these - and more!