Remix.run Logo
ragnese 18 hours ago

Talk about trivializing complexity...

The idea that making things immutable somehow fixes concurrency issues always made me chuckle.

I remember reading and watching Rich Hickey talking about Clojure's persistent objects and thinking: Okay, that's great- another thread can't change the data that my thread has because I'll just be using the old copy and they'll have a new, different copy. But now my two threads are working with different versions of reality... that's STILL a logic bug in many cases.

That's not to say it doesn't help at all, but it's EXTREMELY far from "share xor mutate" solving all concurrency issues/complexity. Sometimes data needs to be synchronized between different actors. There's no avoiding that. Sometimes devs don't notice it because they use a SQL database as the centralized synchronizer, but the complexity is still there once you start seeing the effect of your DB's transaction level (e.g., repeatable_read vs read_committed, etc).

mrkeen 18 hours ago | parent [-]

It's not that shared-xor-mutate magically solves everything, it's that shared-and-mutate magically breaks everything.

Same thing with goto and pointers. Goto kills structured programming and pointers kill memory safety. We're doing fine without both.

Use transactions when you want to synchronise between threads. If your language doesn't have transactions, it probably can't because it already handed out shared mutation, and now it's too late to put the genie in the bottle.

> This, we realized, is just part and parcel of an optimistic TM system that does in-place writes.

[1] https://joeduffyblog.com/2010/01/03/a-brief-retrospective-on...

ModernMech 17 hours ago | parent [-]

+5 insightful. Programming language design is all about having the right nexus of features. Having all the features or the wrong mix of features is actually an anti-feature.

In our present context, most mainstream languages have already handed out shared mutation. To my eye, this is the main reason so many languages have issues with writing asynch/parallel/distributed programs. It's also why Rust has an easier time of it, they didn't just hand out shared mutation. And also why Erlang has the best time of it, they built the language around no shared mutation.