[Haskell-cafe] MVar considered harmful
Alexandru Nedelcu
groups7 at alexn.org
Wed Jan 2 00:44:25 UTC 2019
Hello,
I’m the author of the `MVar` implementation in Cats-Effect.
> Recently I had an interesting discussion on MVars with cats-effect
> library
> designers. Cats-effect brings MVar synchronization primitive along
> with
> other IO stuff to the Scala programming language. I tried to persuade
> them
> to include some Control.Concurrent.MVar’s functions to the library
> but has
> failed completely. Moreover, now I think that MVar is a poor choice
> for
> basic synchronization primitive.
I believe `MVar` is a superb choice for synchronisation, because it
behaves like a blocking queue, which in computer science is a pretty
fundamental tool.
It is true that in Cats-Effect an `MVar` might not be a primitive, but
as I explained in that thread, on top of the JVM the real primitives are
the low level building blocks like `AtomicReference`.
> 1. It’s complex. Each MVar has 2 state transitions, each may block.
Blocking is a feature. If you have to build that logic via `Ref`
(`IORef`), you’d have to model the state machine by yourself and
that’s complexity being pushed to the user.
> 2. It does not play well in presence of asynchronous exceptions. More
> specifically, `take` and `put` operations should be balanced (each
> `take`
> must be followed by `put`)
The `take` followed by a `put` rule is only for your “modify”
use-case.
The problem is that a `modify` function that’s described via `take` +
`put` is not an atomic operation and this is a problem, but only if any
of the actors accessing the `MVar` are doing so in a different order.
This isn’t a problem for other use-cases tough.
> this force programmer to mask asynchronous
> exceptions during the MVar acquisition and since `take` function may
> block,
> this will delay task cancelation.
I don’t have much experience with Haskell’s async exceptions, but if
you mean that `take` must be executed as `uncancelable`, via `bracket`,
then this is a problem that we can fix in Cats-Effect 2.x, as mentioned
in that thread.
> What could be the sensible alternative? Guy from the cats-effect
> suggested
> me IVar + atomic reference (IORef). This pattern separates concern of
> blocking (synchronization) from the atomic mutation. So everything can
> be
> represented as atomic reference with IVar inside. Just look at this
> beautiful mutex implementation
> https://github.com/ovotech/fs2-kafka/blob/master/src/main/scala/fs2/kafka/internal/Synchronized.scala
As I said above, most things on top of the JVM can be implemented via an
`AtomicReference` due to its memory model and this is no exception.
But it’s not elegant, or simple ;-)
> (By ”beautiful” I mean approach itself of course, but not the
> Scala’s
> syntax. Scala is one of most ugliest girls after C++ I was forced to
> date
> with by my employer for money. Thankfully he didn’t force me to do
> the same
> things with her grandma Java).
That’s unnecessary and TBH a turnoff.
Cheers,
--
Alexandru Nedelcu
https://alexn.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20190102/28036ba9/attachment.html>
More information about the Haskell-Cafe
mailing list