3 ms·
I think we're talking past each other. > I like immutable structures and use them frequently. Are you talking about immutable structures in Clojure(script)/H
by iLemming 1y ago
I think we're talking past each other.
> I like immutable structures and use them frequently.
Are you talking about immutable structures in Clojure(script)/Haskell/Elixir, or TS/JS? Because like I said - the difference in experience can be quite drastic. Especially in the context of state management. Mutable state is the source of many different bugs and frustration. Sometimes it feels that I don't even have to think of those in Clojure(script) - it's like the entire class of problems simply is non-existent.
- recursive 1y agoOf the languages you listed, I've really only used TS/JS significantly. Years ago, I made a half-hearted attempt to learn Haskell, but got stuck on vocabulary early on. I don't have much energy to try again at the moment. Anyway, regardless of the capabilities of the language, some things work better with mutable structures. Consider a histogram function. It takes a sequence of elements, and returns tuples of (element, count). I'm not aware of an immutable algorithm that can do that in O(n) like the trivial algorithm using a key-value map.
- iLemming 1y ago> I made a half-hearted attempt to learn Haskell Try Clojure(script) - everything that felt confusing in Haskell becomes crystal clear, I promise. > Consider a histogram function. You can absolutely do this efficiently with immutable structures in Clojure, something like (reduce (fn [acc x] (update acc x (fn [v] (inc (or v 0))))) {} coll) This is O(n) and uses immutable maps. The key insight: immutability in Clojure doesn't mean inefficiency. Each `update` returns a new map, but: 1. Persistent data structures share structure under the hood - they don't copy everything 2. The algorithmic complexity is the same as mutable approaches 3. You get thread-safety and easier reasoning for a bonus In JS/TS, you'd need a mutable object - JS makes mutability efficient, so immutability feels awkward. But Clojure's immutable structures are designed for this shit - they're not slow copies, they're efficient data structures optimized for functional programming.
- pka 1y ago> immutability in Clojure doesn't mean inefficiency. You are still doing a gazillion allocations compared to: for (let i = 0; i < data.length; i++) { hist[data[i]]++; } But apart from that the mutable code in many cases is just much clearer compared to something like your fold above. Sometimes it's genuinely easier to assemble a data structure "as you go" instead of from the "bottom up" as in FP.
- iLemming 1y agoThe allocation overhead rarely matters in practice - in some cases it does. For majority of "general-purpose" tasks like web-services, etc. it doesn't - GC is extremely fast; allocations are cheap on modern VMs. The second point I don't even buy anymore - once you're used to `reduce`, it's equally (if not more) readable. Besides, in practice you don't typically use it - there are tons of helper functions in core library to deal with data, I'd probably use `(frequencies coll)` - I just didn't even mentioned it so it didn't feel like I'm cheating. One function call - still O(n), idiomatic, no reduce boilerplate, intent is crystal clear. Aggressively optimized under the hood and far more readable. Let's not get into strawman olympics - I'm not selling snake oil. Clojure wasn't written in some garage by a grad student last week - it's a mature and battle-tested language endorsed by many renowned CS people, there are tons of companies using it in production. In the context of (im)mutability it clearly demonstrates incontestable, pragmatic benefits. Yes, of course, it's not a silver bullet, nothing is. There are legitimate cases where it's not a good choice, but you can argue that point pretty much about any tool.
- pka 1y agoIf there was a language that didn't require pure and impure code to look different but still tracked mutability at the type level like the ST monad (so you can't call an impure function from a pure one) - so not Clojure - then that'd be perfect. But as it stands immutability often feels like jumping through unnecessary hoops for little gain really.
- iLemming 1y ago