Babashka: Fast native Clojure scripting runtime
babashka.org
babashka.org
And I love this page describing it. I hadn't seen it before today.
After seeing Michiel Brokent -- the project's original creator/author -- present on it at a meetup, I wrote a tidy overview of babashka (bb) which you can find here: https://amontalenti.com/2020/07/11/babashka
The end result is that anything the least bit non-trivial becomes a Babashka script, and I've created tools containing dozens (or potentially, hundreds) of sub-commands.
Joyful is the correct adjective.
Babashka Babooka: Write Command-Line Clojure - https://news.ycombinator.com/item?id=34261010 - Jan 2023 (14 comments)
Babashka is a fast-starting scripting environment for Clojure - https://news.ycombinator.com/item?id=33909241 - Dec 2022 (42 comments)
Babashka Clojure nREPL as a system interface - https://news.ycombinator.com/item?id=33761877 - Nov 2022 (23 comments)
Clojure Scripting on Node.js - https://news.ycombinator.com/item?id=32339979 - Aug 2022 (33 comments)
Ad-hoc ClojureScript scripting of Mac applications - https://news.ycombinator.com/item?id=29779353 - Jan 2022 (8 comments)
Replacing my Octopress blog with 200 lines of Babashka - https://news.ycombinator.com/item?id=28982952 - Oct 2021 (27 comments)
Clojure Babashka scripting notebook - https://news.ycombinator.com/item?id=25227419 - Nov 2020 (2 comments)
Using Clojure in the command line with Babashka - https://news.ycombinator.com/item?id=24353476 - Sept 2020 (36 comments)
Babashka: A quick example - https://news.ycombinator.com/item?id=22382381 - Feb 2020 (16 comments)
Babashka – A Clojure for the grey areas of Bash - https://news.ycombinator.com/item?id=22254793 - Feb 2020 (65 comments)
Babashka: a tiny Clojure in Clojure for shell scripting - https://news.ycombinator.com/item?id=20667509 - Aug 2019 (1 comment)
There seems to have been an academic attempt to do that (for a subset of the language) with promising results: https://epub.jku.at/obvulihs/download/pdf/501665
[1]: https://www.graalvm.org/latest/graalvm-as-a-platform/languag...
You can combine technologies. Compile the Clojure compiler to a native image as a library to make text->bytecode fast, then invoke it from the babashka wrapper if there's no JAR for the script inside a disk cache, otherwise run the JAR if found. If the Clojure bytecode were lazier and you combined it with AppCDS the startup time would be fine.
I've got a similar sort of concept but using Kotlin. The scripting syntax is convenient for the use case of replacing bash and the generated bytecode is simple and efficient. Unfortunately compiling Kotlin is really slow, so whilst finished scripts start up nice and fast the edit/compile/run cycle is poor.
However, if you want to use Native Image, then I think Truffle is the only viable way to improve the runtime performance. Even if you NI the current Clojure compiler, there would still be no way to run it short of running the resulting classes on OpenJDK, and those classes would need to be intialised, so NI would buy you little. I don't think that loading and initialising the compiler is the dominant factor in Clojure's startup; I recall it being the loading of user/library classes.
1. Make the Clojure compiler emit more efficient and lazier bytecode, so it doesn't init everything all at once at startup (the stdlib gets compiled into what is effectively one mega-class). No change required to anything, it just starts up faster once they upgrade to a new Clojure version. Constant Dynamic was made for this problem.
2. AppCDS, Leyden. No semantics change, only workflow.
3. A Truffle version that operates on source code. Some workflow changes. Have to switch to a new runtime, eliminate build steps and ship sourcecode instead of bytecode (which may not matter).
4. Compile end user programs themselves down to native with native-image. Semantics and workflow both change but all the dead code in the stdlib can be eliminated this way.
Lots of options. (1) is the lowest hanging fruit but I suspect the intersection of people who know about the newest bytecode features, people who can modify the Clojure compiler, and people with the time and energy to do so, is currently the empty set.
My point wasn't so much to suggest to Clojure's stewards a course of action but to say that since Babashka already makes use of Native Image to get fast startup and already depends on a separate interpreter implementation that suffers from runtime performance, then Babashka may want to consider basing their interpreter on Truffle to improve runtime performance. If you already picked Native Image for your product and already decided to create a separate implementation of the language based on a source-code interpreter, might as well try basing it on Truffle.
One of the side projects I keep wanting to try is to see how far I can drive GPT-4 to develop a Lisp interpreter for Truffle. Lisps are simple languages, and it does know at least some of the API.
That said, the executables for GraalVM are enormous, so I'm absolutely open to something comparable that avoids that. I'll give Babashka an install and play with it.
* - More than half of my time with Clojure has been with Advent of Code challenges the last 3 years, so I'm in the ~250 hour club.
Nonetheless it is an impressive achievement. Just one that I deem, like GraalVM's native compilation itself, an unnecessary one.
Why is simple, use the language you already know that has good libraries available for scripting.
We're using it at work, together with Clojure, it works just fine, but it is the weird sibling.
That helps drive clojure adoption in a way that suggesting that instead dev teams adopting clojure should also learn scheme and write some of their code in that seems not nearly as compelling.
It's the same reason that clojurescript is supportive of the overall clojure community, rather than being a distraction and diversion of resources.
* It's not 100% the same, but for what's needed to replace bash scripts, it rounds to 100%.