Clojure First Impressions
Studying is my favorite hobby. Last winter I spent most of my evenings studying Clojure, the cool Lisp like language hosted on JVM. But the story started a long time ago at the Helsinki University of Technology where I started my Software Engineering studies in 1991. The professors of the university had decided to use Scheme, a Lisp dialect, as an introduction language to programming — a cunning idea which put practically all freshmen at the same starting line regardless their previous programming background with C, Basic or something else. So, we read Structure and Interpretation of Computer Programs and wrote Scheme.
When reading those books and experimented the examples with REPL I tried three IDE candidates. The first one was Emacs with Cider. I have used Emacs a couple of decades in all kinds of servers (Emacs installs easily to any Solaris, Aix or Linux distro) so I had to give Emacs a chance. And it was pretty good. You could do paredit editing with Emacs, slurping and barfing worked fine, REPL integration was good and it even provided a crude Clojure debugger. Second candidate was Eclipse with Counterclockwise plugin. It was also decent. But I had switched from Eclipse world to IntelliJ IDEA a bit earlier — I had used PyCharm for Python coding and decided that it makes sense to use IntelliJ IDEA for Java coding to have the same kind of look-and-feel in both IDEs. So, my third candidate was IntelliJ IDEA with Cursive plugin. I pretty soon fell in love with this candidate. IntelliJ IDEs were already pretty familiar to me, and Cursive provided excellent user experience for Clojure coding. Everything works just great. You have your favorite IDE and practically everything works exactly the same way as in IntelliJ IDEA and PyCharm. Cursive integrates to IDEA excellently and you can modify the IDE, e.g. keymaps, to work the way you want. I immediately turned on Emacs mode and configured slurping and barfing to work the same way I already used to work with them in Emacs + Cider.
Editing Clojure code with IDEA+Cursive is just a joy. Some might be intimidated by Lisp parentheses but using Paredit mode and slurping and barfing it soon comes as a second nature to be really productive to write Clojure code. IDEA syntax highlighting and intelligent code completion are there and working splendidly, of course. REPL integration is just great. You can create various Run configurations for REPL just like you do in IDEA for Java and PyCharm. And it is also pretty fast with my Ubuntu Linux 32GB RAM machine.
Clojure is marvelous. Finally a Lisp you really can use to create enterprise software. As Rich Hickey, the creator of Clojure, said in Software Engineering Radio interview: Earlier Lisp implementations were great but they were great isolated islands. Clojure runs on JVM and embraces the Java ecosystem with all its libraries. So, with Clojure you get the battle tested JVM which has been ported to practically any hardware and OS, and you can use all the existing Java libraries.
Clojure is dynamic, meaning it’s pretty easy to work with data using Clojure, e.g. you can query a relational database and get a list of maps returned. Clojure’s data structures are immutable by default making multi-threaded programming a lot easier than e.g. using Java’s synchronization. And one of the cool things is the language’s homoiconicity: Clojure (like all Lisps) uses the same structure (S-expression) for its program code and data structures. Clojure provides also excellent macro programming capabilities like all Lisps (don’t confuse Lisp macros with e.g. C macros, Lisp macros are a way to extend the language so that your own extensions work exactly like the core language). And the syntax is almost non-existing as in all Lisps.
The Programming Model
Clojure like all Lisps is a functional language. Functional paradigm sits pretty well in backend data programming. You create filter type functions and feed the data from one function to another. Functions are first-class citizens in Lisp worlds — you can assign a function to a parameter or variable and return functions from functions. It pretty soon becomes a second nature to create higher-order functions which take other functions as parameters.
Clojure provides an excellent REPL. I had already used REPL with Python, but with Python I had used REPL mostly experimenting some Python code structure before moving it to actual source code. Clojure REPL just blew my mind in a couple of days. You can import namespaces (kind of packages) in REPL, require other namespaces, integrate to your actual source code with REPL and experiment your functions in many ways using the REPL. Don’t confuse REPL to a debugger. There is also a debugger in Cursive, of course, if you want to step through your functions. I haven’t used it hardly ever since REPL provides so much interaction capabilities to experiment with the code that running a debugger is needed a lot less than e.g. with Java or Python.