Closing Over Simplicity
In the world of software development, there are two similar goals that run somewhat opposed to each other. One is speed and ease of creating new software. It’s important to go fast and get things done. Another goal is code that’s simple to reason about and easy to maintain and extend. It’s very easy to quickly generate reams of code that basically works, but leaves behind a complex web of entangled logic. If you’d like to learn more about these two somewhat opposed ideas, and the characteristics of each, do yourself a favor and watch Rich Hickey’s talk Simple Made Easy. (There are two recordings of this talk. This is a more recent version given in March of 2012.) Once you watch it, wait a week and watch it again. Many have reported getting more out of it with repeated viewings.
What are the key components of maintainable software? One is code that is simple to reason about. Another is doing more with less. If solution A takes 20 lines and the functionally equivalent solution B takes 10, is solution B better? Possibly, unless it abstracts away the details to the point where if a second developer comes along, they cannot understand it.
Clojure is a relatively new language, created in 2008 by the previously mentioned Rich Hickey and designed with simplicity over ease in mind. It’s based on Lisp which is relatively old, but remains relevant. Clojure runs on the JVM and achieves near native-Java speed while leaving behind a lot of the cruft of the host language. It encourages (but doesn’t enforce) functional programming concepts. Everything distills down to functions that operate on data structures. Ideal functions are pure, free of side effects and simply transform data from one representation to another. Since side effects are still required to do something useful like output to the screen or write to disk, Clojure allows side effects. But they tend to be explicit. The core data structures in Clojure are immutable, which means once they are set, they do not change. This does not mean things must remain static. To make a change, you make a copy of the original data to a new location with the required change. Loops are declared using functional iterators and recursion instead of being constructed manually with counters.
It’s a different way of thinking. Those accustomed to imperative programming where variables can be set and changed at will, and object oriented design where object methods modify state will have some initial learning curve to get over before becoming truly productive. The side effect of learning these concepts is the ability to build software that is simple to reason about, and ready for concurrency, since data stored in memory does not change and can be accessed safely across threads.
At Open Source Bridge in Portland last week, I gave an introduction to using Clojure to build web apps, and the slides are below.
There are many resources on the web for Clojure and Lisp, and if you decide to pick it up, you’ll likely need to go over the ideas repeatedly and from a few different sources for it to really sink in. I think it’s worth it!