A quick introduction to Clojure

####Clojure is a Lisp.

Lisp is a family of programming languages, that also includes Common Lisp, Scheme and Racket, based on the original LISP language first described by John McCarthy in 1958.

Lisp is the oldest language still in widespread use today (although Fortran, which is still in use, is older) and, interestingly, for a language so old, its use is growing.

Peter Norvig has said that “Python can be seen as a dialect of Lisp with ‘traditional’ syntax” and he has written Python for Lisp Programmers to explain why.

Paul Graham has explained at some length what is special about Lisp.

Clojure is an attempt to make a Lisp available in the programming environments and with the data structures that most developers are familiar with. It runs on the JVM, on Microsoft’s CLR, and also compiles to JavaScript (ClojureScript).

For a detailed explanation of Clojure, you may want to watch Rich Hickey’s comprehensive presentation, Clojure for Java Programmers.

####Lisp code is just a list

Lisp (*“LISt Processing”) uses lists, which are written like this:

(x y z)

Compare with Python:

[x, y, z]

Lisp code is also a list:

(+ 1 2)

Compare with Python:

1 + 2

These two code snippets demonstrate the key syntactic difference between Lisp and Python (and indeed any other language you probably know about).

####Infix vs prefix notation

1 + 2

With infix notation the operator goes between the two operands. This is what we are all familiar with and we learn infix notation in school from a young age.

(+ 1 2)

In prefix notation the operator comes first. It was first described in 1924 by Polish logician, Jan Łukasiewicz. For this reason, it is sometimes also know as Polish notation.

This notation has certain advantages.

Compare:

1 + 2 + 3 + 4

With:

(+ 1 2 3 4)

Lisp code is just a list. When you type Lisp, you are typing one long list. A list of lists.

The first item in each list is a function and the subsequent items are arguments.

+ is the function and 1, 2, 3 and 4 are the arguments.

####Clojure from Python

Here is factorial in Python:

def factorial(n):
    if n == 1:
        return 1
    return n * factorial(n-1)

And here it is in Clojure:

(defn factorial [n]
    (if (= n 1)
        1
        (* n (factorial (dec n)))
    )
)

defn is itself a function. Its first argument is the name of the function. Its second argument is a vector of arguments. A vector is a lot like a Python list. Its third argument is another list containing the implementation of the function.

There is a fair bit going on here, but if you translate the Python infix notation into Clojure prefix notation, it is very similar. The most obvious differences are that there are no explicit returns: by default all lists are evaluated in Clojure and return a result.

Another difference is that we have used the Clojure function dec as in (dec n). We could also have used:

(- n 1)

In Clojure, whitespace and commas are interchangeable and indentation is not significant. The factorial function above could also have been written:

(defn factorial [n] (if (= n 1) 1 (* n (factorial (dec n)))))

To reiterate, this Clojure code is also a list. It contains four items. The fourth item is itself a list that contains another four items. The fourth item within that list is again a list, this time containing three items. And the last item in that list is yet another list, now containing two items. In every case, the first item in each list is a function.

####Vectors and other data structures

In most Lisps, sometimes a list is evaluated and sometimes it is not. If the first item of a list is a function, then it is evaluated, otherwise it is not. It is not always obvious when looking at some Lisp code whether the list you are looking at is meant to be evaulated or not. This can make Lisp confusing to read.

In Clojure, vectors are lists that are not evaluated. They are more like lists in other languages.

Rich Hickey, the creator of Clojure, has a great talk in which he explains why he introduced vectors to Clojure (the “Parens are Hard!” slide starting at 24:48). He wants it to be clear to the reader when something is a function call and when it is a data structure. Vectors do that.

Clojure also has maps, which like Python dicts use { }, and sets, which use #( ).

Next: an abridged Clojure reference.