Diving into Clojure
Tagged: readings clojure
This note will be part review of Web Development in Clojure and part description of my first encounter with functional programming.
Why functional programming and why Clojure? I've been interested in the idea behind functional programming for a while now - being used to OOP languages with minor functional elements such as Python and Ruby. Functional programming offered a whole different paradigm of solving problems. I also kept hearing about things like Erlang and Haskell, which sound really cool. The straw that broke the camel's back was "Object Oriented Programming is an Expensive Disaster Which Must End". At the time I read it, it seemed like I was working on something that was a prime example of all the points the above article makes on OOP. I was fighting with keeping a gang of objects in the correct state over a number of steps, performing the right operations on the right objects at the right while maintaining the whole collection in a specific state. Of course each step mutated each state (of a single object and of the whole gang) in multiple ways. A user could also go back to any one of the preceding steps and alter state. There is a point in the whole process where a user is asked to submit information but under certain conditions, that information is meant to not be saved. It just disappears into /dev/null (this is a project constraint - the backend must mimic the design).
Working on this felt like fighting first Rails and then Ruby itself. The pull of functional programming was too strong. I checked out a few languages - Haskell, Erlang, Clojure, and Scala. I dismissed Scala because it allows for OOP code, which I wanted to get away from. Haskell felt far too alien from anything I've known. It was a really hard choice between Clojure and Erlang. I finally chose Clojure because of the good things I've heard about the JVM and the promise of easy cross platform development (including android). Erlang is still in my sights though. Both languages seem to have great communities and job prospects. The most important part of the latter are companies that work on interesting projects.
I initially started out with the Joy of Clojure, which was a great overview of the whole language. It introduces the basic rules governing Clojure and then goes into the details of what makes Clojure great. The first - sequences, lazy evaluation, tail calls, destructuring - I was able to soak in and it got me really excited. The latter - atoms, regs, agents, protocols, macros were so alien to me that I need a small example project to really get these. There's also the issue of Java. Clojure can use any Java library, which gives the language a lot of power. Well, first I gotta read up on the Java library to even use all of that power.
Keeping this in mind, I thought my first project should be something that I'm somewhat familiar with - web development. That's when I picked up Web Development in Clojure and slowly went through the examples.
The book introduces the basics of using Clojure for the web by first exposing the reader to Ring - the library responsible for handling requests and responses - much like Rack in the Ruby world. The next step involves introducing Compojure, which I believe acts like an extension for Ring in that it sits atop of Ring and provides a lot of comfort-functions to make things easier. Compojure, I also think, adds a general project skeleton that makes developing easy. The last basic component introduced is
lib-noir - a library that provides a lot of functionality: session management, password hashing, input validation, redirects and more. Check it out here for a full list of functionality.
Using just these basic blocks, it's possible to go a long way. This really reminds me of Django in the aspect that it's very modular. It's much more modular than Django, to be honest. I like how in every part of the project (which is its own namespace), the developer has to specify all the requirements. This takes away much of the "magic" that happens in Rails where you think that information will flow a certain way and more often than not - it does, except when it doesn't. Here, you can't really guess as you're using basic building blocks so everything is out in the open. Does this add extra overhead? Yes. Is it worth it? Hell yes.
The book later takes us on a tour of accomplishing basic web developer tasks in the Clojure way. It's divided into two parts: accessing a database and rendering the front-end markup in the most basic way possible and doing the same things but using a templating engine and an ORM.
The first group of chapters deal with using simple tools to complete the usual developer tasks - things like accessing a database by hand writing SQL, using Java to handle file uploads, using
lib-noir to create a user registration and authentication component, and finally using Hiccup to render Clojure as HTML, which I thought was really cool. The last feature was interesting because Hiccup uses standard Clojure data structures to create markup. Since we're dealing with pure Clojure, it's possible to use all the magic of functional programming here - things like macros and closures.
The book goes into a good deal of detail about each of these steps and everything is illustrated with a good amount of code. This made it easier to follow and soak in more Clojure specific knowledge along the way too. It lacked most of the advanced Clojure features that I mentioned earlier (protocols, agents, etc), but I think that's due not having to bother with solving concurrency issues while making a simple CRUD application. It does however illustrate macros in an accessible manner as well sheds a tiny bit of light on creating Java classes using
deftype. Considering all of this, I think it's a great introduction to web development using Clojure as it gives you just enough tools to be dangerous, yet leaves you craving for more.