In another life I will be a Haskell programmer
Why not python ?
Concurrency in Haskell: Fast, Simple, Correct
11–20 of 129 posts
Re: Concurrency in Haskell: Fast, Simple, Correct
#12I thought it was a bit odd that the author claims there’s no mutexes in sight, the TVar is effectively a mutex guard unless I’m misunderstanding this? (I’ve written exactly 0 lines of Haskel). Or is the claim that the lack of ceremony and accidental complexity around threading is the real win for concurrency here?
You are correct, Haskell has quite a few mutex-like types. MVar is one of them. However, if memory serves me right, TVar is a building block for the transactional memory subsystem. The guard on TVar with, say, modifyTVar is not really stopping execution at entrance but simply indicating that the block modifies the variable. In my mental model, some magic happens in an STM block that checks if two concurrent STM block…
Re: Concurrency in Haskell: Fast, Simple, Correct
#13I thought it was a bit odd that the author claims there’s no mutexes in sight, the TVar is effectively a mutex guard unless I’m misunderstanding this? (I’ve written exactly 0 lines of Haskel). Or is the claim that the lack of ceremony and accidental complexity around threading is the real win for concurrency here?
No, a TVar is not a mutex guard. A TVar is a software transactional memory (STM) variable. STM works just like a database: you batch together a sequence of operations into a transaction and then execute them. During execution of a transaction, all changes made to the contents of the TVar are stored in a transaction log. If some other transaction occurs during the execution then the whole thing is aborted and re-run.…
This library is full of STM-oriented data structures. They perform better than a simple `TVar (Map k v)`.
It's kind of a fun trick actually. The stock Map is just a tree. The STM Map is also a tree [1] but with TVars at each node. So this helps a lot with contention - you only contend along a "spine" instead of across the whole tree, which is O(log n).
[1] Technically a HAMT a la unordered-containers - trie, tree, you get the idea :)
Re: Concurrency in Haskell: Fast, Simple, Correct
#14In another life I will be a Haskell programmer
Re: Concurrency in Haskell: Fast, Simple, Correct
#15Rust has a bunch of these while being maintainable.
The concurrency stuff in the stdlib + the mainstays in the ecosystem are pretty stable and noncontroversial..there's stuff in Haskell that churn but this is not one of them.
Re: Concurrency in Haskell: Fast, Simple, Correct
#16I thought it was a bit odd that the author claims there’s no mutexes in sight, the TVar is effectively a mutex guard unless I’m misunderstanding this? (I’ve written exactly 0 lines of Haskel). Or is the claim that the lack of ceremony and accidental complexity around threading is the real win for concurrency here?
You are correct, Haskell has quite a few mutex-like types. MVar is one of them. However, if memory serves me right, TVar is a building block for the transactional memory subsystem. The guard on TVar with, say, modifyTVar is not really stopping execution at entrance but simply indicating that the block modifies the variable. In my mental model, some magic happens in an STM block that checks if two concurrent STM block…
Haskell's STM is pretty world-class though. That's fair to say :)
Re: Concurrency in Haskell: Fast, Simple, Correct
#17Re: Concurrency in Haskell: Fast, Simple, Correct
#18I thought it was a bit odd that the author claims there’s no mutexes in sight, the TVar is effectively a mutex guard unless I’m misunderstanding this? (I’ve written exactly 0 lines of Haskel). Or is the claim that the lack of ceremony and accidental complexity around threading is the real win for concurrency here?
Here's an example in perhaps more familiar pseudocode.
var x = "y is greater than 0"
var y = 1
forkAndRun {() =>
y = y - 1
if (y
y = y + 1
if (y > 0) {
x = "y is greater than 0"
}
}
In the above example, it's perfectly possible, depending on how the forked code blocks interact with each other, to end up with x = "y is less than or equal to 0"
y = 1
because we have no guarantee of atomicity/transactionality in what runs within the `forkAndRun` blocks.The equivalent of what that Haskell code is doing is replacing `var` with a new keyword `transactional_var` and introducing another keyword `atomically` such that we can do
transactional_var x = "y is greater than 0"
transactional_var y = 1
forkAndRun {
atomically {() =>
y = y - 1
if (y
y = y + 1
if (y > 0) {
x = "y is greater than 0"
}
}
}
and never end up with a scenario where `x` and `y` disagree with each other, because all their actions are done atomically together and `x` and `y` are specifically marked so that in an atomic block all changes to the variables either happen together or are all rolled back together (and tried again), just like in a database.`transactional_var` is the equivalent of a `TVar` and `atomically` is just `atommically`.
Re: Concurrency in Haskell: Fast, Simple, Correct
#19Earlier quoted context omitted.
You are correct, Haskell has quite a few mutex-like types. MVar is one of them. However, if memory serves me right, TVar is a building block for the transactional memory subsystem. The guard on TVar with, say, modifyTVar is not really stopping execution at entrance but simply indicating that the block modifies the variable. In my mental model, some magic happens in an STM block that checks if two concurrent STM block…
I think Clojure has some kind of STM too? Haskell's STM is pretty world-class though. That's fair to say :)
Basically it's the difference between focusing only on transactional variables without having a good way of marking what is and isn't part of a larger transaction and having a higher-order abstraction of an `STM` action that clearly delineates what things are transactions and what aren't.