Getting Started with Clojure
Why Clojure? Pick your favorite answer from Quora, and don’t forget that the most important one is that Clojure is fun.
About Lisp: yes, Clojure belongs to the glorious family of Lisp languages. Full stop. No more on this, because Common Lisp is completely different from Scheme, and the two have very little in common with Clojure.
So, why is it fun?
-
Great tooling for project automation
-
Clojure code is a sequence of lists, called forms, that you can manipulate exactly as other data lists. The right way to create the API of your framework is to provide the most convenient syntax to use it. That’s way it is so great to create Domain Specific Languages (DSLs). More elaboration on this? Check Paul Graham.
-
It targets the JVM, and the layer separating Clojure from Java is ultra-tight. Using Java code is immediate.
-
It is a great platform for experimentation. What is the next paradigm you want to play with? For sure you will find an implementation in Clojure. Think about asynchronous programming based on channels (something popularized by Go), Software Transactional Memory, or transducers.
-
If you like data analysis, you find Clojure DSLs everywhere: Cascalog for Hadoop, Flambo for Spark, Storm has a nice Clojure DSL, Riemann etc.
-
Web development in Clojure is cool. On the backend, you have an modular ecosystem of components talking ring. But Clojure is a good choice for the frontend also. Clojurescript is an effective Clojure compiler targeting javascript, and providing bindings to Javascript code. I mean… it’s Node.js but the other way around.
These are my notes on Clojure, and these five points are also the TOC for this series of posts.
Install
You need a JDK installed. I assume you have it.
The Clojure compiler is distributed as a jar file. You can download this file from clojure.org, and run it using java
,
but I strongly suggest to use Leiningen.
It makes incredibily easy to manage clojure installations, as well as the handling of libraries your projects depend on.
Leiningen
Leiningen is probably the most popular Clojure project. It is the Clojure package manager, and it takes care of
-
building new projects, whose layout is based on templates
-
downloading the specified version of Clojure (which by the way comes as a jar archive)
-
downloading all the dependencies of your project. The community repository of Clojure libs is Clojars. It handled Java dependencies as well, targeting any Maven repository.
-
building, compiling, running, deploying your project
It has a rich set of plugins, that allows to extend its capabilities. There is much delivered in that little script! Not really. It’s a little wrapper around the leiningen jar, which will be downloaded the first time you run it.
To install, you just have to download the lein (or lein.bat if you are on Windows) script.
On Linux or Mac you need to run something like
| $ mkdir ~/bin
$ cd ~/bin
$ wget https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein
$ export PATH=~/bin:$PATH
|
on Windows, download lein.bat
. Then open the command prompt, go in the directory containing the script
and run
| > lein.bat self-install
|
Now it’s time for the first project.
Hello world
So, assuming it is in your path, run
| $ lein new app helloworld
|
It will create for you a directory called helloworld
containing the stub of a project.
Check leiningen documentation about the project templates. Important parts are:
1. project.clj
, the leiningen configuration. The clj
extension is used for Clojure source code files. Indeed, that’s Clojure code.
-
src
for source code. There is one directory for the namespacehelloworld
, which contains the filecore.clj
. -
tests
for unit tests.
Type
| $ lein repl
|
to ask for a REPL.
The first time you run it, it will take some time, because it has to download everything, including the Clojure jar. You should get something like
| $ lein repl
nREPL server started on port 52074 on host 127.0.0.1 - nrepl://127.0.0.1:52074
REPL-y 0.3.5, nREPL 0.2.6
Clojure 1.6.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_40-b27
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)
helloworld.core=>
|
Congratulations! You correctly installed everything.
The most interesting part of the output is the first line. A server is running on our local machine and it is executing a REPL.
In the REPL you can submit Clojure code for evaluation, get the results, and get the prompt back waiting for more input. This is the mechanism used by all IDEs to give us an interactive environment.
Want to see the Hello world
message coming up?
If you are still in the REPL, run
| helloworld.core=> (-main)
Hello, World!
nil
|
The prompt informs us that we are in the helloworld.core
namespace, and we ask to the REPL to evaluate the function -main
, without arguments. It prints Hello, World!
, and it does not return any value, so it evaluates to nil
.
Who provided the -main
? lein in its template called app
(remember the new app
stuff?).
If you quit the REPL with CTRL-D
, you can discover other leiningen functionalities.
You can run directly the project with
| $ lein run
Hello, World!
|
or compile and build a jar ready to be deployed with
| $ lein uberjar
$ java -jar target/uberjar/helloworld-0.1.0-SNAPSHOT-standalone.jar
Hello, World!
|
The standalone jar
will contain all it’s needed to run the project, included the clojure jar and all dependencies.
So, the question is now… which IDE? I am a tmux + vim enthusiast, and maybe I will cover it in another post. But here I’m going to play with LightTable. I really enjoy it, and it runs very well on Mac, Linux and Windows.
LightTable
Point your browser to its website and download the big archive containing everything. Uncompress it where you can find it, and that’s it. Installation done.
In the directory, run the executable, and you are ready to code.
In the toolbar, click on View > Connections
. A new pane will open on the right. Click on Add connection
, and choose Clojure
. You will have to pick a project.clj
file, and LightTable will start executing a REPL in background.
Then open the Console, with View > Console
. This is useful to see stdout/stderr.
How can you interact with the connection with the REPL?
Click on View > Commands
. A new pane on the right opens, containing the list of available commands.
Type repl
, and pick Instantrepl: open a Clojure Instantrepl
.
This is an editor window where you can write any Clojure form, and get it evaluated.
This is made explicit by the UI. On the top-right corner of the editor you should have a blue label telling you that you are going Live
.
You can evaluate the -main
created by leiningen, but we need to specify the namespace, so either
| (helloworld.core/-main)
|
either
| (ns helloworld.core)
(-main)
|
In both cases you will see a nil
at the end of the form, and a Hello, world!
line in the console.
This is a very convenient way of experimenting with Clojure, in particular because it’s interactive to the same degree of a REPL, but you can edit it/save it as in a text editor.
Thus, the next trick is quiet expected. LightTable can turn any editor window in a REPL.
First of all, you need to open your project.
With File > Open Folder
you can navigate to your helloworld
project and open it. Open the file src/helloworld/core.clj
. That’s where we will start to code.
Open again the View > Commands
panel, type Instantrepl
, and pick Instantrepl: make current editor an Instantrepl
.
This time, LightTable will evaluate every form in the editor file, and will add the output of its evaluation at the end of it.
You can toggle this mode on/off simply by clicking on the live
label on the top right of the window.