Today you don't even need to use clojure-mcp for balanced editing. The models do a perfectly fine job.
This was true with gpt-3.5, but things have moved on, dude !
It's like asking 'do movies have sound now?'. The answer is Yes, not just sound, but also color !
I'm the first one to admit my ignorance when it comes to LLM capabilities. Hence the honest question.
Clojure / ClojureScript codebase
This doesn't exactly mean immutable data structures are mandatory, but it helps.
In any case, most of the functions that operate on data structures in Lisp (or Common Lisp) do it in an immutable way.
Is this really a problem with agentic programming? I have done some pretty complex tasks with it and I never thought "this would go a lot faster if the compilation speeds weren't slow." Seems like the time Claude takes dwarfs any build time.
I am not working on 1M+ LOC codebases though, so I could see how slow compilation times could be a problem then, but I imagine the agentic part would also slow down.
State management is generally considered a difficult and complex problem. When you give a way for the agent (or a human programmer) to iterate on stuff without having to reset the state, without having to restart anything, without any (manifestly impractical) rituals, the programmer/agent stops guessing and starts empirically assessing the current state of things and reasoning about the problem space in a much tighter loop, procuring solutions that cost fewer tokens, time and effort.
Imagine building something like a Flappy Bird game, and having to recompile whenever you tweak a moving object's trajectory calculation. What would be simpler - having the programmer mess around with values live, or having to re-compile, restart, reset the state to that point, and check where things stand?
Programming with a Lisp REPL often feels like playing a video game. It's not just fun, it makes far better sense (in comparison)
> programmer/agent stops guessing
I think programmers and agents are fundamentally different, and require different approaches. I don't see the benefits to an agent avoiding recompilation when they may take 30+ minutes on a couple prompts. I don't think compilation time even accounts for 1% of what my agents do, but I could be wrong (again, I'm not working on something massive).
I also don't think I want them to assume they solved something because the current image is working as intended. I don't really trust them to know if they have a working solution, or if they have built up a very specific state that works, but can't get the same solution from scratch.
Also I feel more comfortable doing localized tests through the REPL than letting an agent do it. I would need some kind of test suite or harness to check a bigger trail of behavior than let it assume a problem was fixed. But I doubt this will be a problem for long
It's not so much about time, I think you're missing the point. It's more about "staying in the flow" and in this regard, humans and agents are not much different.
Besides, you're just ignoring the main talking point of my comment - the state. Have you ever had to restore the exact state of things in an app, when you're manipulating and changing certain behavior of it, in a specific moment and a specific combination of values? When you need to re-compile and re-load things, you inevitably end up building some elaborate scripting scaffold, just to deal with these kinds of scenarios. Live image REPLs remove that problem as a class. Immutability by default simplifies it even further.
> I don't really trust them to know if they have a working solution
Well, the agent can prove it by simply evaluating things live. But of course, it's never guaranteed to work the same way when started from scratch, but I'm not saying the behavior shouldn't be tested either way.
They are absolutely different. An LLM can be paused and pick back up in the exact same place. It makes no difference if compilation take a second or an hour. A human has to remember what they were doing. That's what people talk about when they mention flow state.
> Besides, you're just ignoring the main talking point of my comment - the state
I don't think I ignored that, I talk about it directly. I said it could conceivably lead to more problems because the LLM could overly lean on live evaluation as context degrades. I would feel more comfortable with it in an immutable language.
In my own Clojure projects I now even included that as part of the app. I literally have a header (I'm working on webapps, with Datastar btw) with buttons to pause/rewind/forward/fast-forward through my application's states (and I can also move back/forward in time from the REPL ofc). And I can then resume from any past state/inspect any past state from the REPL, save any state, etc.
I used to do it in the past with re-frame and events replayed but it was, IMO, a bit complicated for my needs. I now much prefer to have it all on the server-side and I simplified everything by using SSE / datastar (YMMV: for more complex needs, SSE may be insufficient).
Everything is immutable/functional except for one atom that contains the app's state. And that one is basically both a DB and a DB of all previous states.
I haven't done the full undo/redo as a tree yet (say like Emacs' undo/redo does) but it's been modeled to allow it. So I'll add that "navigation into past app state as a tree" (i.e. when I when backward then forked the state) visualization at some point.
Immutability / functional code / determinism / the passage of time are all fascinating things to me.
And once you've got the ability to walk through time as part of you language/REPL/app, testing and debugging becomes oh-so-much easier.
P.S: and the LLM is surprisingly good at making sense of out how I modeled the passage of time and the ability to walk through time as part of the app.
Pity that the new Summer got to ride an interpreted language, with bindings to native libraries instead.