Clojure is fantastic for its simplicity, and I worked on a Clojure code base full time for 5 years, coming up with ways of translating Java patterns into Clojure. But I've noticed it has not been gaining traction in the job market, and now I feel like that 5 years has been a waste of valuable career building time, which I wish I had spent gaining more experience in (sigh) C# and .NET, so that I could get the more local jobs which all seem to use the Windows ecosystem, so we don't have to uproot our family and move to the city. Not that I don't know C# and .NET, but I definitely don't have 3+ years experience in it and I definitely don't have any experience MS SQL. So being able to do really cool things in Clojure, and especially having excellent rapid development skills with REPL-driven development, has done me no good. The one remote job that I found that uses Clojure turned me down because they used zippers in the code test, and that's literally the one Clojure construct I just can't wrap my head around, which is ironic because idiomatic Clojure really doesn't use recursion in the first place, favoring streams and transducers instead. My career future doesn't really seem to have a lot of Clojure in it unfortunately. Plus most of modern JavaScript has most of the same benefits as Clojure anyway, especially in terms of FP.
“If functional programming is so great, why is it still niche? We have a product that can practically eliminate runtime errors, make refactoring much easier, lighten the testing burden, all while being quite delightful to use. What’s the hold up?”
I'm just getting into Clojure and enjoy working with it so much that I don't care if there are job opportunities at the end of it to justify the time investment and mind-reboot. It's the first language that I didn't feel like I was fighting, and Parinfer has made all those “weird parentheses“ a joy: https://shaunlebron.github.io/parinfer/
That said, there do seem to be more opportunities than last time I looked at Clojure/Scala/Haskell (Functional Works, mentions in HN Who's Hiring) – it feels like people are waking up to FP ideas after React stormed the front-end scene.
> “If functional programming is so great, why is it still niche? We have a product that can practically eliminate runtime errors, make refactoring much easier, lighten the testing burden, all while being quite delightful to use. What’s the hold up?”
I think they are over-estimating how much people care about runtime errors.
I agree. I've worked in both Elm and ClojureScript. In one, I have to constantly deal with compiler errors. In the other, about as much runtime errors. The net time for error handling is the same. But the net time in actually writing code is in favor of ClojureScript, which requires at least half as many lines as Elm (and often much less than half).
Error handling is somewhat over-emphasized in comparison to other things that affect productivity (and maintainability).
> “If functional programming is so great, why is it still niche?
It's niche because learning a language is the exact opposite of fast iterative process with immediate feedback. The feedback cycle of learning and evaluating a language is 6th months to multiple years, which means it takes a lot to really evaluate one. Then the added issue of network effects (ie needing others to know the language in a team).
Functional 'concepts' are not niche, but functional languages still are. If you asked your average Java 8 programmer or JS programmer to write an app in Haskell or Elm, they'd struggle.
I'd consider myself an average JS programmer and would love to try writing web apps in Haskell. I've spent some time on Haskell books, fell in love with the type system, got a basic understanding of monads but found it difficult to "move forward".
I think the issue for me is I predominantly build web apps. Can you recommend any resources for building modern web apps in Haskell or at least fitting it into my day to day at work?
So did C++. But you can't program C++ or Java in a functional manner the way you can an actual FP language. Largely due to lack of proper data structures for FP.
Learning lisp is never in vain. You can almost apply your functional programming paradims learnt in clojure to most of the dynamic languages out there. Plus you will be thinking in the immutable way of doing things.
But "immutable" way of doing things have been encouraged, suggested, marked-in-stone as best-practices in most languages since 2005... am I missing something?
People have been saying that:
- Global Object is bad
- Stateless is better than Stateful
- Singleton becomes an anti-pattern
- Methods/Functions without side-effect (avoid mutation)
Nobody really mentioned to do things the Functional programming way per-se but the characteristics are there.
Immutable programming with proper immutable data structures (i.e. persistent) is very different than immutable programming in a language with lots of constructs for mutation.
You can throw "const" on things but that isn't really the same kind of immutable programming that exists in Clojure.
Because immutable programming is not just about data not changing, it's about the transformations you can do on that data without concern for the costs that would arise if you did those same transformations in a language without immutable data structures.
> which I wish I had spent gaining more experience in (sigh) C# and .NET
I am sort of afraid that I might end up in similar situation if I would need to change jobs. At my current company I worked 1/2y in Java, 1y in Clojure, 1y in Python, 1/2y in C#, 2y in mix of javascript, groovy, ansible and chef-scripts. There seems to be GO on a horizon.
This means that all the well earning "Senior Developer - requires 5 years experience with swing" will probably be out of reach.
But as they say, you shouldn't call yourself $LANGUAGE-programmer anyway, so I hope I will be able to sell myself as the "7 years of devops/process-automation", rather than "2-year Node.js experience" guy :-)
Doesn’t the Clojure way of thinking/programming help you with writing better JavaScript though? I’m a JS Dev and I’ve been looking into Clojurescript to broaden my horizon but I’m also hoping to learn some FP techniques that I can use in my Node/React projects.
I'm a JavaScript developer, and (much to my delight) my team recently switched to a much more FP-heavy style (for example, switching from Flux to Redux for our React app... we even used PureScript for a bit). The differences were night and day; even just prioritizing immutability has transformed our codebase. The project is about ~100,000 LOC, so the benefits we get in maintainability and readability are huge; also, after we switched to Redux, our application's performance jumped tremendously (for several reasons).
So, to answer your question more directly, I can emphatically say: Yes!
I wonder how many people feel the same out of real life experience.
Imperative and mutable objects are still seen as the only way for serious products .. there needs to be a large body of evidence to at least make people consider other options (and I'm not trying to sell my church here, just avoid blindness)
What do you mean by serious products? There are plenty of massive projects written in purely functional languages (e.g. Facebook's Sigma) and while adoption isn't as fast as it could be, things seem to be shifting towards functional/immutable, which makes sense since reasoning about highly parallel code without RT and immutability is pretty much impossible.
I've considered pitching it, I'll be honest... We stumbled upon a pretty nice architecture via trial-and-error, but when I read about re-frame recently, I realized that it was the exact same thing except in a cohesive framework and years older than I'd have imagined (IMHO ahead of its time)!
Hi, I'm a Redux maintainer. I'd love to see a writeup on how your team has been using Redux, what maintainability benefits you've seen, and how the app's performance has improved. If you do write something, please ping me @acemarke and let me know!
> Plus most of modern JavaScript has most of the same benefits as Clojure anyway
Except for the very elegant syntax. Your Clojure code will be at least half the size of equivalent JS code, probably much less than that. And without pulling in explicit dependencies on ImmutableJS, React and others.
Projects with less code have less bugs and are more fun to think about, in general. That's something extra Clojure brings to the table.
It's a bit sad how network effects rule. If businesses weren't sold so much .net maybe there would be more jobs for other, arguably better solutions.
Now, as a side note, there were recent news about clojure CLR. Maybe some will accept having clojure code on top of C# ? (clojure is often used as a better lifestyle on top of Java legacy)
I read a blog post a few days ago about a Clojure compiler from the CLR which is being actively maintained to produce bytecode for Unity. It was posted here a few days ago but didn't seem to gain much traction, perhaps there's more interest in this thread: http://nas.sr/magic/
ClojureCLR is definitely cool, and a few years ago I wrote a simplistic window manager [1] using ClojureCLR for scripting. But local jobs that want a C# person aren't probably the same kind of people who will be open minded about CLR languages, they probably just want someone who can maintain their plain-jane .NET apps that were written by someone fresh out of community college (which is ironically where I learned C++ and VB.NET).
> Plus most of modern JavaScript has most of the same benefits as Clojure anyway, especially in terms of FP.
This is technically an accurate statement, the JavaScript ecosystem is massive and has excellent equivalents to just about every piece of useful Clojure FP construct out there.
But from a practical standpoint, when you start stitching these FP pieces together, you'll notice that the FP model in JS suffers immensely from the mutable-by-default design in its core data structures.
This means FP libraries have to accept and output these mutable-by-default data structures to gain any non-trivial adoption, which in turn often means they can't afford to use persistent data structures internally either, because recursively translating to and from the default mutable data structures, even just on the edges of the system, will often prove to be prohibitively expensive for most libraries. The entire JS ecosystem thus overwhelmingly assumes the use of mutable data structures, and in a program that tries to do FP in JS, any performance wins resulting from the use of structural sharing in persistent data structures (instead of naively cloning the default mutable data structures) get mostly nullified, if not outright negated by the need for recursive translation every time it needs to interact with third-party libraries or core browser APIs.
Even in systems that uses Redux (which as an architecture is about as functional as you can get, and outright forbids direct state mutation) overwhelmingly end up using built-in mutable data structures to represent state. Its Recipe page on "Using Immutable.JS with Redux" (https://redux.js.org/docs/recipes/UsingImmutableJS.html) is littered with a long list of caveats precisely because there exists far too many not-immediately-obvious performance footguns available for one to shoot themselves with when taking up the task of carefully micro-optimizing all the expensive toJS and fromJS calls they'd have to make to build anything non-trivial. This is of course not to throw ImmutableJS under the bus, because it provides an excellent set of persistent data structures by any measure. It does have an uphill battle to fight to justify its adoption though, because it exists in an ecosystem that compels users to reject it for no fault of its own.
I haven't even gotten started on the developer ergonomics of using non-native data-structures, which since ES6 has taken a (relative) nosedive, because of all the syntactic sugar that was introduced for the built-in data structures.
Contrast this with the ClojureScript ecosystem, in which the use of efficient persistent data structures is rarely ever a question, because that's the default, and every third party library and application written in CLJS can just take the associated performance benefits for granted.
P.S. Apologies for the rant. I've been switching back and forth between CLJS projects and JS projects for the past year, and this has always been my biggest pet peeve with the state of functional JS. I'm actually quite happy with just about every other aspect of functional JS, to be honest, but I fear JS may never reach its full potential as a functional language because of this core defect.
...yes, but that comes with burden of complexity and (usually) bad design decisions (like using core async).
Its not just night & day, closurescript > js; a lot of very good stuff exists there, but immutable by design isn’t a silver bullet that magically makes problems go away, and it (cljs that is) does introduce its own problems.
Practical examples of where cljs is tangibly a better choice is probably more useful to people.
For example, I personally have fought a cljs modal that kept an open channel waiting on user input; but when the modal closed, the channel was still there waiting and when it reopened there were now two channels, both getting input events, doing twice the work. Bad design, and not fp at all.
How did immutable structures help? Not at all. The author just used a global state atom to store everything anyway.
I’m just saying; yes, in clojure immutable is on by default, and that is good... but I don’t think I’ve observed, particularly, better code & lower bug rates in the cljs code I’ve worked on as a result...
Oh yes, definitely there are plenty of other tradeoffs involved with CLJS vs JS that are much more nuanced, and as you said, immutable by default is by no means a silver bullet. There's a reason why I still by choice use JS for certain projects when CLJS exists.
I was only lamenting what I consider to be the only major deficiency in JS when it comes to writing functional code, one that I haven't really found any viable way to work around, despite being quite happy with most other aspects of the overall experience of writing functional JS.
Thanks but I'm highly skeptical of the wording, it sounds suspiciously like a pyramid scheme. If they really were in contact with remote Clojure jobs, I don't know why they would hide them behind a free email course. That doesn't seem to benefit the employers or employee candidates, only the people behind this website.
The site's run by a well-respected Clojure developer and educator called Eric Normand. This is not a pyramid scheme, and Eric makes no guarantees of finding Clojure-related work – only that the content will be useful if working in Clojure and FP is of interest to you.
I've found the free drip-fed email course helpful. The free video content is also well presented, as are Eric's talks at Clojure conferences on YouTube. I plan to subscribe, but the video content is also downloadable individually if you want to skip the free tips and offers in the intro emails: https://purelyfunctional.tv/courses/
It might not be a pyramid scheme but the phrasing is certainly very fishy and scammy:
> It can be the first step in a more fun and creative career.
This phrasing is everywhere in the ad. To me, it's just someone trying to make money from teaching a language. Nothing wrong with the teaching part but the hidden-yet-never-spelled-out-promises-because-of-legal-exposure feels very disingenuous and scammy to me.
To me instruction like this is worth more than a library with a few thousand stars on GitHub.
The FP industry could benefit from more programmer-educators that don't actively obfuscate concepts in mathspeak. (That sometimes has its place too, though, and there are other resources that do a good job of deciphering monads etc. without heavy metaphor, like Haskell Programming From First Principles: http://haskellbook.com/.)
FWIW, this answer sets off the scam warning bells in my head.
There are two main reasons I think. First, you originally call the developer well-respected and then when pressed reveal that you really meant "personally like". This comes off as double speak and feels like you just lied in the first comment.
Second and what seals the deal for me, is that you double down on the double speak and argue that your stance is "more valuable". This comes off as highly defensive.
I certainly can't speak for your intentions or the actual content of your messages, but I'm assuming the charitable thing and guess that you might be unwittingly speaking in a way that's putting people off.
That said, these are just my personal gut reactions, so YMMV.
I recognise that it's easy online to mistake enthusiasm for overselling, and that wasn't my intention at all.
I have no stake in this other than to encourage people to give Clojure a try (I just enjoy the language and want to see it grow). I shared my perception that the site owner is well-respected (based on the community's reactions to blog posts, forum posts, and talks), and gave my own reasons (the education style works for me and he speaks with clarity and authority on a topic that can often be mired in academic concerns).
The good thing is that others teach Clojure actively if you're looking for a less job-oriented marketing pitch. For example, https://lambdaisland.com/ is worth learning from (and run by a developer with a popular Clojure project called Chestnut, if that matters to you), http://www.4clojure.com/ and http://clojurescriptkoans.com/ are free practise sites, and the https://www.braveclojure.com/ and Living Clojure books were helpful to me when getting started.
The sad news for Elm/Clojure/Haskell developers is that most of the dev managers are old java/c# folks -- not the sharpest or the most curious folks and they are unlikely to try out functional languages or any new languages for that matter.
I feel your pain but from a different angle, I am trying to find a job right now that is clojure and either its on site in SFO (No thanks) or in London. Breaking in seems hard enough and then hearing stories like this don't instill confidence. I really hate it because going back to dealing with OO is actually painful, it just seems like it's building up a whole big skeleton for little benefit.
I feel the same with not having Clojure around at work anymore after I quit my last job.
That said, at the new place that uses Rails we instilled a culture of avoiding stateful updates, preferring hash structures to mountains of object definitions, and use of functional transforms as much as possible.
Then we needed to ramp up to the next level and chose the JVM for writing concurrent code. But we started with Scala as something that has functional concepts baked in since it's "easier to hire for". Not the same, but there are other paths to dealing with lack of Clojure.
Oh, and the Scala only makes up for part of losing Clojure because we actually use it in a similar way to Clojure plus a bajillion type declarations. With the occasional workaround for a compiler bug (I've encountered three in the past 6 months).
How you deal with two separate tech stacks in single product? I try to shift from Ruby (on Rails) to to Clojure. But I feel hard to rewrite mountains of RoR convieniece and habits into Clojure (1.day.ago, named routes, ActiveMailer, encrypted cookie etc). As I am also partially Java guy, I came to conclusion that migration of project into JRuby and then embedding Clojure parts gradually might ease the transition.
I try to shift from Ruby (on Rails) to to Clojure. But I feel hard to rewrite mountains of RoR convieniece and habits into Clojure (1.day.ago, named routes, ActiveMailer, encrypted cookie etc).
This seems like a bad idea from a business value perspective. What value is delivered by translating mountains of code? Probably none, being honest.
As I am also partially Java guy, I came to conclusion that migration of project into JRuby and then embedding Clojure parts gradually might ease the transition.
Don't transition everything, giant waste of time. Run ruby/rails on jruby, then package the core Clojure logic up as a library, and call into it from rails where needed. Clojure is your core logic, ruby/rails is the web front end to that core.
Dealing with JRuby will just be that much more to manage, but will introduce the JVM in a single app. You don't have to do everything at once if you break into separate apps/boxes/services.
We're growing to the point of needing a few distinct components after building a Rails monolith that already had very strong internal boundaries. As we split out different parts to run on different machines, they will either get an immediate re-write, or eventual re-write from behind the service interface.
It can’t be literally true learning Clojure did you no good... You do need to be conscious in your interviewing, and make sure you have some talking points ready to explain how clojure sharpens your thinking and applies to other languages besides. At that point if the recruiter doesn’t see the fit, you probably want to avoid that employer anyway.
I am surprised that there are more jobs in Windows and .NET at your place. Java platform is more popular than .NET, and your knowledge of JVM is very valuable. I think you are much better off trying for Java/Scala/Clojure jobs.
If you did that you would likely be fired. And for good reason.
Clojure is a language that needs a lot of careful thought before being dropped into a Java shop. It's the complete opposite of Java in many respects and at some point that code will need to be maintained.
This kind of sneaky sneaky subversion is how Linux gained a foothold in corporate IT. And we know how that turned out. This is definitely a method smart underlings can employ to change things for the better.
It is not without some career risks, but it can also open new doors.
I've known more than one developer who successfully did this in their Java job. They were not fired. Some of them ended up speaking at Clojure conferences about it.
My gripe with Clojure is readability. Its like the PERL of FP to me. Why is there so much syntactic sugar to achieve the same thing? Like this line from the article: "Eve: Or if you want - no-hash solution." This shit makes me cringe.
Just pick one way to to do something, and make that the default in the language. This is why Python is one of the more popular languages today, you can go from 0 to relatively proficient in no time. No FP lang can claim the same thing. And people wonder why after 50 years FP hasn't completely taken off (unless you count javascript).
I can read 10 programs solving the same problem in clojure and they can look almost completely different. That is bug, not a feature, I'm sorry. Having "freedom" to do things in different ways just adds cognitive load. We already deal with enough option fatigue in our daily lives, why make it a core part of a language?
Readability might be a fair criticism but syntactic sugar is a weird one, there's not a lot of syntax at all.
Multiple ways to do something is a feature, and there's definitely multiple ways to do things in python:
metaclass vs class decorators
lambdas vs explicit functions (basically the same thing as your no hash example)
map/reduce/filter vs list/generator comprehensions