Ask HN: Is Clojure Dead?

86 points by thisiswrongggg ↗ HN
Hi, I don't see much about clojure over past 2 years or so. Same goes for other industry functional languages (e.g. elixir, scala, F#).

Are they just in later stages of hype cycle or are they dying out the same way perl did?

For better or worse most of news/fuzz these days seem to be about Rust (not that this translates to actual job postings though).

PS: Asking because I want to delve into a functional language but I cannot bring myself to do this seriously if it doesn't translate into market value.

144 comments

[ 3.5 ms ] story [ 217 ms ] thread
1. No.

2. These languages were never very popular to begin with.

"I was seeing more HN posts about it in the past" doesn't equate to "the language was popular before and now it's dead.

Thanks for the answer! About 2. It's not only HN (but I get your point which is why it could be that they are less talked about and more used). Waht worries me is the LinkedIn job ads for clojurists.
Learning functional programming will add value to any programming language that you use as you'll have more strings to your bow, so to speak. You may not get a job writing Clojure, but you'll be able to bring the concepts you learn to any job you do get.

For what it's worth, I do see some jobs for Clojure in the UK and EU on LinkedIn, not as much as other programming languages, but enough that I think I could get one if I were looking for a Clojure job.

Probably LinkedIn is not the best place to find Clojure jobs. Most of the jobs I've gotten has been because of word-to-mouth. Getting into the ecosystem and contributing patches/features to libraries/projects is your best bet to be considered for positions. Second to that, there are dedicated job sites for Clojure (like https://jobs.braveclojure.com/). Thirdly, the #remote-jobs / #jobs channel on the Clojurists Slack is very good to find jobs too.
Yes, definitely this. So many jobs are found through referrals and networking, especially for non-mainstream tech.

That said, I was pleasantly surprised recently by a search on LinkedIn for Clojure and found some big household names hiring (including several large banks who most people think of as being very conservative).

I don't know, you could say the same thing about more popular languages as well. Lots of people get jobs in Java roles from their personal connections. The difference in postings between Clojure and more mainstream languages like Python and Java is multiple orders of magnitude. Clojure has about 500 job postings on LinkedIn in the united states. Compare with Python which has about 750,000, literally 1500 times as many jobs.

The number of roles in all of Canada for Clojure is about 40 on LinkedIn, easily less than the number of applications a job hunter could send out in a day.

Clojure is not dead, the core language is still very strong, but the dev experience has been degrading IME. This is due to a lack of heavy corporate backing and investment, probably by choice. Taking a PL to the mainstream is very expensive.

You cannot compare Clojure and Rust in any way as they're completely different design philosophies.

> You cannot compare Clojure and Rust in any way as they're completely different design philosophies.

That's actually why it is interesting to compare them. Comparing things that are the same would quickly become very boring.

What I mean is that you can only maybe compare them in a vacuum. For a concrete given task, "is Clojure or Rust better" rarely comes up because there is little overlap in application domains.

For instance, one domain where Clojure shines is for complex web apps, as your frontend and backend are in the same language, and can be tightly integrated. I believe dustingetz is working on taking this to the next level.

Do you have examples of the dev experience degrading? My experiences is that the tools and libraries only continue to mature (as does the Clojure language itself).

Do you just mean that things are improving less quickly than they are for, e.g., Typescript?

I mean compared to a few years ago. I tried setting up a new project after 1 or 2 years away from the ecosystem, and struggled a lot : all existing templates to set up new projects (esp. with CLJ/CLJS combined) had bitrotten and were not usable out of the box ; emacs integration no longer working out of the box, etc.

I think it's a "death by a 1000 cuts"/"broken windows" that is may be happening when the ecosystem lacks funding to take care of the boring maintenancey stuff. If I remember well, this is a conscious choice by Rich Hickey, a choice that one should respect, but will prevent Clojure from ever getting to the next level IMO.

I've very recently changed my system from MacOS to Linux, so I've been reibuilding my Clojure environment from scratch. I've found the exact opposite in terms of maturity; Emacs support in particular is far more complete and usable out of the box than it ever was.

I installed Spacemacs fresh, loaded up a Clojure file, and not only did I get automatically get CIDER, but I also got LSP support via clj-kondo and a bunch of other extras. I was genuinely impressed at how mature the tooling was, and how trivial it was to install.

Hi ! I am ever so grateful for all the work you've put in over all these years, to get the Clojure ecosystem where it is today.

What I am kinda saying is that Clojure would be in a better place if it was paying people like you a lot more!

Thank you, I'm glad some of the work I've done could be useful.
Similar experience here. My first Clojure(script) projects used leiningen, now everything is deps.edn and the clojure CLI. Cool, changes happen. But editor integration, REPL tooling, even which compiler to use, etc are not consistent either. The tooling is changing everywhere and bit rot has claimed almost all of my past projects. The code is still 100% compatible but the build system is just broken. I've given up trying to port any projects over - it's easier to generate scaffolding for a new project in the tool-du-jour and move the actual code into that structure.

Since there is no obvious right way, there's little consistency between projects - which means you're likely to follow the wrong path if you follow the wrong README or pick an outdated starter template. This forces developers to make a ton of orthogonal choices up front before they even begin coding.

Case in point: https://clojurescript.org/tools/tools lists 4 different build tools without any explanation as to how they relate or why you might pick one over the other. But don't worry, you'll find out after days of tedious research!

If Clojure had a consistent out-of-the-box experience like Go or Rust, I think it could rule the world. It's a great language but the developer experience is a serious impediment to that.

Exactly my experience !
I recently revisited a repository I was working on and almost gave up (on using Clojure) trying to switch from lein to deps.edn. Granted I didn't have to switch to deps.edn, but it felt like it was going to be the way forward.
Perhaps this is due to how much effort folks want to invest in hobby projects? (that's a broad question aimed at several folks here)

At work, we have a codebase of over 142K lines of Clojure, some of which dates back over a decade. We started with Leiningen (because it was the only game in town). We migrated to Boot in 2015 because we needed easier customization of our dev/test/build pipeline and Boot's "tasks" were a more natural fit. We migrated to Clojure CLI / deps.edn in 2018 because we were running into limitations with Boot as our repository grew and our needs for dev/test/build became more complex.

Each migration took about a week of one person's time.

Over that same period of time, I've probably switched my editor setup a dozen times, going back and forth between Emacs and several other editors/IDEs. I've been on VS Code/Calva for quite a while now -- with LSP/clj-kondo built-in, it's a really solid experience.

That's accurate I think. Hobbies are about building something to scratch an itch - and my itch has absolutely nothing to do with configuring editors and build tooling. If I was working on a paid Clojure project, I'd just put in the time.
Ya, I think everyone is aware that the beginner ramp-up experience isn't great, but no one knows what to do about it.

There's a bit of a chicken and egg, because once you know, you know, and the problem disappears, but that doesn't help the next beginner have an easier time.

In my experience, the old tools are generally rock solid and are still viable—deps.edn is where a lot of the momentum is going, but Leiningen still works as well as ever. I haven't actually tried to create a new project from an old template recently, but projects I created with old template still run fine.

The big exception is ClojureScript. I haven't personally noticed bitrot as much as ClojureScript being generally flaky. I think the situation is improving, though, and the unreliability is mostly in compilation and hot-reloading, not at runtime.

I think Clojure could use more funding to improve tooling, but I do think we have made strides with the funding we have.

I feel your pain regarding ClojureScript.

A few years back there was a 3 month window where I had everything (lein,fighweel, emacs) configured just right, and I could reliably start a Clojure REPL, a Clojure Script REPL connected to a browser window, and switch between them from emacs.

It was really productive, I could work on the backend parts, frontend parts, and effortly switch between REPLS, but then there were some updates and I never got it working without friction again.

This is the same setup also I've been failing to reproduce.
Are you using shadow-cljs?
I've used all combinations lein,deps,figwheel,shadow-cljs,cider and cursive, but haven't been able to reproduce the same frictionless setup I had then, something always breaks when switching between clj and cljs files.
I like Clojure the language but what I found frustrating was that even more than in other ecosystems a package would get momentum, become popular, and then mysteriously die suddenly without any real replacement. A classic example was the statistics package Incanter -- it had the potential to become a new version of Xlispstat for the 21st century and then it just died.
Yeah it is too bad Incanter stalled, it could have been an great alternative to Python's data science stack (pandas/numpy/matplotlib) if it had gotten traction at the right time.

It lacks some polish and has some wierd conventions relative to modern Clojure, but I still use it occasionally.

Some languages judge popularity based on "freshness", others on "quality" and others on other values, like "usage in enterprise" and other variables.

JavaScript ecosystem typically goes by "freshness" and "vanity stats", like GitHub stars or NPM downloads. An average JavaScript developer would check out a GitHub repository and look when the last commit was made, and if it's more than a year ago, decide the project might be too old and possibly abandon, and hence not look further into it.

In contrast, the Clojure ecosystem typically goes by "stability", "maintainability" (simplicity") and therefore age or "last commit" matter less. The average Clojure developer will first look into the code of the repository and make the choice to use it based on the code quality. That the project/library hasn't changed the last year or two matters less and might even be a sign of maturity, that the library is "done" so to say.

As a ex-JavaScript developer (together with many other languages) and now full-time Clojure(Script) developer since a couple of years back, I can only say that the community and ecosystem is more alive than ever, and there is no shortage of either jobs or candidates when you're either looking for work or looking to hire Clojure developers.

Yes, the pay is way more as a Clojure developer, which also means a typical Clojure developer is more expensive to hire than say a JavaScript developer. But for projects where I usually had to hire 2-3 JavaScript developers to hit any sort of interesting development velocity, I find it enough to just hire another Clojure contributor to really hit the ground running.

The real value in writing and maintaining Clojure programs is developer ergonomics. There is no other language that hits as many points as Clojure when it comes to make it simple to write efficient and easy to understand programs. Having your editor connected to a REPL and being able to send code back/forward between the running state of your entire program is such a super power that it's hard to write anything else than Clojure after you've gotten used to it.

However, biggest drawback is that you're gonna have to deal with the JVM sooner or later. When I first dove into Clojure, I had no idea about the Java nor JVM ecosystem, at all, so in the beginning, it took some getting used to the whole thing. But, you don't really have to touch Java the language, mostly details around the JVM, and there is a lot of documentation/material around understanding the JVM, so it's not hard per se.

Overall, before I discovered Clojure programming was mundane and I owe the fun in programming to Clojure wholesale. Now it's hard to do anything else but Clojure. But I'd still recommend anyone curious about functional programming, live editing of programs and lisps in general to give it a serious try. I probably wouldn't be programming anymore if it wasn't for Clojure. That I get paid more than my peers because I do Clojure/Script is just another point for the language, but that's not the main point for me at all.

> Some languages judge popularity based on "freshness"

Thank you for that, I'm now imagining my programming session being interrupted by a pair of little cephalopod people in a Japanese street-facing broadcast booth, announcing what today's acceptable front-end and back-end frameworks are[0]. It seems rather on-brand for... some languages.

[0] https://www.youtube.com/watch?v=1h8KFrqyGtU

You make some great points and I want to echo that Clojure is the only language where, when I am evaluating a library or even when I’m using one and want a bit more information, I look at the code.

I’m quite comfortable in a number of languages, especially Python, Java, C++ and Javascript, yet I rarely look at the source code of libraries I use in those languages. With Clojure, it’s something I feel comfortable doing for some reason, so I do it. That does mean that I care more about how easily I feel I can read or modify the code than about when the last commit was (but I definitely do care about how quickly the author responds to comments/issues/PR’s — they don’t have to actually implement or fix anything asked for, just be responsive and offer some pointers, so I know if I ever get stuck, someone will point me in the right direction should I need it, even if I have to do the work myself).

With that said, I’m not currently working in a Clojure job.

It is a very weird unexpected artifact of Clojure being so focused on backwards compatibility. People finish excellent libraries and because they don't need to constantly update them because they still work perfectly ... the vanity metrics look bad and you have to reassure people that the project isn't dead, it's just finished.

It does a very good job at giving developers what they said they wanted, not having to do this constant annoying churn ... and it turns out a lot of people didn't actually want that, they like the churn and the feeling of productivity that merging dependabot PRs gives you.

I am learning Clojure right now and I can relate to the feeling of not wanting to put time and effort into it if there is no marketable value in return. One thing that is motivating me is I read an article about how niche languages can be lucrative. (I want to say that article was here on HN but too lazy right now to search for it). The other thing that is motivating me is that this type of programming and thinking is completely different to mainstream PLs. It is a fun and challenging exercise and my hope is that it will benefit me in "normal" PL like everyone says it will.

I do have a vague (unrealistic??) idea of maybe getting a PT job using Clojure after studying for a year or so. PT because my FT job has amazing benefits and career potential. We will see. As of right now I am just enjoying learning Clojure and Lisp-style language.

Forgive my ignorance but what is a PT and FT job?
> read an article about how niche languages can be lucrative. (I want to say that article was here on HN but too lazy right now to search for it)

I'm not having any luck finding it -- if you find yourself more eager (heh) I'd love to get a link.

Here is the Google Trends Comparison of Clojure, F#, Rust and Scala.

https://trends.google.com/trends/explore?geo=IN&q=%2Fm%2F03y...

Rust is 4-5 times more popular in searches that Clojure and F#. Interestingly Scala is around 3 times more popular than Rust in searches.

The region is set to India though. If you set it to worldwide Rust is much more popular.
Not sure why "Rust" is part of the comparison there either, it is not a functional language by most definitions, although some parts have functional interfaces.
OP mentioned Rust as a language that has been more talked about. GP brought some data to support that.
You’re right that it’s not a functional language, but its type system and developer experience has proved very attractive to a lot of people who normally are drawn to Haskell.
If you are India ("geo=IN" in the URL), then you are correct. If not, then it is not.
Unrelated, but interesting to see C++ overshadowing all of them, even if you look over larger time intervals seemingly without any signs of decline.
Depends on how you judge a language's "liveliness". Hacker surveys or job postings?

In Sydney, Australia C# and Java have the greatest number of job listings.

One benefit of learning functional languages, whether Haskell or Clojure, is that it makes you a better developer in other, non-functional, languages.
can you clarify "how" it makes one a better developer?

When I think of how the java streams API is used, it generates lots of garbage (i.e. lots of intermediary allocs), doesn't always make things clearer.. i'm genuinely curious (and in fact i like the streams API, it's just often misused by collecting at the wrong step..).

Your programmer’s worldview will expand, you’ll learn new ways of doing things.
I think it helps you better understand how data flows through you program.

My input is A, and I need to create D. A -> A', then another function makes B, then another makes C, then another makes D. You can reason about and relatively easily test each of these steps. However, testing in a repl gets quite messy with calls such as h(g(f(x))). In python, you'd need to decorate you functions with an input/output logger.

Testing in a repl is easier and not messy at all if you use the Clojure arrow macro: (-> x f g h) You can see each step clearly, and build each result on top of what you did previously.
> When I think of how the java streams API is used, it generates lots of garbage (i.e. lots of intermediary allocs)

Not extremely relevant because it’s Lean 4 and not Java, but destructive updates can help with that:

https://arxiv.org/pdf/1908.05647.pdf

Edit: Now linking to the right paper.

I can't speak about Haskell, but Clojure's lazy sequences also generate a lot of intermediate allocs.

For example, here's Clojure's implementation of `map`[1]. It internally uses `cons` to build a cell[2] and `map` to recursively walk the collection (but all wrapped up in `lazy-seq` to delay evaluation).

Transducers[3] do help with this if you are applying a stack of collection transformations. But, and this is just my opinion as a very occasional Clojure user, transducers are harder for me to grok and so I generally avoid using them. If I was doing performance critical work, I might try to build up a better mental model.

My biggest complaint about the Java streams API is that it makes it hard to write your own stream transformation functions. Or rather, you can, but then calling them is awkward. You generally transform a Stream by calling instance methods - e.g. `myStream.map(::f)`. But since Java doesn't have extension functions, there's no way for you to make a custom function callable in the same way as the built-in functions. I ended up writing a small shim to build a stream pipeline without using member functions. You would use it something like this:

    newPipeline(stream)
        .then(map(::mapFn))
        .then(filter(::filterFn))
        .then(customTransform())
        .collect(Collectors.toList());
Contrast that to Clojure, where everything's a function:

    (into []
      (customTransform
        (filter filterFn
          (map mapFn collection))))
Or (using the threading macro, I think this is right)

    (->> collection
      (map mapFn)
      (filter filterFn)
      (customTransform)
      (into []))
Or (using transducers, I'm really not sure if this is right)

    (into []
      (comp
        (map mapFn)
        (filter filterFn)
        (customTransducer))
      collection)
        
                      
[1] https://github.com/clojure/clojure/blob/2b3ba822815981e7f769...

[2] https://github.com/clojure/clojure/blob/2b3ba822815981e7f769...

[3] https://clojure.org/reference/transducers

It depends your area of work.

If you're working on graphic engines, quants, system programming, you won't really be using a GC language anyways. There, being a better programmer is a lot about low level in the small design details.

If you're instead working on enterprise or consumer applications, backend processing, big data, information systems, saas, etc. There, you'll find Clojure makes you a better programmer, because it teaches a lot about in the medium to large design skills for growing such systems, where high/medium level decisions matters more and micro-opromizations a lot less.

Things that I've learned from Clojure are:

    * Better grasp of OOP and polymorphism
    * Better grasp of recursion and memoization in general
    * Better code structure for independent, modular, and reusable designs
    * Better isolation of external effects and internal business logic
    * Better, safer and more clear data manipulation techniques
    * Better domain modeling and data modeling 
    * Better handling of data at the boundaries of my application
    * Logic programming
    * Better understanding of mutation/immutable trade-offs
    * Better balance between spaghetti code and lasagna code
    * Monads and other functional patterns
    * Better use of higher order functions that benefit code understanding, extensibility and reuse
    * Better understanding of language design, code parsing and generation
    * Better understanding of numbers in general and numeric tower details
    * Better understanding of dependency injection and stateful components
    * Better understanding of parallel computing and various lock and lock-free designs
    * Better understanding of asynchronous and concurent computing, use of events, queues, CSP, future/promise, structured concurency, etc.
    * The awesomeness of structural edits, homoiconicity, and Lisp in general
    * The awesomeness of interactive live programming
    * Emacs
Clojure is definitely not dead. There are active Clojure user groups in most countries (even in my little region) and i still (or even more than ever) stumble uppon cool and exiting projects and libs (e.g. https://github.com/borkdude. It's just incredible what a surplus value this dude alone provides to the ecosystem)

Clojure may not have the biggest audience but like others said, it generally focuses more on stability, so using libraries that haven't been updated a while is more of a plus-point and don't mean they are outdated.

Personally speaking, Clojure really brought back the joy of programming and i would never willingly go back to developing in a language without a REPL. The tight feedback loop you have while molding a running program in your editor and the constant dopamine drip feed it causes are just too addictive.

"Dead" is a strong word.

Languages that reach the maturity Clojure has never die, they become undying.

There are active Perl groups in some countries. Perl is so undying. Clojure less so, but...

It's a spectrum where Clojure neither has massive adoption (1.51% in SO's 2022 survey [0]) or rapid community growth (compared to hyped or massively adopted technologies).

Clojure is listed as the top paying language in StackOverflow's 2022 survey.

Clojure is an acquired taste. And it isn't a bad one, either!

[0]: https://survey.stackoverflow.co/2022/

> It's just incredible what a surplus value this dude alone provides to the ecosystem)

Seconded; it's pretty jaw-dropping!

> The tight feedback loop you have while molding a running program in your editor and the constant dopamine drip feed it causes are just too addictive.

Well-said -- I've been needing to write some Python recently, and it's only redoubled my preference for Clojure; the Python shell is a poor substitute at best for the Clojure REPL :(

I found it pretty easy to set up a Python REPL in VS Code, which would allow me to do similar things to the Clojure REPL such as highlighting some text in the editor and evaluating. All in all it was pretty close. I guess the only thing that is really different is that it was not connected to the same process I'm debugging, but a different python process. Is that the main thing you're missing?
Yeah, that's it exactly. For me there's a power and an ease of flow that comes from having the REPL in the context of your running software, with access to program state and the easy ability to modify your code as it runs without having to restart anything or lose state, that's really unbeatable.
Yeah, quite different. Technical as much as procedural and psychological.

In a Clojure REPL, you navigate "modules" like directories. And each directory has "files", or vars you've defined. Basically 'cd' and 'ls', but for module-level structures.

So you 'cd' to one "directory", query an AWS service or read a CSV file, and save results in that namespace ("my_namespace/my_results"). While you're at it, you save the results to a JSON file ('echo ... > tests/saved_results.json').

(You type this all into a REPL, no need to save this one-time command in a file. You can always re-run it by pressing UP like in bash.)

Then, you write a function called 'save_to_db()' in your text editor in the "database" namespace that accepts the input and writes to a database. You send that function to the REPL, and in the REPL, run the function on the results you saved from the first step in the var ("database.save_to_db(my_namespace/my_results)".

While you're at it, you 'cd' to your "tests" namespace in the REPL, and write a quick test in your test editor that parses 'tests/saved_results.json' and calls your "save_to_db" function and verifies the database. Send test to REPL (keyboard shortcut), run the test (another keyboard shortcut), fix the code, send updated code to REPL, rinse and repeat.

And this is all in one process, so you only "start up" Java once. Everything else is basically instant.

There's a ton of Youtube videos on using Clojure REPLs. It's really a game changer...

I’m going to be a contrarian here: the answer is yes.

Yes there commercial jobs out there, yes there are big names that use it, but it’s an increasingly insular community, it’s ceased growing, a lot of people have moved on, and it never really found a niche.

Established programming languages never “die” in the sense of dropping to zero, but to the extent that the question is meaningful, Clojure’s dead.

A lot of living languages are based around insular communities. Clojure just fits a niche (people who want a general purpose LISP on the JVM), that's all. I can't be sure though since I am not a Clojure developer.
Clojure goes out of its way to be insular. Creating a PR upstream requires you to have been given access explicitly from Rich Hickey (or whoever admins their Gitlab instance). The Clojurians slack is invite-only. etc.
I can't speak to developing the language, but Clojurians (a very welcoming and helpful community!) is definitely not invite-only.

Linked here alongside other resources: https://clojure.org/community/resources

Oh, and there's a #clojure-dev channel.

My bad, I must have just not been using Slack right.
You think Java of C# (originally) is any better?
Is Java supposed to be the best or the worst here? comparing oneself to the worst is not a good look…

I’d rather Clojure have a nice open tracker system you can submit issues/PRs to instantly (without preapproval) like most Github/Gitea-hosted OSS projects do.

It's an open source project, the benefit of being a bit closed down is that you can then focus on coding instead of scrolling through issues/PR all day. Who wants to do that?
Open source was invented to make the barrier to contribution easier. Putting up a barrier is therefore counterproductive. By your logic, just force everyone to fork their own copy if they want to make changes, so no one has to scroll through PRs/issues.

And they wonder why no one has solved the curse of lisp?

Sigh. Let's address this persistent misinformation.

There are many ways to contribute to Clojure and its ecosystem: https://clojure.org/community/contributing -- and a PR or patch is often the smallest, simplest part of the process because there is a lot of other work involved in making any change while maintaining stability and performance.

Clojure core and Contrib libraries use Jira for collaboration (and GitHub for hosting source code). Anyone can post to https://ask.clojure.org (maintained by the Clojure core team) with suggestions about changes, enhancements, bugs, or even just general questions. The core team and the various Contrib library maintainers are quick to create Jira issues from posts there.

Once all the groundwork has been done on an issue and it is ready for a potential patch, you can get a Jira account approved (if you're a first-time contributor) and you can attach a patch to a ticket there. See https://clojure.org/dev/dev for information about the development process which emphasizes the groundwork necessary for a change to be considered. Many hundreds of people have gone through this process: https://clojure.org/dev/contributors

Anyone can sign up for the Clojurians Slack at http://clojurians.net -- Slack itself forces the "invite" machinery on us but that self-signup link is well-publicized and, like many OSS community Slacks, is maintained by a team of volunteer moderators. Clojurians is on a Pro plan so it has full history/searching available, sponsored by Slack itself (much appreciated by the thousands of Clojurians!).

Disclaimer: I've been a contributor for about a decade. I've contributed to Clojure itself (a small patch for one release) and I maintain five of the Contrib libraries, which all use Jira and patches as their workflow.

The Clojurians slack is... invite only? Not now, not ever. There's some kind of slack boilerplate sign up thing but it's the same as all Slack channels.
This is just not true at all.

Everyone can join the Clojurians slack, it is a very welcoming place, also to newcomers, in my experience.

Everyone can create issues and patches, getting them accepted may take a long time, but the core team does a great job of maintaining high quality and not breaking things.

clojure adoption is slow but still increasing. If you go by this logic any language that isn't the current most trending one is dead. Clojure has it's niche as immutable lisp. That itself has not the broadest appeal but thats ok.
Closure is weird if you’re not already into lisps (I know, I know our fathers’ parentheses). It’s not easy to just pick up and start solving problems, because everything feels foreign.

I don’t know if it’s dead or not, as I’m sure people still love to use it… it just doesn’t have any major upside that’d make me want to adopt it.

Rust, as you’ve mentioned, is the opposite… huge upside out of the box and easy to adopt, so no surprise it’s getting more talk these days.

> [Clojure is] not easy to just pick up and start solving problems

> [Rust has] huge upside out of the box and easy to adopt

Probably this depends wildly on the person, but I found the opposite to be true.

I had bunch of languages under my belt before I learned Clojure, but none of them functional nor s-expressions, so Clojure was very different than the ones I knew. Took some while to get used to, but after a couple of months I was more efficient than I ever was in any other language.

On the other hand, Rust took longer time to be as efficient as other languages I knew, even though it was on the surface more similar to what I knew since before.

So for me personally, it was easier to become efficient with Clojure, even with 0 experience with lisps or the JVM, compared to Rust. I think it's mostly about the surface-area of what you can learn to become efficient. Once you understand s-expressions, there is not much to Clojure, besides memorizing various APIs, but that's easy. With Rust, there is so much syntax to remember, and other rules to follow, while in Clojure the syntax is really simple, so once you get it, you will never fight with what the right syntax is again.

The lisp syntax was my original reason to accept Clojure. You might need a few days to get used to it, but it is far less than any other syntax, and it quickly falls into your muscle memory in a way no other syntax can. Within weeks you master a handful of basic parens manipulation that are all you need to edit and navigate code. That means that you are 100% focus on implementing your solution to a problem instead of switching between doing that and crafting your solution into an alien syntax, assisted by an ide
I managed to avoid being OOP-ed at the beginning of my programming career when I discovered "Mastering Regular Expressions" by Jeffrey Friedl and "Programming Perl" by Larry Wall. It was a close call as I shared a house with a Java programmer who swore Java was the future. Perl was much cooler so I stayed with it and when Clojure appeared it was that much easier to learn, not having to de-OOP myself.
(comment deleted)
Can't speak to the others, but I'm pretty sure the F# team just doubled or tripled in size (it's still small though). Also the GitHub repo is very active: https://github.com/dotnet/fsharp .
Clojure is a wonderful language, but not so wonderful that I can tolerate its slow startup and compile times. I think lots of developers think the same way. Imo any language nit facilitating fast startup and compile is stillborn. Imo the same goes for any language requiring you to setup a "project" or something to get started.
Yeah, Clojure is not great for CLIs, but pretty much every other use case it excels at. For CLIs, there is always Babashka (https://babashka.org/) which works good enough.

For local development, you usually just compile+eval one function at a time as you change them, and those happens under 1ms, not enough to even notice (unless you develop with a remote REPL, but then network is to blame)

For server usage, you usually compile once in CI and put the resulting binary/JAR on the server. A few seconds for startup matters less in those cases.

The drama of slow Clojure startup is wildly overblown, because basically for no other use case than writing CLIs, does the startup time matter so much it becomes a problem.

Indeed, yes.

For development, if you're finding "slow startup" to be a problem, you're just doing it wrong: start a REPL and leave it running -- mine run for days (or even weeks).

I also worked this way, I've had REPL sessions that ran for months, but IMO this is a workaround rather than a real solution. It's a good workaround, but fast startup would be a game changer.

If Clojure would start fast enough, projects like Babashka would not be needed.

It's not a workaround. It's how Clojure is designed, around its REPL, intended for interactive development at its core.

Start a REPL, connect your editor, develop. You can start your apps in the REPL (from RCFs in your code -- Rich Comment Forms) and never type into the REPL. You can grow the application while it is running, you can run tests via the REPL from your editor.

That interactive approach -- working on your application "live" essentially -- is what sets Clojure's REPL apart from other languages' "interactive consoles" (sometimes misleading also called REPLs :)

And, yes, Babashbka is great for running CLI scripts. But that's a completely different use case to a long-running development process.

I'm very familiar with the live editing aspect of Clojure, and I like it a lot actually.

What I am saying is that Clojure's long startup time is still annoying if you want to restart, for example if you trashed your repl session or want to start with a clean slate.

If Clojure would start fast enough it could also be used for CLI scripts and we would not need Babashka at all.

All in all, I think Clojure is a great language, but the slow startup time is still a disadvantage.

Wait, how slow is it starting for you? On my 2012 Mac Mini, a clean clj 1.11 REPL (with no namespaces loaded) starts in under 5 seconds (using JDK 18).
No namespaces loaded is not a very good benchmark IMO, a real project will have lots of them.

I've worked on a large project with many namespaces and dependencies and it took about 20 seconds.

That seems pretty slow, I've never had it take more than 5 seconds, even on large enterprise backend services.

Maybe your service was also initializing a lot of state/components on startup?

Sure it's a disadvantage, but the way you say it makes it sound like it results in a terribly slow development experience where you're constantly waiting for it to start.

The truth is, the development experience actually gives you much faster feedback with almost no waiting time as compared to the majority of other languages.

That means the impact of the slow startup isn't really felt.

I think where slow startup is a bigger issue is actually for certain production use cases, like CLIs, or serverless settings. There it would be awesome if Clojure JVM also started in sub-millisecond, and we didn't have to change to Clojure interpreted like babashka, or Clojure GraalVM native compilation.

No, you are missing the point. Slow startup and long compiles is a hindrance to all kinds of development. You can ask developers to adapt and use a long-running repl, but they won't. Complain all you want about drama and how stupid people are, they still won't choose Clojure.
> Slow startup and long compiles is a hindrance to all kinds of development

What kind of development do you do where you have to recompile the entire program and restart the process on every change? No Clojure developer develops like that, just like no Smalltalk developer would reload the entire environment for every change, or no Rust developer would recompile the entire dependency tree for every change.

In Clojure land, you just compile/eval what changes without restarting the process, that's like 50% of the reason you'd chose to go with Clojure in the first place.

I'm explaining to you why Clojure won't reach mass adoption. I could offer you a long list of situations for which slow startup is a PITA and you would rebut my points by offering workarounds and I would rebut yours by showing why the workarounds are ineffective, and so on, but it would be waste of time. Users (me included) don't want to have to adapt to their tools. Tools that require users to adapt won't be popular. Perhaps you don't get it, but this is reality.
> I could offer you a long list of situations for which slow startup is a PITA

This is exactly what I'm out after. In practice, slow startup doesn't hurt you, unless you use Clojure like you would use NodeJS or any other interpreted language, but that's not how the Clojure community uses Clojure, because it wasn't meant for that.

Knowing how to use a tool for the job it was designed is not a "workaround", it's part of the documentation or knowing how to actually use it.

If you don't want to adapt to your tooling then yeah, don't give that tool any of your time, because you'll just fight it. Trying to use something but not following what it recommends, is just a waste of everyone's time.

Just like I wouldn't spend time trying to use Docker containers as VMs, you should not use Clojure if you constantly want to restart the process. Or sending high-quality videos via email. Or using VGA cables to send TCP packets. Or trying to use Rust to do meta/dynamic-programming. It wasn't made for that workflow, so why would you try to use it that way?

I don't really care about what you or others adopt, the benefits of Clojure is not that everyone/a lot of people use it, but the benefits you get from adopting to the tooling it provides. So if people are not ready to give that a try, good riddance, I won't lose anything because of it.

> I'm explaining to you why Clojure won't reach mass adoption

I don't think you need to explain that, it's a conservative ecosystem for experienced devs, that was the target niche it was always aiming for. It's intentionally built to not reach that level of "mass adoption", mass-adopted, market dominating tools are one small subset of the set of useful software tools.

REPL driven development is great, but there are still tons of situations where you want a full recompile and restart. Slow compile and start time really slow down development.

Recently I was porting a small application from Clojure to Rust, and 'cargo watch -x run' was faster than 'clojure.tools.namespace.repl/refresh' and is more reliable.

> but there are still tons of situations where you want a full recompile and restart

What situations specifically? In my career as a Clojure/Script developer, making servers, desktop UIs, frontends, CLIs, almost anything, I've never had that requirement. So I'm a bit curious of when that would be required.

When you mess up the repl session somehow, for example by starting a http server on a port but not storing the server object. You now have blocked a port, and restarting the server does not work. Or if you run something like (future (while true ...))

There is some wierdness when redefining protocols and multimethods where a good 'ol restart is the easiest way to set things right.

Try working in an ecosystem with fast compile and startup and you will see why it is an advantage

> When you mess up the repl session somehow, for example by starting a http server on a port but not storing the server object. You now have blocked a port, and restarting the server does not work. Or if you run something like (future (while true ...))

That's true, but how often do you end up in those cases? I usually end up with those one time per project, if it happens at all. Once solved, you won't hit it again. Once you know what can hang a REPL session or block a port you want, you usually don't hit those issues again.

> Try working in an ecosystem with fast compile and startup and you will see why it is an advantage

I have, Clojure is not my first nor last programming language I've learnt. Even working with language that has no compile step at all (interpreted languages), being able to edit the program in real-time is still preferably for me, as it's much easier to iteratively come up with solutions.

But of course, not all approaches are suitable for everyone, to each their own, etc etc.

> Recently I was porting a small application from Clojure to Rust, and 'cargo watch -x run' was faster than 'clojure.tools.namespace.repl/refresh' and is more reliable

I think this tells me we differ greatly in our development approach. Because it seems you still practice a kind of traditional TDD.

I'm not saying one is better, but I think this is either a personal preference of style, or maybe you haven't tried the Repl driven approach?

For example, I almost never use REPL/refresh.

Any amount of, delete state, reinitialize the whole app from scratch, be it by restarting the app like cargo does, or some tear-down/re-init like refresh does, is a very different approach to how I use the REPL, where I make many small changes that I hot-reload as I go, never really needing a full refresh.

That allows me to maintain state and context as I code.

Also, small applications are nice, but most real app will grow to be big applications, not sure how `cargo watch -X run` will keep up in that setting, it doesn't just become compile/start times at some point, it's also how long does it take to instantiate your SQL driver and establish a DB connection, start your web server, etc. REPL driven development allows all this to be initialized in the morning when you start your day, and just kept open till you clock out. So all development throughout the day you get instant hot-reloads of the functions you're changing, while maintaining all that state alive as you go.

I've worked with Clojure for years using the REPL driven approach and found I needed restarts quite often, for example when adding updating dependencies or other changes to the project file.

REPL driven development is great, but sometime you want to make sure that you are not using some function that was only defined in the REPL session but not in the source code. Also the REPL session sometime gets in a bad state when printing big outputs, blocking forever with some concurrency stuff or other mistakes.

> You can ask developers to adapt and use a long-running repl, but they won't

I mean, that's a you problem. My team is well adapted.

Does your team also code in notepad exclusively and chooses to not use an editor with IDE features? Cause I feel that's your argument, that people won't bother using any tooling when developing in a language out of laziness to learn to use tooling?

Even if the REPL started in sub-milliseconds, I'd still be connected to a long-session most of the time. Why restart it constantly? There's no point, you lose your state, you lose the context you were in, it take me out of my productivity zone.

I think it's more of a problem in combination with serverless cloud computing.
Babashka is an excellent Clojure runtime with fast startup that I use for all my scripting needs nowadays. Best part is that you can develop with it interactively via nREPL just like regular Clojure. You just run bb --nrepl-server and connect your editor to it.

https://babashka.org/

Slow compile times? You don't even need to compile Clojure to run it.

It only has slow start time, but since you work at an always connected REPL, it's pretty much instantanuous throughout your entire work day. Start it in the morning (takes a few seconds at most), and then it's instant feedback until you clock out.

And for slow start time for deployment use cases that need fast start time, like CLIs, scripts, serverless, you can either use babashka, Clojurescript, or compile Clojure to native using GraalVM.

It's not DEAD as in no one is using it. A good friend who's crazy into Clojure still gets pinged a lot about Clojure jobs, but most of them are asking him to port Clojure to something else. Even he admits that as other languages' ecosystems continue to grow, Clojure is slowly being pushed to the background. He just finished a job to port Clojure to Python on some financial processing engine.
I would not say it is dead at all.

There are still Clojure jobs and new companies using Clojure.

It is a niche language, and I think it will stay a niche language, but that is fine.

I can say that I (like many others) have built a thriving career on Clojure. I like to change jobs every couple of years, and I've never yet had any trouble finding a Clojure job I'm excited about (and I only consider well-paid remote jobs with friendly teams with companies doing something I feel good about). The community is mostly active on the Clojurians slack (currently ~24,000 users) and clojureverse.org.

So -- it's a niche for sure, but a very successful niche, and one that many people are very happy in. There aren't a ton of jobs out there relative to, say, Python, but there are also fewer people competing for those jobs, so it works out fine for individuals. It can be tricky to find your first Clojure job, but I think that's true in most languages.

I plan to stick with it for the foreseeable future, because there's no other language that I like nearly as much, or can be nearly as productive in.

What domains are you using Clojure in?
Banking (e.g. Nubank) and other high stakes applications (e.g. JUXT).

In my small experience, I've been using Clojure for nearly 4 years to implement real-time ML pipelines.

So far: complex data visualization, transportation logistics, voting-related nonprofit, medical research, and augmented analytics. I like to explore new domains :)
Could you expand a bit on data visualization and medical research? Did you develop libraries in these fields? Thanks!
For the US, Google Trends reveals that Clojure's heyday came in 2013, and it has been on a decline since[0]. It never really reached the interest level of Scala, and of course recently Rust is consuming all the air in the room.

Except, just for kicks I add Golang, and it turns out that all of the above are marginal compared to Go[1].

HN posts are very different from general interest, but yeah, I'd go with "Clojure has sadly missed on its shot to become a popular general-purpose language" rather than "Clojure is dead," but your instincts seem right.

0. https://trends.google.com/trends/explore?date=all&geo=US&q=%...

1. https://trends.google.com/trends/explore?date=all&geo=US&q=%...

Clojure never had a "shot to become a popular general-purpose language". That was never its goal. Popularity is not a useful measure of whether something is actually good technology.

Clojure is designed to solve hard problems, for people who want something objectively "better" than mainstream tools. That's why it tends to attract more senior developers -- people who've felt the pain of other languages and want something better -- although we also see a steady stream of new developers who are interested in better tools even before they've felt that pain.

Of course it's niche -- it's a Lisp! It's alien. It's "too different" for many companies or many developers to even consider it. And that's fine. The space is big enough for niche languages to thrive and for developers to build careers on them, if they wish to do so.

(comment deleted)
Even in the most naive models your "market value" is based off Demand (how many jobs) AND supply (how many people can do the job), you need to be concerned about the ratio, not one side or the other.

If Pytyon has 100 jobs and 100 people then the ratio is 1 If Clojure has 10 jobs and 5 people then the ration is 2 and Clojure has a healthier market for you then python.

Typescript, Python, Kotlin, C#, Rust, Swift, Go. In that order, these are the >1% marketshare langs for new projects that aren't maintenance-mode in the next decade.
I moved away from Clojure to Common Lisp. The Clojure culture doesn't take seriously developer experience, good documentation, easy getting started pages etc. Plus you have to deal with the JVM and slow compile cycles.

Compared to that Steel Bank Common Lisp is rock solid and just works. Even the libraries and documentation are fewer but better.

I did learn a lot from watching Rich Hickey's talks so there's that.

Really? I have the opposite experience. I _want_ to love CL but Clojure wins when it comes to IDE support and libs and documentation.

Maybe it's just me but I find (SB)CL tooling to be very obscure: ASDF, QuickLisp, Roswell etc. My main issue with it is that it's all written in CL itself and doesn't provide handy CLI tools to execute common tasks (compile app, build package, run tests, deploy etc.). Not to mention that documentation is horrendous.

Basically, I want it to have something like Maven/Gradle/Leiningen to manage dependencies, run tasks and so on. Am I missing something?

ros init and ros build should be everything. And emacs for the tooling. Quicklisp for dependency management. Having said that even CL is not perfect. Something like https://fresh.deno.dev/ is so much better when it comes to presentation and ease of use.
I use CL and am currently learning Clojure. I think there are generally more libraries for Clojure and better communities (in some way). Maybe it's due to the JVM, I dunno.
Just to leave some hints for people. - If you don't want to deal with the JVM, Clojure also runs on the Web and .NET. - If you develop with the REPL you don't have compile cycles - Or just use Babashka (no compilation needed)
I find this hard to believe.

I believe you that you haven't see much about Clojure over past 2 years of so. But the cause might be that you simply haven't looked at Clojure in the past 2 years of so. OTOH, I've seen plenty of Clojure in the same 2 years. Perhaps most of news/fuzz is about Rust, but I haven't seen much of that, since I'm not following the news sources that talk about that.

In the end, it depends what you want to do. If you want a great programming language with vast ecosystem and decent number of job opportunities, Clojure is still the thing. If you wish to participate in the most mainstream thing, I believe the Python/Java/Javascript is the answer. But then you're competing with 30 million of other job seekers there.

Perhaps Clojure can't rival the Cardashians or Lady Gagas of this world in the amount of news (for better or worse).

Clojure has probably had its heyday, but it's quite far from dead.

The main issue is that there are other JVM languages nowadays that don't suck--that wasn't the case back in 2009. So, if you wanted the Java ecosystem but didn't want Java, your choices were quite limited. You had Scala (just ... no) and Groovy (oh, hell, no) and ... Clojure.

Since then, Java, itself, has gotten a lot better, and there have become a plethora of JVM languages since. In addition, a lot of languages now have "package managers" like lein. They have also adopted "default const-ness". So, a lot of the issue is that things that were unique to Clojure are no longer that unique in this generation of new languages. Finally, the JVM ecosystem doesn't have the same enterprise pull that it did 10 years ago ... enterprise installations back then only had the JVM, while now you can generally count on a version of Python also being installed.

Computer language adoption is slow in spite of what everybody thinks. Pick a language that you can use as a tool for the future, and don't worry too much as long as it isn't actively un-popular. You'll have to learn a new computer language about once every 15 years anyway.

Thing is that Clojure is a very different language from Java in pretty much every way. People who use Clojure are typically drawn to it because it's a Lisp and facilitates interactive development. I highly doubt that it's popularity is significantly affected by languages like Kotlin that try to be a better Java.

If you're looking for a Lisp that you can use in production then Clojure is your best bet. This is the selling point of Clojure, and why it's unlikely to be displaced by newer JVM languages from its niche.

Clojure being a lisp on the JVM is was what first drew me to try it out. Clojure being immutable-first, data-oriented, and having a core library based largely on the seq abstraction was what hooked me.

The lisp REPL benefits are wonderful, and I miss them all the time in other languages, but I also miss the overall design philosophy equally as much. Value-based data structures with atomic updates where necessary is something that ought to be the default for our industry. Give it another 40 years to settle, I guess.

Yup, once you come to appreciate the elegance of Clojure, most other languages start feeling very clunky. Completely agree that defaulting to immutability was an excellent decision.

I also find that having everything operate on a common set of data structures makes it very easy to build data processing pipelines. If I use a library, I just have to know what data it takes as an input and what it produces as its output. The data is transparent and inert. I don't need to know anything about the internals of the library worry about any special behaviors.

On the other hand, if I'm working with OO based language, then library APIs are object graphs, and objects are opaque and volatile. I now have to worry about the behaviors of each individual object in the graph, and their state.