announcements

nooga 2026-05-06T23:30:41.156379Z

*let-go v1.7.0* - *λ-gophers, assemble* :hamster: Greetings friends! I've been crafting this on and off since 2021 out of pure spite and cope after I had to switch from Clojure to Go for my dayjob. The running joke was that this would make it legal to write Clojure while pretending to write Go. It's not perfect yet, but I can't hold it any longer - here it is. `let-go` is a bytecode compiler + VM for a Clojure-shaped language, shipped as a single *~10MB static binary* that cold-starts in *~7ms*. Currently the smallest and fastest-starting Clojure-family language in Go. 3x faster startup than Babashka, 2x faster than Joker, 48x faster than the JVM. The whole runtime boots inside one `requestAnimationFrame` and still has 10ms to spare at 60fps. Compute performance sometimes within 4% of Babashka, sometimes faster, sometimes slower. *Clojure compatibility:* *4696 / 4921 assertions pass (95.4%)* on the `jank-lang/clojure-test-suite` across 217 files. It won't run your existing Clojure project unmodified yet, but day-to-day idiomatic code reads, writes, and behaves the same - macros, destructuring, lazy seqs, transducers, protocols/records/multimethods, persistent maps & vectors, atoms, regex, BigInts, you name it. *The good stuff:* • `core.async` running on actual goroutines (no IOC state machine) • standard namespaces: `clojure.string`, `set`, `walk`, `edn`, `pprint`, `test`, `core.async`, plus `io`, `http`, `json`, `transit`, `os` • *Babashka pods* support - shares the `~/.babashka/pods` cache, `bb` installs, `lg` runs • `syscall` namespace - yes, you can write a container runtime in Clojure now • `lg` → REPL with syntax highlight and completions, `lg -n -p 2137`→ nREPL server for your favorite Emacs • `lg -c myapp.lgb main.lg` → portable bytecode blob • `lg -b myapp main.lg` → standalone binary • `lg -w outdir main.lg` → self-contained WASM web app with xterm.js terminal • Embeddable in Go: Go structs roundtrip as records, Go channels are first-class let-go channels, Go funcs are callable from let-go and vice versa *Real fun projects written in let-go:* • *Xs of Y -* a roguelike that runs in the browser *and* the terminal from the same lispy source: <https://github.com/nooga/xsofy> • *lgcr* - a decent daemonless container runtime for MacOS and Linux: <https://github.com/nooga/lgcr> *Try it online (WASM REPL):* <https://nooga.github.io/let-go/> *Install:* see GH README *Repo*: <https://github.com/nooga/let-go> Caveats, for now: no STM/refs/agents, sorted collections incomplete, no BigDecimal rounding, no `reify`/`deftype`, regex is Go flavor (re2), numeric overflow wraps silently. Full list in the README. Feedback, :star: s, issues, and PRs warmly welcomed. Join me at <#C04DCFZKPJN|let-go> :bread:

11
🤯 27
🔥 8
9
🙌 7
🙌🏼 1
🎉 51
Steven Lombardi 2026-05-07T00:24:50.865349Z

Holy moly that's nuts. Congrats on the release.

🙏 1
2026-05-07T06:23:34.779789Z

Cool, seems like go is quite the popular target ^^ How does this compare to #gloat?

pez 2026-05-07T06:26:21.541299Z

Firing up a let-go REPL in Calva.

4
🎉 3
pez 2026-05-07T06:27:10.751279Z

Major congrats on the release, @xnooga! 🎉 Totally mind-blowing work.

🙏 1
pez 2026-05-07T06:30:45.768319Z

For that demo clip I wanted to do something the equivalent of (System/getProperty "babashka.version"). Is there?

borkdude 2026-05-07T06:57:48.666929Z

Congrats writing Clojure at work again!

4
😁 1
😂 2
borkdude 2026-05-07T07:23:23.849839Z

It seems we have a revival of Clojure on Go going on this year https://rcarmo.github.io/projects/go-joker/

😮 3
nooga 2026-05-07T07:36:12.329649Z

I was totally unaware of this one!

nooga 2026-05-07T07:36:46.587519Z

need to benchmark against it - I might not be the fastest go impl 🤔

borkdude 2026-05-07T07:45:20.868799Z

the loop example I tend to use for bb:

bb -e "(time (let [x 0 j 10000000] (loop [i 0 j 10000000] (if (zero? j) i (recur (inc i) (dec j))))))"
runs almost as fast on go-joker than JVM Clojure now (around 5-9ms, it's impressive)

👀 1
borkdude 2026-05-07T07:47:32.741339Z

it remains to be seen how compatible go-clojure is when tested with the jank suite though

nooga 2026-05-07T08:14:26.442529Z

@pez added

1
pez 2026-05-07T08:33:27.033899Z

Updated Calva jack-in demo. Feel free to use in docs or wherever, @xnooga. I know I will 😃

❤️ 1
🙏 1
nooga 2026-05-07T08:39:46.106139Z

I'll reshare this on LI, thank you!!

🤘 1
borkdude 2026-05-07T08:51:38.825759Z

I remember when LI was a very boring thing where people just sent me messages to connect, usually recruiters. Somehow a lot of people fled from Twitter etc to there which now makes it the places where all my relatives, professional colleagues from the past and other people hang out.

👆 2
🤘 1
nooga 2026-05-07T09:05:39.608419Z

@borkdude re perf - spoils of a mature WASM JIT target 😄 I ran your one liner on lg and it clocks 3x slower than bb- spoils of GraalVM 😉 go-joker seems to rip through loop-recur but folds under deep recursion and reductions. It crashes on my fib, tak and transduce benches. I think my main goal was never some stellar compute perf - there is only so much that can be done without an optimizing JIT, which would be veeeery impractical in Go. I think tiny footprint and fastest possible boot are still pretty cool though 😁

borkdude 2026-05-07T09:06:38.104789Z

> 3x slower than bb- spoils of GraalVM it's faster on a normal JVM ;)

borkdude 2026-05-07T09:08:40.179799Z

oh yes, I didn't mean to take away any of the joy of your announcement, I was just triggered by Snuffle's remark that go is quite a popular target for Clojure now it seems. performance isn't always the most important bit. it's cool that you support babashka pods. my mind immediately went: what if we can use let-go to build a standalone pod-as-binary instead of go itself, that would be cool too, then we can still use clojure

🙌 1
nooga 2026-05-07T09:10:29.084029Z

definitely something I'd like to try out!

borkdude 2026-05-07T09:11:14.494539Z

it's quite easy to build standalone executables using the binary-blob+zip-file approach. bb uses this too.

vanelsas 2026-05-07T09:16:18.470009Z

@borkdude is LinkedIn now the new (old) Facebook for you?

borkdude 2026-05-07T09:17:00.065989Z

I guess so, except that people talk more about their work there than their vacations

borkdude 2026-05-07T09:17:19.411169Z

at least I can send people a DM when I need to, that's how I usually use it

vanelsas 2026-05-07T09:20:20.805919Z

I ditched FB, twitter and every other social network a long time ago. I still have LinkedIn, but zero notifications. It is such a spam machine, but for work it is sometimes difficult to get around it. Right now I am considering picking up my old Nokia 3310 again as I'm also getting flooded with whatsapp messages.

👍 1
borkdude 2026-05-07T09:20:21.334719Z

I still tend to not post much on LI compared to mastodon/bsky/twitter

borkdude 2026-05-07T09:21:31.829309Z

I know someone who only has a dumb phone and not even a computer at home. He's ahead of the times!

vanelsas 2026-05-07T09:42:54.768929Z

the only reason I haven't done it yet is because my kids hate it if they cannot chat with me like that. But in honesty, I'm perfectly happy having a dumb phone

nooga 2026-05-07T09:44:48.759709Z

that's a luxury :d

knotschi 2026-05-07T09:57:59.959049Z

wow, nice work! there is also https://github.com/glojurelang/glojure but not sure how it compares?

👍 1
borkdude 2026-05-07T10:00:26.798329Z

I think we now have joker + the above mentioned fork glojure + gloat(?) as a fork let-go

nooga 2026-05-07T10:04:13.036809Z

@knotschi it seems that let-go is the smallest and fastest booting, it's also much faster than joker and glojure while using less memory. It's not as complete as the gloat fork of glojure though.

👍 1
pez 2026-05-07T10:05:14.320309Z

Are #joker and go-joker different things?

borkdude 2026-05-07T10:06:02.186859Z

go-joker is a fork with performance enhancements

👍 2
nooga 2026-05-07T10:06:25.275639Z

it seems that @rcarmo forked joker and used its frontend to make a compiler targetting a WASM VM

borkdude 2026-05-07T10:06:27.033409Z

https://mastodon.social/@rcarmo/116529391628857007

nooga 2026-05-07T10:08:13.851529Z

ah, it landed just yesterday? 😄

borkdude 2026-05-07T10:08:38.730169Z

it's in the air

nooga 2026-05-07T10:16:16.246099Z

it's funny how everyone is making their own clojure in Go and nobody seems to know about the others 😄

nooga 2026-05-07T10:16:29.808209Z

the lisp curse v2

😄 5
borkdude 2026-05-07T10:17:48.932379Z

I guess LLM plays a role in this too, lisp curse on steroids

💯 1
pez 2026-05-07T10:18:20.453619Z

I beginning to think that Clojure will win the mainstream by totally obliterating in the reach category.

😁 1
nooga 2026-05-07T10:18:35.294459Z

I was aware of joker and later became aware of glojure, but the goal was to improve on Joker's performance and design while having some fun

😍 2
henrik 2026-05-07T10:20:45.795249Z

Just saturate every language with a Clojure implementation until that becomes the obvious interface for LLMs regardless of runtime. The vibe coders won't even know it happened.

😁 6
nooga 2026-05-07T10:21:12.279299Z

I think it's cool though! more people should write lisps and Clojure is the nicest (IMO) 😄

borkdude 2026-05-07T10:22:39.574969Z

People working on other languages don't know why their LLM wants to build nREPL integration and an embedded clojure runtime, but it really wants to

3
borkdude 2026-05-07T10:23:36.141289Z

"ok, let me build clojure + nrepl layer now for your language". <enter>

nooga 2026-05-07T10:24:27.151189Z

> $20k bill from Anthropic

borkdude 2026-05-07T10:24:55.704549Z

worth it

💯 3
pez 2026-05-07T10:29:57.551909Z

My Rust-y Agical colleague is building a static site builder (a super interesting one, but that’s for another story). It’s now Hiccup all over and a growing Clojure implementation for config. There’s a REPL that Calva is happy to talk to. OK, part is that we’re colleagues and I go on and on about data and Hiccup. But I actually think that Claude has something to do with the going-all-in of it.

p-himik 2026-05-07T12:21:06.080629Z

After all, Clojure is just a library you or your LLM can add to the dependencies of your project. ;)

jussi 2026-05-13T11:57:22.213599Z

So we have now evolved from writing every algorithm naively by ourselves into writing our own implementation of our favourite language? 😅

nooga 2026-05-13T12:05:49.387729Z

I only picked Clojure because I thought long and hard and could not come up with a better language, existing or imaginary

nooga 2026-05-13T12:06:41.527089Z

but langs are my thing kind of, I've been writing small interpreters and compilers for 20 years, now I can make them useful for others instead of being just toys

henrik 2026-05-13T12:08:57.074289Z

In the optimal language, you just require the LLM lib and run it, and it’ll be whatever app you need at that moment.

p-himik 2026-05-13T12:10:21.820119Z

The good old "Make Everything Perfect" button. :)

borkdude 2026-05-13T12:10:48.131029Z

LLM: you get only three wishes.

nooga 2026-05-13T12:11:58.293859Z

you know what, I've made this cool macro once:

(defyolo fetch-tweets [n & tags] 
  "fetch n latest tweets from twitter API tagged with tags") 
it prompts the LLM to write the function body and caches it, you can then call (fetch-tweets 10 "#foo") and see if it worked

🤣 1
nooga 2026-05-13T12:12:17.519039Z

works nice in a REPL 😂

henrik 2026-05-13T12:12:58.444049Z

“For my first wish, I want infinite wishes” “No, that’s against the genie rules” “OK, then I want infinite genies. Also takes care of my second wish: more friends”

borkdude 2026-05-13T12:13:09.416049Z

what if we took only clojure's stdlib with docstrings and then let an LLM one shot JVM Clojure

🧠 1
nooga 2026-05-13T12:13:42.533459Z

I don't think that would work really well based on how much gymnastics it took to get let-go stdlib going 😄

borkdude 2026-05-13T12:13:46.248189Z

the problem, it probably already knows clojure

nooga 2026-05-13T12:14:12.723609Z

by now it probably does, although I've noticed it has huge problems with idiomatic code, both claude and gpt

borkdude 2026-05-13T12:14:19.283099Z

but it would maybe a good test to see how good the docstrings are

nooga 2026-05-13T12:15:59.366599Z

they don't like destructuring, avoid threading macros, overly defensive agains nil, tend to generate long ass let-s and defns mixed with ifs etc.

borkdude 2026-05-13T12:18:15.611639Z

and (boolean something) while it's completely unnecessary

☝️ 1
Daniel Slutsky 2026-05-06T01:04:31.672489Z

https://scicloj.github.io/zulipdata/ is a new small library for pulling and analyzing data from the https://clojurians.zulipchat.com/. Alpha stage, current version 0.1.1.

🆒 6
whilo 2026-05-06T01:45:17.505159Z

*rechentafel 0.1.x — pure-Clojure spreadsheet interpreter* Hi all — first public cut of org.replikativ/rechentafel is on Clojars. A pure-Clojure formula engine: parser, per-cell dependency graph, incremental recalc, ~270 functions, Excel 365 dynamic arrays + LET / LAMBDA, structured table refs, 3D refs. No POI, no LibreOffice, no native deps at runtime. - *Cross-platform*: same .cljc source on JVM and Node/browser cljs - *Persistent*: workbook is an immutable value — set-cell shares structure with the parent, so forking is cheap - *Seedable PRNG*: (assoc wb :rng-seed N) makes RAND/RANDARRAY deterministic - *Optional .xlsx I/O* under the :poi alias (load + dynamic-array round-trip) Verified against POI and LibreOffice on a benchmark suite. ~70× faster than headless LibreOffice on the 10k-cell shapes. GitHub: <https://github.com/replikativ/rechentafel> Feedback / issues / Excel quirks you've hit very welcome.

🆒 3
👀 6
🎉 6
mkvlr 2026-05-06T04:07:19.571979Z

congrats on the release. The library can only read excel files but can’t write them, is that correct?

whilo 2026-05-06T04:39:31.102939Z

It can also write them through Apache POI. Its focus is on the interpreter so far, not storage formats.

👍 1
mkvlr 2026-05-06T04:46:27.354939Z

that’s what we currently use (through docjure)

whilo 2026-05-06T04:51:11.473469Z

Cool! Maybe it would be also reasonable to implement the file format reading and writing in Clojure/Script, I mainly saw that POI does not have comprehensive Excel support and that it would be better to have a cross-platform implementation of the semantics with persistent memory support.

seancorfield 2026-05-06T04:15:23.962279Z

https://github.com/clj-holmes/clj-watson https://github.com/clj-holmes/clj-watson/releases/tag/v6.1.0 -- A Clojure tool that checks for vulnerable dependencies Major release, with a huge amount of work done by @lee -- thank you! Updated to DependencyCheck 12.2.2. • Check dependencies via classpath (separately from deps.edn), inspired by https://github.com/clj-holmes/clj-watson/issues/152, as a way to use clj-watson in contexts where deps.edn is not available or not the primary source of dependencies, e.g., Leiningen projects. • Docs ◦ [OSS Index now requires credentials](README.md#oss-index-configuration), and has migrated to Sonatype Guide; see https://github.com/clj-holmes/clj-watson/issues/133 ◦ Review and freshen docs • Fix references to clj-watson.properties file in the documentation via PR https://github.com/clj-holmes/clj-watson/pull/130 from https://github.com/samumbach. • Update DependencyCheck settings reporting https://github.com/clj-holmes/clj-watson/issues/141 ◦ generalized occluding of sensitive values ◦ show properties filenames and counts of properties ◦ added unit tests • Command line parsing review and fixes https://github.com/clj-holmes/clj-watson/issues/137 ◦ -X/-T exec usage, as per convention, now throws on error instead of explicitly exiting process ◦ -X/-T exec usage now allows for conventional value syntax, e.g. :p '"deps.edn"' now works (in addition to :p deps.edn). ◦ -X/-T exec usage invalid boolean values now trigger an error (instead of being ignored) ◦ now warning when using dependency-check-only options with github-advisory database-strategy ◦ now reporting unrecognized options in appropriate style for -M vs -X/-T usage ◦ command line usage errors reviewed and updated for succinctness and clarity ◦ made code more REPL-friendly by only issuing System/exit from the outer edge of API ◦ added unit tests • Switch to Maven as authority for version ordering https://github.com/clj-holmes/clj-watson/issues/146 • Output maps in reports using a familiar syntax https://github.com/clj-holmes/clj-watson/issues/147 • Bump deps https://github.com/clj-holmes/clj-watson/issues/134 • Add JDK25 to the CI test matrix https://github.com/clj-holmes/clj-watson/issues/143 Follow-up in #clj-watson

🎉 11