As a heavy user of Clojure (my SaaS is written in Clojure/ClojureScript) for 10 years or so, I would fully agree with what Kyle wrote. In addition, things that I found very valuable:
* most of my domain code is in cljc files, so these get compiled both server-side and client-side and I get a huge boost from that
* transducers and transducer pipelines are an under-appreciated feature, I get huge mileage out of them, because of performance, composability and reusability
* stability and longevity: Clojure was created by a very experienced system designer and programmer (Rich Hickey) and it shows. Backwards compatibility is hugely important, and I can focus on my application rather than rely on tools that are a moving target. It's not an accident that an average "Clojure programmer" (I dislike these kinds of tags, but let's run with it here) has 12+ years of experience and earns a salary in the top quartile at least.
Similar story. I'm also running my SaaS on Clojure and maintenance has been a dream compared to other languages. Things rarely break and are easy to upgrade.
Developer experience is fantastic too with HMR, REPL and cljc files. It's fun to write Clojure code :)
What do you use for an editor/IDE? I'd love to write more Clojure, but the tooling story is a bit confusing
HMR?
What % of the overall benefits would you attribute to the JVM vs. Clojure (the language)?
I barely even care about the JVM. I'm happy because it is an impressive feat of engineering, representing tens of years of huge investment into development, compiling my code to levels of performance that poorer VMs cannot reach. But JVM is just one of the environments where my code runs (the other is the JavaScript VM in browsers).
Clojure is not only on JVM. There's Clojurescript. There's ClojureDart. There's ClojureCLR. There a bunch of experimental things like ClojureRS (Rust) and Clojerl (for Erlang). You can "talk to" Python and R from Clojure. You can use Fennel if you need to deal with Lua (It's not Clojure, but it's very Clojure-like lang). The benefits are there, for any platform you choose.
Does Clojure have a decent web framework?
I am not sure what a web framework is, to be honest. The choices for many parts of a web application are really domain-specific and I'm not sure a single "framework" would work for everyone.
As far as web-related components go, my app uses Rum (as an interface to React), ring, http-kit, pushy (for history manipulation), sente (for websockets), buddy (for authentication tools).
If you are looking for a batteries-included "I want to have some sort of webapp right away" thing, I think https://kit-clj.github.io would fit the bill, but the general feeling in the Clojure community is that unlike Python with Django or Ruby with Rails, the choice of app components is not predetermined by the language.
Comprehensive frameworks include: biff, kit.
Both of these rely on some of the most popular and simple libraries for web dev.
Most seem to simply use said libraries directly, mix and match what is needed.
If you’re an experienced web developer but new to Clojure, then you’re going to spend a good weekend or so to set up a proper environment, combine the necessary libs and so on, if you have some guidance. The Clojure community is quite welcoming and helpful in that regard.
There’s an initial learning curve, because it’s a functional Lisp though. That comes with some necessary re-wiring, but also with some unique powers.
The cool thing about writing Clojure is that feeling: „Really that’s it?“ when you realize how simple it is. It’s also simply fun to use, because of how interactive it is.
Because of it's lisp nature with special braces I find it to be nicer for creating DOM than HTML :
really has that "first class" feel when you're working with it rather than feeling tacked on like JSX - at least that's how I remember it.My main problem with Clojure was the dynamic nature of it. I have not used it in very long time now (probably 7 years at this point) - but despite the amazing aspects of it I would not trade in TypeScript annotations.
A question for clojurists here - what is the level of static type checking adoption in CLJ world ? When I was using it last time there were some things like schema validators, but nothing like TypeScript. It looks like there's static typing annotations support now but are the types widely used by popular projects/provided for big libraries ?
Luminus has been around a long time and Kit is newer. Most Clojurists believe in libraries over frameworks though so that's why you don't hear about web frameworks much. I've messed with Luminus a few times and it is really easy to pull out parts and swap in almost any bit of it. They document a lot well and make it really easy to pick different parts out of the gate like different DBs, JavaScript libs, and a lot more. The maintainer roams HN frequently as well :)
Let me add my 2cents on this subject.
I feel that due to its functional nature or perhaps this is just the community bias, Clojurists tend to prefer mixing lower level libraries to build their web application instead of relying on a specific big web framework like RoR for example. Luminus would be one RoR-like system.
But today, I think people would probably choose reitit for the writing the API and use a clojurescript framework for the frontend or perhaps still use reitit to generate HTML pages using hiccup.
"No, but maybe" is how I would answer this question myself. Maybe there is a working framework I'm unaware of - but in my experience using Clojure the last few years is that the concept of frameworks is not in the culture of the Clojure community.
You compose your stack of smaller libs and build your own framework so to speak. The right questions in this context are; what http server to use, what routing lib is decent, what is a good lib for my database, what is a good lib for generating html from the server. etc.
If you wanna start using clojure as a web server. Start with 'ring', and you can recieve http requests. You quickly realize you're missing stuff to do what you need and will go searching for libs. You'll find great libs out there for anything you ordinarily need for a web-server setup.
https://biffweb.com/
I know you’re probably going to think this answer is crazy or stupid, but you don’t need a web framework in clojure. In fact you don’t need all the libraries that many languages need.
It has several. None of them dominate; most people assemble their own from individual libs.
Out of topic, sorry!
> Backwards compatibility is hugely important
Why is this always considered a Good Thing (TM), apart when applied to C and C++?
Why is it OK when languages and systems are bent backwards in order to avoid breaking stuff that works, but the two languages that together support a huge part of the running software are expected to up and break ties with their glorious past and present?
Let me talk about my experience. I was (yes was) mostly an Haskeller. I loved using Haskell, and even a long time ago (in 2007 I think) when I learned it, the book to learn the basic of the language had snipped that no longer worked.
But I still loved, it. And it changed every year, and I was even part of the proponent of the changes.
But after a while, you realise that your old project stop working. That if you want to use a new library, you also need to update many dependencies. But each one has breaking changes, so you start updating your code.
Mainly, if you wrote some code, and forget about it, it will no longer work or will be very hard to use with newer libraries. After a while this became very tedious.
In Clojure, the code I wrote 10 years ago is still working perfectly today. The application still launches.
If a bug is discovered and I need to fix it, for example, by upgrading or adding a new lib, I am not afraid to loose hours finding an fixing my existing code that suddenly become deprecated.
So yes, stability is VERY important for me now.
And last but not least, Rich Hickey talked about it in this talk and make a lot of very great points:
https://piped.video/watch?v=oyLBGkS5ICk
There's a happy medium, I think, and I also imagine that depends on scope of change and the kind of applications involved. Speaking personally, I'm OK rewriting code, say, every decade. In the Ruby world, things moved so fast that my code would rot every six months. Now that I've been maintaining the same software for 20 years I'm really starting to care about that. ;-)
I'll also note a lot of objections to the way C++ does backwards compatibility is their adherence to an ABI which they refuse to break, but also refuse to say they'll never break.
Many of the problem that can't be fixed for backward compatibility reasons are because they'd break the ABI, not new code. I think that's very different from other language's policy, which, from the ones I'm more familiar with, is about building old and new code together, rather than linking old and new code together.
It makes for a much more restrictive, but also ambiguous and not guaranteed, set of requirements on any change.
First one is a security nightmare, second one probably has more features and intricacies than other top three (by popularity) programming languages combined.