[project @ 1996-07-25 20:43:49 by partain]
[ghc-hetmet.git] / ghc / docs / users_guide / glasgow_exts.lit
index f09235b..b10b282 100644 (file)
@@ -28,18 +28,12 @@ to the raw machine types and operations; included in this are
 ``primitive arrays'' (direct access to Big Wads of Bytes).
 Please see \Sectionref{glasgow-unboxed} and following.
 
-%\item[Synchronising variables---\tr{_IVar}s, \tr{_MVar}s:]
-%These are used when reads and writes need to be coordinated,
-%e.g., if the readers and writers are different concurrent threads.
-%Please see \Sectionref{ivars-mvars}.
-
 \item[Calling out to C:] Just what it sounds like.  We provide {\em
 lots} of rope that you can dangle around your neck.
 Please see \Sectionref{glasgow-ccalls}.
 
-\item[``Monadic I/O:''] This stuff will be coming to you For Real
-with Haskell~1.3, whenever that is.
-Please see \Sectionref{io-1-3} (the ``1.3 I/O'' section).
+\item[Low-level monadic I/O:] Monadic I/O is now standard with Haskell~1.3;
+you can still get access to the system at a lower level (the ``PrimIO'' level).
 
 \item[``HBC-ish'' extensions:] Extensions implemented because people said,
 ``HBC does Y.  Could you teach GHC to do the same?''  Please see
@@ -138,13 +132,13 @@ That is, GHC provides a safe way to pass Haskell pointers to C.
 
 Please see \Sectionref{glasgow-stablePtrs} for more details.
 
-\item[``Malloc'' pointers:]
-A ``malloc'' pointer is a safe way to pass a C~pointer to Haskell and
+\item[``Foreign objects'':]
+A ``foreign object'' is a safe way to pass a C~pointer to Haskell and
 have Haskell do the Right Thing when it no longer references the
 object.  So, for example, C could pass a large bitmap over to Haskell
 and say ``please free this memory when you're done with it.''
 
-Please see \Sectionref{glasgow-mallocPtrs} for more details.
+Please see \Sectionref{glasgow-foreignObjs} for more details.
 \end{description}
 
 See sections~1.4 and~1.6 of the ``state interface document'' for the
@@ -153,6 +147,35 @@ them.
 
 
 %************************************************************************
+%*                                                                     *
+\subsection[own-mainPrimIO]{Using your own @mainPrimIO@}
+\index{mainPrimIO, rolling your own}
+%*                                                                     *
+%************************************************************************
+
+Normally, the GHC runtime system begins things by called an internal
+function @mainPrimIO :: PrimIO ()@ which, in turn, fires up
+your @Main.main@.
+
+To subvert the above process, you need only provide a
+@mainPrimIO :: PrimIO ()@ of your own (in a module named \tr{GHCmain}).
+
+Here's a little example, stolen from Alastair Reid:
+\begin{verbatim}
+module GHCmain ( mainPrimIO ) where
+
+import PreludeGlaST
+
+mainPrimIO :: PrimIO ()
+mainPrimIO = do
+        sleep 5
+        _ccall_ printf "%d\n" (14::Int)
+
+sleep :: Int -> PrimIO ()
+sleep t = _ccall_ sleep t
+\end{verbatim}
+
+%************************************************************************
 %*                                                                      *
 \subsection[glasgow-ccalls]{Calling~C directly from Haskell}
 \index{C calls (Glasgow extension)}
@@ -166,25 +189,14 @@ them.
 %import PreludePrimIO
 %\end{verbatim}
 
-SINCE VERSION 0.22: ``Literal-literals'', e.g., \tr{``NULL''}, can now
-be any `boxed-primitive' type---they are not automatically taken to be
-\tr{_Addr}s.  This is cool, except you may sometimes have to put in
-a type signature to force the desired type.
-
-SINCE VERSION 0.19: \tr{ccall} and \tr{casm} have been renamed to
-\tr{_ccall_} and \tr{_casm_} and \tr{veryDangerousCcall} and
-\tr{veryDangerousCasm} have been removed.  It is no longer necessary
-(nor legal!) to unbox/rebox the arguments and results to @_ccall_@.
-GHC does the unboxing/reboxing for you.
-
 GOOD ADVICE: Because this stuff is not Entirely Stable as far as names
 and things go, you would be well-advised to keep your C-callery
 corraled in a few modules, rather than sprinkled all over your code.
 It will then be quite easy to update later on.
 
-WARNING AS OF 0.26: Yes, the \tr{_ccall_} stuff probably {\em will
-change}, to something better, of course!  We are only at the
-musing-about-it stage, however.
+WARNING AS OF 2.01: Yes, the \tr{_ccall_} stuff probably {\em will
+change}, to something better, of course!  We are still at the
+musing-about-it stage, however...
 
 %************************************************************************
 %*                                                                      *
@@ -196,16 +208,16 @@ The simplest way to use a simple C function
 \begin{verbatim}
 double fooC( FILE *in, char c, int i, double d, unsigned int u )
 \end{verbatim}
-is to provide a Haskell wrapper
+is to provide a Haskell wrapper:
 \begin{verbatim}
-fooH :: Char -> Int -> Double -> _Word -> PrimIO Double
+fooH :: Char -> Int -> Double -> Word -> PrimIO Double
 fooH c i d w = _ccall_ fooC ``stdin'' c i d w
 \end{verbatim}
 The function @fooH@ will unbox all of its arguments, call the C
 function \tr{fooC} and box the corresponding arguments.
 
 So, if you want to do C-calling, you have to confront the underlying
-Glasgow I/O system.  It's just your typical monad whatnot.
+I/O system (at the ``PrimIO'' level).
 
 %The code in \tr{ghc/lib/glaExts/*.lhs} is not too obtuse.
 %That code, plus \tr{lib/prelude/Builtin.hs}, give examples
@@ -218,12 +230,12 @@ may be just the ticket (NB: {\em no chance} of such code going through
 a native-code generator):
 \begin{verbatim}
 oldGetEnv name
-  = _casm_ ``%r = getenv((char *) %0);'' name `thenPrimIO` \ litstring@(A# str#) ->
-    returnPrimIO (
+  = _casm_ ``%r = getenv((char *) %0);'' name >>= \ litstring@(A# str#) ->
+    return (
         if (litstring == ``NULL'') then
-            Failure (SearchError ("GetEnv:"++name))
+            Left ("Fail:oldGetEnv:"++name)
         else
-            Str (unpackCString# str#)
+            Right (unpackCString# str#)
     )
 \end{verbatim}
 
@@ -246,18 +258,18 @@ directive to provide \tr{.h} files containing function headers.
 
 For example,
 \begin{verbatim}
-typedef unsigned long *StgMallocPtr;
+typedef unsigned long *StgForeignObj;
 typedef long StgInt;
 
-void          initialiseEFS PROTO( (StgInt size) );
-StgInt        terminateEFS ();
-StgMallocPtr  emptyEFS();
-StgMallocPtr  updateEFS PROTO( (StgMallocPtr a, StgInt i, StgInt x) );
-StgInt        lookupEFS PROTO( (StgMallocPtr a, StgInt i) );
+void          initialiseEFS (StgInt size);
+StgInt        terminateEFS (void);
+StgForeignObj emptyEFS(void);
+StgForeignObj updateEFS (StgForeignObj a, StgInt i, StgInt x);
+StgInt        lookupEFS (StgForeignObj a, StgInt i);
 \end{verbatim}
 
 You can find appropriate definitions for \tr{StgInt},
-\tr{StgMallocPtr}, etc using \tr{gcc} on your architecture by
+\tr{StgForeignObj}, etc using \tr{gcc} on your architecture by
 consulting \tr{ghc/includes/StgTypes.lh}.  The following table
 summarises the relationship between Haskell types and C types.
 
@@ -277,7 +289,7 @@ C type name      & Haskell Type \\ \hline
 \tr{StgByteArray}     & \tr{MutableByteArray#}\\   
                                     
 \tr{StgStablePtr}     & \tr{StablePtr#}\\          
-\tr{StgMallocPtr}     & \tr{MallocPtr#}
+\tr{StgForeignObj}    & \tr{MallocPtr#}
 \end{tabular}
 
 Note that this approach is only {\em essential\/} for returning
@@ -301,32 +313,31 @@ unevaluated arguments and require the C programmer to force their
 evaluation before using them.
 
 \item Boxed values are stored on the Haskell heap and may be moved
-within the heap if a garbage collection occurs --- that is, pointers
+within the heap if a garbage collection occurs---that is, pointers
 to boxed objects are not {\em stable\/}.
 \end{itemize}
 
 It is possible to subvert the unboxing process by creating a ``stable
-pointer'' to a value and passing the stable pointer instead.  (To use
-stable pointers, you must \tr{import PreludeGlaMisc}.) For example, to
+pointer'' to a value and passing the stable pointer instead.  For example, to
 pass/return an integer lazily to C functions \tr{storeC} and
 \tr{fetchC}, one might write:
 \begin{verbatim}
 storeH :: Int -> PrimIO ()
-storeH x = makeStablePtr x              `thenPrimIO` \ stable_x ->
+storeH x = makeStablePtr x              >>= \ stable_x ->
            _ccall_ storeC stable_x
 
 fetchH :: PrimIO Int
-fetchH x = _ccall_ fetchC               `thenPrimIO` \ stable_x ->
-           deRefStablePtr stable_x      `thenPrimIO` \ x ->
-           freeStablePtr stable_x       `seqPrimIO`
-           returnPrimIO x
+fetchH x = _ccall_ fetchC               >>= \ stable_x ->
+           deRefStablePtr stable_x      >>= \ x ->
+           freeStablePtr stable_x       >>
+           return x
 \end{verbatim}
 
 The garbage collector will refrain from throwing a stable pointer away
 until you explicitly call one of the following from C or Haskell.
 \begin{verbatim}
 void freeStablePointer( StgStablePtr stablePtrToToss )
-freeStablePtr :: _StablePtr a -> PrimIO ()
+freeStablePtr :: StablePtr a -> PrimIO ()
 \end{verbatim}
 
 As with the use of \tr{free} in C programs, GREAT CARE SHOULD BE
@@ -340,9 +351,9 @@ message from the runtime system); too late and you get space leaks.
 %call one of the following C functions (according to type of argument).
 %
 %\begin{verbatim}
-%void     performIO  ( StgStablePtr stableIndex /* _StablePtr s (PrimIO ()) */ );
-%StgInt   enterInt   ( StgStablePtr stableIndex /* _StablePtr s Int */ );
-%StgFloat enterFloat ( StgStablePtr stableIndex /* _StablePtr s Float */ );
+%void     performIO  ( StgStablePtr stableIndex /* StablePtr s (PrimIO ()) */ );
+%StgInt   enterInt   ( StgStablePtr stableIndex /* StablePtr s Int */ );
+%StgFloat enterFloat ( StgStablePtr stableIndex /* StablePtr s Float */ );
 %\end{verbatim}
 %
 %ToDo ADR: test these functions!
@@ -352,26 +363,25 @@ message from the runtime system); too late and you get space leaks.
 
 %************************************************************************
 %*                                                                      *
-\subsubsection[glasgow-mallocPtrs]{Pointing outside the Haskell heap}
-\index{malloc pointers (Glasgow extension)}
+\subsubsection[glasgow-foreignObjs]{Pointing outside the Haskell heap}
+\index{foreign objects (Glasgow extension)}
 %*                                                                      *
 %************************************************************************
 
 There are two types that \tr{ghc} programs can use to reference
-(heap-allocated) objects outside the Haskell world: \tr{_Addr} and
-\tr{_MallocPtr}.  (You must import \tr{PreludeGlaMisc} to use
-\tr{_MallocPtr}.)
+(heap-allocated) objects outside the Haskell world: \tr{Addr} and
+\tr{ForeignObj}.
 
-If you use \tr{_Addr}, it is up to you to the programmer to arrange
+If you use \tr{Addr}, it is up to you to the programmer to arrange
 allocation and deallocation of the objects.
 
-If you use \tr{_MallocPtr}, \tr{ghc}'s garbage collector will
+If you use \tr{ForeignObj}, \tr{ghc}'s garbage collector will
 call the user-supplied C function
 \begin{verbatim}
-void FreeMallocPtr( StgMallocPtr garbageMallocPtr )
+void freeForeignObj( StgForeignObj garbageMallocPtr )
 \end{verbatim}
 when the Haskell world can no longer access the object.  Since
-\tr{_MallocPtr}s only get released when a garbage collection occurs,
+\tr{ForeignObj}s only get released when a garbage collection occurs,
 we provide ways of triggering a garbage collection from within C and
 from within Haskell.
 \begin{verbatim}
@@ -403,14 +413,13 @@ atan2d :: Double -> Double -> Double
 atan2d y x = unsafePerformPrimIO (_ccall_ atan2d y x)
 
 sincosd :: Double -> (Double, Double)
-sincosd x = unsafePerformPrimIO (
-        newDoubleArray (0, 1)           `thenPrimIO` \ da ->
+sincosd x = unsafePerformPrimIO $
+        newDoubleArray (0, 1)           >>= \ da ->
         _casm_ ``sincosd( %0, &((double *)%1[0]), &((double *)%1[1]) );'' x da
-                                        `seqPrimIO`
-        readDoubleArray da 0            `thenPrimIO` \ s ->
-        readDoubleArray da 1            `thenPrimIO` \ c ->
-        returnPrimIO (s, c)
-        )
+                                        >>
+        readDoubleArray da 0            >>= \ s ->
+        readDoubleArray da 1            >>= \ c ->
+        return (s, c)
 \end{verbatim}
 
 \item Calling a set of functions which have side-effects but which can
@@ -426,34 +435,34 @@ lookup :: EFS a -> Int -> a
 
 empty = unsafePerformPrimIO (_ccall_ emptyEFS)
 
-update a i x = unsafePerformPrimIO (
-        makeStablePtr x         `thenPrimIO` \ stable_x ->
+update a i x = unsafePerformPrimIO $
+        makeStablePtr x         >>= \ stable_x ->
         _ccall_ updateEFS a i stable_x
-        )
 
-lookup a i = unsafePerformPrimIO (
-        _ccall_ lookupEFS a i   `thenPrimIO` \ stable_x ->
+lookup a i = unsafePerformPrimIO $
+        _ccall_ lookupEFS a i   >>= \ stable_x ->
         deRefStablePtr stable_x
-        )
 \end{verbatim}
 
-You will almost always want to use \tr{_MallocPtr}s with this.
+You will almost always want to use \tr{ForeignObj}s with this.
 
 \item Calling a side-effecting function even though the results will
 be unpredictable.  For example the \tr{trace} function is defined by:
 
 \begin{verbatim}
 trace :: String -> a -> a
-trace string expr = unsafePerformPrimIO (
-                  appendChan# ``stderr'' "Trace On:\n"          `seqPrimIO`
-                  appendChan# ``stderr'' string                 `seqPrimIO`
-                  appendChan# ``stderr'' "\nTrace Off.\n"       `seqPrimIO`
-                  returnPrimIO expr )
+trace string expr
+  = unsafePerformPrimIO (
+       ((_ccall_ PreTraceHook sTDERR{-msg-}):: PrimIO ())  >>
+       fputs sTDERR string                                 >>
+       ((_ccall_ PostTraceHook sTDERR{-msg-}):: PrimIO ()) >>
+       returnPrimIO expr )
+  where
+    sTDERR = (``stderr'' :: Addr)
 \end{verbatim}
 
 (This kind of use is not highly recommended --- it is only really
 useful in debugging code.)
-
 \end{itemize}
 
 %************************************************************************
@@ -501,7 +510,7 @@ the intermediate C (\tr{.hc} file).
 The compiler uses two non-standard type-classes when
 type-checking the arguments and results of \tr{_ccall_}: the arguments
 (respectively result) of \tr{_ccall_} must be instances of the class
-\tr{_CCallable} (respectively \tr{_CReturnable}.  (Neither class
+\tr{CCallable} (respectively \tr{CReturnable}).  (Neither class
 defines any methods --- their only function is to keep the
 type-checker happy.)
 
@@ -527,22 +536,22 @@ Type                &CCallable&CReturnable & Which is probably... \\ \hline
 %------            ----------  ------------    -------------
 \tr{Char}              & Yes  & Yes   & \tr{unsigned char} \\
 \tr{Int}               & Yes  & Yes   & \tr{long int} \\
-\tr{_Word}             & Yes  & Yes   & \tr{unsigned long int} \\
-\tr{_Addr}             & Yes  & Yes   & \tr{char *} \\
+\tr{Word}              & Yes  & Yes   & \tr{unsigned long int} \\
+\tr{Addr}              & Yes  & Yes   & \tr{char *} \\
 \tr{Float}             & Yes  & Yes   & \tr{float} \\
 \tr{Double}            & Yes  & Yes   & \tr{double} \\
 \tr{()}                & No   & Yes   & \tr{void} \\
 \tr{[Char]}            & Yes  & No    & \tr{char *} (null-terminated) \\
                                       
 \tr{Array}             & Yes  & No    & \tr{unsigned long *}\\
-\tr{_ByteArray}        & Yes  & No    & \tr{unsigned long *}\\
-\tr{_MutableArray}     & Yes  & No    & \tr{unsigned long *}\\
-\tr{_MutableByteArray} & Yes  & No    & \tr{unsigned long *}\\
-                                      
-\tr{_State}            & Yes  & Yes   & nothing!\\
-                                      
-\tr{_StablePtr}        & Yes  & Yes   & \tr{unsigned long *}\\
-\tr{_MallocPtr}        & Yes  & Yes   & see later\\
+\tr{ByteArray}         & Yes  & No    & \tr{unsigned long *}\\
+\tr{MutableArray}      & Yes  & No    & \tr{unsigned long *}\\
+\tr{MutableByteArray}  & Yes  & No    & \tr{unsigned long *}\\
+                                      
+\tr{State}             & Yes  & Yes   & nothing!\\
+                                      
+\tr{StablePtr}         & Yes  & Yes   & \tr{unsigned long *}\\
+\tr{ForeignObjs}       & Yes  & Yes   & see later\\
 \end{tabular}
 
 The brave and careful programmer can add their own instances of these
@@ -550,7 +559,7 @@ classes for the following types:
 \begin{itemize}
 \item
 A {\em boxed-primitive} type may be made an instance of both
-\tr{_CCallable} and \tr{_CReturnable}.  
+\tr{CCallable} and \tr{CReturnable}.  
 
 A boxed primitive type is any data type with a
 single unary constructor with a single primitive argument.  For
@@ -560,27 +569,27 @@ example, the following are all boxed primitive types:
 Int
 Double
 data XDisplay = XDisplay Addr#
-data EFS a = EFS# MallocPtr#
+data EFS a = EFS# ForeignObj#
 \end{verbatim}
 
 \begin{verbatim}
-instance _CCallable   (EFS a)
-instance _CReturnable (EFS a)
+instance CCallable   (EFS a)
+instance CReturnable (EFS a)
 \end{verbatim}
 
 \item Any datatype with a single nullary constructor may be made an
-instance of \tr{_CReturnable}.  For example:
+instance of \tr{CReturnable}.  For example:
 
 \begin{verbatim}
 data MyVoid = MyVoid
-instance _CReturnable MyVoid
+instance CReturnable MyVoid
 \end{verbatim}
 
-\item As at version 0.26, \tr{String} (i.e., \tr{[Char]}) is still
-not a \tr{_CReturnable} type.
+\item As at version 2.01, \tr{String} (i.e., \tr{[Char]}) is still
+not a \tr{CReturnable} type.
 
-Also, the now-builtin type \tr{_PackedString} is neither
-\tr{_CCallable} nor \tr{_CReturnable}.  (But there are functions in
+Also, the now-builtin type \tr{PackedString} is neither
+\tr{CCallable} nor \tr{CReturnable}.  (But there are functions in
 the PackedString interface to let you get at the necessary bits...)
 \end{itemize}
 
@@ -606,6 +615,47 @@ hairy with a capital H!
 %************************************************************************
 
 %************************************************************************
+%*                                                                     *
+\subsubsection[glasgow-prim-interface]{Access to the \tr{PrimIO} monad}
+\index{PrimIO monad (Glasgow extension)}
+\index{I/O, primitive (Glasgow extension)}
+%*                                                                     *
+%************************************************************************
+
+The \tr{IO} monad (new in Haskell~1.3) catches errors and passes them
+along.  It is built on top of the \tr{ST} state-transformer monad.
+
+A related (and inter-operable-with) monad is the \tr{PrimIO} monad
+(NB: the level at which @_ccall_@s work...), where you handle errors
+yourself.
+
+Should you wish to use the \tr{PrimIO} monad directly, you can import
+\tr{PreludeGlaST}.  It makes available the usual monadic stuff (@>>=@,
+@>>@, @return@, etc.), as well as these functions:
+\begin{verbatim}
+-- for backward compatibility:
+returnPrimIO    :: a -> PrimIO a
+thenPrimIO      :: PrimIO a -> (a -> PrimIO b) -> PrimIO b
+seqPrimIO      :: PrimIO a -> PrimIO b -> PrimIO b
+
+-- still useful:
+fixPrimIO      :: (a -> PrimIO a) -> PrimIO a
+forkPrimIO     :: PrimIO a -> PrimIO a
+listPrimIO     :: [PrimIO a] -> PrimIO [a]
+mapAndUnzipPrimIO :: (a -> PrimIO (b,c)) -> [a] -> PrimIO ([b],[c])
+mapPrimIO      :: (a -> PrimIO b) -> [a] -> PrimIO [b]
+
+unsafePerformPrimIO    :: PrimIO a -> a
+unsafeInterleavePrimIO :: PrimIO a -> PrimIO a
+  -- and they are not called "unsafe" for nothing!
+
+-- to convert back and forth between IO and PrimIO
+ioToPrimIO :: IO     a -> PrimIO a
+primIOToIO :: PrimIO a -> IO     a
+\end{verbatim}
+
+
+%************************************************************************
 %*                                                                      *
 \subsection[glasgow-hbc-exts]{``HBC-ish'' extensions implemented by GHC}
 \index{HBC-like Glasgow extensions}
@@ -638,39 +688,39 @@ As Lennart says, ``This is a dubious feature and should not be used
 carelessly.''
 
 See also: \tr{SPECIALIZE instance} pragmas, in \Sectionref{faster}.
-
+% 
 %-------------------------------------------------------------------
-\item[Signal-handling I/O request:]
-\index{signal handling (extension)}
-\index{SigAction I/O request}
-The Haskell-1.2 I/O request \tr{SigAction n act} installs a signal handler for signal
-\tr{n :: Int}.  The number is the usual UNIX signal number.  The action
-is of this type:
-\begin{verbatim}
-data SigAct
-  = SAIgnore
-  | SADefault
-  | SACatch Dialogue
-\end{verbatim}
-
-The corresponding continuation-style I/O function is the unsurprising:
-\begin{verbatim}
-sigAction :: Int -> SigAct -> FailCont -> SuccCont -> Dialogue
-\end{verbatim}
-
-When a signal handler is installed with \tr{SACatch}, receipt of the
-signal causes the current top-level computation to be abandoned, and
-the specified dialogue to be executed instead.  The abandoned
-computation may leave some partially evaluated expressions in a
-non-resumable state.  If you believe that your top-level computation
-and your signal handling dialogue may share subexpressions, you should
-execute your program with the \tr{-N} RTS option, to prevent
-black-holing.
-
-The \tr{-N} option is not available with concurrent/parallel programs,
-so great care should be taken to avoid shared subexpressions between
-the top-level computation and any signal handlers when using threads.
-
+% \item[Signal-handling I/O request:]
+% \index{signal handling (extension)}
+% \index{SigAction I/O request}
+% The Haskell-1.2 I/O request \tr{SigAction n act} installs a signal handler for signal
+% \tr{n :: Int}.  The number is the usual UNIX signal number.  The action
+% is of this type:
+% \begin{verbatim}
+% data SigAct
+%   = SAIgnore
+%   | SADefault
+%   | SACatch Dialogue
+% \end{verbatim}
+% 
+% The corresponding continuation-style I/O function is the unsurprising:
+% \begin{verbatim}
+% sigAction :: Int -> SigAct -> FailCont -> SuccCont -> Dialogue
+% \end{verbatim}
+% 
+% When a signal handler is installed with \tr{SACatch}, receipt of the
+% signal causes the current top-level computation to be abandoned, and
+% the specified dialogue to be executed instead.  The abandoned
+% computation may leave some partially evaluated expressions in a
+% non-resumable state.  If you believe that your top-level computation
+% and your signal handling dialogue may share subexpressions, you should
+% execute your program with the \tr{-N} RTS option, to prevent
+% black-holing.
+% 
+% The \tr{-N} option is not available with concurrent/parallel programs,
+% so great care should be taken to avoid shared subexpressions between
+% the top-level computation and any signal handlers when using threads.
+% 
 %-------------------------------------------------------------------
 %\item[Simple time-out mechanism, in ``monadic I/O'':]
 %\index{time-outs (extension)}