* 2020: 2519 responses
* 2019: 2461 responses
* 2018: 2325 responses
* 2016: 2420 responses
* 2020: 2519 responses
* 2019: 2461 responses
* 2018: 2325 responses
* 2016: 2420 responses
It's also worth noting that responses are indicating that companies using Clojure are getting larger, and more people are using it professionally. This likely indicates that many Clojure startups have successfully grown into larger companies at this point. This is also reflected by efforts like Clojurists Together where companies are funding open source projects that are seen to be strategic for the community.
So, overall I don't really see anything to be concerned about here. Clojure is a niche technology, but the community around it is very vibrant even if it's not growing especially fast.
In it, the creator of Rails says:
> it doesn’t have to be a million person movement for it to be a place where you can live and breathe and work. Um, I mean, I created. Base camp when Ruby had nothing, right? In terms of the tooling that I wanted and I needed to create web applications. I just created all that stuff for myself. By hand. I mean, it’s totally doable
And that's how I feel about my choice of using Clojure.
So one reason why the respondents haven't increased much is because its not attracting enough new developers and seasoned developers are giving up too early. Which is too bad because, sure, getting over that initial hump can be frustrating at times but, boy is it worth it! Spending only a few months with Clojure has already made me a much better programmer in the other languages I use.
A few of them went off and were so inspired by REBOL that they created Red[1].
OTOH, Rich Hickey has influenced(in good way) a generation of programmers and doesn't get credited enough.
Javascript is still a very difficult language to work with. Arguably, it is even hard to rate the language as a production-ready PL. The hidden cost associated with building, maintaining, and scaling JS applications is immense. There are so many inconsistencies and oddities in the language - it is not even cute or funny anymore to talk about WATs or "bad parts" of it. It gives you a false sense of simplicity, it feels like an easy language to start writing apps with, but God, very soon, you realize how awful things are (in comparison).
Clojure(script), on the other hand, is so much more practical. It only looks more difficult, but given enough patience, it brings you stability, consistency, predictability, and, most important - the incredible joy of building working software.
Notably, the majority of Clojurists are seasoned, experienced, tired, grumpy software developers. After trying different options they've finally found something that more or less makes sense. People mistakenly characterize that as a "Stockholm syndrome." Which I assure you is not. I personally use Clojure because it simply makes sense. Once it stops making sense, I will move onto something else. Who knows, maybe Javascript will evolve into something better then. But I can honestly say: "Javascript today does not make more sense." It is not a mere opinion of someone with a cursory knowledge of JS, I've used it (and many other languages that transpile/compile into it) for many, many years.
I have a kind nostalgia for JS because it was my first foray into 'proper' programming (alongside PHP), and I quite like TypeScript. I'm comfortable enough with JS that I can open the dev tools, write a moderately complex chunk of code, and save it as a bookmarklet or private chrome plugin. I'm a JS native.
But good lord do I feel so much better working in Clojure or, day to day, Elixir. There's no way I can comare them to JS and argue for the latter, even with the many improvements since the document.write() days.
The secret to this comes down to the Clojure mindset. And where I agree with you is your last statement, Rich Hickey helped push this mindset to other languages, and I'm seeing some of it slowly ramp up in other languages as well. Which is great, but it never comes together as nicely, and who knows where it's going as well.
For me the reasons for not using it as a primary replacement are: I get dizzy from interop; it is much more convenient to embed Clojurescript into JS than the other way around. And secondly and more importantly I cannot use it in collaboration.
Clojure also has debuggers: you can debug from either Cider or Cursive, for instance. I'm not that familiar with debugging outside of those two though.
Nothing is a replacement for a good, "true" REPL. Being able to evaluate any [sub]expression, without any kind of ceremony, anytime, from anywhere in your code is incredibly liberating. Who never used Lisp seriously, would never understand how amazing that workflow is.
I think REPL is the main reason why we still have Lisp dialects. After over six decades Lisp is still alive and thriving.
In that way I feel Clojure's defaults to immutability go a step beyond what's offered in most Lisp's setups. Not everything "just works" though, thought is still needed in order to have certain things be easily reloadable. I'm talking things like using "defonce" forms and having a setup like described here [1].
I'm still exploring this space but I think the gist of it is to create a direct acyclic graph of dependencies, so you can start and stop exactly what you need, not unlike what build systems do.
With most setups nowadays (create-react-app/Webpack, Parcel, etc.) and "hot-module reloading" that's no longer really the case...
...but that doesn't take away from your point, because it can have some truly odd effects on the debugger haha
Today it is possible to run Clojure on:
JVM, JS, BEAM, .NET CLR, Common Lisp runtimes;
Have interop with Python and R. There are Clojure-like Lisp dialects that can compile to Lua and C.
> you don't need the Clojure repl
If you never have experienced the joy of using "true" REPL, you will never understand the immense value of it. Non-lispy languages, sadly have no "true" REPLs.
No, it is still would be very crippled imitation of REPL, merely interactive environment. For a language to have a fully-functional REPL, it is required to have at least some homoiconicity, which JS is not.
Let me demonstrate:
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('root')
);
Can you evaluate that in JS REPL? Can you evaluate any part of it?Now, let's naively "convert" that into Clojurescript:
(ReactDOM.render
[:h1 "Hello, world!"]
(document.getElementById "root"))
You can evaluate every single part of it. You can evaluate "Hello, world!" string; [:h1 ...] vector; document.getElementById function, all these are valid Clojure expressions.
In addition to that - Clojure example is so much easier to modify and change. With just a few keystrokes, you can do a lot.That's basically the workflow - in Clojure, you bootstrap an app with some small, core dependencies, then start a REPL, connect to it and keep modifying your app while running it. That is what gives so much praised productivity boost. It doesn't matter how fast your compiler is (in other languages) - "save & recompile" workflow never going to be as good as working with a "true" REPL.
In another comment you gave an example like: (foo [a b] ((c a) b)) stating that you can eval any part of it, but if you try to eval ((c a) b), won't the repl raise an error stating a and b are not defined?
You see, in Lisp you think and operate in units of s-expressions, any s-expression can be send to the REPL as-is, "code is data" <=> "data is code". In Javascript it also adds some hurdles of things being out of scope. In Clojure, due to default immutability - the problem space is usually small, it encourages you to write smaller functions and it is much simpler model - most of the time you can evaluate anything without any preceding ceremony. In some cases you do need to set the context as you pointed with `((ca) b)` example, but it's so trivial to do so with s-expressions and it's so tedious when working with Javascript (trust me, the comparison not in favor of the latter, I've built JS apps for over a decade).
Even if you were, who am I to judge you? I myself had a chance to learn Clojure back in 2013, and then a few months later, and then once again next year, but I kept saying: "no, thanks". My thoughts were:
- JVM, yikes. JVM means Java, everyone hates Java, am I smarter than everyone else? I hate it too;
- Dynamic typing is so stupid. I've had enough with Javascript, Python and Ruby, I'm not doing that shit again;
- Parentheses. Lots of them. Too many of them. I can't see anything else. I'm drowning in the sea of parentheses.
If only I knew that:
- JVM is actually really robust and extremely good piece of tech; Try managing Nodejs clusters or deal with dependency conflicts in Python's pip. Honestly, JVM is so much nicer.
- That dynamic typing in certain context can be your friend and not the enemy. And REPL driven is much better than "save&recompile" workflow. Besides, there's Spec and it's absolutely dope;
- Parentheses bring structure, simplicity and consistency, and there are not too many of them. Javascript for example has more, and also semicolons and other shit.
Clojure like any Lisp, sadly doesn't do a well job of "introducing itself" to complete newbies. It doesn't look sexy when you're trying it out for the first time. It requires a bit of patience and the leap of faith. And those who are ready to pay that small price, soon may discover an amazing world of possibilities.
I don't quite understand this, could you explain it a little more in depth?
But I think one has to experience it, to understand what makes languages like Lisp and Smalltalk so special, what is so unique about REPL driven workflow that even Python's so much praised Jupyter can't give you that satisfactory feeling.
It's really nice to be able to run anything - from the smallest unit in your program, as well as the whole program and see the immediate feedback. For example: You can evaluate SQL DSL constructs and see what SQL query they compose into, and you can run that query and see the results (all without ever having to write a single line of actual SQL); or you can connect to the browser and change elements of the DOM (without writing a single line of html, css or js).
You can take a complex piece of code that generates a .csv, and then analyze that csv on the fly, changing columns and rows on the go, without even saving and having to wait for the compiler to pass the checks.
You can compose music and data visualizations, and etc.
Aside from the entire Java ecosystem? I know using a Java library from Clojure isn't exactly plug-and-play, but that's a bit dismissive. Java has way more code written in it than JavaScript for most things.