Immutable Approaches
macwright.com
macwright.com
I suppose it’s all a trade off. The pain of jumping through hoops with the libraries mentioned above vs dealing with an entirely different language and having to hire/train for it.
With no libraries, modern JS makes being "diligent about immutability (as the article puts it)" straight forward, making the benefits of something like Clojure very small and not worth it for the majority of projects. Having immutability by default pales in comparison to the benefits of using mainstream languages with big ecosystems IMO.
I’m not sure I can agree with the premise that “developer diligence” is a reliable approach immutability (or any other development ideals). Maybe in a small team of like-minded devs diligence is enough, but in the large, with a multi-paradigm language that allows pretty much anything, you can be sure to see pretty much anything!
The best approach to dealing with that is to isolate that interop at the edges of your program.
I’m currently, coincidentally, working on a wrapper for Express to do just that. The wrapper library is responsible for mapping between the Express req/res objects to simple ClojureScript maps. Combine that with a similar wrapper around something like fetch or axios and all my code can be pure ClojureScript.
I mean, that is the general practice in Clojure/Java land. Write wrappers around the native libraries to isolate the pain that comes from interop.
I’m a sucker for Clojure though, and willing to do the work.
I think the advantage of these functional web languages is in small but high-skill teams where robust code can be written in a minimal number of lines (more expressive, type checked, etc) and everyone on the team is able to pick up new things quickly. The big caveat is that you need to have a solid understanding of JS before learning these languages on top. This makes the barrier too high for all but the best junior developers.
Another point is that Node is not particularly good at vertical scaling, so if you care about this and want a shared language between client and server, F# and OCaml (ReasonML) are much better bets.