Clojure growth is just fine. If average devs have to add something there is Java. In our experience maintenance of Clojure code is orders of magnitude better than average languages (Python, Java, etc). Yes, object orientation in large organizations leads to the most unimaginable mess. People mostly get paid for unproductive behaviour. Clojure is great for startups where you can do things right.
>I'm sure Clojure would have been chosen if it was developed today.
Clojure was already available in 2013. The paper shows they made use of the CLOS object-oriented system, which is a key feature of Common Lisp.
For decades, there have been rumors about the death of dynamic languages in general. And yet the decades pass and not only do those languages continue to flourish, but others come along and get popular too.
Clojure just turned 10 years old and I see no signs of it slowing down. They did consolidate their 2 major conferences in the States into just one annual conference, so there's that (which may not mean anything). But I am in a large city and companies keep appearing and starting up with Clojure as their key language.
With Clojure, it's an oddball because it is very simple and very powerful. Oftentimes, simple languages are not so powerful, and powerful languages are not so simple. But with Clojure, you can very easily get yourself into the situation of having extremely dense logic in just a few lines, where another language might easily take 10x (or more) lines to accomplish the same. This leads to code that can indeed be difficult to read later, especially if you are on a team and others must help maintain it. The Clojure community has come up with some excellent solutions to this problem, most recently the Clojure.spec library which is gaining wide adoption, which not only makes such "cleverness" easier to understand when reading it, but also makes a codebase automatically testable with property generators, which is a major feature. But your point about readability is always going to exist with a language like Clojure if it isn't written with a team in mind. That doesn't take away from its power though, in my opinion.
However, there is one particularly indispensable tool that Clojure offers that I have not seen anything to meaningfully compete with for productivity, and that's ClojureScript. Writing a front end with Reagent or even the alternative libraries is such a major win over everything else I've tried. I've worked a bit with Elm, Typescript, Reason, Bucklescript -- I am so spoiled by the extremely fast turnaround and easy interaction with very powerful features like React in Clojurescript that I don't see anything on the horizon that will come close to replacing that workflow for now. Perhaps some day something will come along to shine an even brighter light on how front ends can be developed, but for now, ClojureScript remains one of the most significant contributions to the software industry in many, many years.
Clojure never had much usage on real world projects. It cannot be extinguishes as it never took of.
I'm not sure what you mean by "never took off" but thousands of developers around the world, myself included, have made their living just writing Clojure code for many years. So, it has certainly taken off for them. And there are many, many companies using it all over the world. I live in a town of about half a million people, so not super big, and there are about 12 companies primarily operating on a Clojure codebase.
Amazon also uses Fortran, Assembly, Awk, Mosel, VBA, K, and Bash, but nobody is going around claiming they have much usage on real world projects.
Walmart is using Clojure for their checkouts as well https://www.youtube.com/watch?v=av9Xi6CNqq4
Boeing is using it in the onboard control systems for the 737 Max https://www.youtube.com/watch?v=iUC7noGU1mQ
It's not some obscure microservice that some intern wrote over the weekend, these companies are using the language for critical applications, and the feedback from these companies is positive.
If anybody led you to believe that their team did “online checkout”, but didn’t care to explain how small of a cog they were in an extremely complex system composed of hundreds of services, then you were grossly misled.
If someone doesn't want to use it for this reason or that, it's their loss not ours. Those who need to find Clojure eventually will, because there is nothing else like it.
You wouldn't want Clojure, Java or any languauge with GC running in a pacemaker either. Those are all also very important distinctions.
C++ actually proved difficult to adopt over C. The language is too difficult and the tooling is too poor. It's too hard to run a static analysis or prove 100% code coverage.
With regards to tooling, the windows visual studio experience for C++ is widely counted as one of the best development setups in the industry for any language. I know lots of people working in other languages that envy what C++ developers get.
Who is making these decisions to rewrite?
It would be great if we can see a before and after comparison.
Clojure is a pretty simple language. Ive taught it to junior devs with only Java experience and they learn it within a few weeks without any major problems.
So every hire will be a cost to cross train through language as well as get used to the codebase. And a lot of more seasoned devs are very binary about lisps. I personally wouldn't work at a place that wanted me to do Clojure over Scala/Java/Kotlin.
I worked at a globally known media company that were primarily a Scala company and they had made a handful of applications from people with Scala experience a year at best. The churn of every skilled dev leaving being replaced by someone very green is a horrible opportunity cost even for a large business.
(I remember my boss at one of my previous jobs literally saying to me "you know, we could let you write that in something more advanced, like Ruby or Python, but then when I'll be hiring, I'll have to pay 2x to a Ruby programmer than I have for a PHP programmer, so PHP it is".)
Shortsightedness is not a new invention.
I have plenty of anecdata for when I invested in a better tech fit without asking anybody and it always ended up great. EVERY. SINGLE. TIME. I got a few slaps on the wrist because managers don't like not controlling how you breathe but even they were forced to admit that I saved them money in the mid- and long-term.
I am getting old and cynical and quite frankly I never ask business people questions I know the answer to anymore. I also don't go fanboy mode about languages and tech anymore. If I find a better alternative for something that keeps bleeding my employer's money and human resource with no end in sight, I'll switch it over on both technical and long-term cost-saving merit.
To hell with anyone who disagrees. My stance these days is -- "I know both programming and some business. You only know business. I am better equipped to make the decision than you."
Fine, it wasn't 100% clear: "it ended up being great every single time". By saying that I didn't mean that I got tingles in my stomach for using some tech, I am saying that I helped an employer stop bleeding money and human resources in a black hole.
--
Related: I sometimes wonder just how much money companies lose on trust issues. Even with regular people, I often see companies spending money doing everything imaginable to make it as difficult as possible for workers - on which, too, they spend money - to do their jobs.
It only goes downhill for these companies and they lack the maturity and intelligence to recognize they brought it upon themselves and maybe start trying to turn things around.
Oh well, screw them.
Today I would love to start a project in Elixir/Phoenix (or more realistically: Python/Django), but I don't know any Elixir devs in Berlin. And I don't know too many web devs using Django in Berlin. Again if I had to build a static website, I would choose PHP (+ Laravel framework). And if it was a dynamic web app, I'd choose Node+React. It's all about availability and feasibility.
Edit: punctuation
(1) You keep saying you didn't know technology X or Y devs in Berlin. Sorry to partially derail but why is remote forbidden in your organization? I mean, you're pointing at a limitation that's rather easy to overcome.
(2) Bigger developer availability == good for business, you claim. That's very 50/50, neither side of this argument is anywhere remotely universally correct. "If all you know are hammers all problems look like nails". I've had PHP devs ruin near-perfect projects in teams where I was working. Their reliance on the arcane-but-overall-working comparison operator alone introduced at least 150 bugs over a year.
Bigger dev pool != better for business. It just helps you treat people like replaceable cogs in a bigger machine. That's not the same thing at all.
(3) Known tech != quick onboarding. You yourself pointed out your new hires needed to learn Symfony. And you claim to be interested in Elixir and Phoenix. Well, for one thing, Elixir is extremely easy to learn as a language; secondly, it's OTP (the Erlang / Elixir concurrency framework) that's hard.
So what you said could absolutely apply to Elixir. The language is learned extremely quickly and then people have to spend some time getting to know a framework. It's the same everywhere really.
I feel your comment was putting too much weight on local physical availability of programmers and that's the wrong metric to use when assessing new (and possibly better) tech.
So no, I disagree. Known language is not quicker onboarding for a framework. You'll save 4-10 workdays out of the several dozens needed for one to become an expert in a framework.
It grinds my gears to hear that legend over and over -- "new language is very risky and slow to adopt!", even though a lot of us know that the language itself is the lowest barrier of all.
On top of framework and codebase I'd also add organizational or team coding style. It becomes a bloody mess pretty damn quickly. I've personally spent 6 months being onboarded in a very finely tuned and hacked to oblivion Rails project -- a technology I knew pretty damn well at the the time -- and then it took me 3 weekends to get my own Elixir / Phoenix project off the ground... and for it be useful in business terms as well.
So these "new language risks" are vastly overstated and are simply an excuse for dogmatic people to not act in the project's best interest.
Also, even if the funding was better: One important aspect is: What if key developers (in that fancy new technology) leave the project? How fast can you find new devs? If it is a widespread technology (say: Node/Express + React) there is no risk. But think of hiring Erlang developers in your region.
I like Scheme (and it's influence on JS), I love functional programming, I like Ruby a lot, I really love Elixir. I like Python and Django a lot. But when it comes to setting up a project there are many aspects that determine my decision for technology. Some very important ones: What are my tech alternatives to tackle a problem? How wide spread is that technology in my region? How fast can I hire talented people in that tech?
I do acknowledge that a small team of good Python+Django devs for instance can work more efficiently than a team of PHP devs who don't appreciate software engineering qualities (not saying that there aren't really profound PHP devs out there, but many PHP devs who don't have profound software engineering qualities). There are only three real alternatives for web dev in Germany (if you have a tight budget): PHP based, Node/Express+React/Angular or Ruby/Rails based. I wouldn't even consider Python/Django, and forget about Elixir/Phoenix.
I was talking about you bringing in remote Elixir talent. It's not so hard nowadays, the dev base is growing.
This is one of the most unforgettable lessons I've learned in life-- 90% of the dev hiring market is between 4 languages: Java, Python, Javascript and C.
Beyond this it barely matters how awesome your language is. The manager at the other end is optimizing for per person cost, and trying to hire as many people as he/she can.
Even training devs isn't an issue. C#, Java, Python, PHP, C, JavaScript, and Ruby developers have had an easy time being productive on the first day because of how high level the language is. Projects tend to be very domain-driven, and a decent editor config let's people get started right away. Within a week of reading code and a tutorial on syntax, I have a perfectly reasonable dev on my team making meaningful contributions to maintenance and feature development. Locality, immutability, and brevity make for an exceptionally fast on boarding experience even when the dev had never used clojure or a lisp before.
How big of a problem this is depends on the team and the company.
I've worked on plenty of medium (30+ dev) projects with <10% yearly turnover and for these teams learning Clojure is practically no cost.
I've also worked on teams with 70%+ yearly turnover and teaching anyone anything was a waste of time.
Media companies tend to be on the higher turnover side and I wouldn't recommend Scala or Clojure.
I was on a major automation project where mgmt nailing down the specifications across four existing departments procedures took over a year... hard to imagine devs working less than a year making sense of it.
Meanwhile, Scala is a much more complex language, and training somebody on it will be a lot more challenging.
But if I had to take an average Java programmer and teach them a new language choosing between Clojure and Scala, I’d choose Scala hands down. The gap in semantics is so much closer, and concepts and libraries are so much more easily translatable. And it is entirely possible to be productive with Scala while knowing <50% of the language.
Meanwhile, my team regularly hires coop students, and we never had to spend more than a couple of weeks training them to be productive in Clojure. Hiring and training people is simply not a real world problem when it comes to Clojure.
With Scala you can start out in better java territory and go from there to wherever you want. I personally don’t use any of the pure functional libraries, but I still greatly benefit from the strongly and strictly typed but flexible type system. In the 50k+ lines on my most recent project, I can count the number of bugs that escaped the type checker with one hand.
Leaving this comment so people who may read this and get scared off understand that it's definitely not the case.
My company has both a) hired a number of Clojure developers, and b) a number of developers who were good programmers, so switching to Clojure was not a problem.
In general, I noticed that you either hire average programmers (in which case Clojure/ClojureScript could be a problem), or good programmers. Good programmers have no problem with Clojure, regardless whether they know it or not.
Leaving this here because people might think the above comment is universally true. It isn't.
Anecdotal evidence incoming: For any rewrite it's always the developer. Every time. It might sometimes be the manager's decision to do it, but it's always instigated by a developer.
It's similar to training someone to use Vim in that it's quite a different tooling set and workflow they're probably used to. I think that's the main barrier.
The language itself is pleasantly simple. And tools like Paredit make it one of the most pleasant languages to write. It's just hard for someone to appreciate Clojure until they put in the work to credentialize in its tooling.
There are many ways to use Clojure, the laziest one of course being the least maintainable. No language can subsitute engineering principles, years of experience, empathy etc.
I wrote a few hints of what I consider maintainable here -> https://blog.vemv.net/maintainable-clojure-beyond-aesthetics...
This is probably true if your building a very very generic small webapp. In which case, maybe use rails if it's the stack your good at.
However, as the complexity of the system grows, the less will easily fit in mvc. When that happens, pushing all the complexity into mvc will make it harder to understand, not easier.
The quoted statement tends to be true regardless!
Perfect example is running Sinatra inside of Rails: https://jacobbednarz.com/posts/sinatra-in-rails
Again: ultimately you have a Rack (ruby, https://rack.github.io) webserver interface that has a Rails app mounted inside of it.
"Rails" is just some code that is running. You can choose to defeat certain parts of it, mount other stuff on the Rack server, turn rails off entirely and just use Activerecord, etc...
I do it all the time.
When you rewrite a project it's always going to be a lot better, because you have a much better understanding of the problem being solved having done that once already.
Why would an average dev not be able to maintain a clojure code base? I'm going to guess what you really mean is a average dev that doesn't know clojure. In which case the argument your really making is that its hard to find "clojure devs". Which I think runs contrary to the numbers which suggest many more people wanting to work in clojure then can find jobs. This piece seems to echo that sentiment: https://juxt.pro/blog/posts/clojure-job-market.html
I think by and large companies probably struggle to find clojure devs in there immediate area. Which is why i see all the clojure jobs either
A) remote B) in big cities
So its possible that companies could get great devs for less if they just allowed for remote.
Nothing backed up here by hard evidence, but worth considering that the language might not really be the only factor here.
Programming language flamewars (one of the hotter circles of hell) are off topic here, as are all flamewars.
I also agree that it's sometimes easier for novices to pick up the language. I've seen students become productive faster than people with a lot of background in imperative style.
Entities:Person, Insurance, Car
Relationships:
Insurance--hasHolder-->Person(m:1)
Insurance--insures-->Car(1:m)
Car--hasPrimaryDriver-->Person(1:1)
Person--drives-->Car(m:n).
Additional constraint: hasPrimaryDriver(C,P) => drives(P,C).
The domain has cyclic relationships, hence I cannot model it as a tree. If everything is immutable, I have to update all entities that reference each other when replacing one?! What's the standard clojure way to implement it?The answer is straight forward: you use unique identifiers instead of references. A lot of your code would become similar to how you write SQL queries. You always use `id` to cross-reference entities. You can use whatever enumerable functions are in the language - List.find, Map.find etc.
Now if you want to mutate a leaf node inside a tree, well that question is itself invalid. You can't "mutate" a "value". Can you say mutate the number 12? Or the letter 'B'? Imagine every complex data-structure was atomic like this: the array [1,2,3] always remain [1,2,3]. You can't mutate it because it is one single value; you can get information from inside it, but that doesn't mean you can go and change it. If you do want to change it, then you "transform" it into a new value. So instead of using `array.push` in Javascript, you'd use `array.concat` which provides a new value. Or even better you always use the rest operator `{...oldHash, someKey: newValue}`.
This also means your complex, large tree structure is a "value". You can't mutate it. You can however transform it into a new value. So if your leaf node has to change, then it means what you now have is an entirely new value. The old value still exist; any variables that pointed to the old value still point to that, because, duh, values don't change. Rich Hickey has articulated all this really well in his talk "The Value of Values" (https://github.com/matthiasn/talk-transcripts/blob/master/Hi...)
You'd now be rightly vary of the space-time implications of copying over large sets of data everytime you want it changed a tiny bit. This is solved in functional languages by using structural sharing. When you get a new tree value with just one node changed, the runtime would actually share most of the tree structure, and newly create just the one we want changed. It'll update the reference pointer of the root node, and the entire path that goes from the root till the leaf that changed. This means if you do a shallow comparison between the new tree value and the old tree value, you'll immediately know they're different. You can also safely assume that the entire path till the changed leaf has a new reference and you can do quick shallow comparisons.
This is however an optimization and implementation detail. We're able to do this because structural sharing still allows us to keep the semantic model of everything is value for all practical purposes yet have the benefits of immutability.
OCaml lets you do both though - it supports the imperative place-oriented way of programming and value-oriented programming. It encourages value-oriented programming through its syntax and runtime library, but when you need it (for performance reasons), it is there for you.