Ask HN: Is Clojure Dead?
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 ] thread2. 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.
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.
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).
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.
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.
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 just mean that things are improving less quickly than they are for, e.g., Typescript?
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 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.
What I am kinda saying is that Clojure would be in a better place if it was paying people like you a lot more!
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.
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.
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.
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.
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.
It lacks some polish and has some wierd conventions relative to modern Clojure, but I still use it occasionally.
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.
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
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 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 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.
I'm not having any luck finding it -- if you find yourself more eager (heh) I'd love to get a link.
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.
In Sydney, Australia C# and Java have the greatest number of job listings.
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..).
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.
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.
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:
Contrast that to Clojure, where everything's a function: Or (using the threading macro, I think this is right) Or (using transducers, I'm really not sure if this is right) [1] https://github.com/clojure/clojure/blob/2b3ba822815981e7f769...[2] https://github.com/clojure/clojure/blob/2b3ba822815981e7f769...
[3] https://clojure.org/reference/transducers
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:
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.
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/
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 :(
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...
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.
Linked here alongside other resources: https://clojure.org/community/resources
Oh, and there's a #clojure-dev channel.
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.
And they wonder why no one has solved the curse of lisp?
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.
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.
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.
> [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.
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.
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).
If Clojure would start fast enough, projects like Babashka would not be needed.
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.
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.
I've worked on a large project with many namespaces and dependencies and it took about 20 seconds.
Maybe your service was also initializing a lot of state/components on startup?
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.
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.
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 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.
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.
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.
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
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.
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.
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.
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.
https://babashka.org/
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.
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.
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.
In my small experience, I've been using Clojure for nearly 4 years to implement real-time ML pipelines.
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 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.
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.
[0] https://survey.stackoverflow.co/2022/#technology-most-loved-...
[1] https://survey.stackoverflow.co/2022/#technology-top-paying-...
https://www.hyperfiddle.net/
https://pathom3.wsscode.com/
https://github.com/HealthSamurai/matcho
Just got my second job in Clojure nearly getting on for double my before Clojure salary
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.
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?
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).
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.
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.
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.
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.