Looks like a pretty solid release, very happy that Clojure is still going strong!
This is really a massive release with many cool new features
My personal favorite is add-libs
You can now write single file demos or minimal examples for issues. Really lowers the friction to share small runnable snippets with people
You can also actually use it to demo Java libraries as well without all the Java boilerplate. Just poke around in the REPL and paste code into a comment on HN or wherever and anyone can replicate your "setup" and get it running exactly the same. No need to clone a repo or anything
Note that Java has a REPL now and scripting support, although something like add-libs is still missing from available meta commands.
Java's REPL is like a kick in the nuts compared to using one in Common Lisp. How does Clojure's REPL feel like in comparison?
Haven't used neither Java's repl nor Common Lisp (just read about both of them) but at a glance Clojure's repl is much closer to CLs repl than Java's.
In fact, I think it's confusing to call the repls of language like Ruby, Java, JavaScript et al "REPL" at all, compared to what lisps offer, as the experience is so different. They're more like "Code evaluators" than anything else.
Typically when using repls outside of lisps, you'd type your code into the actual repl window, while in lisp-land you typically connect your editor to the repl and program like usual, selecting stuff to evaluate and so on.
repl as a name kind of describes the requirements for something to be a repl - it has a read-evaluate-print loop. It would be more confusing to say that something with a read-evaluate-print loop isn't a repl.
Yeah, the problem with "REPL" is that it underdescribes what Clojure, Common Lisp, etc. can do, not that it overdescribes Ruby, Python, etc.
In fact, I think it's confusing to call the repls of language like Ruby, Java, JavaScript et al "REPL" at all
Agreed. I always call them “consoles,” since I work largely in JS and that’s what the browser calls it. There’s no way in a console to jump into a module and modify a single function without resetting any state that the module was tracking.
Many tools are like that, unfortunately Common Lisp didn't took off, and we are still catching up, see Python and Machine Learning, instead of using a powerful dynamic language with native compilers.
However that doesn't mean Java REPL is useless.
JBang can grab dependencies for you.
Cool! You should post an example :)
Just tested it:
You run `clj` to get a Clojure REPL
Then you can for instance paste the following into the REPL
(add-libs {'thi.ng/geom {:mvn/version "1.0.0-RC4"}})
(use 'thi.ng.geom.viz.core)
(use 'thi.ng.geom.svg.core)
(->> {:x-axis (linear-axis
{:domain [-10 310]
:range [50 550]
:major 100
:minor 50
:pos 150})
:y-axis (linear-axis
{:domain [0 4]
:range [50 150]
:visible false})
:data [{:values [[0 100] [10 90] [80 200] [250 300] [150 170] [110 120]
[210 280] [180 280] [160 240] [160 170]]
:attribs {:stroke-width "10px" :stroke-linecap "round" :stroke "#0af"}
:layout svg-stacked-interval-plot}]}
(svg-plot2d-cartesian)
(svg {:width 600 :height 200})
(serialize)
symbol)
- the first line downloads a library and adds it to the running session- the second and third line add the library to the REPL's default namespace
- the rest of the code makes an axis and plots some random values
- the output is then serialized and send out the REPL output
You should get a little SVG plot on the output
PS: Make sure you have version `1.12` by running with `clj --version`. If not, then (re)run the instructions here to get the latest version: https://clojure.org/guides/install_clojure
Using (add-lib 'thi.ng/geom) is sufficient here - it uses the newest version by default.
Parent specified a RC version, does it automatically use the latest RC versions as well? AFAIK, it only uses the latest stable version, but I could be wrong, it happened before.
Here is an example playing with BooFCV's Java API
It'll pop up a little window displaying an image
(add-libs {'org.boofcv/boofcv-all {:mvn/version "0.35"}})
(import 'boofcv.alg.color.ColorRgb
'boofcv.core.image.ConvertImage
'boofcv.gui.ListDisplayPanel
'boofcv.gui.image.ShowImages
'boofcv.io.UtilIO
'boofcv.io.image.ConvertBufferedImage
'boofcv.io.image.UtilImageIO
'boofcv.struct.image.GrayU8
'boofcv.struct.image.ImageType
'boofcv.struct.image.Planar
'java.awt.image.BufferedImage)
(let [image-url "https://kxygk.github.io/web/chengdu.jpg"
color (ConvertBufferedImage/convertFrom (UtilImageIO/loadImage image-url)
true,
(ImageType/pl 3 GrayU8))
weighted (GrayU8. (.width color)
(.height color))
gui (ListDisplayPanel.)]
(ColorRgb/rgbToGray_Weighted color weighted)
(.addImage gui
weighted
(str (.width color)
" "
(.height color)))
(ShowImages/showWindow gui
"RGB222"
true))
Does anyone remember Groovy? It has @Grab annotation which does essentially the same as add-libs you described. Very conventient for writing scripts.
Jbang has a similar feature: https://www.jbang.dev/documentation/guide/latest/dependencie...
Does anyone remember Groovy?
I recall that Atlassian had some kind of scripting console where you could run Groovy and interact with its API / objects. It was useful for exploring when writing plugins for bamboo or Jira ...
Yes! Groovy does have quite a few under appreciated cool gems, and it’s a shame that is barely getting any attention nowadays..
This is a wonderful language I've only just started paying attention to, watching the talks from Rich on YouTube have ruined things I loved (like Either types.) I'm struggling with how to introduce it into my company without recommending my colleagues follow my path of working through 3 books and then watching most of the conj talks from the last 12 years on 1.75x speed, while building a personal project and re-implementing a couple of services I work with every day in it... but the lessons around simplicity I think are so critical, I'm going to find a way.
Every company likes to hear about increased productivity and less bugs, and that's what Clojure/Script gives you. The trade-off is you get less resumes when hiring. The plot twist is the resumes are much higher quality.
Ha.
I personally have sat in a meeting where a clojure enthusiast was explaining how he had quickly built a system.
He could not explain the code he had written only three weeks before.
Clojure suffers heavily from a “less code is good code, write clever code not verbose code” culture.
For newcomers this creates dumpster fires that are quick to create and impossible to maintain.
Anywaaay, long story short: no. It doesn’t.
Specifically, I’ve seen it be a dumpster fire three times.
Perhaps your experience has been different; but you are flat out wrong in your generalisation; and that arrogant attitude has been the root cause of all three failures I have personally had to clean up after.
People who complain about verbosity and boilerplate in Java generally fall in 1 of 2 categories: people who haven't used Java for anything non-trivial in a very long time, or people who are bad at designing abstractions.
Less code can be good code, but they largely are orthogonal axes. Without good abstractions, it doesn't matter whether code is dense or verbose, it will be bad and difficult to grok.
Having done substantial work in both Java and Clojure, my experience with abstraction in both is that in Java, making things more abstract almost always involves making the code larger (adding more interfaces, extending existing types to those interfaces, etc) whereas in Clojure making things more abstract typically means they get smaller.
Over time and at scale, this matters quite a lot. Java code grows and grows at a super linear rate as it handles new and changing requirements. This is ultimately not sustainable. Clojure code typically grows at a more linear rate (accretion of attributes in data or operations on data), but has more tools to create abstraction that can actually (if wielded well), be sub linear instead. This kind of change is not free or easy in any language, but in Clojure it is at least possible.
Honestly, maybe don’t. You love Clojure, that’s awesome. But introducing it at your company if it does not have a lisp culture already might not go so well. You say so yourself: lisp dialects like Clojure come with a steep learning curve, and not everyone will appreciate the shift, especially if they're comfortable with the current stack.
Forcing it on your team could create frustration, confusion, and a lot of resentment, not just toward the language, but possibly toward you. Sure, you might convert a person or two, but most will likely see it as unnecessary complexity.
If you really want to write Clojure every day, you might be better off finding a company that already embraces it instead of trying to turn your current team into Clojurists. Sometimes it’s better to enjoy something for yourself than to make it everyone else’s problem.
I'll second this. Many people are happily complacent with mainstream languages. A minority ventures out in $lang of the day for the fun of it, with functional languages being an even smaller minority.
At a minimum, build some strong clojure skills first, such that when you introduce it to anyone else, you can do so with confidence
it is better to have +1 company with Clojure (potentially hiring), than +1 Clojure dev looking for work
left-right-thingy makes me chuckle every time I watch "Maybe Not"
The way is to drop Clojure and adopt it's principles. Teach your colleagues the functional engineering principles.
You can write code that looks a lot like Clojure in any modern language now, a lot of the functional primitives have been adopted in mainstream. e.g. Async/await => channels.
I started my career as a Clojure/Clojurescript developer 12 years ago. And now I do python for ML research and Typescript for prototyping all day.
Clojure honestly help me back a lot of the time because the tooling is so far behind the large programming communities. Functional programming has a lot of good ideas, but none good enough to leave behind all the packages on pip/npm.
I would only ever advise niche programming languages for small sub-teams that are highly technical were it makes a lot of sense. Something like compiler teams, webgl/triton for GPU programming, etc...
I've been at an organization that went from Java to Clojure about 12 years ago. I think there were two main things that allowed us to make the move:
* No one was in love with Java. It was fine but we were doing the whole spring style super verbose Java and it felt like a lot of ceremony to get anything done. There had been an experiment with Scala previously but that hadn't taken off.
* We had a service-oriented architecture which meant we could try Clojure out on a few new services and see how it felt.
We ended up going from 2 services to moving the whole org over really quickly. A lot of excitement built up and people didn't want to be left out. At the end of things only 2 people decided they didn't want to learn Clojure.
A few other things we did:
* Bought loads of books and left them lying around
* Started a Clojure club where we booked an hour a week and did some exercises in Clojure
* Had a big meeting where we convinced everyone that Clojure was worth an experiment
* Brought in 3 consultants to do some Clojure training for everyone
* Probably strong armed everyone into watching simple made easy - it helped that lots of people had already seen it live that year
There are a few talks about it floating around although they are very very old now and I'm not sure they're worth the time!
https://whostolebenfrog.github.io/clojure,/deployments,/clou...
Find the least important project that one person can take on, and have that be the prototype for the clojure stack.
Ideally, use someone well versed in the tech stack - otherwise, you're taking on double risk of a new tech stack plus unfamiliarity. This prototype needs to demonstrate the value of the clojure stack - which has to have a business value (aka, speed/ease of maintenance etc).
Convince the decision makers to use clojure after the above prototype showed value, and use it to extrapolate value for other projects. This will then require a transition from doing the project, to teaching others (who might not know clojure at all). You cannot rely on just telling people to watch videos or read books - they won't do it, and it will cause failure in subsequent projects.
You will have to hand hold, until the newbie "clicks". Unfortuantely, this is an uphill battle, because management will always want to hire for the "regular/normal" tech stack, and will have trouble finding clojure-ready people. So the company will continue to have to invest in teaching it to new hires, which is a drain that could tank the clojure move.
It's funny because I went the opposite direction - from clojure to Rust, and I feel my programs are more maintainable, easier to re-read code written by myself and others, and runs without needing to bring along a virtual machine.
I do like Rich's talks and agree that static typing can be taken a bit too far though.
ClojureScript in particular is much nicer to work with compared to JavaScript
Dont. It wont be appreciated because nobody but you can work on it, and one day you wont work there anymore and the company is stuck with a few projects in Clojure while the rest is on their regular tech stack. You are creating a major company risk just for your own personal benefit.
Lovely to see add-libs and sync-deps, aren't many (any?) reasons to close down a session at all now.
This release feels like it had a very different scope from previous releases, contains a lot of stuff, which is exciting to see! But I hope it doesn't end up like a hairball a few releases down from increase of pace or something.
But I hope it doesn't end up like a hairball a few releases down from increase of pace or something.
Rich Hickey and the rest of the Clojure Team are very careful designers. I wouldn't worry too much
Rich Hickey and the rest of the Clojure Team are very careful designers. I wouldn't worry too much
I am aware of this, which is why I suppose previous releases haven't included as many features at once as this one. It's this possible change of pace that raised the question in me :)
Add to which, a lot of "new, big features" come in libraries, not the core language itself.
But my point is specifically about the features mentioned in this very release, which are all in the built-in clojure namespaces. Or did I miss something from the release notes?
In fact, the separate libraries have their own release process and isn't part of this release at all, as things should be. So not sure what you're referring to here exactly?
So not sure what you're referring to here exactly?
That the size or pace of this release alone should cause worry about future hairballs.
Pure speculation but I believe this is the first release since Rich Hickey left nubank so could be more attention from him.
They've also hired Michael Fogus to work on Clojure, so more resources are definitely being put into developing the language.
Dumb question: what is clojure usually used for ? (in my view, Java is for "enterprise" stuff, python for AI/data sciences, C for performance, etc.)
"Enterprise" stuff in a much less "enterprise" way is one usage, hence being based off the JVM. Rich Hickey has also mentioned the concept of "situational programs"[1] which Clojure is used in a lot. Clojure is also used in a wide variety of other areas like data science[2] or desktop applications[3] much like other general purpose programming languages.
[1] https://youtu.be/2V1FtfBDsLU?feature=shared&t=639 [2] https://scicloj.github.io/ [3] https://github.com/HumbleUI/HumbleUI
A lot of banking/finance use cases.
It is a general programming language (with great interop with Java). You can pretty much build anything with it - web apps (backend + frontend), APIs, Scripts, etc. Anything you can do in Python / Java you can do it in Cloujure. It even has libraries for data crunching (or can use Java libs).
The same advantages of java in a lisp-like shell.
NuBank, OneStudyTeam, CircleCI, and Guaranteed Rate are some of the larger companies I know about personally that have significant investments in Clojure.
I thought they were going to hold this until Clojure/conj 2024. No particular reason to believe so (besides Clojure 1.10 being released around the same time as Clojure/conj 2021 and the Datomic-becoming-free announcement being done at the very start of Clojure/conj 2023).
Still waiting on spec2, though... for now I am working around rigidity of specs by using Malli but it really isn't a first-class citizen in Clojure (mostly due to inability to check macros, and this is by design of the Clojure compiler). But you can emulate the ideas of schema/select by manipulating malli schemas as data.
The changes for functional interfaces also means we no longer have to maintain utility macros like
(defmacro ->Consumer [f]
`(reify java.util.function.Consumer
(accept [this arg#]
(~f arg#))))
and instead just pass functions directly.What do you mean by “inability to check macros”? You can s/fdef macros with spec and it checks the calls at compile time. In fact Clojure core uses spec to check macro calls as you can see in the stack trace sometimes when you call one wrong. Do you mean something else?
Here's what I mean by Malli's inability to check macros.
https://github.com/clojure/clojure/blob/ad54fec/src/jvm/cloj...
The Clojure compiler directly calls into clojure.spec and does not expose any sort of hook for validating macros. No library can validate macros except clojure.spec. In this sense, Malli feels like a second-class citizen in Clojure compared to the built-in clojure.spec.
Ah thanks for explaining! I did not know they special cased spec. I hope that changes.
I really wanted schema/select after watching “maybe not”, so wrote a library for malli: https://github.com/eval/malli-select
Clojure is great. Brining together Lisp with the Java ecosystem makeand its concurrency model makes it great for building backend system, while still enabling quick changes. One thing that I found noteworthy is that Clujure did not pickup some innovations happening at Java since like version 8, such as Invoke Dynamic in the JVM or streams.
Generally for streams, the equivalent in Clojure with sequences or transducers is much cleaner and simpler so there was not a lot of reason to want them from Clojure. However, it is important to provide interop paths to work with Java libs that make use of them.
The functional interface coercion is implemented with invokedynamic.
What had become of spec? Abandoned? Any news on hopes for it?
It continues to exist and is in use. Lots of work has been done on a successor, but that is stalled while we consider what we want to do on various things.
We had to dump a Clojure code base for Golang because it was too slow for lambda usage. Does any of this release help with startup time?
Does any of this release help with startup time?
Clojure (and indirectly Java) was never created with "fast startup speed" in mind. This is why things like `add-lib` (that was added in this release) is so useful, because you start your developing session once, and it stays open until you either have to restart your computer or done developing the project.
Then the typical deployment target is either "Push this .jar to a server somehow, start the process and let it run" or "User double-clicks executable, waits for application to be ready".
If you really need fast startup, you can go through something like https://github.com/ionutbalosin/faster-jvm-start-up-techniqu...
Or if you're fine with slightly worse runtime performance, give https://github.com/babashka/babashka a try
Finally, if you're OK with JavaScript you could give ClojureScript a try, has fast startup (as fast as NodeJS I suppose) but yeah, it's JavaScript.
But overall, Clojure/Java isn't optimized for the use-case of "Start process for each request, stop process once processed" so I'm guessing you'll face an uphill battle there.
If you're interested in learning more about Clojure, check out the Clojure/conj conference Oct 23-25 in Alexandria, VA. https://2024.clojure-conj.org :)
Lots of cool improvements. The main Lisp like language I usually reach for.
Fantastic. Sure would love to get a clojure job one day.
sync-deps and add-lib seems very cool
Such a pleasure to get a boatload of new features and all my code just runs on it because of the hard work dedicated to avoid breaking changes.
The functional interface changes are huge. Clojure is always at its best when staying close to Java via judicious use of interop and this solves one of the major missing links.
Is it going strong? I'm evaluating it for a new project. I'm considering it together with Clara[0]. However, it does give a vibe that it's not as mainstream as it was before and that the ecosystem is more sparse than what is once was.
I'm not trying to troll. I want to choose it. It seems like a good engineering decision to me, but if it's nosediving in popularity and contributors, this might bite me back in the near future.
[0] https://www.clara-rules.org/
I found myself frustrated a lot when I used it two years ago. A lot of abandoned libraries. There's not a huge ecosystem around it compared to golang and other popular languages, but there's probably enough that it's a viable option if you really want to work with the language.
I think there is this misconception that lack of activity on libraries indicates they aren't worth using. But I strongly believe a lot of libraries are just feature complete and bug-free enough to leave them be. The syntax of the language changes so minimally that libraries don't have to change at all after updates. This isn't Javascript where everyone keeps tweaking things over and over again.
The problem this creates is that as a potential consumer I can't tell the difference between "effectively done" and "abandoned, half-done, and about to waste a lot of my time".
I don't see an easy answer to this because having "done" be an available state is extremely attractive, and forcing extra work on the author would be the wrong thing to do.
Well, picking libraries shouldn't be done willy nilly by looking at the stars in a github repo or that they contributed 5 minutes ago. There are many curated resources that help pick libraries. Here is a great one: https://www.clojure-toolbox.com/
I agree, solid working libraries often don’t need frequent updates. Sort of Common Lisp: a lot of old very stable code that just works fine.
Also the whole/part of the point of being hosted on the JVM is if there isn't a clojure lib for something you can just use a Java lib.
Something I've found to be more true of Clojure libraries than those in most languages is that they can be finished. Once the code does the thing it set out to do, there's often no need to do anything else. The language is unlikely to break compatibility, and idiomatic code tends to be mostly functional with very clean interfaces.
The one example I can think of where that's emphatically not true is clojure-android, which was tightly coupled to the Android SDK and did not remain usable after the main developer moved on. The Android SDK does not share the aforementioned traits.
Exactly.
Find a random node package that was last changed 4 years ago and it might as well be toxic waste.
Find a clj lib with the same stats and it's probably going to work smoothly.
I find this to be the case in Lispy languages in general (CL, Scheme, Clojure..); I go looking for a library that does X, only to find that someone wrote one more than a decade ago. It looks weird coming from more fast paced languages, but Lisp maintainers tend to their libraries carefully and might tweak them over the years but they're mostly complete already.
I know a lot of people are making the case libraries are just finished not abandoned, but your feelings are valid. It’s like investing in a really low yield but dependable bond, when everyone around you is making huge gains on tech stocks. I like libraries that get more featureful over time, but sometimes you watch your friends go broke.
There are opportunity costs too, maybe you can say Spec is perfectly fine but you’d be forgiven for having mixed feelings with a massive codebase built on that in a world where many have moved to Malli or elsewhere.
But let’s also be honest, loads of promising Clojure libraries do get abandoned, not finished. ClojureQL was a brilliant, composable approach to writing SQL queries but never reached its potential and was left in a fairly buggy state. I’m probably four or five Clojure data access libraries on from that in my career now. Om was highly influential but good luck if you made an investment in that. Incanter could have been enormous but failed to reach critical mass and you’d be crazy to pick it up now. There’s ‘core’ stuff like core.logic that feels like a decade old unoptimised proof of concept that didn’t follow up any of the interesting paths it laid down. Heck, I’ve even got code that relies on libraries from Chris Zheng, who quit the scene after getting a deserved dressing down from Rich Hickey after complaining about the Clojure development process.
None of this is a moral failing on the Clojure community, and there’s no reason to be defensive about it. It’s a small ecosystem and it’s very hard to build critical mass. Clojure people often have magpie brains that pull them to work on new things. You’ve got to judge it for yourself.
Sad to hear about your experience.
I found it to be the opposite. In Clojure you have Clojurists Together: https://www.clojuriststogether.org which funds people to work on Open Source libraries. And more importantly there is Clojure Commons: https://github.com/clj-commons which takes popular Clojure libraries, that are no longer being supported and carries on looking after them.
When I found popular Go libraries that have been abandoned, I asked in the Go community, if there are such initiatives, especially seeing how Google is behind Go. When people didn't understand what I meant, I pointed them at the examples above, from Clojure. To which their response was "TIL, Clojure, never heard of it before! No, we don't have such initiatives in Go."
Maybe the initiatives from Clojure Commons & Clojurists Together need more visibility for the newcomers to Clojure?
This is my favourite example of a not-abandoned library: https://github.com/candera/causatum?tab=readme-ov-file#liven...
"As of this writing (25-Sep-2014) I consider this library alive and well"
... "Update 2017-Oct-16: Still true. :)"
This library has been done-done for a decade now. I used it last week.
What you’re seeing sounds familiar but definitely not new. I’ve used Clojure professionally for 15 years and at no point in that time have you been guaranteed critical mass around any library or framework. Clojure has always been a small ecosystem of high variance people and projects. You get things like Rama and Electric which are bold reimaginings of what systems could look like, but you also get a lot of short lived, burnt out efforts that fizzled.
The good news is nothing really _breaks_ ever, and you have access to the entire JVM ecosystem if you want it (many Clojure people find Java interop icky which I personally find moronic).
Ironically, Clojure seems to be the only guest language on the JVM where the community is welcoming of the platform that makes their existence possible in first place.
Similarly to how Groovy used to be, but I am not counting it as it seems only to be around to power Gradle and little else.
Scala and Kotlin folks speak too much about replacing Java, yet I am yet to see their native variants match JVM in any form or fashion.
Even if we take Android into consideration, Google was forced to update their Java support, as means to keep Java libraries ecosystem available for Android developers and their beloved Kotlin.
Electric looks outstanding. It seems like the sort of thing that would take some time to spread but once it does and people take the time to learn it it could be huge.
I don’t do much Clojure anymore (I wish I did!) but agreed on all points. The JVM interop is such a huge, huge advantage that it’s hard to express to people who aren’t used it.
Clojure's slow, deliberate development pace confuses people. The core team takes backwards compatibility very seriously. What you see with each new Clojure release is generally improved performance, better Java interop, and a smattering of new features. This is doubly true for 1.12 which is doing quite a bit of invisible work to make interop considerably better.
So what you don't see is a constant flux of "innovation" followed by a community having to adapt to those innovations. People pull Clojure examples out of books that are 12 or more years old and they still run.
I think there's some very exciting things in the Clojure space, such as Clerk (https://github.com/nextjournal/clerk) for live notebooks, and Babashka (https://github.com/borkdude/babashka) for amazing (and amazingly fast) scripting.
I guess that the GP didn't talk about the language itself, but the users. For me it looks like Scala and Clojure had lost many of its users because of Kotlin and newer Java versions. Generally I see a decline in the usage of functional languages since their heyday in the 2010s. I guess that's because imperative languages either get "functional features" or are "functional enough" - new ones like Rust or Swift.
Clojure is more lindy than Scala.
If someone tells you their project is written in Scala, Golang, Groovy, Coffeescript it almost dates the project doesn't it? Not so much in Clojure.
It's niche but I can bet it's still going to be there 10 years from now, going at least as strongly as now.
Its dead in the water. Sure, some people like it for their private projects and I'm sure there are some commercial products but I wouldn't touch it. I dont particularly like Scala either but at least it has Spark which means it'll be around for decades.
Scala for spark is in decline too - people prefer the Python bindings for some reason.
I'd also look at
https://github.com/oakes/odoyle-rules/
I think the userbase is slowly shrinking, but I'd personally use Clojure even if all Clojure developers disappeared tomorrow. It's not built on shifting sand as the JVM is stable. If you need really niche/cutting edge stuff you're probably going to need to dip into Java or JS interop anyway
Thanks for the link! I’m not the parent poster, but I was thinking of using Clara Rules for prototyping a game idea and to get some experience with rule engines. I don’t think that truth maintenance (which is handled by Clara and not O’Doyle) is important for my use case, and O’Doyle looks simpler to pick up.
Reagent is the clojurescript wrapper to react Reagent has the same API and the same best practices since 2014 Meanwhile, react changed from creactClass to extend Class. From classes to function components.
Many clojure libraries are simply done. There is no reason to commit everyday to a project.
There's another Clojure rules library worth considering. It has a section in the README about why you might prefer it to Clara.
https://github.com/oakes/odoyle-rules
NuBank[0] mainly use clojure for most of their software, and NuBank is a big yet quickly growing company.
[0]: https://en.wikipedia.org/wiki/Nubank
I'd categorize Clojure as stable but niche. It's not nosediving in popularity, but I don't think it's growing by leaps and bounds either. Many libraries are also stable, in the sense that they are finished - sometimes people will see no activity on a GitHub project and assume it is dead when in reality it's just done. Clojure libraries tend to be very small and focused, and often no Clojure wrapper is needed at all due to the ease of Java interop.
I love Clojure, and it's been great for me and all the professional teams I've worked on that use it.
The really nice thing about Clojure is it runs on the JVM.
The entire ecosystem could die tomorrow, and you can still compile new Clojure code for any system that supports Java in the future.
From the last view developer surveys I've paid attention to it didn't seem like Clojure was growing much but it's definitely still large enough of an ecosystem to be a valid choice. So, depends on your definition of 'going strong'. On its merits it's definitely still a great choice, I never really thought of it as particularly mainstream.