Claude Code interagissant avec une boucle REPL Common Lisp active (y compris dans Emacs)



Tags : #claude-code #commonlisp #emacs #sbcl

Créé le 28 juin 2026.

Claude Code est susceptible de lancer un processus nouveau pour chaque commande qu’il exécute. Raisonnable pour la plupart des langages, mais mal adapté à Common Lisp, dont l’un des avantages tient dans une image permanente que l’on fait croître fonction après fonction, instruction après instruction. Relancer SBCL à chaque étape réduit à néant ce qui fait la puissance de la boucle REPL (Read-Eval-Print Loop) de Lisp.

Plutôt que de laisser Claude démarrer ses propres processus jetables, branchons-le sur une boucle REPL, la même image en cours d’exécution que celle dans laquelle nous travaillons. Claude y définit alors des fonctions, charge des fichiers et lance des tests sur une image active ; nous voyons les résultats apparaître, et pouvons aussi entrer des instructions nous-mêmes.

Les instructions sont proposées dans le dépôt claude-lisp-repl, qui ne contient presque pas de code. C’est essentiellement un jeu de prompts : on en propose un à Claude pour mettre en place le REPL partagé, puis on lui parle en langage naturel à partir de ce moment, tout en pouvant toujours entrer des instructions manuellement dans le REPL partagé si on le souhaite.

L’approche la plus simple ne nécessite pas Emacs, mais juste une session tmux. On l’explique à Claude, une fois :

Launch SBCL inside a detached tmux session named lisp.
The user may be interacting with the lisp image through the REPL on
its own, independently from you.
In our future interactions, "stage" instructions would mean send instructions to the REPL without executing them (no 'Enter').

Dès lors, Claude pilote l’image via tmux send-keys et la relit via tmux capture-pane. Nous pouvons la retrouver quand bon nous semble avec tmux attach -t lisp et détacher par C-b d.

Une première interaction : « Create a foo function which doubles its argument. Apply it to 45. Stage (foo 15). » :

Une session SBCL dans tmux : foo définie, (foo 45) renvoie 90, et (foo 15) laissée en attente au prompt

Chaque ligne de cette capture a été tapée par Claude seul.

Charger un fichier fonctionne de façon similaire: « In test.lisp, create a bar function which squares its argument. Load it in the image and apply it to 11. » :

La même session : test.lisp chargé et renvoyant T, puis (bar 11) renvoyant 121

Pour celles et ceux qui préféreraient ne pas quitter Emacs, deux autres méthodes proposées dans le dépôt font tout passer par SLIME au lieu du tmux:
(i) l’une où swank tourne dans une image tmux à laquelle Emacs se connecte par une socket,
(ii) l’autre où Emacs lance d’abord lui-même l’image, par exemple avec M-x slime.

Même image et même REPL partagé pour Claude et l’utilisateur :

Un REPL SLIME : foo définie, (foo 45) renvoie 90, et (foo 15) en attente au prompt CL-USER