4 ms·
Rust does a great job here, but so do languages that make multithreading safer at a higher level -- Erlang/OTP and Haskell are two great examples. Immutable da
by gmfawcett 7y ago
Rust does a great job here, but so do languages that make multithreading safer at a higher level -- Erlang/OTP and Haskell are two great examples. Immutable data may not solve every concurrency problem, but it sure goes a long way.
I also have a lot of respect for Ada's task-based concurrency approach (independent actors, communicating by rendezvous). You don't get the flexibility to roll your own concurrency strategy in Ada, but the language's support for its chosen mechanism is truly excellent. Even if you'll never use Ada, this part of the language is worth studying just as an example of great engineering design.
- DougBTX 7y agoThere's a nice Kevlin Henney talk where he lays out this diagram: | non-shared mutable state | shared mutable state | ----------------------------+------------------------ | non-shared immutable state | shared immutable state | Each quadrant is safe, except the one in the top right: shared mutable state. Functional languages are great at the bottom two, since they strongly encourage immutable state. Message-passing based concurrency strongly encourages non-shared state, the safe two on the left. Rust is the only language I've seen which encourages all three safe quadrants, while making the fourth a compile-time error.
- redisman 7y agoSpeaking of Shared mutable state, unlearning OOP is going to be a big task for the industry to tackle. Feels like it's on its way out on the backend at least already. It's definitely been my biggest stumbling block in grokking parallel compute.
- whateveracct 7y ago> Functional languages are great at the bottom two, since they strongly encourage immutable state. Haskell actually has safe & ergonomic shared mutable state via STM And it has proven-to-be-not-shared mutable state via ST.
- kccqzy 7y ago> Each quadrant is safe, except the one in the top right: shared mutable state. No. Your database is one giant shared mutable state. How is using a database safe then? Transactions. Haskell has had software transactional memory for fifteen years now. Microsoft tried to copy it in .NET but it's nearly impossible to do right in a language without clear separation of pure and impure code.
- astine 7y ago"> Each quadrant is safe, except the one in the top right: shared mutable state. No. Your database is one giant shared mutable state. How is using a database safe then? Transactions." Transactions are less an occasion where shared mutable state is made 'safe' during concurrency and more a situation where concurrent processes are forced to temporarily interact and operate in a sequential, non-concurrent, manner. They use locks under the covers. Databases manage to be parallel because different processes operate on different sets of data at the same time; they lock when two or more processes attempt to access the same row on a table. Transactional state access is still vulnerable to deadlocks and other difficulties of concurrent programming. This means that transactional state is not 'safe' in the same way that immutable and non-shared state are safe. It's just a much easier way of managing the kind of difficulties you have with shared mutable state than say, raw locks.
- kccqzy 7y agoNo. Please read about MVCC: https://en.m.wikipedia.org/wiki/Multiversion_concurrency_control https://en.m.wikipedia.org/wiki/Multiversion_concurrency_con... The tl;dr is that > Locks are known to create contention especially between long read transactions and update transactions. MVCC aims at solving the problem by keeping multiple copies of each data item. In this way, each user connected to the database sees a snapshot of the database at a particular instant in time. Any changes made by a writer will not be seen by other users of the database until the changes have been completed (or, in database terms: until the transaction has been committed.) In other words, the system uses immutable state under the hood plus some atomics/locking to present the abstraction of safe shared mutable state.
- jandrese 7y agoThe trick is using the three safe quadrants without bottlenecking on memory bandwidth copying the data over and over again.
- astine 7y agoIf immutability is a language level guarantee and not just a convention, you can use structure sharing to address this problem pretty effectively. Just about any functional language with immutable datastructures does it.
- hopia 7y agoFor the record, Erlang also has an internal transactional in-memory database called Mnesia, which is essentially large-scale shared mutable state.