Epistemic status: Anecdotes and opinions.
I’ve used Clojure for over a decade now: I first learned it in 2012 and started using it professionally in 2013. I’ve been reflecting on what has happened and what the future looks like. In this post, I want to share a few musings about it.
Missed opportunity: production REPLs
REPL is so central to Clojure that people even talk about REPL-driven development. It’s not just about having a prompt for typing commands like in Python1. Instead, it’s a way of connecting your editor to a running Clojure system.
Usually this is done only during the development. You could connect to the REPL of production system to debug or maintain it, if you dare. There are stories about adventurous Clojure developers doing to hotfix a running system.2 Usually these stories end with a word of caution: the devs will tell you about a time when they forgot to commit the fix to the version control system and the changes were lost the next time the system was restarted.
You used to be able to do it, anyway. Nowadays when the standard model of deploying software is ephemeral containers in a Kubernetes cluster, the production REPL is less meaningful. If you need to apply the same hotfix to eight different containers and Kubernetes can re-schedule them at any moment, there isn’t much point to this. Your services are now cattle, not pets.
At Metosin, we had this belief that a small but skilled team using sharp tools can deliver better software faster than an ordinary team relying on standard tools. The recent blog post by Tailscale about their database choices seems like an example of this: SQLite is an unusual choice for their setup, but they know what they’re doing and it’s working great.
I wonder if we’ve missed a similar opportunity here. Ephemeral containers have their benefits, especially for scaling, but do they always outweight the productivity benefits of using production REPLs for debugging?3
FaaS did not kill Clojure
A few years ago, Function-as-a-Service (FaaS) platforms such as AWS Lambda were surging in popularity. I thought it could be the end of Clojure for web services. Replacing all the glue code of web services with an API gateway and some lambdas seemed like a big win: all your code is about the business logic; the infrastructure has been abstracted away. I didn’t see what Clojure could offer here: it’s startup time was slow and REPL-driven development didn’t fit the FaaS platforms.
I was wrong. People still develop long-running server software just as they did in 2015. AWS Lambda became a popular tool scripting AWS services and for connecting them to each other, but it didn’t replace traditional web backends. As far as I understand, the startup time problems have been mitigated, too, and Clojure lambdas are a feasible choice nowadays.
Thinking back, I expected AWS Lambda developer experience to be rapidly improved. This didn’t happen and it still clunky if you have a lot of lambdas. Frameworks such as Serverless tried to smooth it out, but they never hit the big time. Is this another missed opportunity?
There’s a lot to like about developing browser applications with ClojureScript. Tools such as shadow-cljs and Google Closure Compiler are great – I’ll take them any day over configuring webpack. There are a bunch of good libraries such as Reagent, and of course the language itself is nice.
As a teenager, I fixed my websites by editing the PHP files directely on the server over SFTP. Now that was continuous delivery. ↩︎
Another thing I wonder about is what Erlang and Elixir are doing here. Their support for distributed systems is on the next level. If you have seen a good article on how Erlang and Elixir people deploy and interact with their production systems, please send it my way! ↩︎
Admitedly you may still need to use webpack, and it’s still difficult to configure. ↩︎