Clojure - a Lisp I Like

Clojure is a Lisp for the JVM. I don’t normally like Lisps - the code tends to feel cluttered, and the libraries are scattered and difficult to penetrate. Whilst in Python you’d perform a ‘import string’, in PLT Scheme you’d have to ‘(require (lib "string.ss" "srfi" "13"))’.

Clojure solves that by having a small, functional core, and farming everything else out to Java. It works surprisingly well, and the code ends up looking rather clean. It’s rather similar to Arc in style; with short function names, a small core, and liberal amounts of simple syntax sugar. Where Clojure differs is it’s more functional style, it’s advanced concurrency primitives, and it’s integration with the Java.

But you can read about Clojure’s features on its website. Where Clojure is a little lacking is in code examples, so here’s a “hello world” web server using Clojure and Jetty:

(import '(org.mortbay.jetty Server)
        '(org.mortbay.jetty.servlet Context ServletHolder)
        '(javax.servlet.http HttpServlet HttpServletRequest HttpServletResponse))
 
(defmacro servlet [& content]
  (concat '(proxy [HttpServlet] []) content))
 
(defmacro defservlet [name & content]
  (list 'def name (cons 'servlet content)))
 
(defservlet test-servlet
  (doGet [req resp]
    (let [out (. resp (getOutputStream))]
      (. out (println (str "The current date is " (new java.util.Date)))))))
 
(def server (new Server 8080))
(def root (new Context server "/" (. Context SESSIONS)))
 
(. root (addServlet (new ServletHolder test-servlet) "/*"))
(. server (start))

And to run that example:

java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=4096 -cp 'clojure.jar:jline-0.9.94.jar:servlet-api-2.5-6.1.9.jar:jetty-6.1.9.jar:jetty-util-6.1.9.jar' jline.ConsoleRunner clojure.lang.Repl server.clj

I’ll probably create a small web framework for Clojure - only something very minimal - and package it up with the Jetty and JLine jars. It’ll give me a reason to use Github too, which I’ve been meaning to try out.