State of Clojure Survey 2019 Analysis
danielcompton.net
danielcompton.net
Clojure is the language that I have always wanted to learn, but the benefits never seemed very apparent. I'm hoping your response will make them clear.
You can watch him live-code the game 2048 in the screencast where he introduces DevCards[0]. Notice that the video came out 4 years ago!
One thing that really drew me to Clojure is that it seems to be a nexus of really good ideas that have trickled out into the larger community. If Clojure was where all the smart kids ate their lunch, maybe if I ate lunch with them too (so to speak), some of their smarts might rub off on me :)
This is a provincial take. That is, “do everything I need to” is strongly limited by what a person currently knows. If you don’t have at least moderate amounts of experience with alternative ways of thinking, it’s impossible to know what you are missing. There are many things which are needlessly complex, slow, brittle, unproductive, ... in any particular programming environment, and javascript is one of the more limiting choices IMO.
Ideally, students would be exposed to a broad range of approaches and tools in school to build a strong foundation, but in practice this often doesn’t happen, and the folks I know who reliably build the best systems are the ones who spend a decent fraction of their time learning new tools and ideas throughout their careers, many entirely self taught.
So there are lots of places where it doesn't make any sense at all or it's just a very, very poor choice for a particular task.
There is a big world of computing outside of apps and websites.
Clojure is a locus of things I really, really like and I have no reason to change despite the recent FUD around it. Namely: Lispiness, dynamic typing, functional programing, immutability, lean pragmatic design, and it runs on the JVM. I haven't seen anything that compares to it in these regards that also has the community support that Clojure has (great projects like Leiningen, Lacinia, and so on).
I've tried Haskell but felt I was fighting the compiler due to the static typing (I hate static typing). It also felt like it was designed for eggheads and not people like me just doing a job. Scala feels like it doesn't know what it wants to be when it grows up. Elixir and Erlang are neat but I haven't had a chance to really try them out, but Elixir's choice to emulate Ruby-like syntax is unfortunate.
That said, I do have a high degree of proficiency with Python, which shares dynamic typing and kinda-functional programming with Clojure. Python was my language of choice for years before I finally gave Clojure a try, and I haven't really looked back. The poor handling of the Python 3 switch really soured me to Python.
I also did a good chunk of Go, but the static typing and syntax weirdness just killed it for me. Amusingly, Go seems to have a similar "ivory tower" approach to language design to Clojure - which indicates that type of management isn't really a problem for me.
Of the languages that I've enjoyed, I've spent the most time in Go. I've kind of just hitched my wagon to it, regardless of whether I like it or not.
Of the languages you mention, Elixir seems to me like the closest experience to Clojure. Of this list:
"Lispiness, dynamic typing, functional programing, immutability, lean pragmatic design, and it runs on the JVM."
Only missing "Lispiness" and "runs on the JVM".
As for "Ruby-like" syntax, this sounds like people not trying Lisp because "too many parentheses".
It'd be hard to give up my precious parentheses though.
Yeah, that's the "Lispiness".
Elixir does have macros, but I still don't think any macro system is as powerful or user friendly without S-expressions.
It's kind of the last step of a language becoming just another Lisp.
I personally prefer Racket because of the ease with which you can use it to hack on itself. Macros are no stranger to LISPs, but Racket goes beyond by having the entire system around it built to accommodate language design and modification.
Want to use dynamic typing? Just use #lang racket. Want to use static type checking? Use #lang typed/racket. Reactive programming is there with #lang frtime. And that's before we even consider things like Scribble.
As an aside, I totally agree with you on Elixir. Erlang is wonderful for what it's built for. Elixir's choice to use Ruby syntax, however, ruins Elixir for me -- and it's not because I hate Ruby. I actually like Ruby a fair deal. Instead, it's because using Ruby syntax makes it more difficult (for me) to truly and fully think in the paradigm. Erlang/Elixir are nothing like Ruby. Making the syntax Ruby-like just obfuscates what's actually going on in the system. (I find similar issues whenever I try to program using imperative chunks in, say, F# or Scala.) Just my two cents.
That said, the JVM is a huge part of why I like Clojure. Because of the mountains of corporate code written in Java there is an insane amount of pretty high quality (if extremely object oriented) code available for it. I can find a library for basically any third party tool I'd want to use and if someone hasn't written a Clojure wrapper for it yet I can whip one up pretty quickly most of the time.
EDIT: Oh, but just getting started:
- How to Design Programs 2nd edition (new to programming or structured reasoning about programs)
- Racket Guide (new to Racket)
- Racket Docs (for reference)
The docs are pretty great, but IMO there’s an opportunity for people to blog about production use cases.
Also, I dream of something like R’s tidyverse being written for Racket... maybe by me, but ideally by someone smarter and better.
I'll check out serverracket!
But Racket... oh, Racket. Every time I get to write Racket, I feel like it’s the past, present, and future.
I do like some of the immutable collection abstractions in Clojure, and I like that there’s always a library in Java that’ll allow me to mostly still write Clojure. But Racket is definitely my language sweet spot.
The issue with dynamically typed FP is that FP is essentially about functions as mathematical objects, and there's really nothing mathematical about dynamic typing. Primarily, static types act as a proof, and because we're talking functions in the mathematical sense, you can actually reason about your program in the normal way.
Haskell is for eggheads though. What I really like is Rust, which feels like you're using Haskell and C at the same time. It's both powerfully low level and powerfully high level, and extremely pragmatic.
All that said, it sounds like you're super passionate about clojure, and I hope no one rips it out of your hands. I know what it's like to play the language wars games, and I wish you and all our fellow brethren the best of luck.
[1] https://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hi...
Repl driven development (100x productivity boost, especially with immutability, fp and expression oriented language)
Focus on data and data transformations (without classes, types and other clutter including syntax)
Concurrency (from simple state management with atoms to CSP and STM)
Libraries (this is where JVM really shines)
Unfortunately I couldn’t find anything even close to Clojure.
Regarding the benefits, for me it's the practical benefits of interactive development and the simplicity of everything in the Clojure ecosystem, which allow me to focus.
Of course, I would encourage everyone to be open to alternatives to Clojure!
> Wouldn't the same be said by most programmers with a high degree of proficiency with a language?
Perhaps for some, but not for me. Clojure is by far my favorite language, despite not being one that I'm most proficient in -- maybe not even my top 5 right now.
> What sets Clojure apart from Haskell or Scala or Elixir or Erlang?
For one thing, I've never written a (non-trivial) program in any of those other languages. :-)
Based on just what I've heard: Elixir and Erlang sound like good languages, and they're next on my list to learn, and I might well feel the same about them. For Scala, the one thing I've heard consistently is that it's incredibly complex, which is the opposite of one of the main reasons I like Clojure, so it's unlikely I would feel the same about it.
> Do you have a high degree of proficiency with something else?
Yes, I've earned money for writing assembly, C, C++, Java, C#, Python, Ruby, Tcl, Common Lisp, Objective-C, Swift, JavaScript, and probably a couple others I'm forgetting at the moment. Even after a couple years in those other languages, when I felt I was getting pretty good, I never felt like any of them were a great model of computation.
> Clojure is the language that I have always wanted to learn, but the benefits never seemed very apparent. I'm hoping your response will make them clear.
Writing a program in a language like C# or Swift or Python, to me, means taking 100 random pieces of kit (which look like the inside of Anders'/Chris's/Guido's head) and being creative enough to find a way to assemble them into something that works like I want today. None of them ever matches the problem space very well, so I have to pick how to compromise the design, and guess what axis of flexibility I'll want in the future. Next week when my requirements change, I learn that I often picked wrong, so now I have to redo part of it. The syntax is complex. Managing state is complex. Decomposing problems into reusable pieces is hard. Developing a new version of a program usually means rewriting methods I've already written (for new features, additional genericity, etc), and I personally find that frustrating. I want to finish things, once. I like it when languages let me extend built-in types with methods I think they ought to have had in the first place, but I'm also annoyed that I have to write these at all.
When I first tried Clojure, almost everything felt natural right away. The syntax is pretty simple -- just complex enough, beyond classic Lisp, to make common data structures (list/array/dict/set) easy to type. Learning Clojure mostly consisted of learning their new names for functions -- either functions I already knew, or which I guessed would probably exist (and always did). Remarkably, I usually find that the easiest way to solve any given problem in Clojure happens to result in functions which are already generic and composable and reusable. Once written, I very rarely have to touch a Clojure function again, either for correctness or modularity. (The obvious exception is the front-end, which is a thin simple layer that is easy to change.)
I can pretty much guess how I think something ought to work in Clojure, and it does. The work is not figuring out how to map my problem to the syntax of the language (and then having to maintain that state and those invariants), but simply writing some simple functions (map data to data) to transform the format I have to the format I need.
I say "died" but I know that people still write in Scala and Groovy, but how many new projects are you seeing in those languages?
At one point I set out to find work doing Clojure, but not much turned up in my locale. I did one professional project at a former company and only got the green light for using Clojure because it was basically a throw-away in a couple years when a new business process was coming in anyways.
Good luck to you, but it's not a niche I would want to be in. You have to mold yourself to the market, not the other way around (usually).
F# and Clojure are notably ranked as the highest paid languages for the past 2-3 years in a row. Trust me - market is shifting towards FP and Clojure one of the best choices.
Some superstitious people would say, don't tempt fate by saying that out loud!
It is by far the most pleasant language I've ever used, I feel at home writing it, and it improves the quality of my work.
Very familiar. Be sure to diversify. (Ex Smalltalker here.)
And yeah, like I said elsewhere I know my way around Python quite well and it's impossible to write a lot of Clojure and not know Java too. If both of those end up dying along with Clojure down the line then I'll be in a bad spot. :)
Very true. Coming from a Ex Perl programmer.
Though Perl is still around and you can solve problems using it for everyday work. But you will hard pressed to find a job that requires you writing or maintaining Perl code.
And I am glad Clojure has a lot of such fanatic proponents.
There's a whole bunch of languages with small dedicated communities doing interesting stuff. D and Julia occur to me off the top of my head. It's not "failure" that Clojure doesn't really challenge Kotlin or Scala for mindshare. It's nonetheless disappointing for people like me who used to be really excited by Clojure's potential.
Could it have been different? I don't know. The powers that be could definitely have been more committed to growing the base, but it never seems to have interested them. Would it have made a difference? I honestly don't know.
Coupled with powerful meta-programming capabilities, while having quite fast compilation times.
They just suffer from being a tiny community, so everything kind of improves slowly.
It is not easy to find that sweet spot that makes a language take off.
Ruby was unknown for almost a decade until Rails came along, for example.
Also, I don't see why we need to keep pitting languages against one another like this. Sure, there is a market, but can't we be happy that there is a diverse offering pushing language design forward? Not every language needs to become Java in terms of adoption.
The second realm was languages that I picked purely because they filled a niche better than anything else. Often these were side projects, or tooling, or things that I could sell based on how quickly and efficiently I could get up and running with X language that would save us money even if we eventually had to replace it if no one learned it.
I used F# for big data processing because I am an FP guy and they wanted .Net and I could do data manipulation like nobody's business. I used tcl/tk because I needed a super quick and dirty UI for tooling that I could quickly update to add new features. I used Racket when meta programming would hugely benefit me.
The problem is that for a lot of our jobs we are stuck with realm 1, the things we can't change. This is the area where we end up pitting languages against each other because they end up used way more than realm 2. You have to push really hard and hope someone listens but more often than not you just keep on doing what you're doing.
I worked on a huge JVM based project and even though no one in the company knew Java there was just no selling upper management on using Clojure. FP would have reduced complexity, meta programming and dynamic code generation would have made it much more robust without a lot of effort, but it was just too foreign (or at least not advertised as being used in places well enough), too new, and when you Googled it the "major" issues developers had scared everyone.
Just tell management you're using a Java library called Clojure, they'll never know the difference ;)
The core team is rocking right now and feel like we are on the tail of lifting spec to the next level (and out of alpha), and interested in finding ways to work better with the community. Some many great ideas in the hopper for REBL and other things too. 2019 is going to be a great year for Clojure.
Number of "Clojure" results is 109, compared with 98 for "Haskell", for instance (in London, according to indeed.co.uk). So both are not scoring big, certainly, but those numbers are nevertheless better than 3-4 years ago.
Can you share (some of) the reasons for that decision?
...of course, for the other team to be able to do this, they still needed to learn some Clojure in order to understand our code, but even in the cases where they actually liked doing Clojure, they were still forced to do the rewrite. The company was/is expanding very rapidly, so part of me can understand the decision to narrow it down to fewer "allowed" languages, to allow services/responsibilities/teams to move around more freely.
But it was one of the main reasons I decided to leave the company. I had joined after years hoping for Clojure to be my main professional programming language (for a substantial part of my career, at least), and I left a somewhat more bitter developer, but at the same time feeling a bit more free and relaxed - there are sooo many opportunities to pick from, now what I'm a bit more open when it comes to the tech!
OCaml can embed or be embedded in native applications, but that's not the point.
I think that the main problem with Clojure is the lack of types.
Just look at how much Scala is more popular than Clojure, although it's also a strange functional language derived from OCaml/SML.
There is a common opinion that types are a necessity, even ruby, racket and python are adding them. Clojure people are just trying to substitute types with a runtime evaluated contracts/Hoare triplets, which is not an adequate substitution.
This narrative makes intuitive sense to me. Clojure is not the most beginner friendly language. It goes harder on functional programming concepts than the popular scripting languages, which is a bit of a learning curve. The cultural tendency to prefer smaller scoped libraries to broader frameworks means puts more cognitive load on the developer, who has to decide which libraries to use and how to wire them up. But this is a positive attribute for a more experienced developer, who might have strong opinions on how an application should be structured.
I really disagree here. My first job out of college was at a Clojure shop and it has been the easiest language I've ever learned. There is a small hurdle of switching to lisp syntax when all you've ever used is C style languages, but that's about it. I also find frameworks more effort to learn than pulling in a small library that does the one thing I need.
I suspect much of that time was spent "unlearning" habits from procedural languages.
I know Carnegie Mellon now teaches functional programming as the introductory course, and only introduces advanced topics like "mutability" later. I think that sequence makes it easier for beginners to reason about what their program is going to do and experience less frustration.
For example, consider how a beginner can write Ruby and Python in notepad.exe while a lisp would be insufferable (and a common, awful first experience for that reason). Also, some of its best features, like cider/nrepl and Paredit, are hidden behind yet more tooling and keyboard shortcuts.
It's certainly a filter.
Now that you've gotten everything setup, let's write a program! Open up your favorite text editor and type in the following:
puts 1+2 Save your program (yes, that's a program!) as calc.rb (the .rb is what we usually put at the end of programs written in Ruby). Now run your program by typing ruby calc.rb into your command line. It should have put a 3 on your screen. See, programming isn't so hard, now is it?
It's this sort of thing that probably drives the likes of Alan Kay crazy when even learning a language isn't interactive by default.
(println (+ 1 2))
Then clojure calc.cljAbsence of that filter is the reason almost all of the programming crowd today is locked into advanced beginner mode all life.
Agreed. I'll add though that the problems with Clojure are soft ones. Here's my summation:
* it's business- and Java-friendly. Enterprise-focused.
* it's quite beautiful, though steeped in Java-isms
* its license is GPL-incompatible
* it's not a community-focused language and project; it's Cognitect's [edit: Rich's] project which they're graciously sharing with us.
That last one (IMO, the last two items) is a problem. For example:
* docstrings. Real improvements from the community?
* Lein? The clear winner, and yet for the longest time there was no mention of it in the getting-started guide on clojure.org, and then Boot was created. And then clj. NIH?
* It took ages until they began accepting PR's for their docs.
* I don't know the status of improving error messages. They've been complained about for years.
Clojure is Cognitect's [edit: Rich's] industrial-strength enterprise-ready Java-replacement and they sell consulting services for that. That's what Clojure is for and it's very good at that. It's also a seductively beautiful language, but if you're expecting a community-driven project with grassroots adoption and support, you're going to be disappointed.
docstrings - we apply many docstring fixes in every release.
NIH - are we literally never supposed to try to make anything new? Doesn't this non-argument apply to literally the creation of every language, library, and tool? This is silly. clj has different (quite clear) goals than Lein or Boot and both doesn't do things they do (like builds) and does things they do not (like git deps).
We have been accepting PRs for docs on the site for 3 years. Who cares how long it took before we started doing that if we're doing it now? Wouldn't it be more productive to praise for what you like than crap on how someone used to do something you didn't like?
Isn't it a good thing that Clojure is such as productive tool that it can support a consulting company that can afford to pay decent salaries so the core team can continue working full time on Clojure making it even better? This is a good thing. I suppose we can also ignore the hundreds of tickets, patches, and contributors to the language, many of whom have nothing to do with Cognitect or their consulting, as that's more convenient for this line of reasoning.
Do you think Clojure would be in a better place today if it did not have this support from a company willing to champion it? How often has that been a successful strategy for languages?
My apologies; I don't mean to insult. Thanks for the reply. My point is that it says something about what the core team thinks is important. Glad to hear that the team has been accepting doc PR's for years now.
> Isn't it a good thing that Clojure is such as productive tool that it can support a consulting company that can afford to pay decent salaries so the core team can continue working full time on Clojure making it even better?
I think we're arguing at cross-purposes. Certainly Clojure is a productive environment. But I'm interested in community-focused projects. These projects often have less corporate adoption than projects like Clojure. I was disappointed with Clojure, but not because it lacked a company championing it (it has one), not because it lacked corporate adoption (it doesn't), and not because there's anything in particular wrong with the language (I think it's an excellent language) -- by those metrics Clojure is certainly successful.
I'm amazed when people complain that they can't get their boss on board with introducing Clojure into their enterprise Java project. That appears to me to be exactly the market Clojure is targeting and succeeding in, when employed there.
I get it. Clojure is Rich's gift to the world and he will do with it as he see's fit. That's all well and good but make that clear so that people thinking about checking out Clojure know it up front.
http://insideclojure.org now has weekly journals detailing everything we're doing in Clojure dev if you're interested.
I think the build tool is the part of the tool chain where you most want a single project to rally behind. You want everyone building artifacts and expressing dependencies the same way.
Unless they all work the same at that level?
Trying to understand what you mean here. I write a lot of ClojureScript as well as Clojure and I'm not seeing Java influences in there at all.
Could you expand upon your comment a little more?
Clojure's life time was limited from day one because it's simply going against the trend.
Static typing helps. It doesn't have to be Java-esque. F# & friends have really nice static type systems where you don't need to declare types for most things - they're automatically inferred.
But the relative share of programmers writing code in statically typed languages appears to be increasing. When the web got big, there was a very rapid growth in dynamically typed scripting languages: Perl, Python, Ruby, etc. Then, when client side web development became a thing, JS got huge and then CoffeeScript.
In the past decade or so as developers have moved to writing larger more performance-intensive client-side applications (read: mobile with touch UIs running at 60 FPS), there is now a turn back towards static typing: TypeScript, Kotlin, Swift, etc.
Also, the sophistication of static type systems is increasing. Generics are now a given, control over variance is increasingly common, as is static control over null references.
This doesn't mean the graph will go towards static types forever, but it certainly appears to be right now.
CD's are not going to become popular again to listen to music because "pendulums swing".
When a trend is clearly going toward increased comfort or clear progress, there is only one direction that the trend is going.
I argue that statically typed languages are headed in that direction and that in ten, twenty years from now, dynamically typed languages will be looked at as "something that seemed like a good idea at the time".
I argue that in ten or twenty years from now, we will have great tools in dynamic languages to express constraints when needed, without requiring proofs.
These are opinions, not facts.
"Clojure's life time was limited from day one because it's simply going against the trend."
Python and Javascript are going to be around for a while, sure, but 1) they are also moving toward static type safety and 2) fewer and fewer projects will be started in these languages because statically typed alternatives are a better choice across the board.
"an intentionally misrepresented proposition that is set up because it is easier to defeat than an opponent's real argument."
The parent poster stated that clojures days were numbered because in his opinion statically typed languages were becoming increasingly popular and Clojure didn't follow this trend.
I specifically mentioned JavaScript and python because people have been extolling the virtues of static typing literally before either shipped, while both rose to prominence, and became wildly popular. I'm arguing that neither posters personal preference nor even a correctly assessed trend in computer language design is by itself a useful tool to predict the future success of a given language.
This especially rings false when the same prediction is made several decades in a row.
I wont even address your analogy because analogies are like buttholes. Everyone has one and yours stink.
TypeScript is now the #7 language on GitHub.
Matz has said that a major goal of Ruby 3.0 is optional static types [3].
Facebook has reportedly ported large amounts of their PHP code to Hack, which adds static types to PHP.
[1]: https://docs.python.org/3/library/typing.html
Indeed grafting types onto python, ruby, and even php seems more likely than people stopping using.
My point about static type systems is broader and actually backed by science and mathematics. And also, just observing the trend and seeing where the wind blows.
The best, recent thing I found was a study done about 5 years ago or so (I think) by a fellow at UC Davis, and the data were pretty weak. Functional programming, and the requisite memory management, had at least as big an effect as static typing.
At this point some Haskell snob steps in and say “sound typing”... :-)
In a nutshell, you can mathematically prove a certain degree of soundness of your code when you have type annotations.
There is no such thing in dynamically typed languages.
Being "sound" just means you can prove things are consistent with the assumptions you can encode in it. If there are things you can't encode in the types, or if your assumptions are wrong (misapprehension being one of the main problems in software), or if your requirements change, soundness is not going to save you.
Static types and proofs are valuable. Programs like compilers have fixed inputs and outputs and are excellent places to lean on things you can prove. But most of the programs I've worked on are not like compilers. They run for years, the requirements change, they have to deal with dirty data, talk to other messy systems, etc. And I'm not saying that dynamic types are perfect either.
My point is simply that static types are not a magical end goal of programming. They are a tool with tradeoffs.
This is both a straw man and a fallacy. Nicely done.
Also something I never claimed.
You are basically saying that since you can't prove a program can be 100% demonstrated to be correct, there's no point in trying to approach this goal, therefore dynamically typed languages are good enough.
With your reasoning, we wouldn't be using safety belts because they can't guarantee you'll survive a car crash 100%.
Sure, static types have trade offs, but they are a clear improvement on all dimensions over dynamic types, which is why we see dynamic languages converging toward static typing and never the other way around.
In ten years from now, we'll look at dynamically typed languages as "It looked cool at the time, but we know better now". A bit like we look at FORTRAN and COBOL today.
That has not been my experience and I don't think there is much objective proof of this. Most of the (admittedly not great) studies I've seen show dynamic languages as comparing favorably or better in bug counts for example.
Some of the things we're working on in the next version of spec are is head-on the notion of how to define expressive contracts for functions and allow those to meaningfully evolve in compatible ways over time as program requirements change.
I look at FORTRAN as a great language for its domain, so maybe you're right. :)
This statement seems self-contradictory.
In a nutshell, if you can mathematically prove a certain degree of soundness of your code, you have not done anything to show your code does what it is supposed to do.
Basically, you could be doing wasted work to satisfy your compiler, and have made zero progress in solving your problem, because that's not what the type system does.
Dynamical languages focuses on solving problems of human beings. The human beings' requirements are often inherently arbitrary, logically unsound, or even self-contradictory. Shoehorning a type system in there often serves to make solving human's problem harder. Consequently, in practice, most popular programming languages are dynamic. The current craze with types is just a fad, in my opinion.
> Shoehorning a type system in there often serves to make solving human's problem harder.
For the first pass author maybe. Subsequent readings and modifications of the code by other authors are much, much harder without "annotated" code (be that types or schema like spec)
Clojure is a Lisp. When the evidence and pragmatism of static type systems become scientifically proven facts I'm sure someone will figure out a way to extend the language without turning it into a disaster. Right now Clojure makes sense and it is way more productive to use it than any statically typed language.
Anyway, using LinkedIn, roughly 70 results in Boston, 30 in Denver, 130 in San Francisco. 867 across the US. I worked for three years with clojure and just chose between two new job offers after a short search, also in clojure. I’m seeing the language get use in microservices in larger, more established orgs that may already have a jvm docker image that their devops supports.
You are the guy who manages to turn the rumor that Clarice in accounting is home sick with a cold into Clarice is dying of cancer.
I do suspect that the survey is under-weighting how much beginners must struggle to navigate setting up CLASSPATH. If you don't come to Clojure from Java then the toolchain is a bit intimidating with whatever a Maven is, followed by a process of trying to follow what both Java and Clojure tools are doing. This is one area Clojure compares very poorly with, eg, C (similarly awful setup process, but usually all the burden is shouldered by the distribution provider) or Python (use pip).
It is interesting coming at Clojure from a Debian background at how resistant Leiningen has been to being integrated into the Debian apt archive. I think the package was removed in 2014 and only came back in 2018; so still isn't in the most recent stable. Given that Leiningen is itself probably the first choice of tool to manage dependencies, this raises questions about the technical underbelly of the tools used to build Clojure programs.
The Clojure answer is similar to the python one: use lein. This basically solves all classpath issues. In the 3 years I used Clojure professionally, there were only small handful of times I had to deal with the classpath directly, and that was only for pretty exotic packaging issues.
> It is interesting coming at Clojure from a Debian background at how resistant Leiningen has been to being integrated into the Debian apt archive. I think the package was removed in 2014 and only came back in 2018; so still isn't in the most recent stable. Given that Leiningen is itself probably the first choice of tool to manage dependencies, this raises questions about the technical underbelly of the tools used to build Clojure programs.
What questions does it raise? Debian doesn't deal gracefully with any external dependency management systems, as far as I know.
Most of them. I struggled a lot with the specific case of "I have jogl installed through apt and I want to use it in a Clojure lein setup".
> In the 3 years I used Clojure professionally
That is why I think the issue is underappreciated. Java provides a very comprehensive set of concepts to deal with making Java code run everywhere, and that sort of thing is just baggage when trying to learn a language as an amateur on one system. I expect it becomes a feature when something needs to be done professionally and platform is no longer a given.
> What questions does it raise?
* In a language that requires a lot of probably-new mental models to understand, how much extra burden is created if mistakes are made configuring dependency management?
* Can a novice successfully identify what is going wrong if they muck up their dependencies in a 3rd party tool?
* Will a novice identify that they should be using a 3rd party tool to manage their dependencies, rather than relying on other mechanisms that might be familiar to them?
* Is the hosted nature of Clojure creating interesting new failure modes for novices in the build system as issues might now straddle two languages?
These aren't questions that a professional would encounter, I expect being across complicated build systems is sort of how things are. But the leap from pure Clojure, having fun in the repl, to pure Clojure + a library is a very steep learning curve. The quality of the project setup has to go up a long way. At the moment, based purely on that learning curve, it must be one of the early barriers that causes beginners to drop the language. I'm surprised it doesn't get mentioned in the survey.
Watching Rich's talks, I always got the impression that dependencies in general are an outstanding to-be-thought-about problem.
> Debian doesn't deal gracefully with any external dependency management systems, as far as I know.
External dependency management systems fail to meet Debian user's expectations of quality and stability, tyvm :). Yeah, you're right.
The questions you raise here are real issues. I've been able to scaffold things for newcomers to the language in the past, but I can easily imagine how they could go off the rails without some guidance. I believe that the new "deps.edn" mechanism is meant to be the official, paved path for dependency and platform interaction in the future. But until everybody is using it, there will be two ways of doing things and the confusions that goes with having a choice. Perhaps it's necessary to move the platform forward.
git clone https://github.com/clojure/clojure.git
cd clojure
mvn -Plocal -Dmaven.test.skip=true package
https://clojure.org/guides/getting_startedIn any case, why not remove the Maven example? It's weird to see Maven promoted over tools like Leiningen and Boot.
In my opinion, the "first step" should cover all three operating systems as Leningen or Boot already does (and as the getting started page admits).
The Maven example is a way to get a standalone local-only (spec libs included) jar. Some people do this (it seems weird to me, but people do).
Leiningen and Boot are not official tools and are more than you need to get started (excepting the Windows caveat, which is a small portion of the Clojure user base that will be plugged, hopefully soon).
Now what?
Neither "Learn Clojure" nor "Programming in REPL" even mention how to run it. I'm assuming you need to just type `clojure` in the shell (I'm only assuming this because I have experience with other languages that allow this, neither Java no C/C++ have this)?
"Learn Clojure" has a bunch of examples before it even gets to REPL. I guess I can run them? Somewhere?
The there's the "Programming at the REPL" section and... Then what? How do I start a project? How do I create a program? How do I compile and build a project? Run it? Test it? Configure it? Where is all that?
Fully learning the language, the tools, and how to make a project are all different topics, and have their own interactions with whatever other tooling they are using. I think a lot of that is there but I'll take your point that they aren't guided well enough. Definitely worth taking a few more passes, thanks.
It's definitely not a "next logical step". A next logical step is "create, test, and deploy a clojure program". For some reason these important topics are given a total of maybe 5 paragraphs inside a section on CLI tools?
> I think a lot of that is there but I'll take your point that they aren't guided well enough
"A lot is there" is a total of two paragraphs on writing a program outside of REPL, a total of two paragraphs not even on testing but on how to include a test directory. And that's it.
As a beginner I wouldn't even know where to look for this (Google is often not enough).
Clojurescript is slightly better in this regard. At least after the quick start guide I have some understanding on what goes there.
I may open an issue if I don't forget tomorrow :D
This year’s survey also included a question about how long people had been programming professionally. 1 in 10 Clojure users have over 20+ years of developing experience; 49% had over 10+ years of experience. In comparison, only 42% of JVM developers have that much programming experience.
Clojure having a higher than average percentage of experienced developers directly contributes to the quality of the language and the ecosystem around it.
[1] https://jaxenter.com/clojure-2019-java-8-functional-155236.h...
There is just way more hand holding in these massive communities (JS/Python).
Another big reason is that if you want to write production level code in Clojure, you have to know Java and its APIs well, the same for Clojurescript and Javascript, making the barrier to entry much bigger.
So yes, IMO, right now Clojure is a language meant for experienced developers and my guess is that will remain so.
The good thing is, Clojure and Rich brought some good concepts to mainstream use. He did a good marketing job.
I can't go back and test my theory (I've been doing Java for what feels like a century) but I feel like it will be difficult for people without a Java background to get a production Clojure project off the ground.
I'd always consider language power to be an amplifier of experience...a 20+ year veteran that knows clojure like the back of his hand is going to be more productive than a java dev of similar experience. But the community size gap is huge. I deal with this as a scala programmer quite a bit. The ecosystem is pretty great for how small it is, but it's never going to be as good as java devs have it.
Of course that point is spurious at best. Clojure devs can use java libraries about as well as java devs can use C libraries: it's an unidiomatic nightmare with tons of unsafe sharp edges. And java devs can even use clojure libraries, but they don't and probably never will. Using java libs from scala is a hell of a lot easier than using them from java, but I still avoid them like the plague. If we're comparing the relative merits of ecosystems for different languages, it makes sense to compare the ecosystems developed natively in that language, not lumping in the thousands of other ecosystems that technically can interop with it.
My point is that the clojure ecosystem is weak in comparison to other more popular languages because experience in absolute quantities matter far more than percentages. The Arc ecosystem basically consists of a single 20+ year veteran, Paul Graham. That's 100% veteran composition. According to your line of argument, they surely must have the world's greatest programming language ecosystem. Does it?
At best, the clojure ecosystem can claim to be good enough for most uses. That's certainly a lot better than the vast majority of languages. I'd be overjoyed if SML, Pony, MiniZinc, or Mercury had the ecosystem that clojure enjoys. But compared to Javascript, Java, Python, C++, C, Javascript, Swift, Ruby, etc., it's not even close.
>My point is that the clojure ecosystem is weak in comparison to other more popular languages because experience in absolute quantities matter far more than percentages.
And yet in 8 years of working with Clojure I have yet to run into a situation where the ecosystem failed me.
>But compared to Javascript, Java, Python, C++, C, Javascript, Swift, Ruby, etc., it's not even close.
And Clojure leverages both Java and Javascript ecosystems directly. The whole ClojureScript ecosystem is based around React. When you write web apps you build them on top of React components, and other Js libraries. And this is how seamless interop is:
https://github.com/yogthos/semantic-ui-example/blob/master/s...
The ecosystem is not an interesting problem to solve. Interesting things are happening in the code you write. The business logic of your application is where the language matters. Even when interop is unsafe you're doing it at the edges of the application, and you treat it the same way as you would any side effect.
The power and joy derived from the above is incredible and (to many) even more important: it means Clojure is not sitting idly in its own ivory tower it plays very well with real world day to day situations.
Try to find languages that see eye to eye with Clojure here.
I’m super excited about the language and the welcoming community. Also super fascinating to see how so many community efforts are composing and compounding so well. I wish other languages / communities would look more closely and adopt some (more) of it.
A bit confused with some of the comments here but then again YMMV and just wanted to jot some of my thoughts down before I transition into some late-night recreational coding that I was looking forward to the whole day. < 3 Clojure
Based on some of the comments in the thread I see there is some veracity to the claim that interest in Clojure is leveling off or declining. However, it has been my experience that the community embraced Clojure around 2013-14 to the point of "irrational exuberance". The reality that the ecosystem is full of under-engaged projects and dead ends really set in for me after I went to Clojure / West in 2014 and saw several demos break on stage.
I want to use Clojure at work, but I'm just not productive in it yet as other languages and I haven't found the time to build momentum with it. That said, I still want to get there.
You'd start reading and even before finishing a second sentence you'd realize - the person has no clue what they're talking about. Listen, Clojure is not a small language like Lua - you probably won't be able to form an educated opinion about it by trying to build something simple over a weekend.
People would say the hate JVM, when they actually mean "Java". In 3 years of using Clojure I almost never had to even read Java code. They'd dismiss the language immediately because it is not statically typed. If you think maintainers of the language have no clue about type theory and completely unaware of all the research of recent years happening in Racket, Haskell, Julia, Agda and Idris - you are very wrong. Things you can do with clojure.spec are absolutely mind-blowing.
If you claim that it's hard to find a Clojure job - that's not true. It is not harder than finding a job in Scala, OCaml, Erlang, Haskell or F#. If you've forced yourself to "love" Javascript, Python, Java or Typescript simply because they can guarantee an employment - I'm truly sorry for you. Sometimes I think people must be either crazy or completely ignorant - who in the right mind would choose JSX over Hiccup and Json over EDN?
If you claim that it is hard to hire Clojure developers - that not true either, you simply need to be ready to pay more. People come to Clojure out of curiosity - not for dogma, not for points in résumé. Clojuristas are usually more experienced devs, tired of all the bullshit that inevitably gets accumulated overtime in almost every language. Clojure(script) is not a silver bullet either. But in most-cases it simply makes sense and it just works.
It's not exciting if you're not a Clojurist, but if you are then 1.10 was one of the coolest releases recently.
It doesn't make for the best headlines or hypest hype: "Clojure improves on something people hated about it."
Same reason you don't hear about Haskell or nearly as much about Rust despite them both being conceptually exciting projects.
Hype can be trending, while the underlying thing being hyped, is stable/mature. The aforementioned Haskell is an excellent example of this.
I also think languages can suffer because their scope is so limited. There have been times I've thought that I'll switch languages and solve a bunch of problems, only to find out that most of my problems are still there. The requirements are still vague, the team still has its dysfunctions, and the surrounding systems are still unreliable, poorly specified, and run by teams that have no interest in helping because of some organizational dynamic set in place ten years prior.
None of this should be a surprise, but the real point is that even a putative perfect programming language can only address a relatively small fraction of the problems that arise in software work. That can make it even more difficult for minority languages like Clojure to produce a positive risk-adjusted return on the investment they require to adopt in a serious way..
Contrarily, nearly every other popular modern programming language project (Haskell, Rust, Scala, Crystal, to name a few) hopes to provide nuanced, robust type systems and compile time guarantees--these projects focus less on pragmatics and problem solving and more on correctness and safety. Even elm, which is just a language for building frontends, boasts of its compile time guarantees and elimination of runtime issues using a type system. Clojure is the only recent language that I know of to go against the grain in this regard. That might factor into its decline in popularity--presumably all of these languages are going after type safety and correctness because they are perceived as features people desire these days and clojure never emphasized these properties (some of the things it emphasized instead, such as immutability, problem solving, and interoperability with an existing platform are still important features ,they just don't happen to be as prized right now as correctness/safety and perhaps noiseless/sparse syntax).
The introduction of spec can even be perceived as a sort of concession to this popular demand. Even the spec about page hints at the slight[1] incongruence between spec and the overall Clojure philosophy:
"However it has always been a guiding principle of Clojure, widely valued and practiced by the community, to simply represent information as data. Thus important properties of Clojure systems are represented and conveyed by the shape and other predicative properties of the data, not captured or checked anywhere since the runtime types are indistinguishable heterogeneous maps and vectors."
https://clojure.org/about/spec
[1]: Slight because the purposes of spec are not those of a type system or compile checks. What spec does do, however, is introduce some of the bookkeeping sorts of procedures that, in my estimation, the design behind clojure intended to minimize as much as possible.
The last couple years have been much more ... boring in that respect. Things have consolidated into whatever the big cloud vendors want to support, and even their pace of innovation seems to be slowing dramatically, not too unlike cellphone tech.
k8s is probably the buzziest thing, but even that, I have trouble getting very excited about something primarily oriented around ops.
From my perspective, it has never been better than it is now and there are a few more things coming this year that are the cherry on the cake.
It's very challenging to stop thinking about mutating state in an object graph and adopt a functional programming model using immutable data-structures. Be prepared to face quite a bit resistant on that (as well as static vs dynamic typing, and the expressiveness of types vs. something like spec or schema)
I'm not too concerned about selling to management (well, I'm the CTO, so 1/3 of management is on board ;) since there are many success stories around Clojure and the list of well-known companies using it in some fashion is pretty large. When pushed, I just mention NuBank (over 4 million customers) which runs their business on Clojure.
I had a similar epiphany to you in that coming from a Python background, Clojure radically changed how I thought about and approached problems. Rich Hickey's work is fantastic and I'm very happy to have spent time in that particular corner of the tech world.
It's impossible to be productive in a large Java code base within a month even if you joined as a seasoned Java developer. But it is routine for a programmer who has not even heard of Clojure before to become productive in a production Clojure code base in two weeks. We do this all the time with our interns.
It's all optics and bullshit. Scala is pretty easy to pick up, as is any programming language. The problem is you have to spend the time. Time for most people, me included, is extremely limited.
In some parallel universe, I'm sure Clojure is the #1 JVM language. It's great and Rich taught me so much about functional programming and many other things. But at the end of the day, Clojure here in this universe didn't take off and I'm not sacrificing my career to beat that drum anymore. I tried hard, I really did: 2013 & 2014 were the years that were make or break. The wave didn't crest. When the people maintaining the plugins to Eclipse faltered, it broke down hard. IDEA never had solid support, either. Then, when the support tooling faltered, it was really hard to make the case to management, especially when other asshole developers were arguing for their pet tools. Type safety, meh! I don't need it, never have... So I write Java Streams and it pisses me off every single fucking day.
There is nothing more to say than "if you can find a job doing Clojure you are extremely fortunate."
I hope we move on from Slack as a community hub. It's not about searchability -- it's totally unsuitable for public/open communities. If you've been in there recently you probably know what I mean -- it's vulnerable to griefing in a way that, to my understanding, Slack is not interested in fixing.
spoofing identities (or, I guess, making sockpuppet ones) to @-everyone and post porn gifs & racial slurs from slackbot in #clojure
--
Yes, the Clojure community is awesome! I only mean that Slack has problems that allow malicious people to spoil the fun. I don't know if it's been addressed. I logged out the last time it happened.
I know there's been a couple efforts to find a place to relocate to, but it's never really gone anywhere.
If you think it's an easy problem to solve, please point out a single resource (library, website) which is 100% high-quality, comprehensive, up-to-date, IDE-integrated, and noncontroversial. Where is it? Why haven't we all adopted it?
The facts are: we have good-enough docs, nREPL, a massive corpus of beginner material (books, videos) and real-time support from enthusiasts on Slack.
If you ain't clojuring, it's because you don't want to!
I've been Clojuring since 1.0, contributed 100s of examples to Clojure docs websites, and I still don't understand some of the .core docstrings even when I know exactly how to use the function.
It may not be easy to solve, but it does need to be solved.
Have you filed documentation issues on the Clojure web site? If not, we don't know what needs to be improved. We have closed 100s of PRs and issues on the site in the last couple years: https://github.com/clojure/clojure-site/issues?utf8=%E2%9C%9...
Thank you for your tireless work on improving Clojure and the surrounding ecosystem.
He made this clear a few years ago - I don't know if he has changed his mind since?
This would probably help beginners more than anybody else.
Examples are also great. We would love to have documentation pages (or even doc functions in the repl) that combine multiple sources of information to help you out (docstrings, examples, see alsos, etc). That stuff does not have to be "in the docstring" for it to be available to you as a user.
For example, clojuredocs.org does exactly this, combining multiple sources of information into one combined page (ex: http://clojuredocs.org/clojure.core/zipmap). There used to be an api for clojuredocs.org and a repl lib you could use that would give you an additional function to get those examples at the repl too (I think that fell out of maintenance).
The summary is, we can both have docstrings that don't include examples AND provide examples by merging docstrings with other things for the user.
Worth pointng out: if you know exactly how to use a function, how much of an actual problem is that the docstring is contrived?
I'd sure like nicer docstrings, but also I understand that the authors (core and community alike) have limited bandwidth.
So we may never see a "100% solution", which is perfectly fine.
(Thought exercise: say the docstrings get just a little nicer. Couldn't that create even more problems in some ways? Now everyone expects nice docstrings, and bikesheds about format, contents, etc)
I assume my knowledge is fallible, and that the docstring is the de facto source of information for that function.
If my knowledge clashes with what I understand the docstring to convey, then my understanding vanishes. I go from happily coding to "Uh, I don't know what I'm doing" in seconds.
It's not a super frequent issue, and I've reported it when it is, but I've heard many other people express similar sentiments. It's a slow process to improve this because everyone understands written language slightly differently.
Still... it does need to continue improving.
(I guess the library design is controversial, or rather, it is now... Collections are looking rather outdated just to cite the obvious. But as for the documentation, it's still killer.)
https://dev.clojure.org/display/design/Improving+Clojure+Sta...
I've asked a clojure dev the other day about it and he told me this was experimental and not very common.
[1]: https://github.com/clojure/core.typed