Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Immutable Approaches (macwright.com)
20 points by Tomte on March 8, 2021 | hide | past | favorite | 11 comments


There is an active TC39 proposal to add immutable types to JS: https://github.com/tc39/proposal-record-tuple


This approach is sort of similar to an LSM - you can make this more efficient by doing a routine compaction in your storage whereby you collapse many patches on top of the original version and call it v2. You can say have a row with the same id (manage those conflicts!), a reference to the last patch applied, and a new version number. Then, you just always query the latest "version".


Depends on whether you've gone crypto or not. If each patch is authored and signed by some form of crypto id in a permissionless p2p system, there's no central authority to create the compact version of the patch.


The clunkyness of this is what drove me away from JS (among other things). Now I functional compile-to-js languages and it's a joy!


I think it’s interesting that libraries like Immutable.js, Immer and Ramda show that there is a real appetite amongst JavaScript developers to embrace a more functional approach, but at the same time languages like ClojureScript, Elm, and Rescript don’t see more adoption.

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.


I suppose it’s all a trade off. The pain of jumping through hoops with the libraries mentioned above

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.


It depends on the language. Elm does not allow you to call JS directly, but ReasonML and Fable (F#) both do. This means with a little effort you can use any JS library.

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.


I definitely agree about the benefits of a mainstream language/big ecosystem when it compares to something more niche (Although ClojureScript with shadow-cljs [0] has an excellent interop story with the JavaScript ecosystem).

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!

[0] https://github.com/thheller/shadow-cljs


Clojurescript still has the annoying problem of having to convert between the two language data structures. So even with shadow-cljs(no idea how good it is) Cljs is no smooth sailing either. Immer seems to be the best compromise and more ergonomic approach to immutability in JS. Immutability is also needed much less in single-threaded environments where JS operates where async code is pretty much used for IO 99% of the time.


Agree that converting between JS and CLJS data structures is a pain.

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.


Why cant you just reduce these changes with trigger on update? I think Postgres allows even writing functions in JS.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: