The fact that I can use the same language to develop business model code that runs on both the client and the server, or that I don't have to use a different on-the-wire format for sending data between them (EDN does the job great) is just icing on the cake in this context.
I am very thankful to Rich and the entire Clojure (and ClojureScript) teams for giving me access to all their work (for free!).
BTW, if you haven't seen any of Rich's talks, go see them — they are worth it even if you do not intend to use Clojure.
The very good backwards compatibility is attractive but as the result of the small community, there's also a lot of abandoned packages and fewer QoL packages (formatters, linters, etc); I know there are some but for example I had setup `cljfmt` in Emacs and it wouldn't work, didn't look further.
I'm not a hot shot programmer, entirely self-taught but a decent architect who thinks hard about problems, and with LLM agents Clojure shines for me. There are some fantastic databases also starting with Datomic -- free now thanks to Nubank -- and everything inspired by it and the Clojure flavor of Datalog. These include Datalevin, Datahike, DataScript, XTDB. Datomic itself is probably best for enterprise though there's now an embedded version.
But I'm pretty convinced that most LLMs I've used are more reliable with Clojure (and Elixir) than with most of the popular languages, and I can say they use Datalog extremely well, seemingly much better than SQL despite the vast difference in corpus size. For one thing Datalog just gets rid of joins issues.
I created my own job :-)
(although there are Clojure jobs in my area)
With LSP mode the standard `lsp-format-region` and `lsp-format-buffer` commands should work, and on the CIDER side `cider-format-defun`, `cider-format-region` and `cider-format-buffer` should also invoke cljfmt.
Clojure for me is a rich vocabulary to talk interact with data. When Jank becomes stable, Clojure will be unstoppable.
Both Clojure and Elixir really changed the way I think about programming. They’ve both basically ruined me as far as other languages go. Structural editing + repo driven development in Clojure, BEAM + pattern matching in elixir.
But there is something just infinitely more fun about writing Clojure code, and insanely satisfying. I’m eagerly awaiting the day that jank takes off and I can start building native mobile apps in Clojure (and who knows, maybe some web backend tech stack will spring up around it!)
Nothing wrong with that, having different target audiences makes sense and is probably preferable, but Janet is more than just "Clojure without the JVM" much like C# is more than just "Java without the JVM".
In my experience, while I have found Clojure enjoyable and practical, it is still a "dynamic" language. A good deal of run-of-the-mill programming can manage quite well with such a language, but as projects become larger, deeper, and more complex, the lack of static types really does become a cost and an impediment. To understand any function and what it expects, you often need to read a few layers in to find what exactly something consumes and returns. Types really are a boon in such code bases. Some may point to various schema libraries in Clojure. While these can be helpful, they are often comparably inscrutable in practice (both in terms of specification and the resulting errors) and really do not compare to bona fide types, especially with LSP integration. And when you model something using types, the code sort of just falls out of the type definition.
I've worked with Clojure in a number of companies, it's an elegant language and a thing of real beauty when done well, but it's not so much fun when you're working on a codebase that doesn't respect the philosophy of avoiding breaking changes; especially when these breaking changes are done in library code, and where a more liberal approach has been taken when it comes testing.
"less ceremony, more responsibility" is a good summary, in a larger codebase a bit of ceremony is not always a bad thing though. I'm also glad I learnt Clojure, it made me a far better programmer.
Kudos to Mr Hickey, I'm looking forward to the documentary.
It seems like a small thing, but Clojure's choice to open up for other types of parentheses made seeing the structure of lisp programs much easier. This helped me understand how code is data and how macros are functions that can transform both code and data.
An important design philosophy (which is also hinted at in the trailer) is "simplicity". Clojure is designed to give you the tools to build simple solutions to the problems that you want to solve. It approaches mutability, which is one of the key sources of complexity in programming, with immutable data structures. It's a really clever way to do functional programming where your data is copied a lot but the copies are lightweight.
I don't write Clojure any more these days. I'm mostly doing Rust. But it is true what Eric Raymond said: Lisp has made me a better programmer.
Also: XKCD 224 and 297
Obviously. The point being made is that the Clojure style discourages building DSLs and the like and prefers to remain close to Clojure types and constructs. It departs in various ways from traditionally Lisps.
Programming Clojure, Fourth Edition 4th Edition is on pre-order scheduled to be released May 2026.
https://pragprog.com/titles/shcloj4/programming-clojure-four...
The author recently weighed in on what he’d cut and add to a future version - could be useful to anyone reading today, if they want to skip some things. https://www.reddit.com/r/Clojure/comments/1rxknpj/quick_ques...
Clojure is a beautiful Lisp, and coupled with the JVM it's extremely powerful.
If you want a Lisp Machines like experience with Clojure, support the Cursive folks.
I hope more people get to experience this kind of joy :)
On the backend side, you start your server once, and whenever you change it locally, you apply what you changed directly to the running process, so you don't lose any state and without having to restart the server at all, so iterating on the program becomes very easy. Bugs are easy to track down too, as you can evaluate parts ("forms") of the program inside the process itself, debugging becomes a breeze.
On the frontend side, you have ClojureScript that basically enables the same but in a browser environment. Usually I have the browser on the right, my editor on the left, and whenever I "evaluate a function", it runs in the browser context, so again same thing; the frontend keeps the same state even after your changes, so no more "make change -> wait for compilation -> get frontend into the state that reproduces the issue -> output debug info -> make change again", you just change one part, see the page update and then continue changing.
If you've used React+Redux (or similar) before, it's basically that experience, but much tighter and together with code evaluation inside of the browser context. If I recall correctly, Redux was pretty much directly inspired by ClojureScript and Reagent in the first place, I think Abramov even referenced ClojureScritp/Reagent in the first Redux talk.
BUT
it doesn't have the equivalent of rails, mostly because lispers are an opinionated bunch and can't come together to agree on how web development should be done
the frameworks that do exist are more of a collections of libraries with some plumbing to connect the dots
One big library/framework has huge benefits and network effects, from enabling a big 3rd party plugin ecosystem, to a deeper documentation literature (including paid courses, books, and AI). It means that there's less or virtually zero getting up to speed when changing from one project to an other. It means that the upstream framework team takes care of upgrades whereas you have to consider, when a new technology comes up, how to integrate this into your stack. There's a reason that Laravel, Django, Rails, and Spring each have thousands or hundreds-of-thousands of times more websites in production than all of Clojure combined.
At a meta/discourse level, I also find the Clojure community's tendency to constantly deny and downplay any criticism or even just issue that people face to be really frustrating and counter productive.
See also Rich Hickey's remarks on AI: https://www.youtube.com/watch?v=MLDwbhuNvZo
— Rich Hickey, Effective Programs[0]
[0]: https://www.youtube.com/watch?v=2V1FtfBDsLU&t=4020s
---
A disastrously poor take. I used to work at a Clojure company, and there's no chance I'd ever go back to that.
I think the thing is that yes, `[a] -> [a]` tells you relatively little about the particular relationship between lists that the function achieves, but in other languages such a signature tells you _everything_ about:
- what you need to call invoke it
- what the implementation can assume about its argument
i.e. how to use or change the function is much clearer
if you are going to be modifying the same data with a sequence of functions, you got to write that down somewhere so new people get it.
Lisp is great at processing lists in such a manner.