10 reasons to learn Clojure (or any other Lisp)

January 8, 2010

Horror and disgust. Or, more precisely, (horror (and (disgust))). That’s what I felt when I first saw Lisp code. What masochistic idiot could possibly enjoy using such a language? Reading Paul Graham’s essay Revenge of the Nerds was a turning point. Lisp turned out to be a bit like chocolate mousse. At first sight, it might look like dog shit. But once you put aside your prejudices, it turns out to be delicious! Learning Lisp is a bit like learning how to drive a Ferrari, when you only knew how to drive a wheelchair. It’s difficult, but once you get it, it will open up a whole new world for you.

Why should you start learning Lisp? Let me give you some concrete reasons. Some personal frustrations that you might recognise. Frustrations you wouldn’t have had with Lisp. Here are my 10 reasons to learn Clojure (or any other Lisp):

  1. Tired of boilerplate? Tired of having to write the same seven lines of code for each getter and setter? Tired of writing try-catch-finally-catch-finally clauses? Lisp lets you abstract all boilerplate code in simple macros. Once and for ever.
  2. Boilerplate code is no problem? Because “your IDE can generate it anyway”? How often did you change a single line of generated code, because it just didn’t do what you needed? And how often did you have problems, because after that you had to generate the same code again? How often did you have half generated half adjusted code that was unreadable and unmaintainable? Wouldn’t you rather declare a getter and setter in two words, instead of having to generate all this blurring code again and again?
  3. Had to wait for years and years until Sun finally built in an Enhanced For-Each Loop in Java? In Lisp, you’d have created your own for each-loop already years ago. In just a few lines of code. And you’d have used it over and over again.
  4. Libraries are reusable program code. Design patterns are reusable architecture. Libraries can be written once and reused every time. Design patterns have to rewritten again and again. Not in Lisp. In Lisp you’d declare the pattern in a macro and you’d only have to write the actual code.
  5. Thrilled about Domain Specific Languages? In Lisp, embedding languages is the most natural thing to do. And Lisp has been around for over 50 years already. Keep that in mind, the next time a person tells you that the new and overly hyped language X is so great because it supports DSLs so well.
  6. It’s functional! Somehow the idea of reusability got attached to object-oriented programming in the 1980s, and no amount of evidence to the contrary seems to be able to shake it free. But where objects are like big lego blocks, that only fit together in a very specific way, functions can be passed to other functions, combined and reapplied in many ways. And of course, not everything has to be a function.
  7. Were you happy that in your language “everything is an object”? Then look at horrible Java interfaces like ActionListener and think again. An ActionListener is just a function. Wouldn’t you like to treat it as such?
  8. Were you happily surprised when you heard about Aspect Oriented Programming? Were you happy with all the new possibilities it gave you? In Lisp you wouldn’t have needed it. Did you want to add logging to every function? Why not write your own operator for defining a function, that adds logging instantly?
  9. Write less, do more. In chapter 11 of Practical Common Lisp, Peter Seibel writes a unit test framework in only 26 lines of (very readable) code. Less code means less opportunities for bugs and less maintenance. Less code means less work.
  10. Not convinced yet? Then note that Even Jennifer Aniston has quit using other programming languages and now prefers Clojure (see Mark Volkmann’s Clojure Page).

Are there no drawbacks? Sure, learning it will be hard. Writing your first Lisp macros will definitely give you lots of frustrations. But you’ll be rewarded with more power than you’ve ever had in any other language. Think big. Think Lisp. Start today.

Advertisements

Writing a Spring MVC macro in Clojure (part 2)

January 2, 2010

In a previous post, we wrote a Clojure program that implemented two very simple Spring MVC Controllers. The program contained 15 lines of (mainly boilerplate) code. We’ll reduce that to the following:

(ns com.vxcompany.clojuremvc.example
  (:use com.vxcompany.clojuremvc.mvcmacro))

(defmapping com.vxcompany.clojuremvc.MyMapping

  ("/index.html"
    [:index {:info "Life's so much cooler with macros!"}])

  ("/another.html"
    [:another {:info "It's really cooler!"}]))

In part 1 of this manual, we already made a first step. Now, let’s glue the pieces together.

I’m sorry, I lied

My first version of the MVC macro does NOT work. When trying, it went fine when I used the macro within the same jar. It also went fine, when I first expanded the macro manually (macroexpand ‘(defmapping …)). But when I compiled one project with an unexpanded (defmapping), and tried to use that mapping from another project: BAM! The JVM complained that it could not find a method postinit31.

The very short summary is, that in the very special case of (genclass), the macro is expanded at different times. (gensym) might evaluate to different values. And if it does, the JVM looks for postinit33, where it may have been generated as postinit29. So, we should not use (gensym) for generating method names! See also the more detailed explanation here.

To ensure unique method names, we’ll do something else. The post-init method for a mapping com.foo.MyMapping will be -MyMapping-postinit. The following code strips the fully qualified class name:

(defn strip
  "Takes the substring of a string, starting at the index returned by
   the application of (function string)."
  [string function]
  (.substring string (function string)))

;;; with the above function, this does it:
(strip (str name) #(inc (.lastIndexOf % ".")))

Making things more Clojurish

We can now take the macro we created in part 1 of the manual, and paste some code into the post-init method, so the class actually contains the mapping. For each mapping above (index.html and another.html), we’ll generate the necessary boilerplate code, and let Clojure paste the url, view name and model in it. We’ll do that in a moment.

First, let’s make things just a little bit nicer. In the original Clojure MVC controller, we used plain strings as keys for the model (“info”). Spring MVC indeed needs strings for the keys. However, in Clojure, we can also use keywords (:info). Can’t we use keywords in our own code, and let the macro convert the keyword into a string?

This function converts any value to a string. If the value is a keyword, the name of the keyword is returned. Otherwise, a default string conversion is done. We used (cond) instead of (if), so we can easily add more cases later. The last case, true, is an easy way to specify a default case.

(defn tostr
  "Replaces the value by a string, e.g. :a becomes \"a\"."
  [val]
  (cond
    (instance? clojure.lang.Keyword val) (name val)
    true (str val)))

The next function takes a map (in our case, the model) and does the above conversion to each key in a map. Idiomatic for functional languages, we made the function recursive:

(defn keys-to-strings
  "Takes a map and converts its keys into strings, e.g. {:a 1} becomes {\"a\" 1}"
  [a-map]
  (loop [restmap a-map acc {}]
    (if (empty? restmap)
      acc
      (let [[key val] (first restmap)]
        (recur (rest restmap) (conj acc [(tostr key) val]))))))

The macro

With the above adjustments, the macro now becomes:

(defmacro defmapping
  "Defines a Spring MVC URL mapping. See example at
   https://groovyguts.wordpress.com/2010/01/02/writing-a-spring-mvc-macro-in-clojure-part-2/"
  [name & body]
  (let [this (gensym "this")
        shortname (strip (str name) #(inc (.lastIndexOf % ".")))]
    `(do
       (defn ~(symbol (str "-" shortname "-postinit")) [~this]
         ~@(for [[url handler] body]
             `(.registerHandler ~this ~url
                 (proxy [AbstractController] []
                   (handleRequestInternal [request# response#]
                     (let [[view# model#] ~handler]
                       (ModelAndView. (tostr view#) (keys-to-strings model#))))))))
       (gen-class
         :name ~name
         :extends
         org.springframework.web.servlet.handler.AbstractUrlHandlerMapping
         :post-init ~(str shortname "-postinit")
         ))))

The for loop adds all the boilerplate code for each mapping in our definition. Note we have to splice ~@, because for returns a single list of statements. We need the separate statements instead of the list. Also note how we fill in the ~url, view# and model# in the template code.

With this macro, we can specify the mapping as we did at the top of this post.

Did we really need a macro?

There’s one question I didn’t answer. Did we really need a macro? Writing macros is more difficult than writing functions. The rule is: use functions if you can. Use macros only if you cannot do the same thing with functions only.

In this case, we clearly need a macro. There is code in the macro, we only want to evaluate AFTER the macro has been expanded. Take the (gen-class) specification. (gen-class) is evaluated at compile time! Functions are not evaluated at compile time! Putting (gen-class) within a function instead of a macro, would have caused very strange effects. Also, we’re passing parameters to the macro (e.g. a class name), that we don’t want to evaluate before calling the macro. Function parameters are always evaluated before the function is called.

So in this case it’s clear. But don’t forget to always ask yourself if you really need a macro, before writing one!

Summary

We showed how powerful macros are. The original 15 line UrlMapperHandler code, was reduced to a few lines only, that express the intention of the code much better. Of course, this took some effort. We had to write a macro. But we can reuse the macro each time we need it. And the actual code is much cleaner! In Java, doing the same thing would definitely have been more difficult!

Writing a Spring MVC macro in Clojure (part 1)

December 25, 2009

In a previous post I wrote how to write Spring MVC Controllers in Clojure. The result worked, but contained a lot of boilerplate code. Boilerplate code may be an essential part of a Java program, but in Clojure it certainly isn’t. In fact, because of Lisp’s powerful macro system, in Clojure we can eliminate boilerplate code completely! How? Let’s find out, by writing a macro for creating a Spring MVC controller class.

Macros: a very short introduction

In Lisp, there is no fundamental distinction between data structures and programs. Programs work on data structures. Programs create data structures, read data structures and manipulate data structure. But a Lisp program in itself is also a data structure. Consider the following program:

(* (+ 1 1) 2)

The program is a list (or a Lisp form) with three elements. The first element, *, is the operator. The other elements are parameters to the operator. The second element is another list, that can be decomposed the same way.

Since a program is a list, we can use normal list operators to manipulate it. The following expression replaces the 2 by a 3 in the above expression.

(replace {2 3} '(* (+ 1 1) 2))

Why is this so powerful? In Lisp, like any other programming language, you can write a function that operates on data structures. But since in Lisp programs are also data structures, you can manipulate Lisp code in exactly the same way as data. This makes it possible to extend the language, in ways you’d never thought were possible. In Java, you had to wait for years until they finally built in an extended for loop. In Lisp? You’d have extended the language yourself with just a few lines of code. How? You’d have written a macro.

A macro is like a function, but different. A function returns a value. A macro returns a piece of executable code, that is then evaluated.

The parameters to a function are first evaluated and then passed to the function. The parameters to a macro are first passed to the macro. The macro manipulates the parameters and transforms them into (another) piece of executable code. The return value of the macro is evaluated by Lisp.

Macro evaluation goes in two steps:

  1. Macro expansion: the macro is executed and returns a piece of Lisp program
  2. Evaluation: the piece of Lisp program returned by the macro is interpreted by the compiler and executed

Generating the class

Let’s start with generating an empty subclass of the Spring AbstractUrlHandlerMapping. The macro extension will exist of a (gen-class) command, that generates a class at compile time. The name of the class will be a parameter to the macro. We will write the macro in such a way that

(defmapping com.my.Mapping)

defines an (empty) subclass com.my.Mapping of AbstractUrlHandlerMapping.

The basic steps for writing a macro are easy:

  1. Backquote ` the code template you want to generate.
  2. Escape ~ the macro parameters in the code template.
  3. Write code that performs the actual transformations on the code (this is the tough part!)

Let’s apply the first two steps.

(defmacro defmapping [name]
  `(gen-class
    :name ~name
    :extends org.springframework.web.servlet.handler.AbstractUrlHandlerMapping))

(defmapping com.my.Mapping)

(defn -main []
  (println (com.my.Mapping.)))

The backquoted (`) code is returned literally by the macro. Except the ~name. The ~ character tells Clojure that name, unless the rest of the code, should actually be evaluated when generating the macro expansion. To see the result of the macro expansion, type (macroexpand ‘(defmapping com.my.Mapping)) at the REPL.

Adding post-init

Now, let’s make the class actually do something when it’s constructed. We want the macro to return two Lisp forms:

  1. A definition of the -post-init function, and
  2. the above form, that defines the class and refers to the post-init function

However, a macro, like a function, can only return one form. Therefore, we have to wrap the two forms in a (do).

The naive approach would be just to add the post-init method:

(defmacro defmapping [name]
  `(do
    (defn -post-init [this]
      (println "in init"))
    (gen-class
      :name ~name
      :extends org.springframework.web.servlet.handler.AbstractUrlHandlerMapping
      :post-init post-init)))

However, when we compile this, it yields a “Can’t refer to qualified var that doesn’t exist”. What is happening?

Macros in Common Lisp are vulnerable for a mistake called variable capture. Suppose that you wrote a macro that expands to code that uses a variable foo. Suppose that someone else uses the macro within a piece of code, that also uses the variable foo. When the macro is expanded, the piece of code and the macro expansion may interoperate in unintended ways. This is a dangerous and common mistake in Common Lisp.

Clojure protects you from this error. Each symbol you use in a Clojure macro must refer to an existing, qualified name. Otherwise, you’ll get errors like “Can’t intern namespace-qualified symbol” or the error above.

Luckily, the solution is easy. To make sure that variable capture doesn’t occur, you have to let Clojure generate the symbol names for you. You can do this in two ways:

  • Extend the name in your macro code with #. Clojure will generate a unique name, that won’t collide with names in code that’s using the macro. In our example, we will use this# instead of this.
  • Use an explicit (gensym) command. (gensym) generates a new unique symbol for you, that you can assign to a variable and use in your macro. Because we need the post-init symbol in two different occurrences (-post-init and post-init), we will use this approach for
    post-init.

Our code now becomes:

(defmacro defmapping [name]
  (let [post-init (gensym)]
    `(do
       (defn ~(symbol (str "-" post-init)) [this#]
         (println "in init"))
       (gen-class
         :name ~name
         :extends org.springframework.web.servlet.handler.AbstractUrlHandlerMapping
         :post-init ~post-init
         ))))

Note the following things:

  • The first command, (let [post-init (gensym)] is NOT within the back quote. Therefore, this code is actually evaluated at macro expansion time. The command defines a variable binding post-init, that exists at macro expansion time only.
  • (str “-” post-init) builds a string that prefixes the generated name for the post-init method with a minus. (symbol) translates the string back into a Clojure symbol that can be used within a (defn). Because it is the RESULT of this expression that must be inserted in the macro expansion, and not the expression itself, we escape it with a ~.
  • Just like ~name, we also prefix ~post-init. We do not want the literal value “post-init” as the name of our post-init method, but the value of the post-init variable.
  • All other code within the back quote is returned by the macro literally, and evaluated after returning from the macro.

What’s next?

We created a macro that generates a subclass of AbstractUrlHandlerMapping with a parameterisable name. I explained why macros are so powerful. And I showed you the basic concepts how you create a macro.

The macro itself doesn’t do much yet. In a next post, we’ll add functionality to the class. I’ll show you how you can easily eliminate all the boiler plate code, by just specifying it once and forever in a single macro.

Struggling with REST in Grails

December 19, 2009

I’ve been trying to implement RESTful web services with Grails. Grails turned out to have some nifty features. But I also struggled a lot, and got frustrated too. I’ll tell you what I found out about content negotiation and mapping different HTTP methods. But first, a short recapitulation of RESTful services.

REST, a short recapitulation

REST is a lightweight way of implementing web services. It basically assumes that there are two important concepts for a web service:

  • Resources (data, documents, content)
  • Operations (reading, writing, deleting)

REST conveniently maps those two concepts on the corresponding concepts in the http protocol. Each resource is mapped on a URL.

http://mynaughtydomain.xxx/myapp/people/myself
would refer to a document (e.g. an html page, or a snippet of xml, or both) about “myself”.
http://mynaughtydomain.xxx/myapp/people
would refer to a list of all people known in myapp
http://mynaughtydomain.xxx/myapp/people/johnmccain/photographs
would refer to a list of all photographs of a certain person
http://mynaughtydomain.xxx/myapp/people/johnmccain/photographs/inatigersuit.jpg
would refer to a photograph you don’t really want to see.

Nothing special so far. The URLs have a tree structure. And a GET-request to a URL returns a web page. But there’s more.

A PUT-request to a URL sends information to the web application. The information is not just stored on a web server, but actually read and processed by the application. So, if I PUT an XML-document on http://mynaughtydomain.xxx/myapp/people/sarahpalin, not only mrs Palin will be astronged to mynaughtydomain. She will also receive a confirmation mail. And her credit card will be charged for $10000 too.

Luckily for her, she can also send a DELETE request. But that won’t give her her money back.

Content negotiation

URL mappings in Grails are defined in grails-app/conf/UrlMappings.groovy. The following pattern will provide a mapping for viewing photographs.

"/people/${person}/photographs/${photo}.jpg" {
    controller = "photo"
    action = "show"
}

Requests that match the pattern will be sent to the show action of the PhotoController class. ${person} and ${photo} can be received just as if they were normal http request parameters. Within PhotoController.action, we can refer to them with params.person and params.photo.

Now suppose that for some reason, I do not want to return a JPG-file, but an XML-file with information about the photograph. It would be easy to change the above code into

"/people/${person}/photographs/${photo}.xml" { // don't do this, it doesn't work!
    controller = "photo"
    action = "show"
}

The first URL pattern works. The second does not. Why?

Grails uses a technique called content negotiation, to return a resource in the format that is required by the client. Each http request has an accept header. The request header tells the server, what document formats it is allowed to send back. A browser request includes text/html and application/xml in the accept header. A client that only understands json, would only include the accept header application/json. This way, the server can send the same resource in different document formats. The same URL http://mynaughtysite.xxx/myapp/people will either send html or xml, based on the accept header. Or it will send an error, that it doesn’t know what the heck json is.

Unfortunately, browsers accept headers are fixed. Browsers will always prefer to receive xhtml or html. And there are a number of fixed second choices. So, in a browser, if I ask for http://mynaughtysite.xxx/myapp/people, I will always get the html version of the list and never the xml version. But Spring made a nifty feature to solve this. If you cannot use accept headers, you can append the URL with a format extension. So

http://mynaughtysite.xxx/myapp/people.html
will have the same effect as GETting http://mynaughtysite.xxx/myapp/people with text/html as the accept header
http://mynaughtysite.xxx/myapp/people.xml
will have the same effect as GETting http://mynaughtysite.xxx/myapp/people with application/xml as the accept header

grails-app/conf/Config.groovy contains the following list

grails.mime.types = [ html: ['text/html','application/xhtml+xml'],
                      xml: ['text/xml', 'application/xml'],
                      text: 'text/plain',
                      js: 'text/javascript',
                      rss: 'application/rss+xml',
                      atom: 'application/atom+xml',
                      css: 'text/css',
                      csv: 'text/csv',
                      all: '*/*',
                      json: ['application/json','text/json'],
                      form: 'application/x-www-form-urlencoded',
                      multipartForm: 'multipart/form-data'
]

html and xml are in there as mime types. That is why in the second mapping, we must NOT explicitly specify .xml. Spring’s content negotation will make sure that .xml and .html are mapped correctly. jpg is not in the list of mime types. That’s why the first mapping works as is.

To implement different formats in your controller action, you can inspect the value of request.format. Or, even nicer, you can use withFormat. The first format specified within withFormat is the default format. Note that instead of “html”, request.format may also have the value “form”, which means more or less the same.

HTTP methods

The two specified mappings, map ALL http requests to a single controller action. GET, POST, PUT and DELETE are all mapped to the same method. We can do a switch/case statement within the method. But that is evil. Instead, we can also change the mapping to this:

"/people" {
    controller = "person"
    action = [GET: "list"]
}

"/people/${person}" {
    controller = "person"
    action = [GET: "show", DELETE: "delete", PUT: "chargethebitch"]
}

Requests sent to the application will work as expected. However, the links generated by grails in your scaffolded pages WILL NOT!!!

Grails provides <g:link>, <g:actionSubmit> and <g:form> tags that reverse map names of controllers and actions to URLs. In the tags, you specify the controller and action you want to link to. At runtime, Grails replaces the controller/action-specification by the URL you specified in UrlMappings. Or at least that is what it should do.

If you use request method specifications in your mappings, forward mapping URLs to controller methods works just fine. But reverse mapping controller and action names back to a URL does not! Luckily, according to Graeme Rocher, it’s not a bug, it’s a feature!.

There are at least two ways you can work around this:

  • Use the request method mappings, but do not use the <g:link>, <g:actionSubmit> and <g:form> tags. Instead, use normal html <a> and <form> tags, and explicitly specify the URLs. Since you have thoughtfully considered your RESTful API, the URLs are logical, and are unlikely to change.
  • Do not use the request method mapping, but use a switch/case in the corresponding controller methods. This leads to ugly code.

Or of course, you can implement your own version of the three tags. Grails puts a spring bean grailsUrlMappingsHolder in the application context that might be useful.

Summary

Grails has some nifty features for implementing RESTful services, but it definitely has its rough edges too. Be aware of this, when you’re implementing REST.

Writing Spring MVC controllers in Clojure

December 4, 2009

Lately, I’m getting more and more absorbed by Clojure. The project I am working on, is a program that helps you solve Sudokus. Not that I like Sudokus, but it’s definitely fun reasoning about them. And reasoning about them in Clojure is even more fun. But that’s not the subject of todays post.

Today, I want to write about writing a web interface in Clojure. In the end, the Sudoku solver needs an interface. Let me first explain you my basic thoughts on web application development.

  1. Separating view and controller is a good thing. I don’t want controller logic in my view. I don’t want styling issues in my controller. Compojure seems like a good and straightforward library, but I do not get the impression that it makes separating view and controller very trivial.
  2. JSP is not evil. I’ve used JSP for many years. I know its ins and outs. As long as you do NOT use scriptless (does anyone still today?), it’s a plain language for defining a view. It has many tag libraries already available. Views in JSP and controllers in Clojure seems a perfect combination to me. Sorry, that makes me skip Conjure too, though it does look promising.
  3. Reinventing the wheel is a bad thing. You don’t write a web framework from scratch. There are many good web frameworks available. Spring MVC is a good web framework. It’s easy to use. It’s stable. I know how to use it.
  4. Clojure is Lisp plus Java. The whole point of using Clojure, is that it makes you access Java Code from Lisp. I want to use existing Java Code. Wasn’t that the whole purpose of Clojure? If not, why would you move from plain old Common Lisp to Clojure anyway?

So, we’ll use Spring MVC as a framework. The views are written in JSP, with Spring MVC tag libraries available. And we’ll write the controllers in Clojure. How do we combine them? Let’s find out.

Hooking into Spring MVC

We enable Spring MVC in a Java Web application, by including the Spring dispatcher servlet in our web.xml. Incoming http requests are then handled by the dispatcher servlet. The dispatcher servlet does basically the following:

  1. The dispatcher servlet sends the request to the proper controller. What request is sent to what controller, is defined in a UrlHandlerMapping.
  2. The dispatcher servlet retrieves a model and a view name from the controller. The servlet sends the model to the view specified by the view name.

The view is plain old JSP. For the second step, we can use a plain old InternalResourceViewResolver. Nothing clojurish there.

The exciting part comes in the first step. The code that returns the model and the view, is written in Clojure. So we must make sure, that the UrlHandlerMapping maps the request to a Clojure controller.

Spring MVC has a number of UrlHandlerMapping implementations readily available. My favourite one is the DefaultAnnotationHandlerMapping. It lets you annotate a method with a url pattern, and then it becomes a controller method. Like this:

@RequestMapping("/hello.html")
public ModelMap sayHello(@RequestParam("name") String name) {
    return new ModelAndView("hello", "model", name);
}

It’s something similar I want to do in Clojure. I want to define a clojure function, and annotate the url pattern and request parameters. Clojure allows us to define plain old Java Classes. So, what if we just create the equivalent of the above in Clojure? Then we’re done.

Unfortunately, Clojure has no support for annotations (yet). This is not a bad thing for programming in Clojure itself. You do not really need annotations in Clojure, since Clojure gives you much more powerful language constructs. But for programming Clojure, you don’t need Java classes either. The whole purpose of using Clojure instead of Common Lisp, was the availability of Java! So it is actually bad that annotations are not supported.

Of course, we could create controller classes in Clojure, and map them in the Spring configuration file. But that’s not what I want. I want to use the full power of Clojure not only for writing the controllers, but also for configuring them. So we have to make up a trick.

What if we write our own UrlHandlerMapping? We’ll let our implementation retrieve the mapping information from Clojure code, and let it forward the request to Clojure code. Of course, our UrlHandlerMapping implementation itself is written in Clojure.

Let’s write a prototype, to see that the approach indeed works.

Building a prototype

The UrlHandlerMapping we’ll build here, is just a simple prototype. It will map two hard coded paths to two hard coded views. The code is not elegant. But it does prove that we can easily plug Clojure into Spring MVC. And the prototype can be used as a starting point for something more general.

Each clojure file is compiled into a single class file. The top of a clojure file defines a namespace. The name of the clojure namespace is the Java fully qualified class name. To implement our own UrlHandlerMapping, we must extend the Spring MVC AbstractUrlHandlerMapping. We’ll also need some imports later on. So here’s the start:

(ns com.vxcompany.clojuremvc.UrlHandlerMappingPrototype
  (:gen-class
   :extends org.springframework.web.servlet.handler.AbstractUrlHandlerMapping)
  (:import
    [org.springframework.web.servlet ModelAndView]
    [org.springframework.web.servlet.handler AbstractUrlHandlerMapping]
    [org.springframework.web.servlet.mvc AbstractController]))

I know. Clojure code can be very short and elegant, but explicitly defining Java classes in Clojure is definitely not. Luckily, this is the only Java class that has to be explicitly available from outside our Clojure library.

To register controllers with the AbstractUrlHandlerMapping, we have to call the registerHandler()-method. The method takes two arguments: a url pattern and a controller. The url handler is a String. The controller is a subclass of the AbstractController class. Creating the controller is easy. Just use the (proxy) function in Clojure. The controller implements the handleRequestInternal()-method, that implements the controller method.

(.registerHandler this "/index.html"
  (proxy [AbstractController] []
    (handleRequestInternal [request response]
      (ModelAndView. "index" "info" "Clojure has done it!")))

AbstractController is the class we want to proxy. [] is a list of empty constructor arguments. handleRequestInternal (that takes a request and a response) is the method we are implementing. And (ModelAndView.) calls the constructor of the ModelAndView class, with three arguments.

The above code maps requests to “/index.html” to the specified controller, that forwards to the index-view, with the text “Clojure has done it!” in a model variable named “info”.

The above code must be executed on construction of the UrlHandlerMappingPrototype. Clojure has two constructs for initialising a class. With :init, you can specify the parameters for the constructor of the superclass. Optionally, :init lets you specify a Clojure variable that contains state information for the object. Within :init, you cannot yet access the this object, since it has not been constructed yet. For that, we need the :post-init. Between :extends … and the right bracket, write:

:post-init post-init

This defines that post initialisation of the class is defined in the -post-init function (the minus symbol is the default symbol for functions implementing a class method). Type (doc gen-class) at the REPL if you want to know more about class definition options. Remember, the REPL and the (doc) function are sometimes bigger friends than Google.

The full class is now:

(ns com.vxcompany.clojuremvc.UrlHandlerMappingPrototype
  (:gen-class
    :extends ...     
    :post-init post-init)
  (:import ...))

(defn -post-init [this]
  (do
    (.registerHandler this "/index.html"
      (proxy [AbstractController] []
        (handleRequestInternal [request response]
          (ModelAndView. "index" "info" "Clojure has done it!"))))
    (.registerHandler this "/another.html"
      (proxy [AbstractController] []
        (handleRequestInternal [request response]
          (ModelAndView. "another" "info" "Clojure has done it again!"))))))

Remember that instance methods (like -post-init) take this as their first argument.

Glueing the pieces together

We wrote the implementation for the UrlHandlerMapping. We still have to create a Spring MVC project, with the UrlHandlerMapping in it. In Netbeans, using the Enclojure plugin, I did:

  1. Create a new Clojure project. Include the Spring Framework, Spring Web MVC and Servlet-API libraries. Define the single class UrlHandlerMappingPrototype.
  2. Create a separate Spring MVC project. Include the Clojure library, and the library (compiled jar) for the Clojure project. Create two views index.jsp and another.jsp, that show the contents of the variable ${info}. In your web.xml include the dispatcher servlet. In the dispatcher-servlet.xml set up an InternalViewResolver.
  3. Tell the Dispatcher Servlet to use the UrlHandlerMappingPrototype. Remove other UrlHandlerMappings. Include the following in your dispatcher-servlet.xml:
<bean class="com.vxcompany.clojuremvc.UrlHandlerMappingPrototype"/>

That’s right. A single line in your dispatcher-servlet.xml does everything. Now run the application and surf to ../index.html and ../another.html, and see that it works.

Is that it?

This is just the beginning. The Clojure code we wrote is very verbose. It does not look as nice as the annotated Java method we had earlier at all! The next step is to put the boilerplate code in a reusable element, so we can just specify the url pattern and the handler method. In Java, we used existing classes and annotations as reusable elements. In Clojure, we have something much better. I’ll use the above code as an example why Clojure’s macros are so powerful. But that’s something for another post. In the meantime, enjoy writing your controller methods in Clojure!