[project @ 2004-06-12 12:13:12 by panne]
[ghc-base.git] / GHC / IOBase.lhs
index 312fda9..6fa596a 100644 (file)
@@ -112,7 +112,10 @@ returnIO x = IO (\ s -> (# s, x #))
 -- ---------------------------------------------------------------------------
 -- Coercions between IO and ST
 
---stToIO        :: (forall s. ST s a) -> IO a
+-- | A monad transformer embedding strict state transformers in the 'IO'
+-- monad.  The 'RealWorld' parameter indicates that the internal state
+-- used by the 'ST' computation is a special one supplied by the 'IO'
+-- monad, and thus distinct from those used by invocations of 'runST'.
 stToIO       :: ST RealWorld a -> IO a
 stToIO (ST m) = IO m
 
@@ -164,7 +167,7 @@ It is less well known that
 >     
 >     main = do
 >            writeIORef test [42]
->            bang \<- readIORef test
+>            bang <- readIORef test
 >            print (bang :: [Char])
 
 This program will core dump.  This problem with polymorphic references
@@ -178,13 +181,19 @@ help of 'unsafePerformIO'.  So be careful!
 unsafePerformIO        :: IO a -> a
 unsafePerformIO (IO m) = case m realWorld# of (# _, r #)   -> r
 
+-- Why do we NOINLINE unsafePerformIO?  See the comment with
+-- GHC.ST.runST.  Essentially the issue is that the IO computation
+-- inside unsafePerformIO must be atomic: it must either all run, or
+-- not at all.  If we let the compiler see the application of the IO
+-- to realWorld#, it might float out part of the IO.
+
 {-|
 'unsafeInterleaveIO' allows 'IO' computation to be deferred lazily.
 When passed a value of type @IO a@, the 'IO' will only be performed
 when the value of the @a@ is demanded.  This is used to implement lazy
 file reading, see 'System.IO.hGetContents'.
 -}
-{-# NOINLINE unsafeInterleaveIO #-}
+{-# INLINE unsafeInterleaveIO #-}
 unsafeInterleaveIO :: IO a -> IO a
 unsafeInterleaveIO (IO m)
   = IO ( \ s -> let
@@ -192,6 +201,10 @@ unsafeInterleaveIO (IO m)
                in
                (# s, r #))
 
+-- We believe that INLINE on unsafeInterleaveIO is safe, because the
+-- state from this IO thread is passed explicitly to the interleaved
+-- IO, so it cannot be floated out and shared.
+
 -- ---------------------------------------------------------------------------
 -- Handle type
 
@@ -396,7 +409,7 @@ type FilePath = String
 -- but not less frequently, than specified above.
 -- The output buffer is emptied as soon as it has been written out.
 --
--- Similarly, input occurs according to the buffer mode for handle {\em hdl}.
+-- Similarly, input occurs according to the buffer mode for the handle:
 --
 --  * /line-buffering/: when the buffer for the handle is not empty,
 --    the next item is obtained from the buffer; otherwise, when the
@@ -408,8 +421,8 @@ type FilePath = String
 --    the next block of data is read into the buffer.
 --
 --  * /no-buffering/: the next input item is read and returned.
---    The 'hLookAhead' operation implies that even a no-buffered handle
---    may require a one-character buffer.
+--    The 'System.IO.hLookAhead' operation implies that even a no-buffered
+--    handle may require a one-character buffer.
 --
 -- The default buffering mode when a handle is opened is
 -- implementation-dependent and may depend on the file system object
@@ -518,7 +531,8 @@ showHandle file = showString "{handle: " . showString file . showString "}"
 -- |The type of exceptions.  Every kind of system-generated exception
 -- has a constructor in the 'Exception' type, and values of other
 -- types may be injected into 'Exception' by coercing them to
--- 'Dynamic' (see the section on Dynamic Exceptions: "Control.Exception\#DynamicExceptions").
+-- 'Data.Dynamic.Dynamic' (see the section on Dynamic Exceptions:
+-- "Control.Exception\#DynamicExceptions").
 data Exception
   = ArithException     ArithException
        -- ^Exceptions raised by arithmetic
@@ -537,8 +551,8 @@ data Exception
        -- ^Asynchronous exceptions (see section on Asynchronous Exceptions: "Control.Exception\#AsynchronousExceptions").
   | BlockedOnDeadMVar
        -- ^The current thread was executing a call to
-       -- 'takeMVar' that could never return, because there are no other
-       -- references to this 'MVar'.
+       -- 'Control.Concurrent.MVar.takeMVar' that could never return,
+       -- because there are no other references to this 'MVar'.
   | Deadlock
        -- ^There are no runnable threads, so the program is
        -- deadlocked.  The 'Deadlock' exception is