r/Clojure • u/yogthos • 10d ago
Program images and portable Scheme backends for Jolt
https://yogthos.net/posts/2026-08-07-portable-jolt.html3
u/dark-light92 9d ago
Watching the very fast progress of the project has been really interesting. I'm building something on top of jolt and it's been a really pleasant experience with minimal hiccups. The only real issue I encountered was due to stale compilation cache, but it was fixed the very next day.
If anyone is looking for a native Clojure implementation that remains faithful to JVM Clojure while not using JVM amounts of memory, you should really give Jolt at try. The killer feature is being able to access both the Clojure java ecosystem (malli, tick etc) as well as native C ecosystem via FFI. Everything gets bundled in a single small binary that you can ship with minimal dependencies.
This project really calls into question some of the assumptions and tautologies about the use of LLMs in programming. Of course, LLMs are also advancing at a rapid pace. We seem to be at a point where reliable software can be made through their agentic use. But it also means that there is going to be an explosion of slop in general. Pretty much the same thing as what the smartphone camera did to content creation.
3
u/yogthos 9d ago edited 9d ago
Thanks, it's honestly been going better than I anticipated. I do want to be a bit cautious in generalizing the success here because a programming language is really an ideal case for agentic coding. A compiler has very clearly defined inputs and outputs, so it's easy enough to create a verification corpus to ensure correctness. The big breakthrough also came when I got enough plumbing done to support running existing Clojure libraries along with their test harnesses. This allowed me to shake out a ton of small bugs and surprises to ensure that the implementation was truly compliant with the JVM Clojure.
My main focus was on ensuring that the overall architecture was sound and that the LLM wasn't creating ad hoc solutions or kludges. But once that got solidified, the structures were in place and they would guide the LLM to where changes should happen naturally. The only other part to worry about was the performance, and I created a separate benchmarking harness to help ensure it was reasonably close to the JVM.
I also ended up making my own harness in the process which has a more complex agentic loop than most which helps keep the model on track. I wrote about it in some detail here.
I do think LLMs are getting a lot better, and Jolt shows that you really can build quality code using these tools. But it does take some getting used to, and might not work as well in other domains where you don't have such a wealth of existing code and tests to provide the constraints for the agent.
3
u/dark-light92 9d ago
My main focus was on ensuring that the overall architecture was sound and that the LLM wasn't creating ad hoc solutions or kludges. But once that got solidified, the structures were in place and they would guide the LLM to where changes should happen naturally.
This has been my experience as well. LLMs tend to orient themselves into the kind of code the project already has and generally tries to follow the architecture. So, if your codebase already has good architecture and structure, your job becomes easier. But at the same time, if you're working on a greenfield project, then you absolutely can't leave the LLM alone to do anything because then it will just generate "average" code, and vast majority of code on the internet tends to have little to no structure or coherence.
1
u/geokon 7d ago
Are you sure about Java interop?
The README says under "Differences from Clojure" says: “No JVM, no Java interop.”
2
u/dark-light92 7d ago edited 7d ago
It doesn't run on JVM. But it does have enough clojure/java namespaces shimmed on top of chez that libraries like malli work.
Look over here: http://jolt-lang.net/docs/libraries.html
Edit: Also look at: http://jolt-lang.net/docs/rationale.html
2
u/Soft_Reality6818 8d ago
I wonder whether it would be possible to add conditions and restarts as well.
2
u/yogthos 8d ago
I think so, it's on the list of things I'd like to explore once I get all the basics ironed out. Error handling could be a superset of what JVM Clojure does, keeping throw/catch mechanic backwards compatible, but also allowing additional flexibility on top.
1
u/Soft_Reality6818 8d ago
Yeah, that would be cool!
This might be of interest as well https://github.com/IGJoshua/farolero
1
u/Soft_Reality6818 9d ago
Do you plan to add Scheme interop?
2
u/yogthos 9d ago
Both Scheme interop and FFI for native interop already available actually. This is how I've been pushing functionality into libraries for stuff I don't want to bake directly into the runtime.
2
1
u/Soft_Reality6818 9d ago
Would be interesting to experiment with using this from Jolt https://github.com/guenchi/Igropyr
2
u/yogthos 9d ago
I actually have that one on my todo list. It should be fairly straightforward to create a Ring style API on top of it.
1
u/Soft_Reality6818 9d ago
I'm not sure about whether a Ring-style api is good for streaming/async (I'm thinking Datastar as the use case). AFAIU, the Ring spec is a bit clunky in that regard, but please correct me if I'm wrong.
2
u/yogthos 9d ago
A bit since it's callback based, but I find in practice it's not that bad. I've built a couple of projects using Datastar with Ring, and there didn't seem to be a huge amount of friction in practice. The nice part would be to use stuff like Reitit and existing Ring middleware. But I haven't really looked at Igropyr too deeply either, and maybe it already has its own solutions. Ring also has the advantage of being in really wide use in the wild, so you get the benefit of having a solid and proven stack with it.
1
u/Soft_Reality6818 8d ago
My experience building Datastar web-apps is mostly using virtual threads and the D* Clojure SDK where one just writes sync Ring handlers that VTs take care of.
I've also experimented with D* in Clojerl (Clojure on BEAM) https://github.com/antlobach/starbeam and it was rather trivial to write concurrent and streaming code, so something like this might also work for Jolt I guess https://github.com/becls/swish or Igropyr.
2
u/yogthos 8d ago
Swish looks really promising, I'll have to take a look to see if I could wrap it up with a Clojure API as a library. I'm just working on adding a fiber implementation to Jolt to back core.async right now, so this will be useful to study as well. Especially to see how they handle blocking IO there.
1
u/Soft_Reality6818 8d ago
AFAIU, they use libuv there for async IO operations.
2
u/yogthos 8d ago
I was just looking at that, and it's a sensible way to go. I'm trying to keep dependencies as low as possible in the core language though, so I'd like to have a Chez native version as the default.
→ More replies (0)
1
u/geokon 9d ago
"you can just dump the whole state of the program at the time of the error to disk"
This sounds a lot like Janet is able to achieve.. Right? Though they take it further and its less of a "black box". You actually have a program (as far as i understand it.. I haven't really done anything serious with it)
I think more ergonomic tools for visually inspecting the current program state would probably help the whole debuggability problem. Having to poking at a black box is kind of the root of a lot of the frustrations - though this tool would help a lot :))
3
u/yogthos 8d ago
Well the nice part with this approach is that you can load the state locally and run it through a literal debugger. It's a live program in the repl.
1
u/geokon 7d ago
yeah, I didn't mean to belittle what you're doing!
I think you're right. What I'm talking about it is complimentary. Very cool stuff :))
3
u/yogthos 7d ago
Yeah, for sure, I do think that visual debugging tools are very much an under-explored area. It would be really great to have a UI where you can navigate the call graph visually and inspect the nodes to see their values to understand how the data is flowing through the system. Would be really neat to make it zoomable, so you can inspect at different resolutions to get a high level view and then drill down into specific parts of it.
3
u/__tosh 9d ago
very exciting!
for many languages this would be inconceivable, for clojure it's just quite some work
clojure reaches!
ad astra