The Power of Live Coding May 30, 2018

I took the bait a few weeks ago and answered an oppositional question on Stack Overflow in which the author doubted the value of Lisp. In response to my argument that Lisp is great for live coding, the OP commented:

you gain what exactly. You do not have to restart the jvm but what advantage does that give you aside from a good feeling? How is it functionally any better from any other interpreted language with no compilation step where restarting the execution is basically instant?

While evaluating code live in an editor does seem like a workaround for slow start-up times, its power goes far beyond that. Not having to restart the platform’s process means you don’t have to restore its state and can even change behavior as code is running. For instance, here’s Andrew Sorensen live coding the history of Western music, altering how melodies and harmonies are procedurally generated as the music plays, without interruption. That’s not possible when you have to restart the process, even if it’s instantaneous. Here are a few more uses for live coding I’ve encountered in my own work.

Avoiding expensive I/O. Starting the host environment isn’t the only thing that takes time. Often scripts need to parse files, query databases, or connect to remote APIs. Collecting and preparing data takes time, and if you have to do it over and over to test every code change, you’ll spend extra time waiting, possibly also stressing database resources or hitting API rate limits. Live coding lets you set up the data once, then work with it in memory. This is especially true in Clojure, where the source data is immutable.

Keeping connections. If you have an application that maintains persistent connections, such as websockets, it’s much quicker to redefine the code that processes messages than to restart the server and clients and get them back into the same state. Restoring that state is often non-trivial. Keeping the state you have and changing only the logic is not only faster, but it keeps your focus where it’s needed instead of being constantly distracted by setup.

Retaining subprocesses. I’ve been live coding my browser for several months now, starting up an automated instance of Chrome under Selenium’s control in order to test some complex workflows. If something in my ad hoc scripts break part way through, I don’t have to start over with a new instance of Chrome, I simply alter the code and re-evaluate. Live coding allows you to keep the state of subprocesses too.

Inspecting long-running processes. Some data processing jobs take longer than expected, and rather than stopping them to add debug statements, live coding often lets you add tracing while the process runs. I frequently create namespace-level atoms and swap values into them in order to peek at where a computation is.

Live coding, in my experience, is far more powerful than quick start-up times. Platforms like Node or Python that can restart scripts almost instantly have no mechanisms for maintaining application state between restarts. As a software developer, I spend more time trying to get applications into particular states than I do waiting for them to start, so I very much appreciate it when the platform lets me keep that state between code changes.

If you have other experiences with live coding, let me know on Twitter or by email .