Getting Started with Clojure

December 22, 2007

After finding out about Clojure, I just couldn't wait work on some examples. Step one is getting it downloaded and installed. That's pretty straightforward, you just download it and follow the examples from the website.

One problem is that running it from the command line is a lot of typing and how do a run code I have saved in a file? Something better will probably come along eventually, but here's what I did. First, save closure in /usr/local/lib/closure. Then, copy JLine jar to that directory. Finally, create a shell script at /usr/local/bin/clj with the following contents:

#!/bin/bash 
CLOJURE_DIR=/usr/local/lib/clojure       
CLOJURE_JAR=$CLOJURE_DIR/target/clojure-lang-1.0-SNAPSHOT.jar
if [ -z "$1" ]; then 
    java -cp $CLOJURE_DIR/jline-0.9.93.jar:$CLOJURE_JAR \
        jline.ConsoleRunner clojure.lang.Repl    
else
    java -cp $CLOJURE_JAR clojure.lang.Script $1
fi

So with this, assuming /usr/local/bin is in your path, you can either run a script of invoke the REPL:

#run foo.clj
clj foo.clj

#start the REPL
clj

Now that we've got that out of the way, I thought I would provide a slight variation of the Runtime Polymorphism example:

(defmulti encounter (fn [x y] [(:Species x) (:Species y)])) 

(defmethod encounter [:Bunny :Lion] [b l] 
  (str (b :name) " runs away from " (l :name))) 

(defmethod encounter [:Lion :Bunny] [l b]
  (str (l :name) " eats " (b :name))) 

(defmethod encounter [:Lion :Lion] [l1 l2]
  (str (l1 :name) " fights with " (l2 :name))) 

(defmethod encounter [:Bunny :Bunny] [b1 b2]
  (str (b1 :name) " mates with " (b2 :name)))

(def bugs {:Species :Bunny, :name "Bugs"}) 
(def betty {:Species :Bunny, :name "Betty"}) 
(def simba {:Species :Lion, :name "Simba"}) 
(def scar {:Species :Lion, :name "Scar"}) 

(println (encounter bugs betty)) 
(println (encounter bugs simba)) 
(println (encounter simba bugs)) 
(println (encounter simba scar))

So refer to the documentation on Runtime Polymorphism for a full explanation of what's going on here, but here's my short summary. When you call encounter, the defmulti is called first. The defmulti returns a data structure that is then used to dispatch to a defmethod that matches that data structure. The defmulti uses the value that corresponds to the key :Species in the map to construct that data structure, but the defmethod doesn't know or care where that value came from. The first list in the defmethod for encounter is what should be matched. In other words, if the defmulti returns [:foo :bar], then it calls defmethod encounter [:foo :bar]. The second list is the declaration of the arguments that the method takes.

Another little nugget in there is that the comma is whitespace. Maps are defined as a list of alternating key values, surrounded by curly braces. So {:a 1 :b 2 3 :c :d 4} is a map, but as you can see, sometimes without the commas, it can be confusing. So you can write is as {:a 1, :b 2, 3 :c, :d 4} to make it more clear where the pairs are, but it's not required.

Posted in Technology | Tags Clojure

Comments

1.

thanks dude it is really helpful for the programers who r learning clojure.....i am impresed

regards
lalit ojha

# Posted By lalit on Thursday, July 30 2009 at 1:29 AM

Comments Disabled