The part about the "stability" is a bit surprising - in my experience, I try playing with clojure about once a year, and every time, everything is different (I mean, I had to go through classpathes, then lein, then boot, then deps.edn - what is the current way to "try and run a program" du jour ?)
Also, is running your "hello world" still going to be incredibly slow, or has something changed in the core system (I know I'm supposed to fix that with graails. Or is it babashka ? Or something else, I suppose.)
It's really sad, because i just love the language. Reading about clojure is a pleasure. Trying to write anything has always been a blocker to me, though. Maybe that's the true "immutable" nature of the language ?
While clojure has gained (accreted) more options of ways to run things, every single one of the ways you mentioned still work! It’s extremely stable in this regard. Nothing was taken away because there is a new hotness. Sure, things were added. Why is that bad at all?
Personally, I prefer it when there is a solid default tool chain for a language rather than having to choose from one of several. That way, I know pretty much what to expect when I open any project in that language. I feel like this is one of the few places where Clojure dropped the ball and that deps.edn should've been there from the get-go.
Both Rust and Elixir get this right. I have used both in anger, for money, to ship real stuff, and while neither is perfect, they are both great.
To a first an approximation, every Rust project uses Cargo and every Elixir project uses Mix, and they are both first-party tools so they have a level of stability, approachability, and ubiquity that comes with being tied to the language. I’d kill for Clojure to have something half as good as Cargo or Mix and have it be the only build tool, but that ship has sailed.
And rust. And elixir. And caml, which, after many years, settled on dune. And, apparently, common lisp, which settled on ASDF sometime before I reached puberty. And, probably, every language born after java.
Which is all the weirder : rich hickey could (should ?) have figure that "building infra" was one of the aspect where clojure was a great fit ("lein as an ant+maven killer.") To be fair, it wasn't as much in the zeitgeist at the time.
Still, a new language nowadays must have, on aday one, a package manager and a linter and a formatter and a test runner, etc... - just like it must have an LSP.
It's funny looking a zig trying to fight this.
It's funny watching roc reinventing that weel.
I guess jblow will rationalize against it for jai.
I wonder if someone is going to standardize "the rest" of the toolchain. ("Language dependency manager protocol", anyone ?)
I don't disagree with you from the perspective of someone who is already in the community and already has the experience to make that choice, but I think this question is slightly more complicated for someone with zero Clojure experience. More than once I have seen people confused on whether they should be using Lein, Boot, the first-party CLI, Maven, Shadow CLJS, Figwheel, or something else entirely.
If you like the language, don't let that stop you. Install leiningen and run:
`lein new app my-stuff`. Then type `lein repl` and you should have a repl running.
Alternatively, open the project in IntelliJ with Cursive installed or VSCode with Clava or other supported editors and start evaluating code at the repl.
Go through a few tutorials, then go through one of the free books available online. Don't give up when you're stuck.
The language has a steep learning curve because it requires thinking about the program in a different way than many mainstream languages. But it compensates by giving you many 'aha!' moments which make the day :).
Well, also, sadly, the first thing I would want to be right now happens to be... a GUI, which seems to be the archnmesis of Java in general, and clojure in particular ;)
Ehhhh they work, but at what cost? If you know them already go ahead, but the other popular desktop ui's are probably easier and more maintainable. I really do wish desktop and mobile in Java was more popular. I'd really like to have one language and ecosystem.
> everything is different… I had to go through classpathes, then lein, then boot, then deps.edn
All that stuff still works and I don’t think any of them broke their APIs? A lot of people still use lein for example.
You’re talking about new choices coming along, which is a good thing.
Of all the ones you listed, only one is a product of the core team, so it’s not like there has even been “change” on any official level.
If your mindset is, “I need to be on the latest hot thing” that’s about you, not Clojure. You’re allowed to keep building your projects using any of those tools, they still have the same capabilities.
> If your mindset is, “I need to be on the latest hot thing” that’s about you, not Clojure. You’re allowed to keep building your projects using any of those tools, they still have the same capabilities.
Beware here: it might sound natural to you, but many (and I many _many_) people are working on stacks where "there has been no update to this lib for 6 months" means "the project is discontinuated and has been replaced by something else, it's a waste of time."
So, it might be worth adapting the messaging.
For example, there is an awesome-clojure page with a kitchen sink of every possible libs, some of which are dead, and some of which might not be.
Is there a "boring-clojure" page, where, sure, not everything is awesome, but you can be confident that using this lib and that tool and that IDE is going to, basically, "just work" for the foreseenable future ?
I can't talk about the life cycle of clojure libraries, but i have seen common lisp libraries that haven't been updated for almost 10 years that work perfectly. There is little the maintainer needed to fix.
I've always heard that the JVM[0] in general is considered to have a fairly high startup time compared to other common compiled language targets; is Clojure especially bad in this regard, or is this something that's frustrating coming from outside the JVM ecosystem that just adds additional friction when you're already trying to look into using new language?
[0] Not sure what the correct term is here, but I mean the official default one; I know there are other implementations, and my vague recollection is that there's at least one other one that's either sponsored or maybe even fully developed by Oracle, and that the OpenJDK version is the "canonical" non-enterprise one now anyhow, so saying " first party" feels like it might add more ambiguity than it would resolve
The JVM has bad start up time in the context of milliseconds, but Clojures slow start up is in a different league. It loads a bunch of classes and it can take a full second.
But you're also not recompiling on code change. You're just reloading a function in the REPL. So you only have to load once and then your dev cycle is painless. But the startup time is bad for things like serverless functions unless you use something like GraalVM.
Ran 391 tests containing 1180 assertions.
0 failures, 0 errors.
clj -X:test 30.15s user 2.04s system 203% cpu 15.838 total
~/workspaces/github/pedestal/tests > java -version
openjdk version "23.0.2" 2025-01-21
OpenJDK Runtime Environment Corretto-23.0.2.7.1 (build 23.0.2+7-FR)
OpenJDK 64-Bit Server VM Corretto-23.0.2.7.1 (build 23.0.2+7-FR, mixed mode, sharing)
That's on my Intel MacBook Pro. Pedestal's test suite loads a good amount of Java classes and Clojure namespaces.
To make things faster, there's ahead-of-time compilation (which basically captures the read-eval-create-bytecode part of loading a Clojure namespace as Java .class files that can be packaged into your app).
10+ years ago Clojure had a fantastic introductory experience. lein new and away you go. lein was so good and effective, for both tiny hello world projects and real production apps.
The experience has gotten worse and worse now for a decade. The core team have continued to take things in a worse direction (supported by a small group of fanboys) and most newcomers are now completely baffled by the tooling.
The cli/deps.edn tooling is different from Leiningen, and far, far less complicated IMO. I've written a good number of Leiningen plugins and it was always brutal to get anything to work properly, especially in combination with other plugins.
Leiningen attempts to be everything to everyone in terms of building, testing, and packaging Clojure code. It's Clojure's version of Maven.
cli/deps.edn effectively reduces things down to a) what should be on the classpath and b) what should get executed. Working inside an IDE? You just want it to download the dependencies and build a classpath. Running nREPL? Add that to the classpath, and set the starting namespace to start nREPL. Packaging an application? Run dependencies that do that work, based on the clojure.tools.build library.
I was there myself; I used Leiningen and didn't take the time to figure out deps.edn --- until I did, saw the light, and converted all of Walmart's projects to use deps.edn, which greatly sped up our build and improved our dev experience.
tools.deps is less complicated mostly because it just flat-out does much less. To mimic everything lein can do required adopting half a dozen other libs and writing your own build scripts.
It's better now, but people are pretty uncritical of the core team, and adopted tools.deps before its surrounding ecosystem was ready to fully replace lein.
The upshot was, everyone got to rebuild the wheel for a couple years. And I say this as someone who once lost a week debugging a subtle lein/maven classpath AOT bug.
You can still do lein new and away you go, today. That still works.
Many people still use lein for new projects, especially for larger ones. For small on-off thing, clojure command line is more convenient. So it is a good thing to have more choices.
Also, today, half the docs you find around are about lein, half are about tools.deps, and no one ever gets the full definition because they assume you know your way around. :shrug:, I guess ?
Also, is running your "hello world" still going to be incredibly slow, or has something changed in the core system (I know I'm supposed to fix that with graails. Or is it babashka ? Or something else, I suppose.)
It's really sad, because i just love the language. Reading about clojure is a pleasure. Trying to write anything has always been a blocker to me, though. Maybe that's the true "immutable" nature of the language ?