Rediscover the JVM through Clojure

James Elliott
97 Things
Published in
3 min readJun 7, 2019

Some time around 2007, my office book club read Java Concurrency in Practice by Brian Goetz. We weren’t far past the preface of this important book when we panicked about how wrong our naïve understanding of Java’s memory model had been, and how easily bugs are introduced into multithreaded code. There were audible gasps, and at least one reported nightmare.

In developing a highly concurrent cloud offering, we needed a language that wouldn’t litter our codebase with landmines of shared, mutable state. We chose Clojure: It has solid concurrency answers and favors functional, efficient transformation of immutable data. It runs on the familiar JVM, interoperating smoothly with the huge ecosystem of Java libraries. Though some were hesitant about the unfamiliar Lisp syntax, and about relearning how to program without mutating variables, it was a great decision.

We discovered the benefits of a REPL-centric workflow:

  • No rebuilding or relaunching to test changes
  • Exploring the running system and trying variations instantly
  • Building and refining ideas incrementally

We appreciated Clojure’s bias toward working with data using standard structures and its rich, opinionated core library. You don’t have to create lots of classes—each with its own mutually incompatible API—to model anything.

I rediscovered joy and energy in programming. A talk at the Strange Loop conference about live-coding musical performances in Clojure using Overtone made me wonder: If Clojure was fast enough to make music, surely it could run stage lighting? That led to Afterglow, a project that consumed me for a while. Figuring out how to write lighting effects in a functional style was a puzzle, but Overtone’s functional metronome inspired my effect functions, mapping musical time to lighting positions, colors, and intensities.

I relearned trigonometry and linear algebra to aim different lights at the same point in space. I discovered how to create a desired color using a fixture’s different-hued LEDs. Live-coding stage lighting is a ton of fun.

Then I wanted to synchronize Afterglow’s metronome with tracks playing on the CDJs (today’s digital DJ turntables) I use to mix music. Their protocol is proprietary and undocumented, but I was determined. I set up a network sniffer and figured it out. Early success led to excited contributions from around the world, so I wrote the library Beat Link to make using what we learned easy. I wrote it in Java to be widely understandable, but discovered that using Clojure had made writing Java feel cumbersome.

People built on it and ported it to other languages. I created a quick demo for a show producer on using Beat Link to trigger MIDI events that his video software and lighting console could respond to. It became my most popular project, because it’s useful to non-programmers. Artists are still doing cool new things with Beat Link Trigger all the time, and as a guest at music festivals and touring shows I’ve seen the results. Since it’s Clojure, users can extend it, and their code gets byte-compiled and loaded into the JVM as if it were part of the project all along — another secret weapon Clojure can give you.

I encourage anyone working in Java to take a serious look at Clojure, and see how it can change your experience of life on the JVM.

--

--