“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?”
- http://www.elmbark.com/2016/03/16/mainstream-elm-user-focuse...
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.
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?
Haskell-like (but taking away some of the pain points), for the frontend, compiles to very readable javascript.
There's an effort to make something better and on the same vibe as Haskell's `stack`, which is `psc-package` [1].
I switched to it for all new projects, and while it still has some rough edges, I don't really miss bower.
I think they are over-estimating how much people care about runtime errors.
JVM doesn’t apply hence.
Error handling is somewhat over-emphasized in comparison to other things that affect productivity (and maintainability).
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).
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.
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.
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 :-)
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)
And I'd bet money that if that same project were translated into ClojureScript, it would be less than one-third that size for the same benefits.
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.
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)
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.
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...
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.
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/
With no offence, but what quality code/library/framework has he shared or produced?
Building composable abstractions https://www.youtube.com/watch?v=jJIUoaIvD20
Category Theory From the Universe Up https://purelyfunctional.tv/courses/category-theory/
Data modelling in Clojure https://purelyfunctional.tv/courses/modeling-solitaire-in-cl...
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/.)
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.
> 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.
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).
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.
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.
"Modern Javascript ES2020" + lodash + immutablejs
But lodash and immutablejs don't mix ;) and still, with either two, it won't be as consistent.
But nodejs and its ecosystem is just to hard to ignore for web apps, it really has too much good stuff (and bad too).
I mean, maybe you can even do so in a C# shop, ClojureCLR is a real thing.
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.
It is not without some career risks, but it can also open new doors.
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?
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