If you’re reading this book, you are presumably open to learning new programming languages. On the other hand, we assume that you expect reciprocity for the time and effort you’ll expend to learn a new language, some tangible benefits that can make you more productive, your team more effective, and your organization more flexible.
We believe that you will find this virtuous cycle in effect as you learn, apply, and leverage Clojure. As we are fond of saying, Clojure demands that you raise your game, and pays you back for doing so.
As software developers, we often build up a complex and sometimes very personal relationship with our tools and languages. Deciding which raw materials to use is sometimes dominated by pragmatic and legacy concerns. However, all other things being equal, programmers prefer using whatever maximally enhances their productivity and hopefully enables us to fulfill our potential to build useful, elegant systems. As the old saying goes, we want whatever makes the easy stuff easy, and the hard stuff possible.
Clojure is a programming language that lives up to that standard. Forged of a unique blend of the best features of a number of different programming languages—including various Lisp implementations, Ruby, Python, Java, Haskell, and others—Clojure provides a set of capabilities suited to address many of the most frustrating problems programmers struggle with today and those we can see barreling toward us over the horizon. And, far from requiring a sea-change to a new or unfamiliar architecture and runtime (typical of many otherwise promising languages over the years), Clojure is hosted on the Java Virtual Machine, a fact that puts to bed many of the most pressing pragmatic and legacy concerns raised when a new language is considered.
To whet your appetite, let’s enumerate some of Clojure’s marquee features and characteristics:
Clojure code can use any Java library, Clojure libraries can in turn be used from Java, and Clojure applications can be packaged just like any Java application and deployed anywhere other Java applications can be deployed: to web application servers; to desktops with Swing, SWT, or command-line interfaces; and so on. This also means that Clojure’s runtime is Java’s runtime, one of the most efficient and operationally reliable in the world.
Unlike Java, Python, Ruby, C++, and other members of the Algol family of programming languages, Clojure is part of the Lisp family. However, forget everything you know (or might have heard rumored) about Lisps: Clojure retains the best of Lisp heritage, but is unburdened by the shortcomings and sometimes anachronistic aspects of many other Lisp implementations. Also, being a Lisp, Clojure has macros, an approach to metaprogramming and syntactic extension that has been the benchmark against which other such systems have been measured for decades.
Clojure encourages the use of first-class and higher-order functions with values and comes with its own set of efficient immutable data structures. The focus on a strong flavor of functional programming encourages the elimination of common bugs and faults due to the use of unconstrained mutable state and enables Clojure’s solutions for concurrency and parallelization.
The realities of multicore, multi-CPU, and distributed computing demand that we use languages and libraries that have been designed with these contexts in mind. Clojure’s reference types enforce a clean separation of state and identity, providing defined concurrency semantics that are to manual locking and threading strategies what garbage collection is to manual memory management.
Clojure is dynamically and strongly typed (and therefore similar to Python and Ruby), yet function calls are compiled down to (fast!) Java method invocations. Clojure is also dynamic in the sense that it deeply supports updating and loading new code at runtime, either locally or remotely. This is particularly useful for enabling interactive development and debugging or even instrumenting and patching remote applications without downtime.
Of course, we don’t expect you to understand all of that, but we do hope the gestalt sounds compelling. If so, press on. By the end of this chapter, you’ll be able to write simple programs in Clojure, and be well on your way to understanding and leveraging it to help realize your potential.