I created Schematra[1] and also a schematra-starter-kit[2] that can be spun from claude and create a project and get you ready in less than 5 minutes. I've created 10+ side projects this way and it's been a great joy. I even added a scheme reviewer agent that is extremely strict and focus on scheme best practices (it's all in the starter kit, btw)
I don't think the lack of training material makes LLMs poor at writing lisp. I think it's the lack of guidelines, and if you add enough of them, the fact that lisp has inherently such a simple pattern & grammar that it makes it a prime candidate (IMO) for code generation.
The article mentions a REPL skill. I don’t do that: letting model+tools run sbcl is sufficient.
We should be using LLMs to translate from (fuzzy) human specifications to formal specifications (potentially resolving contradictions), and then solving the resulting logic problem with a proper reasoning algorithm. That would also guarantee correctness.
LLMs are a "worse is better" kind of solution.
This is definitely partly training data, but if you give an LLM a simple language to use on the fly it can usually do ok. I think the real problem is complexity.
Go and Java require very little mental modelling of the problem, everything is written down on the page really quite clearly (moreso with Go, but still with Java).
In GCL however the semantics are _weird_, the scoping is unlike most languages, because it's designed for DSLs. Humans writing DSL content requires little thought, but authoring DSLs requires a fair amount of mental modelling about the structure of the data that is not present on the page. I'd wager that Lisp is similar, more of a mental model is required.
The problem is of course that LLMs don't have a mental model, or at least what they do have is far from what humans have. This is very apparent when doing non-trivial code, non-CRUD, non-React, anything that requires thinking hard about problems more than it requires monkeys at typewriters.
I learned Common Lisp years ago while working in the AI lab at the University of Toronto, and parts of this article resonated strongly with me.
However, if you abandon the idea of REPL-driven development, then the frontier models from Anthropic and OpenAI are actually very capable of writing Lisp code. They struggle sometimes editing it (messing up parens)), but usually the first pass is pretty good.
I've been on an LLM kick the past few months, and two of my favorite AI-coded (mostly) projects are, interestingly, REPL-focused. icl (https://github.com/atgreen/icl) is a TUI and browser-based front end for your CL REPL designed to make REPL programming for humans more fun, whether you use it stand-alone, or as an Emacs companion. Even more fun is whistler (https://github.com/atgreen/whistler), which allows you to write/compile/load eBPF code in lisp right from your REPL. In this case, the AI wrote the highly optimizing SSA-based compiler from scratch, and it is competitive against (and sometimes beating) clang -O2. I mean... I say the AI wrote it... but I had to tell it what I wanted in some detail. I start every project by generating a PRD, and then having multiple AIs review that until we all agree that it makes sense, is complete enough, and is the right approach to whatever I'm doing.
On Mac I can poke virtually any aspect of my system - my Hammerspoon config is written in Fennel - has a REPL.
On Linux, I have a babashka loop with nrepl, that "talks" to Hyprland's IPC through a socket - AI can diagnose the state of WM and move things around, change color temp, affect gamma, etc.
I have made little prototypes with nbb and Playwright, and the model had no difficulty understanding the REPL loop - it was able to inspect every DOM element going to it through the REPL.
We have a few services written in Clojure, we keep nrepl on staging k8s cluster. I have vide-coded, fixed and tested things on the go - LLM can directly eval things there. Fixing bugs in Python, Java and Go takes completely different kind of loop - sometimes it feels like AI even gets excited when there's a REPL to mess around.
If anything - being a lisper in AI-era only reinforced my belief that making a deliberate choice to learn and understand the philosophy of Lisp years ago was the best choice I could've made. I future-proofed myself for decades.
Working with Lisp for a human programmer requires mindset adjustment - AI is no different here - you just have to tell it where the REPL is.
There are some issues of course. Sometimes, Claude Code gets into "parenthesis counting loop" which is somewhat hilarious, but luckily this doesn't really happen too often for me. In the worst case I fix the problematic fragment myself and then let it continue. But overall I'd say Claude Code is not bad at all with Lisps
However, a large part of OP is about REPLs and on that I've also had a hard time with CC. I was working on it this evening in fact, and while I got something running, it's clunky and slow.
I had some test functions where minimization could be optionally used, but wanted to do one where minimization was needed, like the Ackermann function. Most of the frontier models struggled with doing this, although I may have been prompting incorrectly. Although - if I had been prompting totally correctly, I probably could have gotten what I got out of a frontier LLM in early 2025 and before.
Incidentally the test function that tells you if a number is prime in Emacs Lisp with primitive recursion is
(defalias 'prime (c (c (c (r 's (c 'z (p 1))) (p 1) 'z) (c (r (p 1) (c 's (p 2))) (c (c (c (r 'z (c (c 's 'z) (p 1))) (p 1) 'z) (c (r (p 1) (c (c (r 'z (p 1)) (p 1) 'z) (p 2))) (p 1) (p 2))) (p 2) (p 1)) (c (c (c (r 'z (c (c 's 'z) (p 1))) (p 1) 'z) (c (r (p 1) (c (c (r 'z (p 1)) (p 1) 'z) (p 2))) (p 2) (p 1))) (p 2) (p 1)))) (c (c (r 'z (c (r (p 1) (c 's (p 2))) (c (c (r 'z (c (r (p 1) (c 's (p 2))) (p 2) (p 3))) (c (c (c (r 's (c 'z (p 1))) (p 1) 'z) (c (r (p 1) (c 's (p 2))) (c (c (c (r 'z (c (c 's 'z) (p 1))) (p 1) 'z) (c (r (p 1) (c (c (r 'z (p 1)) (p 1) 'z) (p 2))) (p 1) (p 2))) (p 2) (p 1)) (c (c (c (r 'z (c (c 's 'z) (p 1))) (p 1) 'z) (c (r (p 1) (c (c (r 'z (p 1)) (p 1) 'z) (p 2))) (p 2) (p 1))) (p 2) (p 1)))) (c (c (r (p 1) (c (c (r 'z (p 1)) (p 1) 'z) (p 2))) (c (r 'z (c (r (p 1) (c 's (p 2))) (p 2) (p 3))) (p 2) (c (r 'z (c (r (p 1) (c 's (p 2))) (p 2) (c (c (r 's (c 'z (p 1))) (p 1) 'z) (c (r 'z (c (r 'z (c (r (p 1) (c 's (p 2))) (p 2) (p 3))) (c 's (p 2)) (c (c (r 's (c 'z (p 1))) (p 1) 'z) (c (c (c (r 's (c 'z (p 1))) (p 1) 'z) (c (r (p 1) (c 's (p 2))) (c (c (c (r 'z (c (c 's 'z) (p 1))) (p 1) 'z) (c (r (p 1) (c (c (r 'z (p 1)) (p 1) 'z) (p 2))) (p 1) (p 2))) (p 2) (p 1)) (c (c (c (r 'z (c (c 's 'z) (p 1))) (p 1) 'z) (c (r (p 1) (c (c (r 'z (p 1)) (p 1) 'z) (p 2))) (p 2) (p 1))) (p 2) (p 1)))) (c 's (p 2)) (p 3))))) (c 's (p 1)) (p 3))))) (p 1) (p 2))) (p 1)) (p 1) (p 2)) (c 'z (p 1))) (c (c (r 'z (c (c 's 'z) (p 1))) (p 1) 'z) (p 1))) (p 3) (c 's (p 1))) (p 2))) (p 1) (p 1)) (p 1)) (c 's (c 's 'z))))
I wasn't sure if I should expect great results relative to more popular languages with more code for the LLM to train on, but it looks like that's either not a big issue, or Clojure is over the popularity threshold for good results. I also previously expected languages with a lot of static guarantees like Rust to lead to consistently better results with LLM coding agents than languages like Clojure which have few, but that's untrue to the point that "bad AI rewrite in Rust" is a meme.
Some are going to nitpick that Clojure isn't as lispy as, say, Common Lisp but I did experiment with Claude Code CLI and my paid Anthropic subscription (Sonnet 4.6 mostly) and Clojure.
It is okay'ish. I got it to write a topological sort and pure (no side effect) functions taking in and returning non-totally-trivial data structures (maps in maps with sets and counters etc.). But apparently it's got problems with...
... drumroll ...
The number of parentheses. It's so bad that the author of figwheel (a successful ClojureScript project) is working on a Clojure MCP that fixes parens in Clojure code spoutted by AI (well the project does more than that, but the description literally says it's "designed to handle Clojure parentheses reliably").
You can't make that up: there's literally an issue with the number of closing parens.
Now... I don't think giving an AI access to a Lisp REPL and telling it: "Do this by bumping on the guardrails left and right until something is working" is the way to go (yet?) for Clojure code.
I'm passing it a codebase (not too big, so no context size issue) and I know what I want: I tell it "Write a function which takes this data structure in and that other parameter, the function must do xxx, the function must return the same data structure out". Before that I told it to also implement tests (relatively easy for they're pure functions) for each function it writes and to run tests after each function it implements or modify.
And it's doing okay.
Everything in this area is moving so quickly that I haven't yet crystallized my thinking or settled on a working methodology but I am getting a lot of value out of running Claude Code with MCP servers for Common Lisp and Emacs (cl-mcp & emacs-mcp-server). Among other things this certainly helps with the unbalanced parentheses rabbit hole.
Along with that I am showing it plenty of my own Lisp code and encouraging it to adopt my preferred coding style and libraries. It takes a little coaching and reinforcement (recalcitrant intern syndrome) but it learns as it goes. It's really quite a pleasant experience to see it write Lisp as I might have written it.
Yep. Language and libraries too.
1) use a running REPL session 2) ignore pre-compilation time (it will kill the running process, mistaking it as stuck...)
Damn. And here I have a Gemini Pro subscription sitting unused for a year now.
That's what you get with every language. So, not much to really be disappointed by in terms of Lisp performance.
You guys are depressing.
It's though to steal what doesn't exist.
> but AI can write hundreds of lines in one go so that it just makes sense for the AI to use a language that doesn't use the REPL. It is orders of magnitude easier and cheaper to write in high-internet-volume languages like Go and Python
Python doesn't have a REPL?
Now is the time to switch to a popular language and let the machines wrangle it for you. With more training data available, you'll be far more productive in JavaScript than you ever were in Lisp.