28 July 2015
Jonathan Graham

EDIT 10 Aug 2015: The section on Creating Web Applications with Clojure (Chapter 7) has been updated to provide an explanation and remedy for an issue in the exercise.

Living Clojure is writen by Carin Meier, and was published in April 2015 by O’Reilly. The book is available in print and ebook format, and I read the print version, which 8th Light bought for me to study.

The book’s tagline is An Introduction and Training Plan for Developers, and its target audience is experienced programmers who have not worked in Clojure before. Would I consider myself an experienced programmer? Not yet, but I have some experience in several languages, and on reading the free sample chapter I decided that the book would be gentle enough to allow me to follow. And I have worked in Clojure before. In fact, Clojure was the first programming language that I experienced, and I coded it live on stage as Meta-eX. At the time, however, I only learnt how to manipulate existing code, and not how to create well structured programs. Having now switched careers to one of a software developer, I was eager to learn what Living Clojure was really about.

A quick disclaimer: I do know Carin, and I had the privilege of sharing the stage with her at Strange Loop last year, as we live-coded music and robots together. Ask yourself this though: why would you not buy a book writen by someone who live-codes robots?! Robots aside, these are just my thoughts and experiences from reading Living Clojure, and if it sounds like it might be of interest to you then I’d urge you to read on.

So, the book: what do you need to know before you start? Well, you might want to take a look at Alice in Wonderland, as this is what all the examples are based on. It might be an unusual choice to theme a programming book on, and some of the examples seem a little contrived, but go with it and you’ll see the logic in the literary nonsense. Other than that, if you haven’t written any Clojure before just make sure you take a look at the Preface to ensure that you have your environment all setup.

The Structure of Clojure: Chapter 1 gives a gentle introduction to how Clojure is structured, from simple values like intergers and strings, to Clojure collections, like maps and vectors. It then covers creating local (let) and global (def, defn) bindings, and organising these within namespaces. There are limited exercises and examples in the book, so it is well worth taking the time to practice and reinforce what you have learnt by completing the Clojure Koans. I had actually completed some of koans prior to starting Living Clojure, but I’d recommend reading Chapter 1 first, and then setting aside a few hours to complete the problems in Koans 1 - 6.

Flow and Functional Transformations: The pace begins to pick-up in Chapter 2, and starts by covering flow control with if, when and cond. It then moves on to currying, through the use of partial, and combining multiple functions with comp. There is a big emphasis throughout the book on writing clear and understandable code, and the section on destructuring starts to tackle this. The chapter then moves on to working with infinite lists through the use of laziness, and then to the fundamentals of recursion. Recursion is at the heart of the Clojure language, so it’s worth spending the time now to make sure that you’re fully onboard with the concept. The rest of the chapter looks at common abstractions that are built using recursive calls, including map, reduce and filter. Given how fundamental these expressions are for shaping and transforming collections, it is worth spending the time to write your own implementations of them, and I’ll cover this in a future blog.

A lot is covered quickly in this chapter, and at the end Carin advises not to worry if it hasn’t all clicked into place and to forge ahead anyway. This is exactly what I did, but I’d actually recommend that you stop and practice a while first. Again, the Clojure Koans are great for reinforcing what you have learnt, and you should now be able to tackle Koans 7 - 14.

State and Concurrency: Things get exciting in Chapter 3, where we look at how we can manipulate state safely whilst working concurrently. The chapter begins with the atom for independent and synchronous state changes, and introduces multi-threading through the use of the future form. It quickly moves on to coordinated synchronous changes using refs, before covering the use of agents for those times when you don’t need the results right away. Clojure Koans 15 and 16 give exercises for some of these concepts, and I look forward to tackling more involved examples with the safe use of concurrency in Clojure.

Java Interop and Polymorphism: There is a lot of power derived from being built on the JVM, and Chapter 4 briefly explains how to interact with Java classes and libraries. It then moves on to polymorphism, which allows functions to respond differently to alternative types of input. There are multimethods and protocols in Clojure, and I chose to explore the use of multimethods when writing a Clojure implementation of Bencode.

How to Use Clojure Projects and Libraries: I really like how easy it is to create new projects with Leiningen and to include libraries within them. The best way to learn is to do, and Chapter 5 holds your hand as you start working with the project structure. One thing that I found, though, is that it is easy to make mistakes even when following simple examples, and also that the error logs for Clojure are not straight-forward to read and understand. When you are starting out and see an incomprehensible log for the first time, take a look at Clojure Stack Traces for the Uninitiated, which will help you make sense of them.

Communication with core.async: The ability to easily do asynchronous programming is really quite cool, and Chapter 6 shows you the power of async.core, a Clojure library. Sticking with the Alice in Wonderland theme, in this chapter you walk through how to create multiple channels and execute from them asynchronously. It also explains how to create JAR files for easy sharing of your Clojure project.

Creating Web Applications with Clojure: It may not be the most exciting of examples, but Chapter 7 gives you everything that you need to build your own Web App. Follow through the example and you will have the basic project structure and also a knowledge of how it all works together, which will serve you well as a starting point for whatever you want to build. It starts off by creating a compojure project, which gives us a minimal web server, before including Ring-JSON middleware to enable us to handle JSON responses. Next, we look at ClojureScript, enabling us to use Clojure in the browser as well as on the server, and then we include cljs-http so that we can use the power of core.async to handle HTTP calls asynchronously.

I initially had a problem that my keys were returned as strings rather than keywords, and this resulted in the alert containing my JSON response returning {"name":"Cheshire Cat","status":"grinning"}, rather than {:name "Cheshire Cat", :status "grinning"}. After reading about the issue I thought that I needed to make changes to the default middleware settings in the handler.clj file, by adding {:keywords? true} to ring-json/wrap-json-response in app. However, it turns out that the issue results from the order that the app-routes in the handler.clj file are wrapped by the site-defaults and automatic JSON response. When this is first shown in the book (in the section Using JSON with the Cheshire Library and Ring, p119 of the paper book), the app-routes are first wrapped by the site-defaults and then by the automatic JSON response. This leads to the keys being returned as strings, since the JSON response is not wrapped in the site-defaults. However, if you change the order of the wrappers the keys are returned as keywords, as required. The correct order is actually given in the book when the entire handler.clj file is shown:

(ns cheshire-cat.handler
  (:require [compojure.core :refer :all]
            [compojure.route :as route]
            [ring.middleware.defaults :refer [wrap-defaults site-defaults]]
            [ring.middleware.json :as ring-json]
            [ring.util.response :as rr]))

(defroutes app-routes
  (GET "/" [] "Hello World")
  (GET "/cheshire-cat" []
      (rr/response {:name "Cheshire Cat" :status :grinning}))
  (route/not-found "Not Found"))

(def app
  (-> app-routes
    (wrap-defaults site-defaults)))

With the correction made, we can use the Enfocus library to update our webpage with the data we want to display and to apply event handling and effects. The final version of our web app just displays a couple of words that then fade out at different rates, but the final few pages of the chapter point to other libraries and resources that will help you on your way to designing killer apps.

The Power of Macros: The final chapter in Part I covers macros. Some core Clojure expressions, such as when, are macros, and it’s good going back to the source code to understand how they work. The take-home messages for me from this chapter are that macros are great for pattern encapsulation and for adding language features, but that they can easily be misused. For now, I have decided to keep this feature in my back-pocket, but it is there ready for me to pull out when the need arises.

Part II: Living Clojure Training Program: Part II of Living Clojure is all about practicing your skills as a Clojure developer. There is some useful information about where to go for help and resources, and how to get involved in the community, and then comes a seven-week plan of structured training. I’ve currently completed the first three weeks, which involve various 4clojure exercises to help reinforce and practice what you have learnt. You get to see other people’s solutions when you have completed each exercise, and if you would like to see my solutions then you can search for jpg1000. For the more simple problems it is easy to just code your answer directly into the browser, but for more involved exercises I pulled the problems out into a new Leiningen project and developed my solution through a TDD approach. I look forward to completing the more project-based exercises in the rest of the training program over the following few weeks.

CONCLUSIONS: When I first started the book I was unsure about how helpful it would be. I found the pace at the start a little slow, and the examples didn’t grab my attention. However, I found my learning curve quickly accelerated and I feel like the book has given me a really good foundation to move forward with Clojure development. I’d recommend anyone new to Clojure to give it a go, and make sure you give yourself plenty of time to complete the Clojure Koans and 4clojure exercises along the way.

If you’d like to buy Living Clojure then go to O’Reilly, and to connect with Carin Meier check her out on twitter.

blog comments powered by Disqus