Question about 'Tackling the Awkward Squad'

Don Wakefield [email protected]
Thu, 25 Jan 2001 13:26:24 -0800 (PST)


I posed the following question on comp.lang.functional, and a helpful
reader emailed me to suggest that I should ask it here. Briefly, I
dabble in Haskell to exercise my mind in a way that my C++ heritage
doesn't, so if I'm asking silly questions or missing seemingly obvious
notions, I beg forgiveness.

The Question. I was reading Simon Peyton Jones' fascinating paper:

   Tackling the awkward squad: monadic input/output, concurrency,
   exceptions, and foreign-language calls in Haskell
       (the January 9th 2001 draft)

when I ran across what appears to be an error. On page 34, while
discussing Channels, he proposes a function called dupChan:

   dupChan (read, write)
     = do { new_read <- newEmptyMVar ;
            hole <- takeMVar write ;
            putMVar write hole ;
            putMVar new_read hole ;
            return (new_read, write) }

The rationale is given thusly:

 "For example, consider a multi-cast channel, in which there are
  multiple readers, each of which should see all the values written to
  the channel ... The idea is that the channel returned by dupChan can
  be read independently of the original, and sees all (and only) the
  data written to the channel after the dupChan call."

But earlier he has defined getChan thusly:

   getchan (read, write)
     = do { head_var <- takeMVar read ;
            MkItem val new_head <- takeMVar head_var ;
            putMVar read new_head ;
            return val }

Since the line which performs the 'takeMVar head_var' leaves the MVar
referenced by head_var empty, the dupChan 'new_read' Stream should block
when the reader tries to *also* use getChan on this Stream, isn't this
so? Am I missing some subtlety? I drew all the pictures :^)~

-- 
Don Wakefield                              Mentor Graphics Corporation
(503) 685-1262                             8005 S.W. Boeckman Road    
[email protected]                  Wilsonville, OR 97070-7777