Getting setup with clojure

In this article we’ll step throught how to get setup with clojure. By the end you’ll have a working clojure installation and a simple “hello world” project that you can run through the repl and on the command line.

First some terminology…

Clojure

Clojure is a lisp-like functional language that runs on the jvm. We won’t go into any detail about the language here. Our main aim here is to show you how to install clojure and get a clojure project up and running.

So at a high level we have clojure the language. But what does that mean in practical terms? In practical terms, it’s a jar file that compiles your clojure code into byte code that can be executed on the jvm. We don’t want to manage compiling our clojure projects manually so we want a tool that will help automate many of the tasks we’ll regularly want to do with our clojure projects. For that we use leiningen.

Leiningen

Leiningen is a build tool for managing clojure projects and their dependencies. E.g. think of rake in ruby or ant in java. Lein fulfils a similar purpose in the clojure universe. We’ll use Leiningen to create projects, package them, run them, start a repl etc. You can get leiningen at leiningen.org

So how do I install clojure?

The short answer is we won’t install clojure directly. Instead we’ll install Leiningen, create a project and add clojure as a dependency on that project. This can be a bit confusing if you’re coming from something like ruby or python, where you install the langauge runtime and then use that to run your scripts or launch a repl.

You could go down the route of installing clojure as a binary and running your projects directly using that binary (along with all the associated class-path-management headaches) but it’s much easier to just use leiningen to manage running your clojure project.

Installing leiningen

The only Prerequisite before getting started is that we have java installed. To check if you have java installed, run java -version at the command line. You should see something like this…

$ java -version
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)

If you get an error message, then you need to go and install java before coming back to this step.

Once you have java installed, you’re ready to install leiningen. Go to leiningen.org and download the lein installer script (or lein.bat if you’re on windows). Make this script executable and run it. The script that you download is an installer, so the first time you run this it will download leiningen and install it.

$ wget https://raw.github.com/technomancy/leiningen/stable/bin/lein
--2013-12-13 14:47:05--  https://raw.github.com/technomancy/leiningen/stable/bin/lein
Resolving raw.github.com... 185.31.17.133
Connecting to raw.github.com|185.31.17.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 11440 (11K) [text/plain]
Saving to: ‘lein’

2013-12-13 14:47:14 (3.96 MB/s) - ‘lein’ saved [11440/11440]

$ chmod +x lein
$ ./lein
Downloading Leiningen to /Users/aidan/.lein/self-installs/leiningen-2.3.4-standalone.jar now...

Once you’ve successfully installed leinengen you should be able to run the lein command. If you run lein –version you should see that you have version 2 installed.

$ lein --version
Leiningen 2.3.2 on Java 1.7.0_45 Java HotSpot(TM) 64-Bit Server VM

Create a new project

Now we’ll use the lein command to create a new project. The ‘lein new’ command creates a new project.

$ lein new app getting-setup-with-clojure
Generating a project called getting-setup-with-clojure based on the 'app' template.

The app argument to ‘lein new’ here specifies which project template to use. Lein has several templates for creating new projects (and you can easily add your own) and the ‘app’ argument here tells it to use the app template. The app template is for creating executable apps. When we run this command we end up with a directory with our new project in it.

Lets take a look at the project directory.

$ cd getting-setup-with-clojure/
$ tree .
.
├── LICENSE
├── README.md
├── doc
│   └── intro.md
├── project.clj
├── resources
├── src
│   └── getting_setup_with_clojure
│       └── core.clj
└── test
    └── getting_setup_with_clojure
            └── core_test.clj

6 directories, 6 files

So this is what a new clojure project looks like. The doc directory is for documentation. The src directory contains your source code and the test directory is where you put your tests. project.clj at the root of the project is where you configure your project. src/getting_setup_with_clojure/core.clj is our entry point for writing clojure code in the project.

In the next section we’ll take a look at the contents of project.clj

Install our project dependencies

Lets have a look at project.clj. Here we define and configure our project and it’s dependencies. You can change your project description, version number, main function, licence, etc. One of the main things you will use project.clj for is adding dependencies for the project. This tells lein which libraries it needs to load when running your project.

(defproject getting-setup-with-clojure "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
    :url "http://example.com/FIXME"
      :license {:name "Eclipse Public License"
                  :url "http://www.eclipse.org/legal/epl-v10.html"}
                    :dependencies [[org.clojure/clojure "1.5.1"]]
                      :main getting-setup-with-clojure.core
                        :profiles {:uberjar {:aot :all}})

We can see here that lein has already added the latest version of clojure as a dependency. Lets add a second dependency to the project. We do this by adding the name and version of the library to the :dependencies vector.

We’re going to add clj-time as a dependency. clj-time is a library that provides a bunch of time related functions. If we go to the clj-time github page and scroll down we can find the dependency vector for the latest version of the clj-time library. In this case it’s [clj-time "0.6.0"]. Most clojure libraries will have this vector for their latest verstion near the top of their README. So we can copy this directly over to our list of dependencies on project.clj

(defproject getting-setup-with-clojure "0.1.0-SNAPSHOT"
  :description "Getting setup with clojure"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
                  :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.5.1"]
                 [clj-time "0.6.0"]]
  :main getting-setup-with-clojure.core
  :profiles {:uberjar {:aot :all}})

So how do we install these dependencies? Well, the next time we run a lein command on our project, lein will automatically install these libraries if we haven’t previously installed them. Lein installs libraries to a local maven repository, if they don’t already exist there. Once you’ve installed a dependency once you don’t need to install it again.

Launch a repl

So now lets launch a repl. We do this with lein repl.

$ lein repl
Retrieving org/clojure/clojure/1.5.1/clojure-1.5.1.pom from central
Retrieving clj-time/clj-time/0.6.0/clj-time-0.6.0.pom from clojars
Retrieving org/clojure/clojure/1.5.1/clojure-1.5.1.jar from central
Retrieving clj-time/clj-time/0.6.0/clj-time-0.6.0.jar from clojars
nREPL server started on port 64843 on host 127.0.0.1
REPL-y 0.2.1
Clojure 1.5.1
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)

getting-setup-with-clojure.core=>

As expected, the first time we launch this, lein will download and install the projects dependencies. Once the dependencies are installed, we end up in a repl, where we can run and evaluate clojure code. Lets run some clojure forms. Each time we enter a form in the repl, it evaluates it and prints the result.

getting-setup-with-clojure.core=> (+ 1 2)
3
getting-setup-with-clojure.core=> (+ 1 2 3 4 5)
15
getting-setup-with-clojure.core=> (* 1 2 3 4 5)
120
getting-setup-with-clojure.core=> (println "Hello world!")
Hello world!
nil

Now lets open up our core.clj file. At the moment this contains our main function, which is the function that will be executed if we run this project from the command line. The default main function just prints “Hello World”.

Let’s import and use clj-time. We use require to import the clj-time core library as :ct. Now we can call functions from clj-time.core using ct/function-name. clj-time has a function called now that returns the current time. Let’s add that to our print statement in the main function.

(ns getting-setup-with-clojure.core
  (require [clj-time.core :as ct])
    (:gen-class))

(defn -main
   "I don't do a whole lot ... yet."
   [& args]
   (println "Hello, World at " (ct/now)))

We’ll save that file and launch a new repl. We can now call ct/now in the repl to get the current time. Lets add that call into the main function too. Now when we call the -main function in the repl, we see that it also prints the current time. (We’re not going to worry about formatting the time here).

getting-setup-with-clojure.core=> (ct/now)
#<DateTime 2013-12-17T11:30:39.294Z>
getting-setup-with-clojure.core=> (-main)
Hello, World at  #<DateTime 2013-12-17T11:30:44.957Z>
nil
getting-setup-with-clojure.core=>

Next we’ll create an executable version of our project so that we can run our main function from the command line.

Create an executable jar

We create an executable jar using leins uberjar command. This bundles all the projects dependencies into a single jar file that we can execute from the command line. When we run lein uberjar, we get a jar file in the target directory. We can run that jar file at the command line and it will run our projects main function.

$ lein uberjar
Warning: specified :main without including it in :aot.
Implicit AOT of :main will be removed in Leiningen 3.0.0.
If you only need AOT for your uberjar, consider adding :aot :all into your
:uberjar profile instead.
Created ./target/getting-setup-with-clojure-0.1.0-SNAPSHOT.jar
Created ./target/getting-setup-with-clojure-0.1.0-SNAPSHOT-standalone.jar

Now we can run this jar file directly from the command line.

$ java -jar target/getting-setup-with-clojure-0.1.0-SNAPSHOT-standalone.jar
Hello, World at  #<DateTime 2014-02-06T09:11:34.736Z>

What’s next?

We’ve created a clojure project, installed clojure, installed an external dependency, started a clojure repl for your project and created an executable jar for your project. Now it starts to get fun! Next up - exploring the repl.