I have been a Clojure newbie for over 3 years now and here is why I am still using it:
1. Clojure code makes sense to me : I could go back to Clojure code someone wrote three years ago and I would have no problem in figuring out what the code was doing. With Java or Javascript, unless the code is documented with extreme diligence, the nuance are hard to decipher.
2. REPL based coding makes it easy to get code right before making it part of my namespace
3. lack of strong typing has not been a stopper for me yet. Spec is good enough for my needs
4. State and concurrency : Its hard to screw up concurrency and state mutation with Clojure
What're you using it for? I really like the language, but it seems geared to replace Java for heavy enterprise enterprise applications. A lot of the benefits I hear people talk about sound like they require a large project to be properly noticed.
I've used Clojurescript for a couple toy projects, but it seems awkward to me.
Clojure is good for everything you'd use Java for. So pretty much anything that's going to be long running, like services, or big apps meant to be open for a while. Yes, that fits the enterprise use case perfectly. A backend for any service oriented architecture, ETL jobs, data processing pipelines, backend for websites, rest/rpc/graphql services, client/server applications, big data analysis, machine learning, etc.
Clojure is not good for quick scripts, use bash, python, perl, hy, clojurescript, etc. for that.
Clojure is not good for low level code, like drivers, embedded systems, os, etc. Use rust, c, c++, D, etc. instead.
Clojure isn't good for squeezing every ounce of power out of hardware, such as games, use C++, assembly, etc. for that.
Clojure isn't good for mobile app development, use Java, swift, c#, objective-c, etc. for that.
Clojure isn't good as an embedded scripting language, use LUA, python, javascript, tcl, scheme, etc. instead for that.
Therefore Clojure competes mostly against Java, Scala, C#, F#, GO, NIM, Haskell, etc. Now as an astute reader, you've noticed how none of the competing languages I've listed are dynamic or of the lisp family. This makes Clojure unique in its space and the most controversial.
I agreed with most of your comment, but not the end.
I don't think Clojure competes with Go or Nim. And Clojure seems to be the antithesis of Haskell. Clojure competes with Java, Kotlin, Scala, and C# if you're on an MS platform.
I used Clojure for pet projects for a while (it's a gorgeous language) but eventually went back to Python because I wanted something with:
* easier interop with C/native libraries,
* faster startup (though for scripts, [inlein](http://inlein.org/) mitigates this issue)
* no requirement of the JVM
* better error messages / more help finding my bugs
* smaller memory and cpu footprint
Looked at some Schemes (Chicken), but couldn't stomach the car/cdr/dotted-pair stuff after having nice data structures like in Clojure, Python, et al. Not interested in ClojureScript, as I don't want JS underneath. Still prefer Clojure-the-language to Python-the-language, but here we are.
Go and Nim are both mostly used for backend services, long running processes deployed inside docker instances, etc.
I agree it competes a little less then it does against Java, C#, et all. But it still does, in that there's overlap for what projects they'd be good candidate for.
I think Clojure fits well to quick scripts and exploraory programming, because of the rapid turnaround in interactive development. The finished tool, if compiled, will start fast enough (~1 second for hello world) even though it loses a bit to Python scripts.
Clojure also lets you drop down to the most basic JVM primitives, like unboxed types and atomics/volatile, so you can do lower level stuff than in other dynamic languages. You can even follow the asm code generated by the JIT. Combined with macros and other DSL building capabilities, I'd say doing low level or performance oriented work can be pretty productive with Clojure.
DSL building blocks and dynamic nature also make it a pretty good embedded scripting language.
Many embedded systems are plenty powerful enough to run Clojure (or Python or Java), so it works there too.
While you can use Clojure for script, or performance heavy tasks, or embedded systems, I think it's pretty obvious it's not the right tool for those, at least not yet.
If you want to mess around with scripts, performance heavy tasks or embedded systems, sure you can use Clojure, but if you are serious about any of them, it wouldn't make sense. You'd turn to languages that are better suited.
- You mention sub second load times. Based on https://dev.clojure.org/display/design/Improving+Clojure+Sta..., the surveyed timings are around 2 to 5 seconds, going to 60 seconds for some. That's a bit too much for scripts, you can live with it, but users are going to be annoyed about it for sure.
- Another issue is the difficulty in starting them. You need to invoke java with a class path setup. So you can't have self executing scripts. You can use inlein, but that brings us to my third point.
- The bigget issue is that Java and Clojure are not standard on any machine. While python and bash tend to be. To use Clojure for scripts require each machine to be imaged with java, Clojure and inlein setup.
About performance and low level tasks. I'm not sure which of my use case you're specifically talking about. But an OS and drivers need to be compiled to specific hardware, so Clojure isn't an option for low level code like that. Now the JVM isn't performant enough for major games, you can't control memory yourself, or target specific CPU instructions.
Finally, only a minority of embeded chips support running a JVM instance, I'm not sure I need to explain any further, if you work in embedded systems, it just doesn't make sense to restrict yourself only to the more powerful chip that can run an embedded JVM.
P.S.: I love Clojure, I wish it was great at all these use cases, but it currently isn't, and I think we do the community a diservice to make people believe it is, because they'll try it, and have a subpar experience, leaving them feeling like Clojure isn't that great afterall. I'd rather people try it for what it's good at.
That survey is unrepresentative for scripting, since it's a survey of all Clojure applications. Scripting tends to be one-off, custom high level logic. I'm sure any Clojure user will tell you that short programs start fast enough for scripting - and for development, you are live-reloading in the REPL with 0 startup time.
About deployment and distribution, I think the JVM story is much better than the competition (Python, Node, etc) - you can just package everything in a single .jar and you need only this along with the JVM.
Embedded systems, like I wrote above, are hardly restricted to this kind of tiny chip. Embedded systems these days are frequently powerful enough to run Clojure. There's a big market for developing embedded solutions that value memory-safety, fast turnaround times and on-devices development ability along with access to JVM libs.
To summarize, I still disagree that all these broad sectors would be weak for Clojure (like you argued in your original post). There are be smaller niches inside these sectors that Clojure is not well suited to (like operating systems, or low-powered embedded, or frequently executed end-user scripts that need sub-second startup times, or code inside operating system kernels) but this hardly excludes Clojure for all your listed broad application areas.
I haven't worked those sectors personally, so I'm not going to pretend I know fully their requirements and if Clojure would be a smart choice. But from what I've heard and read, embedded systems is dominated by C. Very little chips support embedded java from my googling about it. Serious work still needs compact binaries, and to maximise the chips output. The exceptions are critical use cases, where they might use java and have a TLS proof with it which I don't think would work if using Clojure, or they'll go with Haskell or Agda, because they need to guarantee there's no bugs. Now I say this only from searching online and people I know who work in embedded systems.
Is there a sector for scripting? I was thinking of IT mostly, sys admin, that kind of stuff. In those cases, configuring java and clojure and inlein feel pretty heavy to me. I've never seen it in practice. It always adopts a language that is bundled with the OS like sh, perl, python, powershell, batch, etc.
It seems to me like the niche in these sectors would be Clojure being the right language. But I don't have real stats, so you might be 100% right. Personally, I didn't feel it is, I can think of more examples of use cases where bash is a better choice for scripting, or more examples where C is a better choice for embedded.
If you work in those sectors you probably know better, but I didn't get the impression you did, so I guess neither of us really knows.
if you could elaborate on awkward part, i'd love to give you a hand. i have 1 react native app built with cljs and 1 chrome extension. using cljs is the best technical decision i've ever made.
I'm still a n00b, but I found the errors to be obscure. Often times, I couldn't even get an error to display when I _knew_ something was wrong. After I fixed that error, the app would show up again.
For the most part, everything was incredible while it worked, but every so often very technical errors would come up and that makes me hesitate to advocate for its use at my job.
Here are the reasons I stopped using clojure (a phenomenal language) a year ago, in order of importance:
1. No C/C++ FFI.
2. Lack of a strong type system (clojure.spec almost solves this problem now, but when I quit this didn't exist yet).
3. Horrific startup times: although clojure itself is fast, its startup time isn't. This makes scripting in clojure unsatisfying. And you don't feel like a ninja when it takes 30 seconds to start a REPL. You can use clojurescript to target node to get around this, but then you cut yourself off to most of the powerhouse clojure libraries.
I now use Haskell (with C/C++ FFI). I do miss the homoiconicity (and slightly more concise syntax) of clojure. In my opinion Haskell and clojure are the two sexiest mainstream languages that you can get stuff done in.
If in any case you still feel the same about Clojure, you should try Common Lisp, it has the three things you want:
1. Easy calls to C with CFFI. No Clojure->Java->JNI->C, just straght CL->C.
2. Useful, optional, type system (which can also catch mistakes at compile time with SBCL and other compilers)
3. Very fast startup times.
and many more features like for example an object system that is massively above what Clojure and Java bring to the table, better exception handling, very explícit errors and nice stack traces, it can also compile to JVM if you want, etc.
If you like Lisp, try it. You already learned a Lisp so the jump is easy.
Chiming in to give Racket a shout out. Good FFI, good libraries, good tooling, good community, good (soon to get even better) performance, subjectively more modern feel than CL, great type story via Typed Racket.
1. There is JNI. I made an example project[1] a while ago. I'll admit it's a little involved but it does exist.
2. Spec does solve the problem for me, but I don't really like static typing anyways.
3. I keep Clojure REPLs open for days. I restart if I need a new dependency and for other minor reasons, but startup time is almost a non issue for development. For scripting, you can try Planck, although yeah you lose the Java interop. I love Clojure, but I just don't use it for scripting.
Not trying to tell you you're wrong, just offering some insight into how Clojure could address (or not address) your points.
With cider and clojure-refactor mode, you can hotload a dependency without restarting the repl. It is kind of brittle but when it's working hot damn is it good.
That way lies SOAP, and it's not the compiler that tells the client it can't call an API some way but a broader build tool. And you still need some runtime verification somewhere on the server anyway since without it nothing stops any arbitrary stream of bytes.
My own related exaggeration is that type declarations without performance gains are useless. Get them out of my dynamic langs unless you can deliver the performance goods. (Like Common Lisp can. It can also tell you you're stupid locally trying to make an invalid call, at compile time, since COMPILE is built-in.)
I think useless might be a stretch. While I certainly prefer compile time checks as well, spec is a huge step forward for folks that are committed to Clojure. If there was no merit to runtime checking, Haskell wouldn't have QuickCheck and would exclusively rely on compile time checking.
I've wrapped C and C++ code via the JNI and called it from Clojure. There are a good number of projects wrapping C code in Clojure. It's a little awkward (Clojure -> Java -> JNI -> C), but works well enough.
We get around the startup time by keeping our work either in the REPL, or just having large enough tasks that the loading is dwarfed by the time it takes to get started. Webdev might be a little crappy if you're used to the turn-around cycle of either node or PHP.
There can be problems with state management, which I've only seen with our web application. Sometimes a hard stop / start is what you need unless you designed the application for reload-ability. We're working towards that for our web application. Frameworks especially seem to exacerbate this problem, since you have limited control over the execution of your program.
I gave up on Clojure despite spending a lot of hobby time on it and moved to Scala because it's simply a much easier language to sell to other engineers and management.
For me the C/C++ was a minor issue since if you're going to the trouble to do it on the JVM you may as well build that part in Java.
Any tips for how you sold Scala? I don't even like it but I picture the sell to be at least as hard as Clojure, at least if you're selling Scala honestly... Clojure can't hide its alienness anywhere but a Scala intro can. I'd like to find a way to push for Kotlin at the moment, which would be nicer day-to-day than plain Java plus open the door later for other JVM languages.
Show examples of large companies using Scala in production (Twitter, LinkedIn, Walmart etc)
Gradual low risk introduction of Scala using Gatling load test and ScalaCheck
Production ready frameworks like Play and Akka
Demonstrate that Scala can be introduced at various levels from "Java without semi colons" to "You need to learn category theory to understand this" and what we would do to make sure everyone on the team would be up to speed.
Build a prototype
What counted against Clojure and Common Lisp was the immediate reaction of people with no exposure to lisp languages was "those brackets" and the lack of a large stable framework one can pick up and use as a gateway to using the language.
Simply put there can be a gradual adoption of Scala in a company that's really not possible with Clojure.
Happy to see there are good learning resources for Clojure.
The more Clojure users out there, the better, since it is a Lisp language, and as more people learn and use Lisp, it will be more easy for them to also able to also use Scheme, Racket, Common Lisp, LFE and the other friends in the illustrious Lisp family.
This, in the same way people can easily learn C, Java, C++, Rust, by knowing just one of those four languages. Once you understand the syntax, it gets really easy.
1. Clojure code makes sense to me : I could go back to Clojure code someone wrote three years ago and I would have no problem in figuring out what the code was doing. With Java or Javascript, unless the code is documented with extreme diligence, the nuance are hard to decipher.
2. REPL based coding makes it easy to get code right before making it part of my namespace
3. lack of strong typing has not been a stopper for me yet. Spec is good enough for my needs
4. State and concurrency : Its hard to screw up concurrency and state mutation with Clojure
edit: formatting