[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.
 
 ``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[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
 
 \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.
 
 
 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.''
 
 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
 \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)}
 %*                                                                      *
 \subsection[glasgow-ccalls]{Calling~C directly from Haskell}
 \index{C calls (Glasgow extension)}
@@ -166,25 +189,14 @@ them.
 %import PreludePrimIO
 %\end{verbatim}
 
 %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.
 
 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}
 \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}
 \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
 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
 
 %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
 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
         if (litstring == ``NULL'') then
-            Failure (SearchError ("GetEnv:"++name))
+            Left ("Fail:oldGetEnv:"++name)
         else
         else
-            Str (unpackCString# str#)
+            Right (unpackCString# str#)
     )
 \end{verbatim}
 
     )
 \end{verbatim}
 
@@ -246,18 +258,18 @@ directive to provide \tr{.h} files containing function headers.
 
 For example,
 \begin{verbatim}
 
 For example,
 \begin{verbatim}
-typedef unsigned long *StgMallocPtr;
+typedef unsigned long *StgForeignObj;
 typedef long StgInt;
 
 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},
 \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.
 
 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{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
 \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
 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
 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 ()
 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
            _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 )
 \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
 \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}
 %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!
 %\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
 %*                                                                      *
 %************************************************************************
 
 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.
 
 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}
 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
 \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}
 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)
 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
         _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
 \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)
 
 
 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
         _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
         deRefStablePtr stable_x
-        )
 \end{verbatim}
 
 \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
 
 \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{verbatim}
 
 (This kind of use is not highly recommended --- it is only really
 useful in debugging code.)
-
 \end{itemize}
 
 %************************************************************************
 \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
 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.)
 
 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{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{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
 \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
 \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
 
 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#
 Int
 Double
 data XDisplay = XDisplay Addr#
-data EFS a = EFS# MallocPtr#
+data EFS a = EFS# ForeignObj#
 \end{verbatim}
 
 \begin{verbatim}
 \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
 \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
 
 \begin{verbatim}
 data MyVoid = MyVoid
-instance _CReturnable MyVoid
+instance CReturnable MyVoid
 \end{verbatim}
 
 \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}
 
 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}
 %*                                                                      *
 \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}.
 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)}
 %-------------------------------------------------------------------
 %\item[Simple time-out mechanism, in ``monadic I/O'':]
 %\index{time-outs (extension)}