Vibe Clojure 3: Medley

One significant step in a new Clojure dialect should be running a real app with it. If it can’t do that, it’s not ready for any kind of…

Share

One significant step in a new Clojure dialect should be running a real app with it. If it can’t do that, it’s not ready for any kind of real-world use.

The Clojure ecosystem and apps written for portable Clojure dialects are something of a mixed bag. Few apps seem to meaningfully exist that are written in pure, portable Clojure, since that’s kind of difficult to accomplish: there isn’t a whole lot you can do that’s interesting without tying into the native platform. Files or network are the obvious things. Also, many “portable” libraries have to target differences in dialects anyway, since there aren’t portable ways to do everything.

I wanted to give medley a try with clojurust, since it is mostly portable Clojure and exercises a bunch of Clojure features really well. It took a few days of back and forth to get the test suite running at 100%, and I was using Claude Opus mainly for doing research on why certain things weren’t working; usage has been seriously nerfed on the consumer level plans, so I had to be judicious in what I had it do vs. what I tackled myself.

Nearly everything that needed changing or implementing was things that Claude had done incompletely or left unimplemented entirely from previous sessions. Regular expressions were not implemented at all, and error types were just passed around as maps. I did those myself — implemented regular expressions with the regex crate, and implemented a new ExceptionInfo type that captures the Error types when they’re propagated. Most of the other errors were problems with lazy sequences, and I had Claude debug those, which it did a decent job of. I’m a little wary about whether it did the right thing or the easy thing.

One thing it tried doing was adding a sleep to the thread macro, so it would “replicate thread pool delays on the JVM”, to work around a (sleep 1) call in clojure-test-suite. Not great. That’s what instills the greatest fear in me when using agentic coding tools: I can spot some bad, hacky things it does when I understand them. What is it doing in the parts that I don’t fully understand?

Medley itself needed only a few :rust options in reader conditionals. My branch with some fixes is here: https://github.com/csm/medley/tree/rust. Clojurust can execute the test suite on that branch with 100% success! And the AOT-compiled test suite can run in 0.31s on my laptop, vs. ~5 seconds for lein test in medley itself! That’s likely more startup costs than anything else, but it’s still awesome to watch that work.

I’m starting a new job next week, so activity on this project will slow down significantly, but this was fun.