A Blog about Business, Enterprise Architecture and Software Design by the Founders of ZenModeler

Practical Starter Tips for Clojure

In this article, I share my experience of developing with Clojure over the last months. I focus on the practical tips that will allow you to start seamlessly on Mac Os X (but should apply with Linux and Windows).

Clojure logo

Clojure Resources

When learning Clojure, first of all: have great resources to rely on and not get lost.

Books

If you begins with functional programming I suggest you to start with Clojure Programming from Christophe Grand, O'Reilly, once more experienced you can follow with the amazing Joy of clojure for hindsightful thoughts about programming applied with clojure (a 2nd edition is out). For those of you that prefer a more "example oriented" approach, have a look at the nice Clojure Cookbook. If you have a Java/OO background I suggest you to read Functional Programming for the Java Developer and Functional Programming for the Object Oriented Programmer. Of course, the bible, for more fundamental stuffs: Structure and Interpretation of Computer Programs (A good PDF and EPUB version are available).

Cheatsheet and documentation

I tend to have a Clojure Cheatsheet and a browser always opened on clojuredocs.org. I cloned the clojuredocs repo so I always access the clojuredocs on my Mac even when I'm offline. You can also access clojuredocs directly from the REPL with clojuredocs-client. You should also have a look at the Clojure Style Guide.

Update: there is now an up-to-date alternative to ClojureDocs named Clojure Grimoire, also Clojure Grimoire is available offline. The Clojure Cheatsheet is even updated to link to Grimoire instead of ClojureDocs.

Community news through newsletters and blogs

Clojure is already well-stocked with newsletters: Clojure Gazette, (def newsletter), Read Eval Print λove and agreggators: Planet Clojure and Clojurls.

Tero Parviainen, that organized ClojureCup, also has a great list of Clojure resources, another list of clojure resources.

I personaly gave a clojure presentation at the Lausanne Java User Group some times ago, here are my "Clojure Introduction slides".

Online resources

BraveClojure has great and detailed articles about Clojure and for exercising you've got 4Clojure and ClojureKoans. Clojure from the ground up is also a good introduction, and Clojure Distilled will introduce you to the mindset needed when using Clojure.

Conferences

Some conferences are entirely dedicated to Clojure: ClojureWest and clojure/conj in US, EuroClojure in Europe. Some have a good inclination towards Clojure like StrangeLoop or LambdaJam.

Common Environment for Clojure Programming

Java / Clojure / Leiningen

A JDK, Clojure, and Leiningen if you want your repl loaded with all the classpath dependencies of your project just type lein repl.

Make the non-US keyboard more hacker-friendly

The (caps-lock) key is almost unused and as a very convenient and accessible one I suggest you to remap it to ctrl. All the non-US keyboard layout are painful for daily use (I use a french one!), especially when you type a lot of (), {} and []. Therefore, I installed KeyRemap4MacBook and assign the [ to a single keystroke on the (shift) key. Of cource I assigned ( for the left one, and ) for the right one. The combination of of 'alt-shift' but by hitting the 'alt' or 'cmd' key first print me respectively a { or [ (and so on for the right side } and ]). Here is my modified KeyRemap4MacBook private.xml as a gist.

iTerm2

iTerm2 is a terminal emulator for Max OS X with impressive features, its configurability is the major one for me.

tmux

tmux is a terminal multiplexer allowing you to manage window and panes in one terminal and in a persistent way (that's to say you can close the terminal window, your session stay alive in the background with the tmux process). The best part of tmux is that it allows to script all my development environment in one command invocation: starting all the databases, the web server, the log tail, a window for the front-end, the backend, the infrastructure, etc.. The tmux book from pragprog is a must have to get started.

zsh

zsh is a shell designed for interactive use, hence the shortcuts and auto-completion it provides are simply awesome. Install oh-my-zsh to get a bundle of useful plugins in a seamless installation.

Here are some links to discover the power of zsh:

As a conclusion, here is a great blog post about the text triumvira that the combination of zsh, tmux and vim is.

Clojure Editor

The very first goal is to have an editor opened in one window and a clojure REPL beside, then to send code in the REPL for evaluation. That's all I need and it's called REPL-Oriented Development! beside the IDE choice, a good workflow with the REPL is also mandatory, here are some links about the subject: the famous Clojure Workflow Reloaded based on tools.namespace, Give your Clojure Workflow more flow.

There are basically 2 schools of thoughts on the editor subject: vim and emacs.

The vim School of Thought

Vim is a basic choice with limited features about the language comprehension as vim almost edit text only but also easier to start with. I don't cover the basics of working with vim as there is plenty of resources on the web, here are some:

Clojure and Vim

Install VimClojure and then C-c C-c will send the form under the cursor to the REPL hosted in a tmux pane. The first time you invoke the command it will ask you the tmux window.pane you want your selection to be sent. It's the most simpler and immediate development environment I used myself for some months. I didn't use the nailgun plugin for interacting with a repl as the level of clojure integration is very low with vim. At that time I prefered to just send basic text to the repl and switch between vim and the repl inside a tmux pane. A better integration and understanding of the edited language is also why I migrate to emacs.

I suggest you to read "The Text Triumvirate", a great blog post about the productive environment resulting from the use of the "vim/tmux/zsh".

The Emacs School of Thought

I switch from vim to emacs to get a better integration between the Clojure source and the repl. Emacs has a different philosophy compared to Vim, here is the emacs manual to get through it, and an Emacs CheatSheet for a reference.

Starting and Quitting Emacs

Emacs should be started in the background as its initialization is costly.

      $ emacs --daemon
   

then start instantaneously emacs with:

      $ emacsclient your_file.clj
   

Then to kill softly the daemon:

      $ emacsclient -r "(kill-emacs)"
   

Basic Functions I use with Emacs

  1. Start the cider repl: M-x cider-jack-in (should auto complete!)
  2. Evaluate the entire file: C-c C-k
Essential Emacs Functions key binding
Undo C-x u then q to quit the undo-tree
Load file C-x f
Save file C-x C-s
Split window vertically C-x 3
Go to the beginning of the file M-<
Go to the end of the file M->
Move to other window C-x o (should really work on this for a more straightforward keystroke as this function will be call several times per minutes)

Interacting with nrepl

Install emacs live

I find the "emacs live" bundle to be a good one to start with for clojure development, it bundles the cider project to boost emacs REPL capabilities.

nREPL Functions key binding
Switch the namespace of the repl buffer to the namespace of the current buffer C-cM-n
Evaluate the form preceding point and display the result in the echo area. If invoked with a prefix argument, insert the result into the current buffer C-xC-e
Evaluate the form preceding point and display the result in a popup buffer C-cC-p
Evaluate the top level form under point and display the result in the echo area. If invoked with a prefix argument, insert the result into the current buffer. C-M-x or C-cC-c
Evaluate the region and display the result in the echo area. C-cC-r
Interrupt any pending evaluations. C-cC-b
Invoke macroexpand-1 on the form at point and display the result in a macroexpansion buffer. If invoked with a prefix argument, macroexpand is used instead of macroexpand-1. C-cC-m
Invoke clojure.walk/macroexpand-all on the form at point and display the result in a macroexpansion buffer. C-cM-m
Eval the ns form C-cC-n
Select the REPL buffer. With a prefix argument - changes the namespace of the REPL buffer to the one of the currently visited source file. C-cC-z
Clear the entire REPL buffer, leaving only a prompt. Useful if you're running the REPL buffer in a side by side buffer. C-cM-o
Evaluate the current buffer. C-cC-k
Load a file. C-cC-l
Display doc string for the symbol at point. C-cC-d
Display the source for the symbol at point. C-cC-s
Display JavaDoc (in your default browser) for the symbol at point. C-cC-j
Jump to the definition of a symbol M-.
Return to your pre-jump location M-,
Complete the symbol at point. (For auto-complete integration, see ac-nrepl) M-TAB

I also wrote a short emacs-lisp function, called nrepl-send-to-repl, that send the form under the cursor as text to the repl.

paredit-mode

At first, I found the paredit-mode to be the most annoying one I ever met until I understood the "way of seeing it": think of the function as moving parens to the left or to the right and not moving the text (see the first two examples below). The 3 paredit functions I constantly use are the followings:

Paredit Function Binding Example
paredit-forward-slurp-sexp (foo (bar |baz) quux zot) ---> (foo (bar |baz quux) zot)
paredit-forward-barf-sexp (foo (bar |baz quux) zot) ---> (foo (bar |baz) quux zot)
paredit-splice-sexp M-s (foo (bar| baz) quux) ---> (foo bar| baz quux)
disable paredit

In short I constantly move the "end" paren to the right or to the left (I actually seldom move the "start" paren) end remove enclosing parens. The rest "nice-to-have" paredit functions are not as mandatory as that 3 ones and I often replace one paredit function with a sequence of that 3 basic ones (like splitting a (foo bar) into (foo) (bar) just ). Then I sometimes disable paredit to insert or remove a specific paren like any "dumb" editor. Finally, here is the best paredit explanation I stumbled upon.

The outsiders

The community is quite active in the IDE field. Here are some other options you should consider:

Being an occasional Sublime Text user and a Light table backer, I don't have an opinion about these environments. I'm quite happy with my emacs choice for the moment and should stick with it in the short term.

Conclusion

This post should give you a good overview of the resources to get started with Clojure and what it's like to install and use a Clojure development environment.

Simple and Easy Software Design – QCon London 2012

The talks I remember the most on QCon‘s second day are those from Rich Hickey. I was lucky enough to attend both the keynote in the morning (slides available) and the one about the modeling process (slides also available at the GotoCon website) in the evening at the London Java Community Group.

I was pretty amazed by the clarity of Rich’s thoughts in the Clojure documentation but I found a real visionary with the datomic service disclosure a few days ago. He’s a sort of philosopher, who tries to go very deep at first to grasp the essence of concepts like state, identity or time and then applies his thoughts to technology and I’m fond of this way of thinking and doing.

I already wrote about state, identity and behavior a few weeks ago. Here is a more general way to write about simplicity and is also the subject of Rich’s keynote at QCon : « Simple made easy ». Simplicity is a subject that fascinates me, as I see it as one of the ultimate goal in my design activities. In the following sections I will humbly mix my thoughts on that subject (sentences starting with « I ») with the ones from Rich (sentences starting with « Rich »).

Simple and Easy

Rich started by talking about the core and boundaries of these two words:

  • Simple : one fold, which is not composed
    • From the latin simplicem, "without a fold"
    • Is the opposite of complex
    • It is an objective concept that is independant of the human observe
  • Easy : lie near

Complication or complexity?

As a first step to grasp the concept of « simplicity » I started to look at what the opposite, complexity, is. So I separate at first complication and complexity:

  • Complication:
    • Deterministic, has a lots of details and connections, but with linear « cause and effects »
  • Complexity:

Finally, even though it’s interesting from an intellectual point of view to separate complication and complexity I think we can just use the following definition:

Complexity is a measurement of how difficult it is for someone to understand how a system will behave or to predict the consequences of changing it Therefore the latter definition is relative to the subject trying to understand a system, so I think that what is pertinent to analyze here is the subject’s perception of complexity.

What makes a system difficult to understand?

High level of variety in its components

Low variety in the system vs High variety in the system's constituents

Lack of order

Same relations between the elements but some organization (partitioning) added on the left

Same relationship between the elements but some organization (partitioning) was added to the left Same relations between the elements but organization (grouping) added

High degree of connectivity

Linux apache system calls for serving an image

Windows IIS system calls for serving an image

Which one do you prefer to work with? :-) But is simplicity only a lack of complication and complexity? It’s a good start (high order, low connectivity and low variety) but I think there is something more to it: *simplicity is also defined by what you add with clarity, purpose, and intentionality *(look at the DDD intention-revealing interface pattern). I think the most difficult part of simplicity lies in the latter.

Complexity and Simplicity toolkit

Rich’s morning talk was a praise to Clojure and a line of arguments about why Clojure is better on simplicity and easiness. Rich reborns an old english verb « complect » : « To join by weaving », and compare complexity and simplicity constructs to what they complect. Actually, it was a confrontation of the OOP/imperative way of thinking versus the functional one with the exposure of the different concepts on each side :

Complexity tool kit

Construct complects Elements
State complects everything that touch it
Objects complects State, Identity, Value, Operations
Methods complects Function and state, namespace
Syntax complects Meaning (derives meaning), order
Inheritance complects Types
Switch/matching complects Multiple who/what pairs
Variables complects Value and Time
Imperative loops, fold complects What and How
Actors complects What and Who
ORM complects OMG
Conditionals complects Why and the rest of the program

Simplicity toolkit

Construct Get it via
Values final, persistent collections
Functions a.k.a stateless methods
Namespaces language support
Data Maps, arrays, sets, XML, JSON etc.
Polymorphism a la carte Protocols, type classes
Managed refs Clojure/Haskell refs
Set functions Libraries
Queues Libraries
Declarative data manipulation SQL/LINQ/Datalog
Rules Libraries, Prolog
Consistency Transactions, values

It appears that the Clojure concepts have all the simplicity labels :-). Nevertheless it’s a good kick in the ass of the OOP approach.

What brings simplicity in our programs?

  • Composition of simple components together
    • This is really the fundamental way to have a simple design in a direct application of the Single Responsibility Principle.
    • In tune with the Unix philosophy that composes small programs (cat, grep, sed, awk) and link them together through text interface (the pipe). Actually, I think each point of the Unix philosophy helps bringing simplicity in every design.
  • Modularity by partitioning or grouping
    • But be careful, grouping and partitioning are enabled by simplicity, not by the opposite.
  • State always bring complexity

Example of incidental complexity with the « order » concept

Then Rich talks about the « order » concept, which gives a concrete example of one that brings incidental complexity and infects a lots of our usual programming constructs without any usefulness. Why « order » brings incidental complexity? because modifications are inhibited: a change in the order impacts the usage others have on the collections.Hence we find the « order » concept in the following constructs on the left while the construct on the right side fulfill the same needs but without that over-added « order » concept.

Order in the Wild

Complex Simple
Positional arguments Named arguments or map
Syntax Data
Product types Associative records
Imperative programs Declarative programs
Prolog Datalog
Call chains Queues
XML JSON, Clojure literals
... ...

Conclusion

Why take all this times to write about simplicity in what can be seen as very philosophical? because simplicity is a key concept and a key skill to design our softwares, not only in their technological aspects but very firstly in their domains. Yet the most significant complexity of many applications is not technical. It is in the domain itself, the activity or business of the user. When this domain complexity is not dealt with in the design, it won’t matter that the infrastructural technology is well-conceived. A successful design must systematically deal with this central aspect of the software Eric Evans, author of Domain Driven Design. « Simplicity » and « Common Sense over Common practice » was also the corrolary of the « test considered harmful » and « ORM OMG ! » that were higlighted several times during the conference. What I like the most in QCon is the « think differently » that I could feel in some talks given by opinionated people. And after that exposure I started looking at things and thinking differently, so thank you Rich for having given me that! Other write-up about that second day at QCon :