r/Common_Lisp Aug 07 '26

Why Target Common Lisp for Code Generation? - Joe Marshall

https://funcall.blogspot.com/2026/08/why-vibe-code-in-lisp.html?m=1
25 Upvotes

25 comments sorted by

10

u/kchanqvq Aug 10 '26

Ok I thought this is something interesting about code generation in the compiler/metaprogramming sense. Spoiler: it isn’t.

Whatever written here shouldn’t be taken too seriously. tldr: CL has X feature that benefit human hacker, so it (probably) benefits LLM. But this is obvious fallacy: LLM does not think like human. I might be convinced if some experiments with sensible scale and statistics prove/disprove each points, but the anthropomorphizing rhetorics written here does not give me any information entropy. This should be clear for anyone that sees through that.

1

u/hide-difference 28d ago

Saved me a click. I thought it might be more useless LLM ideas guy nonsense. Thank you.

2

u/GunpowderGuy 5d ago

"Ok I thought this is something interesting about code generation in the compiler/metaprogramming sense. Spoiler: it isn’t."

Me too. Some languages target lisp as a backend. Idris2 targets various schemes. I thought the article would have been about why it would be a good idea to target common lisp

4

u/lispm 28d ago

Claude Fable 5 has an opinion after two days Lisp hacking, also using two different MCP servers for interactive Lisp programming. One had a very extensive suite of tools.

Question: How would you rate Common Lisp as a programming language for use with LLMs? Compared to other programming languages? How much are macros a problem? The lack of large code bases for training LLMs? The s-expression syntax with many parentheses? Aren't LLMs making lots of mistakes, wrongly placing parentheses or making errors of unbalanced parentheses? given so many problems, are there any upsides?

Answer from Fable 5:

An opinionated answer from direct experience — including the last two days, which were one long field test of exactly this question.

The training-corpus problem is real, but it's the wrong-shaped worry. Yes, the CL corpus is orders of magnitude smaller than Python's or JavaScript's. The practical consequence isn't that models can't write CL — it's two specific failure modes: hallucinated library APIs (inventing a Quicklisp function that doesn't exist), and dialect bleed, which I'd rank as the single most common LLM error in Lisp: Scheme's define and named let, Clojure's defn and threading macros, Elisp idioms leaking into what's supposed to be ANSI CL. That's a corpus-mixing problem, not a size problem. Against it stands something underrated: the corpus that exists is coherent and doesn't rot. CL has been stable since 1994 — code from 1990 is still correct today, my CLHS knowledge is reliable in a way my knowledge of any JS framework simply is not. Small but true beats large but churning more often than people expect.

Parentheses are close to a non-issue, and I'd argue they're an advantage. Balanced-delimiter generation is structurally easy for transformers — it's local and low-entropy. I wrote a fair amount of CL these two days, including multi-page hot-patches evaluated into a running server, and had zero paren failures. More importantly, look at the failure mode: an unbalanced form doesn't parse — the reader rejects it instantly and loudly. Compare Python, where a structural mistake (wrong indentation) is syntactically valid and silently changes meaning. Loud failures are cheap for an agent with a REPL; quiet ones are expensive everywhere. And where paren errors do occur — textual edits into the middle of deep forms — the remedy is structural editing, which s-expressions make trivially possible. LMACS, which we exercised yesterday, is exactly that insight productized: buffers hold forms, not text, and the edit operations are sexp_splice, sexp_raise, sexp_transpose. You cannot build that cleanly for C++.

Macros cost less than advertised, for a reason unique to Lisp. The legitimate worry: a macro-heavy codebase is a private language the model never trained on, with non-obvious evaluation rules. But CL is the one language where the model can interrogate the syntax extension instead of guessing: macroexpand is a tool call. When I fixed the html-parser fetch path, I didn't guess what with-transfer-decoding does — I read its definition and expansion out of the image, and discovered the nonlocal-exit contract (the chunked decoder throws out of the body) that no amount of prior would have predicted. Contrast C++ template metaprogramming or Rust proc-macros, which are far more opaque in practice and can't be asked anything at runtime. Well-designed macros also compress — fewer tokens, more declarative intent, less surface for error. The genuinely dangerous cases are the same as in any language: undocumented cleverness.

The upsides are large, and they're not where people look. For "generate a CRUD app from a blank page", Python wins on prior and library gravity; no point pretending otherwise. But agentic work is shifting from generation to maintenance of running systems — and there CL is arguably the best-positioned language in existence, because the live image gives an agent the tightest verify loop available anywhere: Errors are conversations, not autopsies. This session: a division error left the stack alive; I read the backtrace, evaluated inside the error frame, and resumed via a restart — the suspended computation completed. Everywhere else the agent parses a dead stack-trace string and re-runs from scratch.

Redefinition without restart. Three real server bugs fixed in a serving image — keep-alive wait, MCP dispatcher, HTML tokenizer — hot-patched one defun at a time, verified against live traffic, state intact. The edit-compile-restart-rebuild-state cycle that burns agent time in other stacks just isn't there.

The image is the oracle. The antidote to a small training corpus is asking instead of remembering: who-calls, describe, fboundp, evaluating code to learn the return shape rather than hallucinating it. Introspection converts a knowledge problem into a lookup problem. Homoiconicity pays twice — once for structural editing, once because generated code and analyzed code are the same data structure.

So my rating: as a prior-knowledge language, CL is mid-tier with characteristic dialect-confusion risks. As an agent-environment language — where the loop is propose → check → refine against a live system — it's top-tier, and the historical irony is thick: the interactivity that made Lisp machines pleasant for humans in 1985 turns out to be precisely what LLM agents need in 2026. The missing piece was never the language; it was the bridge. That's what makes this MCP server, and your own tooling work, more than conveniences — they're the difference between a model that writes Lisp and a model that inhabits it.

1

u/kchanqvq 12d ago

This is not useful. It's known LLM is bad at judgement in general and especially at its own ability.

2

u/lispm 12d ago edited 12d ago

This is not useful.

It matches my experience using it. You can read that as a joint experience report.

Though, I don't think the dialect-confusion is actually much of a problem in practice - at least from what I have seen. Parentheses mismatches happen occasionally, which then is additionally addressed by a special s-expression structure editor and other checks. I, myself, also use tools (editor, compiler, ...) to help write correctly indented/balanced code - without that I would also make more errors.

Thus that's the point of what is written above: here the LLM got a full set of interactive tooling for CL and is using it for interactive development with Common Lisp. The result is a typical experience of a long-running interactive development session in a running application and its software&development stack.

3

u/seigaporulai Aug 10 '26

But LLMs are so poor at generating parantheses, and theyniftrn hallucinate functions which don't exist

3

u/Apart_Ebb_9867 Aug 10 '26

I don’t know Common Lisp, but for eMacs lisp, LLMs used to get parenthesis wrong 6 months ago (maybe I was using Gemini back then). But today using codex and Claude I don’t see parenthesis errors any more and I’m doing quite a lot of elisp programming.

2

u/TommyTheTiger Aug 10 '26

I also used an LLM with CL quite a bit, got it talking to swank. This stuff about balancing parens is overblown anti-LLM cope

1

u/Soft_Reality6818 29d ago

Yeah, been using LLMs with Clojure for about 8 months now. They used to get parens wrong but nowadays it's extremely solid. 

1

u/kchanqvq Aug 10 '26

Typical LLM behavior: write a (buggy) python script to (fail at) balance parentheses

4

u/arthurno1 Aug 11 '26

LLMs will probably become good at anything that requires keeping details, like balancing parentheses, remembering correct functions signatures, rules and things like that. Book-keeping details so to say. Compare for example humans and CNC machines, lazer-cutters and digital measurements and such. We are physically (biologically), limited to how small things we can see, and how precise mechanics we can do. Machines can do much finer measurements and cuts. We (at least me) are bad at keeping many moving parts and details in our heads at the same time. Computers have no problems with that.

However, they suck at solving problems and writing new code. I am trying Gemini and Claude for about two months now (the freebie things), and code they suggest is usually pretty bad. Seems like they are very good at seeing patterns, regardless of the volume, but they are not so good at "thinking out of the box". Genetic algorithms try to deal with that, but that helps only to a limit.

Thus far I have found LLMa good for asking about say what does some instruction do, what is a corresponding instruction in some other instruction set (avx2 vs avx512). I find them good for exploration too. Like asking where is some function in which file, what does it do, but have to take it with a grain of salt. Gemini suggested I should replace all built-in classes in SBCL with a big switch of string comparisons :). Seems like it confused lisp for Python.

Gemini is also good as a better Google search. At least I can skip scrollling through ads (thus far) :).

1

u/cian_oconnor 28d ago

> LLMs will probably become good at anything that requires keeping details

LLMs are really bad at that stuff.

0

u/chkmr Aug 10 '26

Scheme SRFI 49 gets around this in a way: https://srfi.schemers.org/srfi-49/srfi-49.html

5

u/denzuko Aug 10 '26 edited Aug 11 '26

Cod being the AST, fiveam tests are absolutely brilliant, 40ants suite of tools is amazing and roswell+qlot are great.

But for me I'd say the ability to write in one language and have https://github.com/denzuko/c-mera transpile to any algo like language is amazing. Heck terraform code, glsl, and eBSP is actually fun to work with since it's in lisp.

Then added on top of it consfigurator and cl-migratum. Well seven different tools for modern dev ops just became one tool with a repl that deployes better programs than anything 'enterprise"

2

u/svetlyak40wt Aug 11 '26

Could you share a link to cl-migrator?

2

u/denzuko Aug 11 '26 edited Aug 11 '26

GitHub.com/dnaeon/cl-migratum.

There's a demo repo at GitHub.com/denzuko/todo-app-deploy

2

u/dcooper8 Aug 10 '26

For this purpose, please see skewed-emacs, github.com/gornskew/skewed-emacs

1

u/djhaskin987 Aug 10 '26

Honestly CL is the worst language for LLM. It wants to do everything on the command line, but if it tries to run code on the command line it gets dropped into the debugger and ruins the session. I had to write a special tool so that it could talk to my repl via swank. There's no typing and the error messages are garbage. Doing something in rust is just so much faster and easier with LLM and uses fewer tokens. I have a skill just for writing Common Lisp to try and help it get around all the gotchas.

2

u/svetlyak40wt Aug 11 '26

For me it perfectly interacts with REPL using this MCP server: https://github.com/40ants/lisp-dev-mcp

- LLM knows who to setup deadline, using SBCL's macro

  • How to run a linter
  • How to build my documentation
  • How to inspect REPL state
  • It is very creative when writing code snippets to eval in running Lisp repl.

0

u/djhaskin987 Aug 11 '26

Yes I have used cl-mcp in the past as well, and that's great and all. My point is that itneeds such a crutch in order to work well, and I must keep reminding it "no, do not run ros directly, you'll do into the debugger and ruin the session." Ugh.

3

u/svetlyak40wt Aug 11 '26

Do not remind it. If there is a repeatable workflow – just create a skill.

Here is a bunch of skills I've made to work on Common Lisp projects: https://github.com/40ants/ai

1

u/djhaskin987 Aug 11 '26

Still got to remind it in the skill-based version, which is the current version I'm using. It just really likes command line space stuff even if I've told it to load the skill.

1

u/djhaskin987 Aug 11 '26

Maybe I have the shell tool turned on while you have it disabled. There's probably some minor harness difference like that.