Makes sense to me. Giving a formal semantics to the IO version of readIVar
most likely is simpler (taking IO and concurrent IO as given) than the
non-IO version. I didn't understand that before. Thanks for helping me get
it. - Conal
On Dec 9, 2007 12:09 PM, Lennart Augustsson
I would claim that it's fine to use the type readIVar :: IVar a -> a if you're willing to give the "right" semantics to newIVar :: IO (IVar a) The semantics is that sometimes when you create an IVar you'll get one that always returns _|_ when read, sometimes you'll get a proper one. Now if you happen to read an IVar and it deadlocks your program, well, sorry, you were unlucky and got a bad IVar that time.
So it's possible to explain away the deadlock as something non-deterministic in the IO monad. Doing so comes at a terrible price though, because you can no longer reason about your program.
-- Lennart
On Dec 9, 2007 7:48 PM, Conal Elliott
wrote: Thanks, Luke. I'd been unconsciously assuming that the IVar would get written to (if ever) by a thread other than the one doing the reading. (Even then, there could be a deadlock.)
- Conal
On Dec 9, 2007 9:37 AM, Luke Palmer
wrote: (moving to haskell-cafe)
readIVar' :: IVar a -> a readIVar' = unsafePerformIO . readIVar
so, we do not need readIVar'. it could be a nice addition to the libraries, maybe as "unsafeReadIVar" or "unsafeReadMVar".
The same argument applies any to pure function, doesn't it? For instance, a non-IO version of succ is unnecessary. My question is why make readIVar a blocking IO action rather than a blocking pure value, considering
On Dec 9, 2007 5:09 PM, Conal Elliott
wrote: that it always returns the same value?
But I don't think it does. If we're single-threaded, before we writeIVar on it, it "returns" bottom, but afterward it returns whatever what was written. It's a little fuzzy, but that doesn't seem referentially transparent.
Luke
- Conal
many many answers, many guesses... let's compare these semantics:
readIVar :: IVar a -> IO a readIVar' :: IVar a -> a readIVar' = unsafePerformIO . readIVar
so, we do not need readIVar'. it could be a nice addition to the
but the other way:
readIVar v = return $ readIVar' v
does not work. with this definition, readIVar itself does not block anymore. it's like hGetContents. and...
readIVar v = return $! readIVar' v
evaluates too much: it wont work if the stored value evaluates to 1) undefined or 2) _|_. it may even cause a 3) deadlock:
do writeIVar v (readIVar' w) x<-readIVar v writeIVar w "cat" return x :: IO String
readIVar should only return the 'reference'(internal pointer) to
On Dec 8, 2007 11:12 AM, Marc A. Ziegert
wrote: libraries, maybe as "unsafeReadIVar" or "unsafeReadMVar". the read object without evaluating it. in other words: readIVar should wait to receive but not look into the received "box"; it may contain a nasty undead werecat of some type. (Schrödinger's Law.)
- marc
Am Freitag, 7. Dezember 2007 schrieb Paul Johnson:
Conal Elliott wrote: > Oh. Simple enough. Thanks. > > Another question: why the IO in readIVar :: IVar a -> IO a, instead > of just readIVar :: IVar a -> a? After all, won't readIVar iv yield > the same result (eventually) every time it's called? Because it won't necessarily yield the same result the next time you run it. This is the same reason the stuff in System.Environmentreturns values in IO.
Paul.
_______________________________________________ Haskell mailing list Haskell@haskell.org
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe