so I got Jolt to the point where it can run Selmer now using deps.edn, nrepl works as well https://github.com/jolt-lang/examples/tree/greeter-example/greeter A really nice thing with using Janet as the runtime is that it has a pretty extensive stdlib so it's easy to map Java interop to it, Selmer uses a bunch of IO and date APIs from Java, and I got all of the plumbed so it works seamlessly, I'd like to get to the point where I can run Ring using Janet http, and connect to Postgres, so far things look pretty promising. I'm also creating specification tests as I go which is helping map out a contract for what defined behavior actually is. I'd like to get the compiler to be as much Clojure in Clojure as possible with minimal shim needed from the host, and the compiler bootstrapping itself iteratively in stages. https://github.com/jolt-lang/jolt/tree/main/test/spec if anybody wants to chat or team up to work on it, I made a #C0B8G0WB63C channel to chat about it
Compiler?
yup, I'm doing actual compiling now, although SCI is still in the loop for reference and to compile stuff like one off macros at runtime which can be cheaper than compiling
ah ok, I didn't look for 5 minutes so I kinda missed that development
the github description still says "A clojure interpreter"
oh yeah I'll need to do a pass to update the docs
the compiler part is still work in progress, I'm curious how far I can shrink Janet part of it
I was thinking I could extend deps.edn for Jolt libraries to specify C libraries they depend on in a similar way we pull in Java libraries in Clojure, and then I could create shims on top of them for Java APIs Clojure libraries use, so then I could grow the API surface to support more and more existing Clojure libraries that way
Have you found any advantage to using the Janet runtime? Like performance? I guess single binary bundles, small bundle size, embedding, and maybe smaller memory footprint?
yeah it ends up building at just 1 meg for the whole runtime, has a tiny memory footprint, and starts up in 6ms
I haven't focused on raw performance so far, so that's going to be something to explore, but for making stuff embedable or running on devices like rpi this seems like a perfect option
and Janet being somewhat similar to Clojure provide a good base with its bytecode and existing runtime
gtime -v build/greeter
Hello JOLT!
motd: deps.edn libraries running on Janet
- Selmer templates
- yogthos/config
- an nREPL you can connect an editor to
- a native executable build
Command being timed: "build/greeter"
User time (seconds): 0.11
System time (seconds): 0.00
Percent of CPU this job got: 84%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.13
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 18240
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 105
Minor (reclaiming a frame) page faults: 1190
Voluntary context switches: 4
Involuntary context switches: 76
Swaps: 0
File system inputs: 0
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 16384
Exit status: 0Ya, those small binary sizes are attractive. BB is great, but self-contained binaries still lean big-ish.
yup, and being easily embedable is really nice too
C ecosystem is also pretty vast and mature, so really anything you can do on the JVM you can do with it too for the most part, and if I can make it easy enough to wrap C libraries into the runtime, that could open up the whole ecosystem to Clojure
gotta think about how to make this repl friendly though, like maybe you build a runtime for dev with the libraries included and then start a repl on top of that for doing dev on the app, then when you package you build the whole thing
Janet doesn't have a REPL ?
well it has its own repl, but not a Clojure compatible nREPL
and I'm just thinking out loud how it would work if you make a library that depends on some C library underneath
Just pushed a new version of https://github.com/dynamic-alpha/hyper .
h/defc: write client-side web components in Clojure (Squint dialect), compiled to JS on the JVM at macro expansion without any node or build step. The server pushes data in via attributes, components emit events back that you handle with regular h/action. Supports a seamless mode (`mount`/`update`/`unmount`) so JS libs like d3 can animate data changes and survive server re-renders. REPL redefinition hot-swaps live components over SSE. Basically defc wires hyper's render cycle into cljs / js libs. Follows a syntax very similar to shadow-grove
h/expr: write Datastar expressions as Clojure instead of JS strings
Updated examples in the example app
This is very early stages but would love to see what people think of it and whether it helps power some richer client-side use cases.
Thanks for sharing, happy to see squint being put to good use
Wow, it covers quite a lot of ground. So it's a batteries-included replacement for Datastar's official clojure sdk. And squint looks like a good fit for this kind of apps with small client-side requirements. I was about (today or next week, depending on token availability) to try out Datastarβs official clojure sdk on a toy project; I think I'm going to try this instead. Looks like the opinionated defaults and additional features will help propel the project much faster.
Awesome to hear @danieljomphe - I'd say its an opinionated flavor of how some of the concepts and experiences that datastar promotes could be expressed in idiomatic feeling clojure. LLMs do quite well with it in my experience - I recommend pointing them at the readme and asking them to draft a repo local implement-hyper skill.
Feel free to join us in #C0AMQ47RABV if you have any questions along the way!