Hacker Read top | best | new | newcomments | leaders | about | bookmarklet login

Have you tried Clojure with the GraalVM native-image? I am curious to what extent native-image can delete the overhead of Clojure and make fast natively compiled binaries.


sort by: page size:

GraalVM native-image is not a listed option, but I regularly use it to produce binaries that are competitive with (often better than) Go in terms of size and (start time) perf.

A Clojure tool that parses, traverses and processes JSON (caro, see below) worked out to 3.2MB. I'm sure C and Rust can do better, but it's not bad compared to a JVM, and it's an order of magnitude better than the best option in the article. It's also small enough that while comparisons like "that's three floppies!" are interesting historical perspective, you can't reasonably complain about having a 3 MB binary in ~/.local/bin.

Examples:

https://github.com/latacora/wernicke/releases https://github.com/latacora/recidiffist-cli/releases https://github.com/latacora/caro/releases

It mostly works out of the box. My biggest frustration is that you can't easily link in dynamic libraries, which makes it a little annoying to do e.g. EC TLS with a single binary. (Go would have a similar problem but sidestepped it by reimplementing most of it natively.) Second biggest frustration: it is not a fast compiler. You're definitely doing development on the JVM (I use Graal as my default JVM now) and a "production build" afterwards with native-image.


You can create a graalvm native image for your Clojure app. You have to jump through some hoops to build it though.

This is a good example of where Graalvm's native image is interesting. This is a CLI tool that lets Clojure developers create scripts that are as fast as bash scripts. Clojure may well not be your bag, but stay with me - we're talking about CLI or TUI's written in Java (or a java-based language) that are easy to distribute as statically compiled binaries.

Lately GraalVM can be used to compile a native binary, since Clojure compiles down to Java bytecode.

https://www.innoq.com/en/blog/native-clojure-and-graalvm/

Sometimes the trade-off of slow startup vs. having a JIT'ed VM is better, since you get a lot more performance, if you're working w/ long-lived processes.


There is now an option to compile a binary, it uses GraalVM native-image technology

We're growing a scripting ecosystem in Clojure now thanks to this, it's still relatively new

As a newcomer, I've made several native binaries for different operation systems


There's a burgeoning ecosystem in Clojure for creating native apps using GraalVM native image

https://github.com/borkdude/babashka is a good place to start


Does GraalVM work with Clojure? I would assume that would solve the startup time issue for a project like a CLI tool.

For me the most interesting part is how it gets rid of the JVM startup time.

So there are two parts to the solution: The first part is Small Clojure Interpreter (sci) which is a "(subset of) Clojure written in Clojure", so kind of McCarthy for Clojure. A cool project in itself but it still needs a VM to run.

So here is where the second part comes in: the GraalVM produces native binaries from various things, including Clojure code and SCI is simple enough to work with GraalVM.

It's cool how these two pieces of tech combine together to create something greater than the sum of the parts.


Nowadays you can use GraalVM to have quick startup time for commandline tools with Clojure.

GraalVM is interesting technology. I've been playing a little bit with native-image in a Kotlin project and it allows me to build native binaries from my Kotlin code. With support for a lot of the existing java/kotlin library ecosystem.

The binaries are a bit large (10MB for a Kotlin hello world) but they are fast. I'll be using this for some personal cli tools since Kotlin+Maven is my personal 10x platform.

Besides cli projects I've also done some experimentation with GUI and database stuff. Using the Gluon plugin GraalVM is able to compile a native binary for a JavaFX app that talks to a Sqlite database.

When using a library that relies on reflection there might be some graalvm config to fiddle with but mostly it just works, and some of the libraries are already "native-image ready" with the necessary config inside the published package.


Graalvm does native compilation.

GraalVM, ClojureScript, etc...

Back when I wrote Clojure professionally, using GraalVM to generate a native executable of things like clj-kondo basically eliminated the startup latency.

Yeah, somewhat agree. The Clojure community has put so much effort into working with GraalVM.

* https://convexhuman.com/graalvm-clojure.html * https://nitor.com/en/articles/fast-cold-starts-for-clojure-i... * https://www.innoq.com/en/blog/native-clojure-and-graalvm/

Since development in the REPL is so common (watch any Clojure live coding session), JVM startup time isn't much of an issue in practice.


Yes I've installed babashka. It really is a cool project.

Must look into GraalVM at some point, but, as someone new to Clojure, I'm wary of spending too much time on tooling yet. I've found in the past I can tinker so much with such things that it interferes with getting fluent with more fundamental stuff.

I'd be interested to see if either now or in the future Clojure + JavaFX in GraalVM would be feasible.

Edit: I don't quite get the install size issue - I thought native image was an entirely standalone executable?


I've only done one project with GraalVM and I've been pretty happy with it in regards to faster startup time.

I was doing stuff in Clojure. Clojure is a great language but it tends to have very slow startup times, even by JVM standards (it's not weird for a large Clojure program to take 5-6 seconds to start. Even a "hello world" can take upwards of a second or two). Graal mostly Just Worked with the standalone uberjar produced by Leiningen and created an executable that started in about 3 milliseconds. It was amazing.

While the lack of proper reflection support was a little annoying, it actually wasn't as horrible with Clojure as you might think; most problems were fixed with basic type hinting, and all but one Clojure library I used (http-kit) worked flawlessly.


However, the elephant in the room (which I also like to ignore as a Clojure enthusiast) is that the start up time of a Java based GUI app is too slow (this is exacerbated even moreso when Clojure is involved)

I'm expecting a GraalVM rejoinder from someone. For anyone who's used GraalVM (particularly with Clojure) - what are the downsides and limitations?


Graalvm can compile a native binary for all major OSs that does not contain the JVM but does run the substratevm which generates binaries in the order of tens of megabytes (2 in my case) it eradicates JVM startup time so now things like scripting is viable without using JS

Runtimes for Clojure include JVM, JavaScript engines, .NET then there are less popular runtimes like Go Erlang python? realistically I'd use one of the first three till the community is bigger

I don't know another language with as much practical reach as Clojure has


Perhaps someone already mentioned it here, but GraalVM lets you interop between Java and anything LLVM, and therefore Rust, without the JVM startup cost, with breakpoints across languages, even (as I understand it). Compile time is long, though.

borkdude has been releasing for some very cool stuff using this stuff. Here's a Clojure/Rust combo:

https://github.com/borkdude/clojure-rust-graalvm

next

Legal | privacy