Top
Best
New

Posted by marcingas 10 hours ago

Show HN: I made a Clojure-like language in Go, boots in 7ms(github.com)
Let-go is a Clojure-like language (~90% compatible with JVM Clojure) written in pure Go. It ships as a ~10MB static binary and cold boots in ~7ms - that's about 50x faster than JVM and 3x faster than Babashka. It has decent throughput on algorithmic workloads - within ballpark of the GraalVM-backed sci.

I started this project in 2021 as an elaborate practical joke: I wanted to have an excuse for writing Clojure while pretending to write Go.

Jokes aside, it turned out to be pretty decent: it feels like real Clojure, it has an nREPL server (supported in Calva, CIDER, etc.), it's easily embeddable in your Go programs (funcs, structs and channels cross the boundary without fuss). It's good for writing CLIs, web servers, data processing scripts and even doing some systems programming - I used it to write a deamonless container runtime. Oh, and it runs on Plan9.

Under the hood there is a fairly simple compiler and a stack VM, both handcrafted specifically for running Clojure-like code. The compiler can work in AOT mode producing portable bytecode blobs and standalone binaries (runtime+bytecode).

This is not a drop-in replacement for Clojure in general - it does not load JARs, it does not have all Java APIs and it most probably won't run your exiting Clojure projects without modifications. At least not at the moment.

Take it for a spin, tell me what you think. Issues and PRs are welcome!

119 points | 37 comments
veqq 1 hour ago|
Nice! I recently played around with a Lisp syntax for Go semantics: https://codeberg.org/veqq/Joe

As far as JVM-free Clojure-like, Janet is really nice. I've been using it in production for a while: https://janet-lang.org/ There's also Fennel if you want the Lua vm and libraries.

marcingas 1 hour ago|
Thanks! Joe looks good! As for Janet - never tried it myself but I always thought it's doing its own thing instead of trying to be Clojure.
boguscoder 48 minutes ago||
Micro nit: it says 7ms cold start and then 6ms just few lines lower.. maybe it gets faster as you read README
ingy 5 hours ago||
Try out this Wasm browser REPL https://gloathub.org/repl/

Gloat is a Glojure AOT automation tool. I worked with James Hamlin to get Glojure AOT going last summer and have been moving it forward since. I've also been working with marcingas (nooga) to get Gloat/Glojure/let-go all cooperating.

bjconlan 5 hours ago||
This is the kind of clojure port that I always was looking for. Mostly because I thought go's core library and channels abstractions hits a simpler/nicer base API which would with the core & async apis (not to mention scratches my big beautiful binary itch)

Thanks for your work will definitely check it out again once I get over renewed love for cpp (26)

Edit how did glojure go under my radar also a great project from the looks

giancarlostoro 5 hours ago||
I have played with the idea of making a “old school PHP” style DSL that takes advantage of the Go runtime and packages under the cover. I say old school PHP because PHP used to be a web focused DSL its no longer the case, I feel like it would make for an interesting easy to use backend language similar to PHP but with the full power of Go behind it. Clojure is an excellent choice.
marcingas 5 hours ago||
Thanks for kind words! Please don't forget to drop me an issue or two when you eventually get to it :)
faangguyindia 2 hours ago||
I am finding i need "Rails" but i like single binary deployment of Go and fast/low resource usage like Go.

Is it possible for now?

marcingas 2 hours ago|
I think you could make a framework on top of this. It doesn't yet run unmodified Clojure libs like hiccup but it wouldn't be hard to roll something relatively simple and solid in let-go. IMO
chr15m 4 hours ago||
PR most welcome for https://github.com/chr15m/awesome-clojure-likes
marcingas 4 hours ago|
Added https://github.com/chr15m/awesome-clojure-likes/pull/27 Thanks for letting me know :)
dmitrygr 6 hours ago||
You should see how fast libc gets mmaped() into the VM and the first instr runs :)
marcingas 5 hours ago|
Sure, I should clarify: The 7ms here is measured at the point where let-go starts executing user code. It takes 7ms to initialize the compiler, load all stdlib namespaces and compute all vars. So it's not "time to first instruction", it's "time to running your code".
brazukadev 5 hours ago||
do you know about Glojure?

https://github.com/glojurelang/glojure

marcingas 5 hours ago||
Yes, I know about this one. I'm even comparing against it in my benchmarks :)
rcarmo 1 hour ago||
You need to update the go-joker numbers, I removed the GIL yesterday or so and did some changes to the IR. ;)
marcingas 1 hour ago||
I think I've pulled the latest today but will double-check and update them again tomorrow. I'm still puzzled why it doesn't run the tak function. Btw. Have you tried running my benches? I'm very curious about your results!
ingy 5 hours ago||
https://github.com/gloathub/glojure is the actively maintained fork.
More comments...