What is purpose of CVar?

Hi, all, I’m reading Concurrent Haskell paper and I don’t get what is CVar. It looks like MVar but with additional acknowledgment. I don’t see difference between MVar and CVar.

I’ve also found this repo where guy plays around with the primitives, but when I rewrote CVar example, I, again, didn’t see difference

Could someone help me with that?

The code just for reference

newtype CVar a
  = CVar
      ( MVar a, -- Producer writes, Consumer reads
        MVar () -- Consumer writes, Producer reads

newCVar :: IO (CVar a)
newCVar = do
  w <- newEmptyMVar
  r <- newEmptyMVar
  putMVar r ()
  return $ CVar (w, r)

putCVar :: CVar a -> a -> IO ()
putCVar (CVar (w, r)) v =
  print "consumed ackVar"
    >> takeMVar r
    >> print "publishing dataVar"
    >> putMVar w v

getCVar :: CVar a -> IO a
getCVar (CVar (w, r)) =
  print "consumed dataVar"
    >> takeMVar w
    >>= \v ->
      print "publishing ackVar"
        >> putMVar r ()
        >> return v

I think what that paper calls CVar is now called MVar. Perhaps that’s the source of your confusion?

In particular, the paper says that what they call an MVar is allowed to put a value even if the previous value was not taken away by the consumer. They introduce CVar to ensure that the producer waits for the consumer to first take the value that was produced. That is now how MVar works.

1 Like

yeah, I didn’t know it, thank you a lot for fast response, I greatly appreciate it

1 Like

what happens when you write to a MVar when there is a value? with the current version you block waiting until the MVar is emptied but if am not mistaken this previously raised an exception so to model a channel exception free you needed 2 MVars to make sure you never wrote while there was a value.

1 Like