Functional Programming with Clojure

clojure

I’ve been playing about with a nice little functional programming language based on the JVM called Clojure. It’s a dialect of Lisp, but sheds a lot of the older conventions that have been stuck with Lisp and other functional languages because of historical reasons. Because of this, it makes the syntax very pure, and it’s a great introductory language into the thread-safe, multi-process world of functional programming languages.

Functional what-what?

So, what’s functional programming? Functional programming languages express the idea that everything is a function, there is no state and there is no mutable data. When we take a look at imperative languages such as PHP, Ruby and Python, which have standard operators, standard data-types (not including functions) and mutable data structures, and compare them to functional languages such as Erlang, F# and Clojure (my functional language of choice), you can clearly see the differences in paradigm and how each of the paradigms work.

I chose Clojure as my functional language of choice for a number of factors. First, it’s a great intermediate language as it’s not quite as strict as others - for instance, it tries to discourage mutable data but accepts that sometimes it’s necessary. It’s also based on the JVM - so it’s written on a very portable, tried & tested, powerful platform. It’s got a very clean syntax, it’s well designed and it contains a complete standard library.

Setting up Clojure

You can download Clojure from the Clojure website - the download is a small folder with a readme, the Clojure .jar, the source and the build files. To run the Clojure Repl, which is a dynamic shell similar to Ruby’s irb, you need to add the Clojure .jar to the classpath and call clojure.lang.Repl in the JVM. The following command will do it on the fly:

I’m currently running the most recent, stable release of Clojure, which is 1.0.0, but replace the file name above to whatever the filename is in the download. Running that command will open up the Repl, which will allow you to run any Clojure commands and write scripts interactively in the shell.

You’ll also want to configure your environment up to work with Clojure. I use the TextMate bundle for Clojure, but there are lots of alternatives available.

Everything is an expression

An interesting thing about the Clojure language, and something that confused me to begin with was the fact that everything, including operations, are expressions. Expressions are then evaluated down to data structures before being parsed. This means that with every operation, every function call, every assignment is all written through an expression.

Let’s look at some examples of this. To define a method, we use the defn function, passing first a docstring, then the parameters (as a list), then finally the function’s code itself. We’ll create the Hello World of functional languages: the factorial function.

If the syntax confuses you (too many parentheses!) then don’t worry - it’ll become more familiar over time. The important thing to notice here is that we’re using defn to create a method, and the order of the defn method’s parameters are important. Docstring, Params, Code. Of course, this function also highlights another feature of Clojure - functions can be recursive. Like Ruby, there is no explicit call to “return” to return values - the result of the expression is used as the return value automatically.

Another thing that the factorial function notes is the if method. You call if, pass the statement as the first argument, pass the ‘true’ expression second and the ‘false’ (or the ‘else’ block) third. So, if we want to check to see if the “jamie” variable equals “awesome”, we can use this code:

So, to compare two values, we passed those two values to the = function. There is no difference between operators and functions, and as we saw in the factorial function we can do this with any of the standard operators.

Concurrency

One of the big pluses for Clojure is that it’s been directly designed for concurrent programming. The normal procedural languages we’re used to are usually not thread-safe by default, and implementing thread-safety is very difficult.

Thread-safety is where multiple processes of a single application can be run concurrently, and data shared between them is synchronized automatically. Clojure handles this by encouraging immutable data (data that can’t be changed once initialized), but it also has great support for concurrent variables. So much so that if I change a variable in one thread, it will automatically be changed in other threads.

To stop this effect from happening, we need to bind the variable to a temporary variable that will be thread-independent, and to do this we can use the binding method. To show an example of this, say we have a program that keeps a user’s current status in the system. We want to keep each status independent of each user.

Data Types

Apart from the standard integers, strings and functions, we have four major datatypes that you should be aware of.

The first type are lists. Lists are effectively expressions, and are what code is written in, but lists can also contain values. If you want to use a list as a sole datatype, without it being evaluated as an expression, you can prepend it with an apostrophe. The second datatype is a vector - very similar to lists but they perform better in code for larger sets of data as they have constant-time access through position (much like an array). Vectors are defined using square brackets instead of parentheses.
A third datatype is a map. We use maps to associate keys and values - much like an associative array, a hash or a dictionary. Maps are defined with curly braces, and take keys and there value, but there aren’t any separators. You’ll see how this works better in the code example below. The final type is a set. Sets work just like in mathematics - they contain a group of elements and make sure that each element is only included once.

Here is a code example of all four data types:

Avec Java

As Clojure runs on the JVM, and it’s code is compiled down to JVM bytecode, it makes it very easy to use Java classes in your Clojure application. In fact, it’s so easy, you just pull them straight from the java namespace, and if they’re in the JVM path they will be accessible.

Here’s an example where we see if a file exists by calling the exists function on Java’s io.File class.

Clojure for functional, concurrent, sexy programming

So I hope this brief overview has been enough to show you how cool Clojure actually is. It’s quite an underdog, and I definitely think it deserves more recognition. You’ll also want to check out Compujure, a cool Sinatra-like framework for web development with Clojure. Of course, this post is merely an introduction into Clojure programming - there are loads of cool language features such as atoms, refs, macros and much more.