[project @ 2000-01-05 11:14:06 by rrt]
authorrrt <unknown>
Wed, 5 Jan 2000 11:14:08 +0000 (11:14 +0000)
committerrrt <unknown>
Wed, 5 Jan 2000 11:14:08 +0000 (11:14 +0000)
VSGML files changed back to plain SGML during change from LinuxDoc to DocBook.

23 files changed:
ghc/docs/users_guide/4-00-notes.sgml [new file with mode: 0644]
ghc/docs/users_guide/4-01-notes.sgml [new file with mode: 0644]
ghc/docs/users_guide/4-02-notes.sgml [new file with mode: 0644]
ghc/docs/users_guide/4-03-notes.sgml [new file with mode: 0644]
ghc/docs/users_guide/4-04-notes.sgml [new file with mode: 0644]
ghc/docs/users_guide/debugging.sgml [new file with mode: 0644]
ghc/docs/users_guide/glasgow_exts.sgml [new file with mode: 0644]
ghc/docs/users_guide/gone_wrong.sgml [new file with mode: 0644]
ghc/docs/users_guide/installing.sgml [new file with mode: 0644]
ghc/docs/users_guide/intro.sgml [new file with mode: 0644]
ghc/docs/users_guide/lang.sgml [new file with mode: 0644]
ghc/docs/users_guide/libmisc.sgml [new file with mode: 0644]
ghc/docs/users_guide/libraries.sgml [new file with mode: 0644]
ghc/docs/users_guide/license.sgml [new file with mode: 0644]
ghc/docs/users_guide/parallel.sgml [new file with mode: 0644]
ghc/docs/users_guide/posix.sgml [new file with mode: 0644]
ghc/docs/users_guide/profiling.sgml [new file with mode: 0644]
ghc/docs/users_guide/runtime_control.sgml [new file with mode: 0644]
ghc/docs/users_guide/sooner.sgml [new file with mode: 0644]
ghc/docs/users_guide/users_guide.sgml [new file with mode: 0644]
ghc/docs/users_guide/using.sgml [new file with mode: 0644]
ghc/docs/users_guide/utils.sgml [new file with mode: 0644]
ghc/docs/users_guide/vs_haskell.sgml [new file with mode: 0644]

diff --git a/ghc/docs/users_guide/4-00-notes.sgml b/ghc/docs/users_guide/4-00-notes.sgml
new file mode 100644 (file)
index 0000000..4fddc0d
--- /dev/null
@@ -0,0 +1,168 @@
+<sect1>Release notes for version~4.00---10/98
+<label id="release-4-00">
+<p>
+
+<sect2>Language matters
+<p>
+
+<itemize>
+
+<item> Universal and existential quantification: see Section <ref
+name="Explicit universal quantification"
+id="universal-quantification"> and Section <ref name="Existentially
+quantified data constructors" id="existential-quantification">
+respectively.
+
+Universal quantification was in in GHC 2.10 and later, but the
+syntax has changed: it's now <tt>forall a. ...</tt> instead of <tt>All a =&gt; ...</tt>.
+
+<item> Multi-paramter type classes.  We have relaxed some of the rules
+  since GHC 3.00.  In particular
+
+<descrip>
+  <tag><tt>-fallow-overlapping-instances</tt></tag>
+         allows overlapping instances
+  <tag><tt>-fallow-undecidable-instances</tt></tag>
+         allows you to write instance contexts that constrain non-type-variables
+</descrip>
+
+Full details in Section <ref name="Multi-parameter type classes"
+id="multi-param-type-classes">.
+</itemize>
+
+<sect2>New Libraries
+<p>
+
+Documentation in <url name="GHC/Hugs Extension Libraries"
+url="libs.html">.
+
+<descrip>
+
+<tag><tt>Dynamic</tt></tag>
+
+Dynamic types.  
+
+<tag><tt>Exceptions</tt></tag>
+
+The library <tt>Exception</tt> in <tt>-syslib exts</tt> provide an interface for
+exception handling.  Calls to <tt>error</tt>, pattern matching failures and a
+bunch of other exception can be caught.
+
+</descrip>
+
+<sect2>Compiler internals
+<p>
+
+The intermediate language used by GHC has had a radical overhaul.
+The new Core language (coreSyn/CoreSyn.lhs) is much smaller and
+more uniform.  The main transformation engine (the "simplifier")
+has been totally rewritten.  The compiler is several thousand lines
+shorter as a result.  It's also very much easier to understand 
+and modify.  (It's true.  Honest!)
+
+
+<sect2>Run time system
+<p>
+
+There is a completely new runtime system, aimed at integration with
+Hugs.  Tons of cruft removed.  Some changes to code generation; things
+typically run a bit faster as a result.
+
+An overview of the new RTS is available: <url name="The New GHC/Hugs
+Runtime System" url="http://www.dcs.gla.ac.uk/~simonm/rts.ps">.
+
+<sect2>Storage Manager/Garbage Collector
+<p>
+
+The new storage manager features a dynamically resizing heap, so you
+won't need those pesky <tt>-H</tt> options anymore.  In fact, the <tt>-H</tt> option
+is now ignored for compatibility with older versions.
+
+Stacks are now also expandable, and the <tt>-K</tt> option now specifies a
+<em/maximum/ heap size.  The default is (a perhaps conservative) <tt>1M</tt>.
+
+The garbage collector now collects CAFs, so there's no more space
+leaks associated with these.  If you think you have a CAF-related
+space leak, we'd like to hear about it.
+
+The storage manager current only has a two-space garbage collector,
+which will be slower than 3.02's generational collector when the
+amount of live data is large.  A new generational collector is high on
+our priority list.
+
+For the other new tweakables, see Section <ref name="RTS options to
+control the garbage-collector" id="rts-options-gc">.
+
+<sect2>Profiling
+<p>
+
+There is a new profiler based on <em/Cost Centre Stacks/.  This is an
+extension of the previous cost centre scheme, whereby the profilier
+stores information about the call-graph of the program and attributes
+costs to nodes of this graph.
+
+For a quick demo, try compiling a program with <tt>-prof -auto-all</tt>, then
+run it with <tt>+RTS -p</tt> and see what comes out (in the <tt>&lt;prog&gt;.prof</tt>
+file).
+
+The feature is still experimental, and the call graph may not be
+exactly what you were expecting.  Also, we only have time/allocation
+profiling at the moment; heap profiling will follow shortly.
+
+<sect2>Miscellaneous
+<p>
+
+<itemize>
+
+<item> Concurrent Haskell is now the default.  No need to
+compile/download special libraries.  The context switch interval isn't
+tweakable any more; threads just yield after allocating a fixed amount
+of heap (currently 4k).  If you want a quicker context switch, that
+won't be possible: this decision was made for efficiency reasons (it
+reduces the penalty for runnning threaded code to almost zero).  We
+might allow the context switch interval to be increased in the future;
+but also context switches are pretty fast (faster than before).
+
+<item> <tt>forkIO</tt> now returns a <tt>ThreadId</tt>, and there's a new operation
+<tt>killThread</tt> which will terminate an existing thread.  See Section
+<ref name="The Concurrent interface" id="concurrent-interface"> for
+more details.
+
+<item> You need <tt>-syslib concurrent</tt> to get the <tt>Concurrent</tt> library.
+
+<item> The rewritten IO library from 3.03 has been ported to 4.00.
+
+<item> New constructs: <tt>foriegn import</tt> and <tt>foreign export</tt> for
+H/Direct.
+
+<item> Supported architectures: all the development has been done on
+x86(mainly FreeBSD/Linux) so this is the most stable environment.
+Sparc (Solaris) and x86/Win32 (cygwin32) have also been mildly tested, and
+an Alpha port is in the works.  Everything else will need a little
+porting effort; we don't have machines here, so any help would be
+greatly appreciated.
+
+<item> Code is faster and smaller, but programs might run slower due
+to the garbage collector (see "Storage Manager" above).  Increasing
+the minimum allocation area with the <tt>-A</tt> RTS option can claw back
+some of this speed.
+
+<item> We now use GMP 2.02, and attempt to use an already-installed
+copy if available.  If you have GMP on your system but the configure
+script doesn't detect it, we'd like to know.
+
+<item> <tt>seq</tt> works better than in 3.xx - you can now <tt>seq</tt> functions
+without crashing the program.
+
+<item> The <tt>Eval</tt> class has been removed (i.e. every type is assumed
+to be in class <tt>Eval</tt>).  This change has been made in anticipation of
+Haskell 98.
+
+<item> The native code generator has had very little testing (it's not used
+on x86 yet), so Sparcs may have some trouble with it.  Try -fvia-C if
+strange errors occur.
+
+<item> The compiler is slightly faster, but sometimes needs more heap.
+If you have an example where this is the case, please let us know.
+
+</itemize>
diff --git a/ghc/docs/users_guide/4-01-notes.sgml b/ghc/docs/users_guide/4-01-notes.sgml
new file mode 100644 (file)
index 0000000..d0aaa7c
--- /dev/null
@@ -0,0 +1,31 @@
+<sect1>Release notes for version~4.01---11/98
+<label id="release-4-01">
+<p>
+
+<itemize>
+
+<item> <tt/relocate_TSO/ bug fixed.
+
+<item> Weak pointers implemented, and new <tt/Weak/ library provided
+(see <htmlurl name="GHC/Hugs Extension Libraries" url="libs.html">).
+The <tt/ForeignObj/ interface no longer supports finalisation - use
+the <tt/Weak/ interface for that.
+
+<item> Foreign funcion interface is now complete and working.
+
+<item> New interface file format for compatibility with Hugs.  No
+user-visible changes except that you'll have to update any .hi-boot
+files you have lying around - check out some GHC-generated .hi files
+for examples.
+
+<item> Space leak in the compiler is partially fixed -
+<tt/-dcore-lint/ is still recommended for decent space behaviour.
+
+<item> New API to the RTS (not interesting unless you're an RTS client
+writer).
+
+<item> <tt/thawIOArray/ added to <tt/IOExts/.
+
+<item> Many many small bugs fixed.
+
+</itemize>
diff --git a/ghc/docs/users_guide/4-02-notes.sgml b/ghc/docs/users_guide/4-02-notes.sgml
new file mode 100644 (file)
index 0000000..0a4eebf
--- /dev/null
@@ -0,0 +1,59 @@
+<sect1>Release notes for version~4.02---12/98
+<label id="release-4-02">
+<p>
+
+<itemize>
+
+<item> Full Haskell 98 language support.
+
+<item> Scoped type variables implemented (see Section <ref
+name="Scoped Type Variables" id="scoped-type-variables">).
+
+<item> Several bugs in _ccall_GC and foreign export fixed.
+
+<item> Warnings for unused variables should work now (they didn't before).
+
+<item> Simplifier improvements:
+   <itemize>
+        <item> Much better treatment of strict arguments.
+        <item> Function arguments of unlifted type are treated as strict.
+        <item> Better treatment of bottoming Ids.
+        <item> No need for worker/wrapper split for fns that are merely strict.
+        <item> Fewer iterations needed, I hope.
+   </itemize>
+
+<item> Strictness of primitive operations is now explicit and used by
+the simplifier.
+
+<item> Less gratuitous renaming in interface files and abs C.
+
+<item> <tt/OccName/ is a separate module, and is an abstract data type.
+<item> A new generational garbage collector: the number of generations
+is variable, using the -G RTS option (see <ref id="rts-options-gc"
+name="RTS options to control the garbage-collector">).  This collector
+is faster and more space-efficient than the two-space collector in 4.01.
+
+<item> Error messages and warnings are now printed out in the order they
+occur in the source code.
+
+<item> <tt/isEmptyMVar/ operation added to the <tt/Concurrent/ library.
+
+<item> Two new functions exported from <tt/ST/ (and <tt/LazyST/):
+<tt/unsafeIOToST/ and <tt/stToIO/.
+
+<item> The <tt/+RTS -H&lt;size&gt;/ option is reinstated.  Now it
+means "use about this much memory" (see Section <ref
+id="rts-options-gc" name="RTS options to control the garbage
+collector">).  This option was added mainly so that 4.02 GC times look
+good compared to 3.02 :-).
+
+<item> <tt/finalise/ and <tt/mkWeakNoFinaliser/ operations added to
+<tt/Weak/ library.
+
+<item> Ticky-ticky profiling works again (cost-centre profiling is
+still broken).
+
+<item> Better <tt/egcs-1.1.1/ support.
+
+</itemize>
diff --git a/ghc/docs/users_guide/4-03-notes.sgml b/ghc/docs/users_guide/4-03-notes.sgml
new file mode 100644 (file)
index 0000000..a99df0c
--- /dev/null
@@ -0,0 +1,26 @@
+<sect1>Release notes for version~4.03---3/99
+<label id="release-4-03">
+<p>
+
+<itemize>
+<item> <tt/Weak/ library changes:
+        <itemize>
+        <item> Finalise is now spelt finalize in all function names.
+        <item> <tt/finalize/ now runs the finalizer immediately, and
+               waits for it to complete before returning.
+        <item> <tt/mkWeak/ now takes a <tt/Maybe (IO ())/ for the finalizer,
+               and <tt/mkWeakNoFinalizer/ is removed.
+        </itemize>
+
+<item> Changed representation of <tt/Integer/ type to speed up
+computations on small integers.  The performance of <tt/Integer/ is now
+only slightly slower than <tt/Int/ for values between <tt/minBound :: Int/
+and <tt/maxBound :: Int/.
+
+<item> On Win32 platforms, added support for using (and producing) dynamic
+link libraries (DLLs) containing ghc-compiled code.
+
+<item> Added <tt>-funbox-strict-fields</tt> for unboxing/unpacking strict
+constructor fields.
+
+</itemize>
diff --git a/ghc/docs/users_guide/4-04-notes.sgml b/ghc/docs/users_guide/4-04-notes.sgml
new file mode 100644 (file)
index 0000000..8b885ab
--- /dev/null
@@ -0,0 +1,243 @@
+<Sect1 id="release-4-04">
+<Title>Release notes for version&nbsp;4.04&mdash;7/99
+</Title>
+
+<Para>
+
+<ItemizedList>
+<ListItem>
+
+<Para>
+<Literal>Weak</Literal> library changes:
+
+<ItemizedList>
+<ListItem>
+<Para>
+Finalise is now spelt finalize in all function names.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+<Literal>finalize</Literal> now runs the finalizer immediately, and
+waits for it to complete before returning.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+<Literal>mkWeak</Literal> now takes a <Literal>Maybe (IO ())</Literal> for the finalizer,
+and <Literal>mkWeakNoFinalizer</Literal> is removed.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+A weak pointer whose key is itself a weak pointer will now do the right
+thing.
+</Para>
+</ListItem>
+
+</ItemizedList>
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+Changed representation of <Literal>Integer</Literal> type to speed up
+computations on small integers.  The performance of <Literal>Integer</Literal> is now
+only slightly slower than <Literal>Int</Literal> for values between <Literal>minBound::Int</Literal>
+and <Literal>maxBound::Int</Literal>.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+On Win32 platforms, added support for using (and producing) dynamic
+link libraries (DLLs) containing ghc-compiled code.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+Added <Literal>-funbox-strict-fields</Literal> for unboxing/unpacking strict
+constructor fields.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+GHC now has a license!  Check out <Literal>fptools/ghc/LICENSE/</Literal>.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+Added CPR analysis, which reduces allocation by unboxing function results
+(thanks to Kevin Glynn <Literal>&lt;keving@cs.mu.OZ.AU&gt;</Literal>).
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+UsageSP analysis added, but not yet functional.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+Added a simple common sub-expression analysis pass.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+Implemented update-in-place for certain very restricted cases.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+Replaced GHC's old and worn yacc/lex parser with a new one based on Happy. 
+Fixed several Haskell 98 non-conformance issues in the process.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+Added <Literal>Concurrent.yield :: IO ()</Literal>.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+Added RULES pragms&mdash;transformation rules for Haskell source.
+This is used for list fusion: now intermediate lists between map,
+foldr, list comprehensions are removed automatically.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+Unregisterised/unmangled builds now work.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+Much performance tuning: GHC 4.04 produces faster code than all previous
+compilers.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+GHC now defines <Literal>&lowbar;&lowbar;HASKELL98&lowbar;&lowbar;</Literal> when compiling files with <Literal>-cpp</Literal>.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+<Literal>hppa1.1-hp-hpux</Literal> port reinstated.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+New operations for unsafely thawing byte arrays:
+<Literal>unsafeThaw&lcub;Byte,ST,IO&rcub;Array</Literal>.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+<Literal>mkdependHS</Literal> now lives in GHC's lib directory, not the
+binary directory.  It isn't intended to be run standalone, only via
+<Literal>ghc -M</Literal>.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+Asynchronous exceptions are now supported (see <XRef LinkEnd="concurrent-interface">).  New operations:
+
+<ItemizedList>
+
+<ListItem>
+<Para>
+<Literal>Exception.killThread</Literal> now raises an exception 
+(<Literal>AsyncException.KilledThread</Literal>) in the killed thread.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+<Literal>Exception.raiseInThread</Literal> allows a thread to raise an
+exception in another thread.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+<Literal>Concurrent.myThreadId</Literal> returns the <Literal>ThreadId</Literal> of the calling thread.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+Stack overflow results in <Literal>AsyncException.StackOverflow</Literal>
+being raised in the offending thread.
+</Para>
+</ListItem>
+
+</ItemizedList>
+
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+Assertion failures now raise an <Literal>AssertionFailed</Literal> exception.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+Added simple high-level interface to the Regex library, see <XRef LinkEnd="RegexString">.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+<Literal>forkIO</Literal> now handles any uncaught exceptions cleanly.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+<Literal>integer2Int&num;</Literal> isn't sign preserving any longer, but modulo <Literal>(maxBound::Int + 1) * 2</Literal>.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+<Literal>-ddump-rdr</Literal> is now called <Literal>-ddump-parsed</Literal>.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+Signal handling with the <Literal>Posix</Literal> library now works.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+Many, many bugs fixed.
+</Para>
+</ListItem>
+
+</ItemizedList>
+</Para>
+
+</Sect1>
diff --git a/ghc/docs/users_guide/debugging.sgml b/ghc/docs/users_guide/debugging.sgml
new file mode 100644 (file)
index 0000000..5586ad0
--- /dev/null
@@ -0,0 +1,676 @@
+<Sect1 id="options-debugging">
+<Title>Debugging the compiler
+</Title>
+
+<Para>
+<IndexTerm><Primary>debugging options (for GHC)</Primary></IndexTerm>
+</Para>
+
+<Para>
+HACKER TERRITORY. HACKER TERRITORY.
+(You were warned.)
+</Para>
+
+<Sect2 id="replacing-phases">
+<Title>Replacing the program for one or more phases.
+</Title>
+
+<Para>
+<IndexTerm><Primary>GHC phases, changing</Primary></IndexTerm>
+<IndexTerm><Primary>phases, changing GHC</Primary></IndexTerm>
+You may specify that a different program be used for one of the phases
+of the compilation system, in place of whatever the driver <Literal>ghc</Literal> has
+wired into it.  For example, you might want to try a different
+assembler.  The
+<Literal>-pgm&lt;phase-code&gt;&lt;program-name&gt;</Literal><IndexTerm><Primary>-pgm&lt;phase&gt;&lt;stuff&gt;
+option</Primary></IndexTerm> option to <Literal>ghc</Literal> will cause it to use <Literal>&lt;program-name&gt;</Literal>
+for phase <Literal>&lt;phase-code&gt;</Literal>, where the codes to indicate the phases are:
+</Para>
+
+<Para>
+<InformalTable>
+<TGroup Cols="2">
+<ColSpec Align="Left" Colsep="0">
+<ColSpec Align="Left" Colsep="0">
+<TBody>
+<Row>
+<Entry><Emphasis>code</Emphasis> </Entry>
+<Entry><Emphasis>phase</Emphasis> </Entry>
+</Row>
+
+<Row>
+<Entry>
+L </Entry>
+<Entry> literate pre-processor </Entry>
+</Row>
+<Row>
+<Entry>
+P </Entry>
+<Entry> C pre-processor (if -cpp only) </Entry>
+</Row>
+<Row>
+<Entry>
+C </Entry>
+<Entry> Haskell compiler </Entry>
+</Row>
+<Row>
+<Entry>
+c </Entry>
+<Entry> C compiler</Entry>
+</Row>
+<Row>
+<Entry>
+a </Entry>
+<Entry> assembler </Entry>
+</Row>
+<Row>
+<Entry>
+l </Entry>
+<Entry> linker </Entry>
+</Row>
+<Row>
+<Entry>
+dep </Entry>
+<Entry> Makefile dependency generator </Entry>
+</Row>
+
+</TBody>
+
+</TGroup>
+</InformalTable>
+</Para>
+
+</Sect2>
+
+<Sect2 id="forcing-options-through">
+<Title>Forcing options to a particular phase.
+</Title>
+
+<Para>
+<IndexTerm><Primary>forcing GHC-phase options</Primary></IndexTerm>
+</Para>
+
+<Para>
+The preceding sections describe driver options that are mostly
+applicable to one particular phase.  You may also <Emphasis>force</Emphasis> a
+specific option <Literal>&lt;option&gt;</Literal> to be passed to a particular phase
+<Literal>&lt;phase-code&gt;</Literal> by feeding the driver the option
+<Literal>-opt&lt;phase-code&gt;&lt;option&gt;</Literal>.<IndexTerm><Primary>-opt&lt;phase&gt;&lt;stuff&gt;
+option</Primary></IndexTerm> The codes to indicate the phases are the same as in the
+previous section.
+</Para>
+
+<Para>
+So, for example, to force an <Literal>-Ewurble</Literal> option to the assembler, you
+would tell the driver <Literal>-opta-Ewurble</Literal> (the dash before the E is
+required).
+</Para>
+
+<Para>
+Besides getting options to the Haskell compiler with <Literal>-optC&lt;blah&gt;</Literal>,
+you can get options through to its runtime system with
+<Literal>-optCrts&lt;blah&gt;</Literal><IndexTerm><Primary>-optCrts&lt;blah&gt; option</Primary></IndexTerm>.
+</Para>
+
+<Para>
+So, for example: when I want to use my normal driver but with my
+profiled compiler binary, I use this script:
+
+<ProgramListing>
+#! /bin/sh
+exec /local/grasp_tmp3/simonpj/ghc-BUILDS/working-alpha/ghc/driver/ghc \
+     -pgmC/local/grasp_tmp3/simonpj/ghc-BUILDS/working-hsc-prof/hsc \
+     -optCrts-i0.5 \
+     -optCrts-PT \
+     "$@"
+</ProgramListing>
+
+</Para>
+
+</Sect2>
+
+<Sect2 id="dumping-output">
+<Title>Dumping out compiler intermediate structures
+</Title>
+
+<Para>
+<IndexTerm><Primary>dumping GHC intermediates</Primary></IndexTerm>
+<IndexTerm><Primary>intermediate passes, output</Primary></IndexTerm>
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>-noC</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-noC option</Primary></IndexTerm>
+Don't bother generating C output <Emphasis>or</Emphasis> an interface file.  Usually
+used in conjunction with one or more of the <Literal>-ddump-*</Literal> options; for
+example: <Literal>ghc -noC -ddump-simpl Foo.hs</Literal>
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-hi</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-hi option</Primary></IndexTerm>
+<Emphasis>Do</Emphasis> generate an interface file.  This would normally be used in
+conjunction with <Literal>-noC</Literal>, which turns off interface generation;
+thus: <Literal>-noC -hi</Literal>.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-dshow-passes</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-dshow-passes option</Primary></IndexTerm>
+Prints a message to stderr as each pass starts.  Gives a warm but
+undoubtedly misleading feeling that GHC is telling you what's
+happening.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-ddump-&lt;pass&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-ddump-&lt;pass&gt; options</Primary></IndexTerm>
+Make a debugging dump after pass <Literal>&lt;pass&gt;</Literal> (may be common enough to
+need a short form&hellip;).  You can get all of these at once (<Emphasis>lots</Emphasis> of
+output) by using <Literal>-ddump-all</Literal>, or most of them with <Literal>-ddump-most</Literal>.
+Some of the most useful ones are:
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>-ddump-parsed</Literal>:</Term>
+<ListItem>
+<Para>
+oarser output
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-ddump-rn</Literal>:</Term>
+<ListItem>
+<Para>
+renamer output
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-ddump-tc</Literal>:</Term>
+<ListItem>
+<Para>
+typechecker output
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-ddump-deriv</Literal>:</Term>
+<ListItem>
+<Para>
+derived instances
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-ddump-ds</Literal>:</Term>
+<ListItem>
+<Para>
+desugarer output
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-ddump-spec</Literal>:</Term>
+<ListItem>
+<Para>
+output of specialisation pass
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-ddump-rules</Literal>:</Term>
+<ListItem>
+<Para>
+dumps all rewrite rules (including those generated by the specialisation pass)
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-ddump-simpl</Literal>:</Term>
+<ListItem>
+<Para>
+simplifer output (Core-to-Core passes)
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-ddump-usagesp</Literal>:</Term>
+<ListItem>
+<Para>
+UsageSP inference pre-inf and output
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-ddump-cpranal</Literal>:</Term>
+<ListItem>
+<Para>
+CPR analyser output
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-ddump-stranal</Literal>:</Term>
+<ListItem>
+<Para>
+strictness analyser output
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-ddump-workwrap</Literal>:</Term>
+<ListItem>
+<Para>
+worker/wrapper split output
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-ddump-occur-anal</Literal>:</Term>
+<ListItem>
+<Para>
+`occurrence analysis' output
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-ddump-stg</Literal>:</Term>
+<ListItem>
+<Para>
+output of STG-to-STG passes
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-ddump-absC</Literal>:</Term>
+<ListItem>
+<Para>
+<Emphasis>un</Emphasis>flattened Abstract&nbsp;C
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-ddump-flatC</Literal>:</Term>
+<ListItem>
+<Para>
+<Emphasis>flattened</Emphasis> Abstract&nbsp;C
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-ddump-realC</Literal>:</Term>
+<ListItem>
+<Para>
+same as what goes to the C compiler
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-ddump-asm</Literal>:</Term>
+<ListItem>
+<Para>
+assembly language from the native-code generator
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+<Para>
+<IndexTerm><Primary>-ddump-all option</Primary></IndexTerm>
+<IndexTerm><Primary>-ddump-most option</Primary></IndexTerm>
+<IndexTerm><Primary>-ddump-parsed option</Primary></IndexTerm>
+<IndexTerm><Primary>-ddump-rn option</Primary></IndexTerm>
+<IndexTerm><Primary>-ddump-tc option</Primary></IndexTerm>
+<IndexTerm><Primary>-ddump-deriv option</Primary></IndexTerm>
+<IndexTerm><Primary>-ddump-ds option</Primary></IndexTerm>
+<IndexTerm><Primary>-ddump-simpl option</Primary></IndexTerm>
+<IndexTerm><Primary>-ddump-cpranal option</Primary></IndexTerm>
+<IndexTerm><Primary>-ddump-workwrap option</Primary></IndexTerm>
+<IndexTerm><Primary>-ddump-rules option</Primary></IndexTerm>
+<IndexTerm><Primary>-ddump-usagesp option</Primary></IndexTerm>
+<IndexTerm><Primary>-ddump-stranal option</Primary></IndexTerm>
+<IndexTerm><Primary>-ddump-occur-anal option</Primary></IndexTerm>
+<IndexTerm><Primary>-ddump-spec option</Primary></IndexTerm>
+<IndexTerm><Primary>-ddump-stg option</Primary></IndexTerm>
+<IndexTerm><Primary>-ddump-absC option</Primary></IndexTerm>
+<IndexTerm><Primary>-ddump-flatC option</Primary></IndexTerm>
+<IndexTerm><Primary>-ddump-realC option</Primary></IndexTerm>
+<IndexTerm><Primary>-ddump-asm option</Primary></IndexTerm>
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-dverbose-simpl</Literal> and <Literal>-dverbose-stg</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-dverbose-simpl option</Primary></IndexTerm>
+<IndexTerm><Primary>-dverbose-stg option</Primary></IndexTerm>
+Show the output of the intermediate Core-to-Core and STG-to-STG
+passes, respectively.  (<Emphasis>Lots</Emphasis> of output!) So: when we're 
+really desperate:
+
+<Screen>
+% ghc -noC -O -ddump-simpl -dverbose-simpl -dcore-lint Foo.hs
+</Screen>
+
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-ddump-simpl-iterations</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-ddump-simpl-iterations option</Primary></IndexTerm>
+Show the output of each <Emphasis>iteration</Emphasis> of the simplifier (each run of
+the simplifier has a maximum number of iterations, normally 4).  Used
+when even <Literal>-dverbose-simpl</Literal> doesn't cut it.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-dppr-&lcub;user,debug</Literal>&rcub;:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-dppr-user option</Primary></IndexTerm>
+<IndexTerm><Primary>-dppr-debug option</Primary></IndexTerm>
+Debugging output is in one of several ``styles.''  Take the printing
+of types, for example.  In the ``user'' style, the compiler's internal
+ideas about types are presented in Haskell source-level syntax,
+insofar as possible.  In the ``debug'' style (which is the default for
+debugging output), the types are printed in with
+explicit foralls, and variables have their unique-id attached (so you
+can check for things that look the same but aren't).
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-ddump-simpl-stats</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-ddump-simpl-stats option</Primary></IndexTerm>
+Dump statistics about how many of each kind
+of transformation too place.  If you add <Literal>-dppr-debug</Literal> you get more detailed information.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-ddump-raw-asm</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-ddump-raw-asm option</Primary></IndexTerm>
+Dump out the assembly-language stuff, before the ``mangler'' gets it.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-ddump-rn-trace</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-ddump-rn-trace</Primary></IndexTerm>
+Make the renamer be *real* chatty about what it is upto.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-dshow-rn-stats</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-dshow-rn-stats</Primary></IndexTerm>
+Print out summary of what kind of information the renamer had to bring
+in.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-dshow-unused-imports</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-dshow-unused-imports</Primary></IndexTerm>
+Have the renamer report what imports does not contribute.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+</Sect2>
+
+<Sect2 id="checking-consistency">
+<Title>Checking for consistency
+</Title>
+
+<Para>
+<IndexTerm><Primary>consistency checks</Primary></IndexTerm>
+<IndexTerm><Primary>lint</Primary></IndexTerm>
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>-dcore-lint</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-dcore-lint option</Primary></IndexTerm>
+Turn on heavyweight intra-pass sanity-checking within GHC, at Core
+level.  (It checks GHC's sanity, not yours.)
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-dstg-lint</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-dstg-lint option</Primary></IndexTerm>
+Ditto for STG level.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-dusagesp-lint</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-dstg-lint option</Primary></IndexTerm>
+Turn on checks around UsageSP inference (<Literal>-fusagesp</Literal>).  This verifies
+various simple properties of the results of the inference, and also
+warns if any identifier with a used-once annotation before the
+inference has a used-many annotation afterwards; this could indicate a
+non-worksafe transformation is being applied.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>How to read Core syntax (from some <Literal>-ddump-*</Literal> flags)</Title>
+
+<Para>
+<IndexTerm><Primary>reading Core syntax</Primary></IndexTerm>
+<IndexTerm><Primary>Core syntax, how to read</Primary></IndexTerm>
+</Para>
+
+<Para>
+Let's do this by commenting an example.  It's from doing
+<Literal>-ddump-ds</Literal> on this code:
+
+<ProgramListing>
+skip2 m = m : skip2 (m+2)
+</ProgramListing>
+
+</Para>
+
+<Para>
+Before we jump in, a word about names of things.  Within GHC,
+variables, type constructors, etc., are identified by their
+``Uniques.''  These are of the form `letter' plus `number' (both
+loosely interpreted).  The `letter' gives some idea of where the
+Unique came from; e.g., <Literal>&lowbar;</Literal> means ``built-in type variable'';
+<Literal>t</Literal> means ``from the typechecker''; <Literal>s</Literal> means ``from the
+simplifier''; and so on.  The `number' is printed fairly compactly in
+a `base-62' format, which everyone hates except me (WDP).
+</Para>
+
+<Para>
+Remember, everything has a ``Unique'' and it is usually printed out
+when debugging, in some form or another.  So here we go&hellip;
+</Para>
+
+<Para>
+<ProgramListing>
+Desugared:
+Main.skip2{-r1L6-} :: _forall_ a$_4 =&#62;{{Num a$_4}} -&#62; a$_4 -&#62; [a$_4]
+
+--# `r1L6' is the Unique for Main.skip2;
+--# `_4' is the Unique for the type-variable (template) `a'
+--# `{{Num a$_4}}' is a dictionary argument
+
+_NI_
+
+--# `_NI_' means "no (pragmatic) information" yet; it will later
+--# evolve into the GHC_PRAGMA info that goes into interface files.
+
+Main.skip2{-r1L6-} =
+    /\ _4 -&#62; \ d.Num.t4Gt -&#62;
+        let {
+          {- CoRec -}
+          +.t4Hg :: _4 -&#62; _4 -&#62; _4
+          _NI_
+          +.t4Hg = (+{-r3JH-} _4) d.Num.t4Gt
+
+          fromInt.t4GS :: Int{-2i-} -&#62; _4
+          _NI_
+          fromInt.t4GS = (fromInt{-r3JX-} _4) d.Num.t4Gt
+
+--# The `+' class method (Unique: r3JH) selects the addition code
+--# from a `Num' dictionary (now an explicit lamba'd argument).
+--# Because Core is 2nd-order lambda-calculus, type applications
+--# and lambdas (/\) are explicit.  So `+' is first applied to a
+--# type (`_4'), then to a dictionary, yielding the actual addition
+--# function that we will use subsequently...
+
+--# We play the exact same game with the (non-standard) class method
+--# `fromInt'.  Unsurprisingly, the type `Int' is wired into the
+--# compiler.
+
+          lit.t4Hb :: _4
+          _NI_
+          lit.t4Hb =
+              let {
+                ds.d4Qz :: Int{-2i-}
+                _NI_
+                ds.d4Qz = I#! 2#
+              } in  fromInt.t4GS ds.d4Qz
+
+--# `I# 2#' is just the literal Int `2'; it reflects the fact that
+--# GHC defines `data Int = I# Int#', where Int# is the primitive
+--# unboxed type.  (see relevant info about unboxed types elsewhere...)
+
+--# The `!' after `I#' indicates that this is a *saturated*
+--# application of the `I#' data constructor (i.e., not partially
+--# applied).
+
+          skip2.t3Ja :: _4 -&#62; [_4]
+          _NI_
+          skip2.t3Ja =
+              \ m.r1H4 -&#62;
+                  let { ds.d4QQ :: [_4]
+                        _NI_
+                        ds.d4QQ =
+                    let {
+                      ds.d4QY :: _4
+                      _NI_
+                      ds.d4QY = +.t4Hg m.r1H4 lit.t4Hb
+                    } in  skip2.t3Ja ds.d4QY
+                  } in
+                  :! _4 m.r1H4 ds.d4QQ
+
+          {- end CoRec -}
+        } in  skip2.t3Ja
+</ProgramListing>
+</Para>
+
+<Para>
+(``It's just a simple functional language'' is an unregisterised
+trademark of Peyton Jones Enterprises, plc.)
+</Para>
+
+</Sect2>
+
+<Sect2 id="source-file-options">
+<Title>Command line options in source files
+</Title>
+
+<Para>
+<IndexTerm><Primary>source-file options</Primary></IndexTerm>
+</Para>
+
+<Para>
+Sometimes it is useful to make the connection between a source file
+and the command-line options it requires quite tight. For instance,
+if a (Glasgow) Haskell source file uses <Literal>casm</Literal>s, the C back-end
+often needs to be told about which header files to include. Rather than
+maintaining the list of files the source depends on in a
+<Literal>Makefile</Literal> (using the <Literal>-&num;include</Literal> command-line option), it is
+possible to do this directly in the source file using the <Literal>OPTIONS</Literal>
+pragma <IndexTerm><Primary>OPTIONS pragma</Primary></IndexTerm>: 
+</Para>
+
+<Para>
+<ProgramListing>
+{-# OPTIONS -#include "foo.h" #-}
+module X where
+
+...
+</ProgramListing>
+</Para>
+
+<Para>
+<Literal>OPTIONS</Literal> pragmas are only looked for at the top of your source
+files, upto the first (non-literate,non-empty) line not containing
+<Literal>OPTIONS</Literal>. Multiple <Literal>OPTIONS</Literal> pragmas are recognised. Note
+that your command shell does not get to the source file options, they
+are just included literally in the array of command-line arguments
+the compiler driver maintains internally, so you'll be desperately
+disappointed if you try to glob etc. inside <Literal>OPTIONS</Literal>.
+</Para>
+
+<Para>
+NOTE: the contents of OPTIONS are prepended to the command-line
+options, so you *do* have the ability to override OPTIONS settings
+via the command line.
+</Para>
+
+<Para>
+It is not recommended to move all the contents of your Makefiles into
+your source files, but in some circumstances, the <Literal>OPTIONS</Literal> pragma
+is the Right Thing. (If you use <Literal>-keep-hc-file-too</Literal> and have OPTION
+flags in your module, the OPTIONS will get put into the generated .hc
+file).
+</Para>
+
+</Sect2>
+
+</Sect1>
diff --git a/ghc/docs/users_guide/glasgow_exts.sgml b/ghc/docs/users_guide/glasgow_exts.sgml
new file mode 100644 (file)
index 0000000..c7d50be
--- /dev/null
@@ -0,0 +1,3748 @@
+<Para>
+<IndexTerm><Primary>language, GHC</Primary></IndexTerm>
+<IndexTerm><Primary>extensions, GHC</Primary></IndexTerm>
+As with all known Haskell systems, GHC implements some extensions to
+the language.  To use them, you'll need to give a <Literal>-fglasgow-exts</Literal>
+<IndexTerm><Primary>-fglasgow-exts option</Primary></IndexTerm> option.
+</Para>
+
+<Para>
+Virtually all of the Glasgow extensions serve to give you access to
+the underlying facilities with which we implement Haskell.  Thus, you
+can get at the Raw Iron, if you are willing to write some non-standard
+code at a more primitive level.  You need not be ``stuck'' on
+performance because of the implementation costs of Haskell's
+``high-level'' features&mdash;you can always code ``under'' them.  In an
+extreme case, you can write all your time-critical code in C, and then
+just glue it together with Haskell!
+</Para>
+
+<Para>
+Executive summary of our extensions:
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term>Unboxed types and primitive operations:</Term>
+<ListItem>
+<Para>
+You can get right down to the raw machine types and operations;
+included in this are ``primitive arrays'' (direct access to Big Wads
+of Bytes).  Please see <XRef LinkEnd="glasgow-unboxed"> and following.
+</Para>
+</ListItem>
+</VarListEntry>
+
+<VarListEntry>
+<Term>Multi-parameter type classes:</Term>
+<ListItem>
+<Para>
+GHC's type system supports extended type classes with multiple
+parameters.  Please see <XRef LinkEnd="multi-param-type-classes">.
+</Para>
+</ListItem>
+</VarListEntry>
+
+<VarListEntry>
+<Term>Local universal quantification:</Term>
+<ListItem>
+<Para>
+GHC's type system supports explicit universal quantification in
+constructor fields and function arguments.  This is useful for things
+like defining <Literal>runST</Literal> from the state-thread world.  See <XRef LinkEnd="universal-quantification">.
+</Para>
+</ListItem>
+</VarListEntry>
+
+<VarListEntry>
+<Term>Extistentially quantification in data types:</Term>
+<ListItem>
+<Para>
+Some or all of the type variables in a datatype declaration may be
+<Emphasis>existentially quantified</Emphasis>.  More details in <XRef LinkEnd="existential-quantification">.
+</Para>
+</ListItem>
+</VarListEntry>
+
+<VarListEntry>
+<Term>Scoped type variables:</Term>
+<ListItem>
+<Para>
+Scoped type variables enable the programmer to supply type signatures
+for some nested declarations, where this would not be legal in Haskell
+98.  Details in <XRef LinkEnd="scoped-type-variables">.
+</Para>
+</ListItem>
+</VarListEntry>
+
+<VarListEntry>
+<Term>Calling out to C:</Term>
+<ListItem>
+<Para>
+Just what it sounds like.  We provide <Emphasis>lots</Emphasis> of rope that you
+can dangle around your neck.  Please see <XRef LinkEnd="glasgow-ccalls">.
+</Para>
+</ListItem>
+</VarListEntry>
+
+<VarListEntry>
+<Term>Pragmas</Term>
+<ListItem>
+<Para>
+Pragmas are special instructions to the compiler placed in the source
+file.  The pragmas GHC supports are described in <XRef LinkEnd="pragmas">.
+</Para>
+</ListItem>
+</VarListEntry>
+
+<VarListEntry>
+<Term>Rewrite rules:</Term>
+<ListItem>
+<Para>
+The programmer can specify rewrite rules as part of the source program
+(in a pragma).  GHC applies these rewrite rules wherever it can.
+Details in <XRef LinkEnd="rewrite-rules">.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+<Para>
+Before you get too carried away working at the lowest level (e.g.,
+sloshing <Literal>MutableByteArray&num;</Literal>s around your program), you may wish to
+check if there are system libraries that provide a ``Haskellised
+veneer'' over the features you want.  See <XRef LinkEnd="ghc-prelude">.
+</Para>
+
+<Sect1 id="glasgow-unboxed">
+<Title>Unboxed types
+</Title>
+
+<Para>
+<IndexTerm><Primary>Unboxed types (Glasgow extension)</Primary></IndexTerm>
+</Para>
+
+<Para>
+These types correspond to the ``raw machine'' types you would use in
+C: <Literal>Int&num;</Literal> (long int), <Literal>Double&num;</Literal> (double), <Literal>Addr&num;</Literal> (void *), etc.  The
+<Emphasis>primitive operations</Emphasis> (PrimOps) on these types are what you
+might expect; e.g., <Literal>(+&num;)</Literal> is addition on <Literal>Int&num;</Literal>s, and is the
+machine-addition that we all know and love&mdash;usually one instruction.
+</Para>
+
+<Para>
+There are some restrictions on the use of unboxed types, the main one
+being that you can't pass an unboxed value to a polymorphic function
+or store one in a polymorphic data type.  This rules out things like
+<Literal>[Int&num;]</Literal> (ie. lists of unboxed integers).  The reason for this
+restriction is that polymorphic arguments and constructor fields are
+assumed to be pointers: if an unboxed integer is stored in one of
+these, the garbage collector would attempt to follow it, leading to
+unpredictable space leaks.  Or a <Literal>seq</Literal> operation on the polymorphic
+component may attempt to dereference the pointer, with disastrous
+results.  Even worse, the unboxed value might be larger than a pointer
+(<Literal>Double&num;</Literal> for instance).
+</Para>
+
+<Para>
+Nevertheless, A numerically-intensive program using unboxed types can
+go a <Emphasis>lot</Emphasis> faster than its ``standard'' counterpart&mdash;we saw a
+threefold speedup on one example.
+</Para>
+
+<Para>
+Please see <XRef LinkEnd="ghc-libs-ghc"> for the details of unboxed types and the
+operations on them.
+</Para>
+
+</Sect1>
+
+<Sect1 id="glasgow-ST-monad">
+<Title>Primitive state-transformer monad
+</Title>
+
+<Para>
+<IndexTerm><Primary>state transformers (Glasgow extensions)</Primary></IndexTerm>
+<IndexTerm><Primary>ST monad (Glasgow extension)</Primary></IndexTerm>
+</Para>
+
+<Para>
+This monad underlies our implementation of arrays, mutable and
+immutable, and our implementation of I/O, including ``C calls''.
+</Para>
+
+<Para>
+The <Literal>ST</Literal> library, which provides access to the <Literal>ST</Literal> monad, is a
+GHC/Hugs extension library and is described in the separate <ULink
+URL="libs.html"
+>GHC/Hugs Extension Libraries</ULink
+> document.
+</Para>
+
+</Sect1>
+
+<Sect1 id="glasgow-prim-arrays">
+<Title>Primitive arrays, mutable and otherwise
+</Title>
+
+<Para>
+<IndexTerm><Primary>primitive arrays (Glasgow extension)</Primary></IndexTerm>
+<IndexTerm><Primary>arrays, primitive (Glasgow extension)</Primary></IndexTerm>
+</Para>
+
+<Para>
+GHC knows about quite a few flavours of Large Swathes of Bytes.
+</Para>
+
+<Para>
+First, GHC distinguishes between primitive arrays of (boxed) Haskell
+objects (type <Literal>Array&num; obj</Literal>) and primitive arrays of bytes (type
+<Literal>ByteArray&num;</Literal>).
+</Para>
+
+<Para>
+Second, it distinguishes between&hellip;
+<VariableList>
+
+<VarListEntry>
+<Term>Immutable:</Term>
+<ListItem>
+<Para>
+Arrays that do not change (as with ``standard'' Haskell arrays); you
+can only read from them.  Obviously, they do not need the care and
+attention of the state-transformer monad.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>Mutable:</Term>
+<ListItem>
+<Para>
+Arrays that may be changed or ``mutated.''  All the operations on them
+live within the state-transformer monad and the updates happen
+<Emphasis>in-place</Emphasis>.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>``Static'' (in C land):</Term>
+<ListItem>
+<Para>
+A C routine may pass an <Literal>Addr&num;</Literal> pointer back into Haskell land.  There
+are then primitive operations with which you may merrily grab values
+over in C land, by indexing off the ``static'' pointer.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>``Stable'' pointers:</Term>
+<ListItem>
+<Para>
+If, for some reason, you wish to hand a Haskell pointer (i.e.,
+<Emphasis>not</Emphasis> an unboxed value) to a C routine, you first make the
+pointer ``stable,'' so that the garbage collector won't forget that it
+exists.  That is, GHC provides a safe way to pass Haskell pointers to
+C.
+</Para>
+
+<Para>
+Please see <XRef LinkEnd="glasgow-stablePtrs"> for more details.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>``Foreign objects'':</Term>
+<ListItem>
+<Para>
+A ``foreign object'' is a safe way to pass an external object (a
+C-allocated pointer, say) 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.''
+</Para>
+
+<Para>
+Please see <XRef LinkEnd="glasgow-foreignObjs"> for more details.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+<Para>
+The libraries section gives more details on all these ``primitive
+array'' types and the operations on them, <XRef LinkEnd="ghc-prelude">.  Some of these extensions
+are also supported by Hugs, and the supporting libraries are described
+in the <ULink
+URL="libs.html"
+>GHC/Hugs Extension Libraries</ULink
+>
+document.
+</Para>
+
+</Sect1>
+
+<Sect1 id="glasgow-ccalls">
+<Title>Calling&nbsp;C directly from Haskell
+</Title>
+
+<Para>
+<IndexTerm><Primary>C calls (Glasgow extension)</Primary></IndexTerm>
+<IndexTerm><Primary>&lowbar;ccall&lowbar; (Glasgow extension)</Primary></IndexTerm>
+<IndexTerm><Primary>&lowbar;casm&lowbar; (Glasgow extension)</Primary></IndexTerm>
+</Para>
+
+<Para>
+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.
+</Para>
+
+<Sect2 id="ccall-intro">
+<Title><Literal>&lowbar;ccall&lowbar;</Literal> and <Literal>&lowbar;casm&lowbar;</Literal>: an introduction
+</Title>
+
+<Para>
+The simplest way to use a simple C function
+</Para>
+
+<Para>
+
+<ProgramListing>
+double fooC( FILE *in, char c, int i, double d, unsigned int u )
+</ProgramListing>
+
+</Para>
+
+<Para>
+is to provide a Haskell wrapper:
+</Para>
+
+<Para>
+
+<ProgramListing>
+fooH :: Char -&#62; Int -&#62; Double -&#62; Word -&#62; IO Double
+fooH c i d w = _ccall_ fooC (``stdin''::Addr) c i d w
+</ProgramListing>
+
+</Para>
+
+<Para>
+The function <Literal>fooH</Literal> will unbox all of its arguments, call the C
+function <Literal>fooC</Literal> and box the corresponding arguments.
+</Para>
+
+<Para>
+One of the annoyances about <Literal>&lowbar;ccall&lowbar;</Literal>s is when the C types don't quite
+match the Haskell compiler's ideas.  For this, the <Literal>&lowbar;casm&lowbar;</Literal> variant
+may be just the ticket (NB: <Emphasis>no chance</Emphasis> of such code going
+through a native-code generator):
+</Para>
+
+<Para>
+
+<ProgramListing>
+import Addr
+import CString
+
+oldGetEnv name
+  = _casm_ ``%r = getenv((char *) %0);'' name &#62;&#62;= \ litstring -&#62;
+    return (
+        if (litstring == nullAddr) then
+            Left ("Fail:oldGetEnv:"++name)
+        else
+            Right (unpackCString litstring)
+    )
+</ProgramListing>
+
+</Para>
+
+<Para>
+The first literal-literal argument to a <Literal>&lowbar;casm&lowbar;</Literal> is like a <Literal>printf</Literal>
+format: <Literal>&percnt;r</Literal> is replaced with the ``result,'' <Literal>&percnt;0</Literal>--<Literal>&percnt;n-1</Literal> are
+replaced with the 1st--nth arguments.  As you can see above, it is an
+easy way to do simple C&nbsp;casting.  Everything said about <Literal>&lowbar;ccall&lowbar;</Literal> goes
+for <Literal>&lowbar;casm&lowbar;</Literal> as well.
+</Para>
+
+<Para>
+The use of <Literal>&lowbar;casm&lowbar;</Literal> in your code does pose a problem to the compiler
+when it comes to generating an interface file for a freshly compiled
+module. Included in an interface file is the unfolding (if any) of a
+declaration. However, if a declaration's unfolding happens to contain
+a <Literal>&lowbar;casm&lowbar;</Literal>, its unfolding will <Emphasis>not</Emphasis> be emitted into the interface
+file even if it qualifies by all the other criteria. The reason why
+the compiler prevents this from happening is that unfolding <Literal>&lowbar;casm&lowbar;</Literal>s
+into an interface file unduly constrains how code that import your
+module have to be compiled. If an imported declaration is unfolded and
+it contains a <Literal>&lowbar;casm&lowbar;</Literal>, you now have to be using a compiler backend
+capable of dealing with it (i.e., the C compiler backend). If you are
+using the C compiler backend, the unfolded <Literal>&lowbar;casm&lowbar;</Literal> may still cause you
+problems since the C code snippet it contains may mention CPP symbols
+that were in scope when compiling the original module are not when
+compiling the importing module.
+</Para>
+
+<Para>
+If you're willing to put up with the drawbacks of doing cross-module
+inlining of C code (GHC - A Better C Compiler :-), the option
+<Literal>-funfold-casms-in-hi-file</Literal> will turn off the default behaviour.
+<IndexTerm><Primary>-funfold-casms-in-hi-file option</Primary></IndexTerm>
+</Para>
+
+</Sect2>
+
+<Sect2 id="glasgow-literal-literals">
+<Title>Literal-literals
+</Title>
+
+<Para>
+<IndexTerm><Primary>Literal-literals</Primary></IndexTerm>
+</Para>
+
+<Para>
+The literal-literal argument to <Literal>&lowbar;casm&lowbar;</Literal> can be made use of separately
+from the <Literal>&lowbar;casm&lowbar;</Literal> construct itself. Indeed, we've already used it:
+</Para>
+
+<Para>
+
+<ProgramListing>
+fooH :: Char -&#62; Int -&#62; Double -&#62; Word -&#62; IO Double
+fooH c i d w = _ccall_ fooC (``stdin''::Addr) c i d w
+</ProgramListing>
+
+</Para>
+
+<Para>
+The first argument that's passed to <Literal>fooC</Literal> is given as a literal-literal,
+that is, a literal chunk of C code that will be inserted into the generated
+<Literal>.hc</Literal> code at the right place.
+</Para>
+
+<Para>
+A literal-literal is restricted to having a type that's an instance of
+the <Literal>CCallable</Literal> class, see <XRef LinkEnd="ccall-gotchas">
+for more information.
+</Para>
+
+<Para>
+Notice that literal-literals are by their very nature unfriendly to
+native code generators, so exercise judgement about whether or not to
+make use of them in your code.
+</Para>
+
+</Sect2>
+
+<Sect2 id="glasgow-foreign-headers">
+<Title>Using function headers
+</Title>
+
+<Para>
+<IndexTerm><Primary>C calls, function headers</Primary></IndexTerm>
+</Para>
+
+<Para>
+When generating C (using the <Literal>-fvia-C</Literal> directive), one can assist the
+C compiler in detecting type errors by using the <Literal>-&num;include</Literal> directive
+to provide <Literal>.h</Literal> files containing function headers.
+</Para>
+
+<Para>
+For example,
+</Para>
+
+<Para>
+
+<ProgramListing>
+typedef unsigned long *StgForeignObj;
+typedef long StgInt;
+
+void          initialiseEFS (StgInt size);
+StgInt        terminateEFS (void);
+StgForeignObj emptyEFS(void);
+StgForeignObj updateEFS (StgForeignObj a, StgInt i, StgInt x);
+StgInt        lookupEFS (StgForeignObj a, StgInt i);
+</ProgramListing>
+
+</Para>
+
+<Para>
+You can find appropriate definitions for <Literal>StgInt</Literal>, <Literal>StgForeignObj</Literal>,
+etc using <Literal>gcc</Literal> on your architecture by consulting
+<Literal>ghc/includes/StgTypes.h</Literal>.  The following table summarises the
+relationship between Haskell types and C types.
+</Para>
+
+<Para>
+
+<InformalTable>
+<TGroup Cols="2">
+<ColSpec Align="Left" Colsep="0">
+<ColSpec Align="Left" Colsep="0">
+<TBody>
+<Row>
+<Entry><Emphasis>C type name</Emphasis> </Entry>
+<Entry> <Emphasis>Haskell Type</Emphasis> </Entry>
+</Row>
+
+<Row>
+<Entry>
+<Literal>StgChar</Literal> </Entry>
+<Entry> <Literal>Char&num;</Literal> </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>StgInt</Literal> </Entry>
+<Entry> <Literal>Int&num;</Literal> </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>StgWord</Literal> </Entry>
+<Entry> <Literal>Word&num;</Literal> </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>StgAddr</Literal> </Entry>
+<Entry> <Literal>Addr&num;</Literal> </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>StgFloat</Literal> </Entry>
+<Entry> <Literal>Float&num;</Literal> </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>StgDouble</Literal> </Entry>
+<Entry> <Literal>Double&num;</Literal> </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>StgArray</Literal> </Entry>
+<Entry> <Literal>Array&num;</Literal> </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>StgByteArray</Literal> </Entry>
+<Entry> <Literal>ByteArray&num;</Literal> </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>StgArray</Literal> </Entry>
+<Entry> <Literal>MutableArray&num;</Literal> </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>StgByteArray</Literal> </Entry>
+<Entry> <Literal>MutableByteArray&num;</Literal> </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>StgStablePtr</Literal> </Entry>
+<Entry> <Literal>StablePtr&num;</Literal> </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>StgForeignObj</Literal> </Entry>
+<Entry> <Literal>ForeignObj&num;</Literal></Entry>
+</Row>
+</TBody>
+
+</TGroup>
+</InformalTable>
+</Para>
+
+<Para>
+Note that this approach is only <Emphasis>essential</Emphasis> for returning
+<Literal>float</Literal>s (or if <Literal>sizeof(int) != sizeof(int *)</Literal> on your
+architecture) but is a Good Thing for anyone who cares about writing
+solid code.  You're crazy not to do it.
+</Para>
+
+</Sect2>
+
+<Sect2 id="glasgow-stablePtrs">
+<Title>Subverting automatic unboxing with ``stable pointers''
+</Title>
+
+<Para>
+<IndexTerm><Primary>stable pointers (Glasgow extension)</Primary></IndexTerm>
+</Para>
+
+<Para>
+The arguments of a <Literal>&lowbar;ccall&lowbar;</Literal> are automatically unboxed before the
+call.  There are two reasons why this is usually the Right Thing to
+do:
+</Para>
+
+<Para>
+
+<ItemizedList>
+<ListItem>
+
+<Para>
+C is a strict language: it would be excessively tedious to pass
+unevaluated arguments and require the C programmer to force their
+evaluation before using them.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ Boxed values are stored on the Haskell heap and may be moved
+within the heap if a garbage collection occurs&mdash;that is, pointers
+to boxed objects are not <Emphasis>stable</Emphasis>.
+</Para>
+</ListItem>
+
+</ItemizedList>
+
+</Para>
+
+<Para>
+It is possible to subvert the unboxing process by creating a ``stable
+pointer'' to a value and passing the stable pointer instead.  For
+example, to pass/return an integer lazily to C functions <Literal>storeC</Literal> and
+<Literal>fetchC</Literal>, one might write:
+</Para>
+
+<Para>
+
+<ProgramListing>
+storeH :: Int -&#62; IO ()
+storeH x = makeStablePtr x              &#62;&#62;= \ stable_x -&#62;
+           _ccall_ storeC stable_x
+
+fetchH :: IO Int
+fetchH x = _ccall_ fetchC               &#62;&#62;= \ stable_x -&#62;
+           deRefStablePtr stable_x      &#62;&#62;= \ x -&#62;
+           freeStablePtr stable_x       &#62;&#62;
+           return x
+</ProgramListing>
+
+</Para>
+
+<Para>
+The garbage collector will refrain from throwing a stable pointer away
+until you explicitly call one of the following from C or Haskell.
+</Para>
+
+<Para>
+
+<ProgramListing>
+void freeStablePointer( StgStablePtr stablePtrToToss )
+freeStablePtr :: StablePtr a -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+As with the use of <Literal>free</Literal> in C programs, GREAT CARE SHOULD BE
+EXERCISED to ensure these functions are called at the right time: too
+early and you get dangling references (and, if you're lucky, an error
+message from the runtime system); too late and you get space leaks.
+</Para>
+
+<Para>
+And to force evaluation of the argument within <Literal>fooC</Literal>, one would
+call one of the following C functions (according to type of argument).
+</Para>
+
+<Para>
+
+<ProgramListing>
+void     performIO  ( StgStablePtr stableIndex /* StablePtr s (IO ()) */ );
+StgInt   enterInt   ( StgStablePtr stableIndex /* StablePtr s Int */ );
+StgFloat enterFloat ( StgStablePtr stableIndex /* StablePtr s Float */ );
+</ProgramListing>
+
+</Para>
+
+<Para>
+<IndexTerm><Primary>performIO</Primary></IndexTerm>
+<IndexTerm><Primary>enterInt</Primary></IndexTerm>
+<IndexTerm><Primary>enterFloat</Primary></IndexTerm>
+</Para>
+
+<Para>
+Nota Bene: <Literal>&lowbar;ccall&lowbar;GC&lowbar;</Literal><IndexTerm><Primary>&lowbar;ccall&lowbar;GC&lowbar;</Primary></IndexTerm> must be used if any of
+these functions are used.
+</Para>
+
+</Sect2>
+
+<Sect2 id="glasgow-foreignObjs">
+<Title>Foreign objects: pointing outside the Haskell heap
+</Title>
+
+<Para>
+<IndexTerm><Primary>foreign objects (Glasgow extension)</Primary></IndexTerm>
+</Para>
+
+<Para>
+There are two types that <Literal>ghc</Literal> programs can use to reference
+(heap-allocated) objects outside the Haskell world: <Literal>Addr</Literal> and
+<Literal>ForeignObj</Literal>.
+</Para>
+
+<Para>
+If you use <Literal>Addr</Literal>, it is up to you to the programmer to arrange
+allocation and deallocation of the objects.
+</Para>
+
+<Para>
+If you use <Literal>ForeignObj</Literal>, <Literal>ghc</Literal>'s garbage collector will call upon the
+user-supplied <Emphasis>finaliser</Emphasis> function to free the object when the
+Haskell world no longer can access the object.  (An object is
+associated with a finaliser function when the abstract
+Haskell type <Literal>ForeignObj</Literal> is created). The finaliser function is
+expressed in C, and is passed as argument the object:
+</Para>
+
+<Para>
+
+<ProgramListing>
+void foreignFinaliser ( StgForeignObj fo )
+</ProgramListing>
+
+</Para>
+
+<Para>
+when the Haskell world can no longer access the object.  Since
+<Literal>ForeignObj</Literal>s only get released when a garbage collection occurs, we
+provide ways of triggering a garbage collection from within C and from
+within Haskell.
+</Para>
+
+<Para>
+
+<ProgramListing>
+void GarbageCollect()
+performGC :: IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+More information on the programmers' interface to <Literal>ForeignObj</Literal> can be
+found in the library documentation.
+</Para>
+
+</Sect2>
+
+<Sect2 id="glasgow-avoiding-monads">
+<Title>Avoiding monads
+</Title>
+
+<Para>
+<IndexTerm><Primary>C calls to `pure C'</Primary></IndexTerm>
+<IndexTerm><Primary>unsafePerformIO</Primary></IndexTerm>
+</Para>
+
+<Para>
+The <Literal>&lowbar;ccall&lowbar;</Literal> construct is part of the <Literal>IO</Literal> monad because 9 out of 10
+uses will be to call imperative functions with side effects such as
+<Literal>printf</Literal>.  Use of the monad ensures that these operations happen in a
+predictable order in spite of laziness and compiler optimisations.
+</Para>
+
+<Para>
+To avoid having to be in the monad to call a C function, it is
+possible to use <Literal>unsafePerformIO</Literal>, which is available from the
+<Literal>IOExts</Literal> module.  There are three situations where one might like to
+call a C function from outside the IO world:
+</Para>
+
+<Para>
+
+<ItemizedList>
+<ListItem>
+
+<Para>
+Calling a function with no side-effects:
+
+<ProgramListing>
+atan2d :: Double -&#62; Double -&#62; Double
+atan2d y x = unsafePerformIO (_ccall_ atan2d y x)
+
+sincosd :: Double -&#62; (Double, Double)
+sincosd x = unsafePerformIO $ do
+        da &#60;- newDoubleArray (0, 1)
+        _casm_ ``sincosd( %0, &amp;((double *)%1[0]), &amp;((double *)%1[1]) );'' x da
+        s &#60;- readDoubleArray da 0
+        c &#60;- readDoubleArray da 1
+        return (s, c)
+</ProgramListing>
+
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ Calling a set of functions which have side-effects but which can
+be used in a purely functional manner.
+
+For example, an imperative implementation of a purely functional
+lookup-table might be accessed using the following functions.
+
+
+<ProgramListing>
+empty  :: EFS x
+update :: EFS x -&#62; Int -&#62; x -&#62; EFS x
+lookup :: EFS a -&#62; Int -&#62; a
+
+empty = unsafePerformIO (_ccall_ emptyEFS)
+
+update a i x = unsafePerformIO $
+        makeStablePtr x         &#62;&#62;= \ stable_x -&#62;
+        _ccall_ updateEFS a i stable_x
+
+lookup a i = unsafePerformIO $
+        _ccall_ lookupEFS a i   &#62;&#62;= \ stable_x -&#62;
+        deRefStablePtr stable_x
+</ProgramListing>
+
+
+You will almost always want to use <Literal>ForeignObj</Literal>s with this.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ Calling a side-effecting function even though the results will
+be unpredictable.  For example the <Literal>trace</Literal> function is defined by:
+
+
+<ProgramListing>
+trace :: String -&#62; a -&#62; a
+trace string expr
+  = unsafePerformIO (
+        ((_ccall_ PreTraceHook sTDERR{-msg-}):: IO ())  &#62;&#62;
+        fputs sTDERR string                             &#62;&#62;
+        ((_ccall_ PostTraceHook sTDERR{-msg-}):: IO ()) &#62;&#62;
+        return expr )
+  where
+    sTDERR = (``stderr'' :: Addr)
+</ProgramListing>
+
+
+(This kind of use is not highly recommended&mdash;it is only really
+useful in debugging code.)
+</Para>
+</ListItem>
+
+</ItemizedList>
+
+</Para>
+
+</Sect2>
+
+<Sect2 id="ccall-gotchas">
+<Title>C-calling ``gotchas'' checklist
+</Title>
+
+<Para>
+<IndexTerm><Primary>C call dangers</Primary></IndexTerm>
+<IndexTerm><Primary>CCallable</Primary></IndexTerm>
+<IndexTerm><Primary>CReturnable</Primary></IndexTerm>
+</Para>
+
+<Para>
+And some advice, too.
+</Para>
+
+<Para>
+
+<ItemizedList>
+<ListItem>
+
+<Para>
+ For modules that use <Literal>&lowbar;ccall&lowbar;</Literal>s, etc., compile with
+<Literal>-fvia-C</Literal>.<IndexTerm><Primary>-fvia-C option</Primary></IndexTerm> You don't have to, but you should.
+
+Also, use the <Literal>-&num;include "prototypes.h"</Literal> flag (hack) to inform the C
+compiler of the fully-prototyped types of all the C functions you
+call.  (<XRef LinkEnd="glasgow-foreign-headers"> says more about this&hellip;)
+
+This scheme is the <Emphasis>only</Emphasis> way that you will get <Emphasis>any</Emphasis>
+typechecking of your <Literal>&lowbar;ccall&lowbar;</Literal>s.  (It shouldn't be that way, but&hellip;).
+GHC will pass the flag <Literal>-Wimplicit</Literal> to gcc so that you'll get warnings
+if any <Literal>&lowbar;ccall&lowbar;</Literal>ed functions have no prototypes.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+Try to avoid <Literal>&lowbar;ccall&lowbar;</Literal>s to C&nbsp;functions that take <Literal>float</Literal>
+arguments or return <Literal>float</Literal> results.  Reason: if you do, you will
+become entangled in (ANSI?) C's rules for when arguments/results are
+promoted to <Literal>doubles</Literal>.  It's a nightmare and just not worth it.
+Use <Literal>doubles</Literal> if possible.
+
+If you do use <Literal>floats</Literal>, check and re-check that the right thing is
+happening.  Perhaps compile with <Literal>-keep-hc-file-too</Literal> and look at
+the intermediate C (<Literal>.hc</Literal> file).
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ The compiler uses two non-standard type-classes when
+type-checking the arguments and results of <Literal>&lowbar;ccall&lowbar;</Literal>: the arguments
+(respectively result) of <Literal>&lowbar;ccall&lowbar;</Literal> must be instances of the class
+<Literal>CCallable</Literal> (respectively <Literal>CReturnable</Literal>).  Both classes may be
+imported from the module <Literal>CCall</Literal>, but this should only be
+necessary if you want to define a new instance.  (Neither class
+defines any methods&mdash;their only function is to keep the
+type-checker happy.)
+
+The type checker must be able to figure out just which of the
+C-callable/returnable types is being used.  If it can't, you have to
+add type signatures. For example,
+
+
+<ProgramListing>
+f x = _ccall_ foo x
+</ProgramListing>
+
+
+is not good enough, because the compiler can't work out what type <Literal>x</Literal>
+is, nor what type the <Literal>&lowbar;ccall&lowbar;</Literal> returns.  You have to write, say:
+
+
+<ProgramListing>
+f :: Int -&#62; IO Double
+f x = _ccall_ foo x
+</ProgramListing>
+
+
+This table summarises the standard instances of these classes.
+
+<InformalTable>
+<TGroup Cols="4">
+<ColSpec Align="Left" Colsep="0">
+<ColSpec Align="Left" Colsep="0">
+<ColSpec Align="Left" Colsep="0">
+<ColSpec Align="Left" Colsep="0">
+<TBody>
+<Row>
+<Entry><Emphasis>Type</Emphasis> </Entry>
+<Entry><Emphasis>CCallable</Emphasis></Entry>
+<Entry><Emphasis>CReturnable</Emphasis> </Entry>
+<Entry><Emphasis>Which is probably&hellip;</Emphasis> </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>Char</Literal> </Entry>
+<Entry> Yes </Entry>
+<Entry> Yes </Entry>
+<Entry> <Literal>unsigned char</Literal> </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>Int</Literal> </Entry>
+<Entry> Yes </Entry>
+<Entry> Yes </Entry>
+<Entry> <Literal>long int</Literal> </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>Word</Literal> </Entry>
+<Entry> Yes </Entry>
+<Entry> Yes </Entry>
+<Entry> <Literal>unsigned long int</Literal> </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>Addr</Literal> </Entry>
+<Entry> Yes </Entry>
+<Entry> Yes </Entry>
+<Entry> <Literal>void *</Literal> </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>Float</Literal> </Entry>
+<Entry> Yes </Entry>
+<Entry> Yes </Entry>
+<Entry> <Literal>float</Literal> </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>Double</Literal> </Entry>
+<Entry> Yes </Entry>
+<Entry> Yes </Entry>
+<Entry> <Literal>double</Literal> </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>()</Literal> </Entry>
+<Entry> No </Entry>
+<Entry> Yes </Entry>
+<Entry> <Literal>void</Literal> </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>[Char]</Literal> </Entry>
+<Entry> Yes </Entry>
+<Entry> No </Entry>
+<Entry> <Literal>char *</Literal> (null-terminated) </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>Array</Literal> </Entry>
+<Entry> Yes </Entry>
+<Entry> No </Entry>
+<Entry> <Literal>unsigned long *</Literal> </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>ByteArray</Literal> </Entry>
+<Entry> Yes </Entry>
+<Entry> No </Entry>
+<Entry> <Literal>unsigned long *</Literal> </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>MutableArray</Literal> </Entry>
+<Entry> Yes </Entry>
+<Entry> No </Entry>
+<Entry> <Literal>unsigned long *</Literal> </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>MutableByteArray</Literal> </Entry>
+<Entry> Yes </Entry>
+<Entry> No </Entry>
+<Entry> <Literal>unsigned long *</Literal> </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>State</Literal> </Entry>
+<Entry> Yes </Entry>
+<Entry> Yes </Entry>
+<Entry> nothing!</Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>StablePtr</Literal> </Entry>
+<Entry> Yes </Entry>
+<Entry> Yes </Entry>
+<Entry> <Literal>unsigned long *</Literal> </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>ForeignObjs</Literal> </Entry>
+<Entry> Yes </Entry>
+<Entry> Yes </Entry>
+<Entry> see later </Entry>
+</Row>
+
+</TBody>
+
+</TGroup>
+</InformalTable>
+
+Actually, the <Literal>Word</Literal> type is defined as being the same size as a
+pointer on the target architecture, which is <Emphasis>probably</Emphasis>
+<Literal>unsigned long int</Literal>.
+
+The brave and careful programmer can add their own instances of these
+classes for the following types:
+
+
+<ItemizedList>
+<ListItem>
+
+<Para>
+A <Emphasis>boxed-primitive</Emphasis> type may be made an instance of both
+<Literal>CCallable</Literal> and <Literal>CReturnable</Literal>.
+
+A boxed primitive type is any data type with a
+single unary constructor with a single primitive argument.  For
+example, the following are all boxed primitive types:
+
+
+<ProgramListing>
+Int
+Double
+data XDisplay = XDisplay Addr#
+data EFS a = EFS# ForeignObj#
+</ProgramListing>
+
+
+
+<ProgramListing>
+instance CCallable   (EFS a)
+instance CReturnable (EFS a)
+</ProgramListing>
+
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ Any datatype with a single nullary constructor may be made an
+instance of <Literal>CReturnable</Literal>.  For example:
+
+
+<ProgramListing>
+data MyVoid = MyVoid
+instance CReturnable MyVoid
+</ProgramListing>
+
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ As at version 2.09, <Literal>String</Literal> (i.e., <Literal>[Char]</Literal>) is still
+not a <Literal>CReturnable</Literal> type.
+
+Also, the now-builtin type <Literal>PackedString</Literal> is neither
+<Literal>CCallable</Literal> nor <Literal>CReturnable</Literal>.  (But there are functions in
+the PackedString interface to let you get at the necessary bits&hellip;)
+</Para>
+</ListItem>
+
+</ItemizedList>
+
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ The code-generator will complain if you attempt to use <Literal>&percnt;r</Literal> in
+a <Literal>&lowbar;casm&lowbar;</Literal> whose result type is <Literal>IO ()</Literal>; or if you don't use <Literal>&percnt;r</Literal>
+<Emphasis>precisely</Emphasis> once for any other result type.  These messages are
+supposed to be helpful and catch bugs&mdash;please tell us if they wreck
+your life.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ If you call out to C code which may trigger the Haskell garbage
+collector or create new threads (examples of this later&hellip;), then you
+must use the <Literal>&lowbar;ccall&lowbar;GC&lowbar;</Literal><IndexTerm><Primary>&lowbar;ccall&lowbar;GC&lowbar; primitive</Primary></IndexTerm> or
+<Literal>&lowbar;casm&lowbar;GC&lowbar;</Literal><IndexTerm><Primary>&lowbar;casm&lowbar;GC&lowbar; primitive</Primary></IndexTerm> variant of C-calls.  (This
+does not work with the native code generator - use <Literal>\fvia-C</Literal>.) This
+stuff is hairy with a capital H!
+</Para>
+</ListItem>
+
+</ItemizedList>
+
+</Para>
+
+</Sect2>
+
+</Sect1>
+
+<Sect1 id="multi-param-type-classes">
+<Title>Multi-parameter type classes
+</Title>
+
+<Para>
+This section documents GHC's implementation of multi-paramter type
+classes.  There's lots of background in the paper <ULink
+URL="http://www.dcs.gla.ac.uk/~simonpj/multi.ps.gz"
+>Type classes: exploring the design space</ULink
+> (Simon Peyton
+Jones, Mark Jones, Erik Meijer).
+</Para>
+
+<Para>
+I'd like to thank people who reported shorcomings in the GHC 3.02
+implementation.  Our default decisions were all conservative ones, and
+the experience of these heroic pioneers has given useful concrete
+examples to support several generalisations.  (These appear below as
+design choices not implemented in 3.02.)
+</Para>
+
+<Para>
+I've discussed these notes with Mark Jones, and I believe that Hugs
+will migrate towards the same design choices as I outline here.
+Thanks to him, and to many others who have offered very useful
+feedback.
+</Para>
+
+<Sect2>
+<Title>Types</Title>
+
+<Para>
+There are the following restrictions on the form of a qualified
+type:
+</Para>
+
+<Para>
+
+<ProgramListing>
+  forall tv1..tvn (c1, ...,cn) =&#62; type
+</ProgramListing>
+
+</Para>
+
+<Para>
+(Here, I write the "foralls" explicitly, although the Haskell source
+language omits them; in Haskell 1.4, all the free type variables of an
+explicit source-language type signature are universally quantified,
+except for the class type variables in a class declaration.  However,
+in GHC, you can give the foralls if you want.  See <XRef LinkEnd="universal-quantification">).
+</Para>
+
+<Para>
+
+<OrderedList>
+<ListItem>
+
+<Para>
+ <Emphasis>Each universally quantified type variable
+<Literal>tvi</Literal> must be mentioned (i.e. appear free) in <Literal>type</Literal></Emphasis>.
+
+The reason for this is that a value with a type that does not obey
+this restriction could not be used without introducing
+ambiguity. Here, for example, is an illegal type:
+
+
+<ProgramListing>
+  forall a. Eq a =&#62; Int
+</ProgramListing>
+
+
+When a value with this type was used, the constraint <Literal>Eq tv</Literal>
+would be introduced where <Literal>tv</Literal> is a fresh type variable, and
+(in the dictionary-translation implementation) the value would be
+applied to a dictionary for <Literal>Eq tv</Literal>.  The difficulty is that we
+can never know which instance of <Literal>Eq</Literal> to use because we never
+get any more information about <Literal>tv</Literal>.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ <Emphasis>Every constraint <Literal>ci</Literal> must mention at least one of the
+universally quantified type variables <Literal>tvi</Literal></Emphasis>.
+
+For example, this type is OK because <Literal>C a b</Literal> mentions the
+universally quantified type variable <Literal>b</Literal>:
+
+
+<ProgramListing>
+  forall a. C a b =&#62; burble
+</ProgramListing>
+
+
+The next type is illegal because the constraint <Literal>Eq b</Literal> does not
+mention <Literal>a</Literal>:
+
+
+<ProgramListing>
+  forall a. Eq b =&#62; burble
+</ProgramListing>
+
+
+The reason for this restriction is milder than the other one.  The
+excluded types are never useful or necessary (because the offending
+context doesn't need to be witnessed at this point; it can be floated
+out).  Furthermore, floating them out increases sharing. Lastly,
+excluding them is a conservative choice; it leaves a patch of
+territory free in case we need it later.
+
+</Para>
+</ListItem>
+
+</OrderedList>
+
+</Para>
+
+<Para>
+These restrictions apply to all types, whether declared in a type signature
+or inferred.
+</Para>
+
+<Para>
+Unlike Haskell 1.4, constraints in types do <Emphasis>not</Emphasis> have to be of
+the form <Emphasis>(class type-variables)</Emphasis>.  Thus, these type signatures
+are perfectly OK
+</Para>
+
+<Para>
+
+<ProgramListing>
+  f :: Eq (m a) =&#62; [m a] -&#62; [m a]
+  g :: Eq [a] =&#62; ...
+</ProgramListing>
+
+</Para>
+
+<Para>
+This choice recovers principal types, a property that Haskell 1.4 does not have.
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>Class declarations</Title>
+
+<Para>
+
+<OrderedList>
+<ListItem>
+
+<Para>
+ <Emphasis>Multi-parameter type classes are permitted</Emphasis>. For example:
+
+
+<ProgramListing>
+  class Collection c a where
+    union :: c a -&#62; c a -&#62; c a
+    ...etc.
+</ProgramListing>
+
+
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ <Emphasis>The class hierarchy must be acyclic</Emphasis>.  However, the definition
+of "acyclic" involves only the superclass relationships.  For example,
+this is OK:
+
+
+<ProgramListing>
+  class C a where {
+    op :: D b =&#62; a -&#62; b -&#62; b
+  }
+
+  class C a =&#62; D a where { ... }
+</ProgramListing>
+
+
+Here, <Literal>C</Literal> is a superclass of <Literal>D</Literal>, but it's OK for a
+class operation <Literal>op</Literal> of <Literal>C</Literal> to mention <Literal>D</Literal>.  (It
+would not be OK for <Literal>D</Literal> to be a superclass of <Literal>C</Literal>.)
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ <Emphasis>There are no restrictions on the context in a class declaration
+(which introduces superclasses), except that the class hierarchy must
+be acyclic</Emphasis>.  So these class declarations are OK:
+
+
+<ProgramListing>
+  class Functor (m k) =&#62; FiniteMap m k where
+    ...
+
+  class (Monad m, Monad (t m)) =&#62; Transform t m where
+    lift :: m a -&#62; (t m) a
+</ProgramListing>
+
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ <Emphasis>In the signature of a class operation, every constraint
+must mention at least one type variable that is not a class type
+variable</Emphasis>.
+
+Thus:
+
+
+<ProgramListing>
+  class Collection c a where
+    mapC :: Collection c b =&#62; (a-&#62;b) -&#62; c a -&#62; c b
+</ProgramListing>
+
+
+is OK because the constraint <Literal>(Collection a b)</Literal> mentions
+<Literal>b</Literal>, even though it also mentions the class variable
+<Literal>a</Literal>.  On the other hand:
+
+
+<ProgramListing>
+  class C a where
+    op :: Eq a =&#62; (a,b) -&#62; (a,b)
+</ProgramListing>
+
+
+is not OK because the constraint <Literal>(Eq a)</Literal> mentions on the class
+type variable <Literal>a</Literal>, but not <Literal>b</Literal>.  However, any such
+example is easily fixed by moving the offending context up to the
+superclass context:
+
+
+<ProgramListing>
+  class Eq a =&#62; C a where
+    op ::(a,b) -&#62; (a,b)
+</ProgramListing>
+
+
+A yet more relaxed rule would allow the context of a class-op signature
+to mention only class type variables.  However, that conflicts with
+Rule 1(b) for types above.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ <Emphasis>The type of each class operation must mention <Emphasis>all</Emphasis> of
+the class type variables</Emphasis>.  For example:
+
+
+<ProgramListing>
+  class Coll s a where
+    empty  :: s
+    insert :: s -&#62; a -&#62; s
+</ProgramListing>
+
+
+is not OK, because the type of <Literal>empty</Literal> doesn't mention
+<Literal>a</Literal>.  This rule is a consequence of Rule 1(a), above, for
+types, and has the same motivation.
+
+Sometimes, offending class declarations exhibit misunderstandings.  For
+example, <Literal>Coll</Literal> might be rewritten
+
+
+<ProgramListing>
+  class Coll s a where
+    empty  :: s a
+    insert :: s a -&#62; a -&#62; s a
+</ProgramListing>
+
+
+which makes the connection between the type of a collection of
+<Literal>a</Literal>'s (namely <Literal>(s a)</Literal>) and the element type <Literal>a</Literal>.
+Occasionally this really doesn't work, in which case you can split the
+class like this:
+
+
+<ProgramListing>
+  class CollE s where
+    empty  :: s
+
+  class CollE s =&#62; Coll s a where
+    insert :: s -&#62; a -&#62; s
+</ProgramListing>
+
+
+</Para>
+</ListItem>
+
+</OrderedList>
+
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>Instance declarations</Title>
+
+<Para>
+
+<OrderedList>
+<ListItem>
+
+<Para>
+ <Emphasis>Instance declarations may not overlap</Emphasis>.  The two instance
+declarations
+
+
+<ProgramListing>
+  instance context1 =&#62; C type1 where ...
+  instance context2 =&#62; C type2 where ...
+</ProgramListing>
+
+
+"overlap" if <Literal>type1</Literal> and <Literal>type2</Literal> unify
+
+However, if you give the command line option
+<Literal>-fallow-overlapping-instances</Literal><IndexTerm><Primary>-fallow-overlapping-instances
+option</Primary></IndexTerm> then two overlapping instance declarations are permitted
+iff
+
+
+<ItemizedList>
+<ListItem>
+
+<Para>
+ EITHER <Literal>type1</Literal> and <Literal>type2</Literal> do not unify
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ OR <Literal>type2</Literal> is a substitution instance of <Literal>type1</Literal>
+(but not identical to <Literal>type1</Literal>)
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ OR vice versa
+</Para>
+</ListItem>
+
+</ItemizedList>
+
+
+Notice that these rules
+
+
+<ItemizedList>
+<ListItem>
+
+<Para>
+ make it clear which instance decl to use
+(pick the most specific one that matches)
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ do not mention the contexts <Literal>context1</Literal>, <Literal>context2</Literal>
+Reason: you can pick which instance decl
+"matches" based on the type.
+</Para>
+</ListItem>
+
+</ItemizedList>
+
+
+Regrettably, GHC doesn't guarantee to detect overlapping instance
+declarations if they appear in different modules.  GHC can "see" the
+instance declarations in the transitive closure of all the modules
+imported by the one being compiled, so it can "see" all instance decls
+when it is compiling <Literal>Main</Literal>.  However, it currently chooses not
+to look at ones that can't possibly be of use in the module currently
+being compiled, in the interests of efficiency.  (Perhaps we should
+change that decision, at least for <Literal>Main</Literal>.)
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ <Emphasis>There are no restrictions on the type in an instance
+<Emphasis>head</Emphasis>, except that at least one must not be a type variable</Emphasis>.
+The instance "head" is the bit after the "=&#62;" in an instance decl. For
+example, these are OK:
+
+
+<ProgramListing>
+  instance C Int a where ...
+
+  instance D (Int, Int) where ...
+
+  instance E [[a]] where ...
+</ProgramListing>
+
+
+Note that instance heads <Emphasis>may</Emphasis> contain repeated type variables.
+For example, this is OK:
+
+
+<ProgramListing>
+  instance Stateful (ST s) (MutVar s) where ...
+</ProgramListing>
+
+
+The "at least one not a type variable" restriction is to ensure that
+context reduction terminates: each reduction step removes one type
+constructor.  For example, the following would make the type checker
+loop if it wasn't excluded:
+
+
+<ProgramListing>
+  instance C a =&#62; C a where ...
+</ProgramListing>
+
+
+There are two situations in which the rule is a bit of a pain. First,
+if one allows overlapping instance declarations then it's quite
+convenient to have a "default instance" declaration that applies if
+something more specific does not:
+
+
+<ProgramListing>
+  instance C a where
+    op = ... -- Default
+</ProgramListing>
+
+
+Second, sometimes you might want to use the following to get the
+effect of a "class synonym":
+
+
+<ProgramListing>
+  class (C1 a, C2 a, C3 a) =&#62; C a where { }
+
+  instance (C1 a, C2 a, C3 a) =&#62; C a where { }
+</ProgramListing>
+
+
+This allows you to write shorter signatures:
+
+
+<ProgramListing>
+  f :: C a =&#62; ...
+</ProgramListing>
+
+
+instead of
+
+
+<ProgramListing>
+  f :: (C1 a, C2 a, C3 a) =&#62; ...
+</ProgramListing>
+
+
+I'm on the lookout for a simple rule that preserves decidability while
+allowing these idioms.  The experimental flag
+<Literal>-fallow-undecidable-instances</Literal><IndexTerm><Primary>-fallow-undecidable-instances
+option</Primary></IndexTerm> lifts this restriction, allowing all the types in an
+instance head to be type variables.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ <Emphasis>Unlike Haskell 1.4, instance heads may use type
+synonyms</Emphasis>.  As always, using a type synonym is just shorthand for
+writing the RHS of the type synonym definition.  For example:
+
+
+<ProgramListing>
+  type Point = (Int,Int)
+  instance C Point   where ...
+  instance C [Point] where ...
+</ProgramListing>
+
+
+is legal.  However, if you added
+
+
+<ProgramListing>
+  instance C (Int,Int) where ...
+</ProgramListing>
+
+
+as well, then the compiler will complain about the overlapping
+(actually, identical) instance declarations.  As always, type synonyms
+must be fully applied.  You cannot, for example, write:
+
+
+<ProgramListing>
+  type P a = [[a]]
+  instance Monad P where ...
+</ProgramListing>
+
+
+This design decision is independent of all the others, and easily
+reversed, but it makes sense to me.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+<Emphasis>The types in an instance-declaration <Emphasis>context</Emphasis> must all
+be type variables</Emphasis>. Thus
+
+
+<ProgramListing>
+instance C a b =&#62; Eq (a,b) where ...
+</ProgramListing>
+
+
+is OK, but
+
+
+<ProgramListing>
+instance C Int b =&#62; Foo b where ...
+</ProgramListing>
+
+
+is not OK.  Again, the intent here is to make sure that context
+reduction terminates.
+
+Voluminous correspondence on the Haskell mailing list has convinced me
+that it's worth experimenting with a more liberal rule.  If you use
+the flag <Literal>-fallow-undecidable-instances</Literal> you can use arbitrary
+types in an instance context.  Termination is ensured by having a
+fixed-depth recursion stack.  If you exceed the stack depth you get a
+sort of backtrace, and the opportunity to increase the stack depth
+with <Literal>-fcontext-stack</Literal><Emphasis>N</Emphasis>.
+
+</Para>
+</ListItem>
+
+</OrderedList>
+
+</Para>
+
+</Sect2>
+
+</Sect1>
+
+<Sect1 id="universal-quantification">
+<Title>Explicit universal quantification
+</Title>
+
+<Para>
+GHC now allows you to write explicitly quantified types.  GHC's
+syntax for this now agrees with Hugs's, namely:
+</Para>
+
+<Para>
+
+<ProgramListing>
+        forall a b. (Ord a, Eq  b) =&#62; a -&#62; b -&#62; a
+</ProgramListing>
+
+</Para>
+
+<Para>
+The context is, of course, optional.  You can't use <Literal>forall</Literal> as
+a type variable any more!
+</Para>
+
+<Para>
+Haskell type signatures are implicitly quantified.  The <Literal>forall</Literal>
+allows us to say exactly what this means.  For example:
+</Para>
+
+<Para>
+
+<ProgramListing>
+        g :: b -&#62; b
+</ProgramListing>
+
+</Para>
+
+<Para>
+means this:
+</Para>
+
+<Para>
+
+<ProgramListing>
+        g :: forall b. (b -&#62; b)
+</ProgramListing>
+
+</Para>
+
+<Para>
+The two are treated identically.
+</Para>
+
+<Sect2 id="univ">
+<Title>Universally-quantified data type fields
+</Title>
+
+<Para>
+In a <Literal>data</Literal> or <Literal>newtype</Literal> declaration one can quantify
+the types of the constructor arguments.  Here are several examples:
+</Para>
+
+<Para>
+
+<ProgramListing>
+data T a = T1 (forall b. b -&#62; b -&#62; b) a
+
+data MonadT m = MkMonad { return :: forall a. a -&#62; m a,
+                          bind   :: forall a b. m a -&#62; (a -&#62; m b) -&#62; m b
+                        }
+
+newtype Swizzle = MkSwizzle (Ord a =&#62; [a] -&#62; [a])
+</ProgramListing>
+
+</Para>
+
+<Para>
+The constructors now have so-called <Emphasis>rank 2</Emphasis> polymorphic
+types, in which there is a for-all in the argument types.:
+</Para>
+
+<Para>
+
+<ProgramListing>
+T1 :: forall a. (forall b. b -&#62; b -&#62; b) -&#62; a -&#62; T1 a
+MkMonad :: forall m. (forall a. a -&#62; m a)
+                  -&#62; (forall a b. m a -&#62; (a -&#62; m b) -&#62; m b)
+                  -&#62; MonadT m
+MkSwizzle :: (Ord a =&#62; [a] -&#62; [a]) -&#62; Swizzle
+</ProgramListing>
+
+</Para>
+
+<Para>
+Notice that you don't need to use a <Literal>forall</Literal> if there's an
+explicit context.  For example in the first argument of the
+constructor <Literal>MkSwizzle</Literal>, an implicit "<Literal>forall a.</Literal>" is
+prefixed to the argument type.  The implicit <Literal>forall</Literal>
+quantifies all type variables that are not already in scope, and are
+mentioned in the type quantified over.
+</Para>
+
+<Para>
+As for type signatures, implicit quantification happens for non-overloaded
+types too.  So if you write this:
+
+<ProgramListing>
+  data T a = MkT (Either a b) (b -&#62; b)
+</ProgramListing>
+
+it's just as if you had written this:
+
+<ProgramListing>
+  data T a = MkT (forall b. Either a b) (forall b. b -&#62; b)
+</ProgramListing>
+
+That is, since the type variable <Literal>b</Literal> isn't in scope, it's
+implicitly universally quantified.  (Arguably, it would be better
+to <Emphasis>require</Emphasis> explicit quantification on constructor arguments
+where that is what is wanted.  Feedback welcomed.)
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>Construction </Title>
+
+<Para>
+You construct values of types <Literal>T1, MonadT, Swizzle</Literal> by applying
+the constructor to suitable values, just as usual.  For example,
+</Para>
+
+<Para>
+
+<ProgramListing>
+(T1 (\xy-&#62;x) 3) :: T Int
+
+(MkSwizzle sort)    :: Swizzle
+(MkSwizzle reverse) :: Swizzle
+
+(let r x = Just x
+     b m k = case m of
+                Just y -&#62; k y
+                Nothing -&#62; Nothing
+  in
+  MkMonad r b) :: MonadT Maybe
+</ProgramListing>
+
+</Para>
+
+<Para>
+The type of the argument can, as usual, be more general than the type
+required, as <Literal>(MkSwizzle reverse)</Literal> shows.  (<Literal>reverse</Literal>
+does not need the <Literal>Ord</Literal> constraint.)
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>Pattern matching</Title>
+
+<Para>
+When you use pattern matching, the bound variables may now have
+polymorphic types.  For example:
+</Para>
+
+<Para>
+
+<ProgramListing>
+        f :: T a -&#62; a -&#62; (a, Char)
+        f (T1 f k) x = (f k x, f 'c' 'd')
+
+        g :: (Ord a, Ord b) =&#62; Swizzle -&#62; [a] -&#62; (a -&#62; b) -&#62; [b]
+        g (MkSwizzle s) xs f = s (map f (s xs))
+
+        h :: MonadT m -&#62; [m a] -&#62; m [a]
+        h m [] = return m []
+        h m (x:xs) = bind m x           $ \y -&#62;
+                      bind m (h m xs)   $ \ys -&#62;
+                      return m (y:ys)
+</ProgramListing>
+
+</Para>
+
+<Para>
+In the function <Literal>h</Literal> we use the record selectors <Literal>return</Literal>
+and <Literal>bind</Literal> to extract the polymorphic bind and return functions
+from the <Literal>MonadT</Literal> data structure, rather than using pattern
+matching.
+</Para>
+
+<Para>
+You cannot pattern-match against an argument that is polymorphic.
+For example:
+
+<ProgramListing>
+        newtype TIM s a = TIM (ST s (Maybe a))
+
+        runTIM :: (forall s. TIM s a) -&#62; Maybe a
+        runTIM (TIM m) = runST m
+</ProgramListing>
+
+</Para>
+
+<Para>
+Here the pattern-match fails, because you can't pattern-match against
+an argument of type <Literal>(forall s. TIM s a)</Literal>.  Instead you
+must bind the variable and pattern match in the right hand side:
+
+<ProgramListing>
+        runTIM :: (forall s. TIM s a) -&#62; Maybe a
+        runTIM tm = case tm of { TIM m -&#62; runST m }
+</ProgramListing>
+
+The <Literal>tm</Literal> on the right hand side is (invisibly) instantiated, like
+any polymorphic value at its occurrence site, and now you can pattern-match
+against it.
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>The partial-application restriction</Title>
+
+<Para>
+There is really only one way in which data structures with polymorphic
+components might surprise you: you must not partially apply them.
+For example, this is illegal:
+</Para>
+
+<Para>
+
+<ProgramListing>
+        map MkSwizzle [sort, reverse]
+</ProgramListing>
+
+</Para>
+
+<Para>
+The restriction is this: <Emphasis>every subexpression of the program must
+have a type that has no for-alls, except that in a function
+application (f e1&hellip;en) the partial applications are not subject to
+this rule</Emphasis>.  The restriction makes type inference feasible.
+</Para>
+
+<Para>
+In the illegal example, the sub-expression <Literal>MkSwizzle</Literal> has the
+polymorphic type <Literal>(Ord b =&#62; [b] -&#62; [b]) -&#62; Swizzle</Literal> and is not
+a sub-expression of an enclosing application.  On the other hand, this
+expression is OK:
+</Para>
+
+<Para>
+
+<ProgramListing>
+        map (T1 (\a b -&#62; a)) [1,2,3]
+</ProgramListing>
+
+</Para>
+
+<Para>
+even though it involves a partial application of <Literal>T1</Literal>, because
+the sub-expression <Literal>T1 (\a b -&#62; a)</Literal> has type <Literal>Int -&#62; T
+Int</Literal>.
+</Para>
+
+</Sect2>
+
+<Sect2 id="sigs">
+<Title>Type signatures
+</Title>
+
+<Para>
+Once you have data constructors with universally-quantified fields, or
+constants such as <Literal>runST</Literal> that have rank-2 types, it isn't long
+before you discover that you need more!  Consider:
+</Para>
+
+<Para>
+
+<ProgramListing>
+  mkTs f x y = [T1 f x, T1 f y]
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>mkTs</Literal> is a fuction that constructs some values of type
+<Literal>T</Literal>, using some pieces passed to it.  The trouble is that since
+<Literal>f</Literal> is a function argument, Haskell assumes that it is
+monomorphic, so we'll get a type error when applying <Literal>T1</Literal> to
+it.  This is a rather silly example, but the problem really bites in
+practice.  Lots of people trip over the fact that you can't make
+"wrappers functions" for <Literal>runST</Literal> for exactly the same reason.
+In short, it is impossible to build abstractions around functions with
+rank-2 types.
+</Para>
+
+<Para>
+The solution is fairly clear.  We provide the ability to give a rank-2
+type signature for <Emphasis>ordinary</Emphasis> functions (not only data
+constructors), thus:
+</Para>
+
+<Para>
+
+<ProgramListing>
+  mkTs :: (forall b. b -&#62; b -&#62; b) -&#62; a -&#62; [T a]
+  mkTs f x y = [T1 f x, T1 f y]
+</ProgramListing>
+
+</Para>
+
+<Para>
+This type signature tells the compiler to attribute <Literal>f</Literal> with
+the polymorphic type <Literal>(forall b. b -&#62; b -&#62; b)</Literal> when type
+checking the body of <Literal>mkTs</Literal>, so now the application of
+<Literal>T1</Literal> is fine.
+</Para>
+
+<Para>
+There are two restrictions:
+</Para>
+
+<Para>
+
+<ItemizedList>
+<ListItem>
+
+<Para>
+ You can only define a rank 2 type, specified by the following
+grammar:
+
+
+<ProgramListing>
+   rank2type ::= [forall tyvars .] [context =&#62;] funty
+   funty     ::= ([forall tyvars .] [context =&#62;] ty) -&#62; funty
+               | ty
+   ty        ::= ...current Haskell monotype syntax...
+</ProgramListing>
+
+
+Informally, the universal quantification must all be right at the beginning,
+or at the top level of a function argument.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ There is a restriction on the definition of a function whose
+type signature is a rank-2 type: the polymorphic arguments must be
+matched on the left hand side of the "<Literal>=</Literal>" sign.  You can't
+define <Literal>mkTs</Literal> like this:
+
+
+<ProgramListing>
+  mkTs :: (forall b. b -&#62; b -&#62; b) -&#62; a -&#62; [T a]
+  mkTs = \ f x y -&#62; [T1 f x, T1 f y]
+</ProgramListing>
+
+
+
+The same partial-application rule applies to ordinary functions with
+rank-2 types as applied to data constructors.
+
+</Para>
+</ListItem>
+
+</ItemizedList>
+
+</Para>
+
+</Sect2>
+
+</Sect1>
+
+<Sect1 id="existential-quantification">
+<Title>Existentially quantified data constructors
+</Title>
+
+<Para>
+The idea of using existential quantification in data type declarations
+was suggested by Laufer (I believe, thought doubtless someone will
+correct me), and implemented in Hope+. It's been in Lennart
+Augustsson's <Literal>hbc</Literal> Haskell compiler for several years, and
+proved very useful.  Here's the idea.  Consider the declaration:
+</Para>
+
+<Para>
+
+<ProgramListing>
+  data Foo = forall a. MkFoo a (a -&#62; Bool)
+           | Nil
+</ProgramListing>
+
+</Para>
+
+<Para>
+The data type <Literal>Foo</Literal> has two constructors with types:
+</Para>
+
+<Para>
+
+<ProgramListing>
+  MkFoo :: forall a. a -&#62; (a -&#62; Bool) -&#62; Foo
+  Nil   :: Foo
+</ProgramListing>
+
+</Para>
+
+<Para>
+Notice that the type variable <Literal>a</Literal> in the type of <Literal>MkFoo</Literal>
+does not appear in the data type itself, which is plain <Literal>Foo</Literal>.
+For example, the following expression is fine:
+</Para>
+
+<Para>
+
+<ProgramListing>
+  [MkFoo 3 even, MkFoo 'c' isUpper] :: [Foo]
+</ProgramListing>
+
+</Para>
+
+<Para>
+Here, <Literal>(MkFoo 3 even)</Literal> packages an integer with a function
+<Literal>even</Literal> that maps an integer to <Literal>Bool</Literal>; and <Literal>MkFoo 'c'
+isUpper</Literal> packages a character with a compatible function.  These
+two things are each of type <Literal>Foo</Literal> and can be put in a list.
+</Para>
+
+<Para>
+What can we do with a value of type <Literal>Foo</Literal>?.  In particular,
+what happens when we pattern-match on <Literal>MkFoo</Literal>?
+</Para>
+
+<Para>
+
+<ProgramListing>
+  f (MkFoo val fn) = ???
+</ProgramListing>
+
+</Para>
+
+<Para>
+Since all we know about <Literal>val</Literal> and <Literal>fn</Literal> is that they
+are compatible, the only (useful) thing we can do with them is to
+apply <Literal>fn</Literal> to <Literal>val</Literal> to get a boolean.  For example:
+</Para>
+
+<Para>
+
+<ProgramListing>
+  f :: Foo -&#62; Bool
+  f (MkFoo val fn) = fn val
+</ProgramListing>
+
+</Para>
+
+<Para>
+What this allows us to do is to package heterogenous values
+together with a bunch of functions that manipulate them, and then treat
+that collection of packages in a uniform manner.  You can express
+quite a bit of object-oriented-like programming this way.
+</Para>
+
+<Sect2 id="existential">
+<Title>Why existential?
+</Title>
+
+<Para>
+What has this to do with <Emphasis>existential</Emphasis> quantification?
+Simply that <Literal>MkFoo</Literal> has the (nearly) isomorphic type
+</Para>
+
+<Para>
+
+<ProgramListing>
+  MkFoo :: (exists a . (a, a -&#62; Bool)) -&#62; Foo
+</ProgramListing>
+
+</Para>
+
+<Para>
+But Haskell programmers can safely think of the ordinary
+<Emphasis>universally</Emphasis> quantified type given above, thereby avoiding
+adding a new existential quantification construct.
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>Type classes</Title>
+
+<Para>
+An easy extension (implemented in <Literal>hbc</Literal>) is to allow
+arbitrary contexts before the constructor.  For example:
+</Para>
+
+<Para>
+
+<ProgramListing>
+  data Baz = forall a. Eq a =&#62; Baz1 a a
+           | forall b. Show b =&#62; Baz2 b (b -&#62; b)
+</ProgramListing>
+
+</Para>
+
+<Para>
+The two constructors have the types you'd expect:
+</Para>
+
+<Para>
+
+<ProgramListing>
+  Baz1 :: forall a. Eq a =&#62; a -&#62; a -&#62; Baz
+  Baz2 :: forall b. Show b =&#62; b -&#62; (b -&#62; b) -&#62; Baz
+</ProgramListing>
+
+</Para>
+
+<Para>
+But when pattern matching on <Literal>Baz1</Literal> the matched values can be compared
+for equality, and when pattern matching on <Literal>Baz2</Literal> the first matched
+value can be converted to a string (as well as applying the function to it).
+So this program is legal:
+</Para>
+
+<Para>
+
+<ProgramListing>
+  f :: Baz -&#62; String
+  f (Baz1 p q) | p == q    = "Yes"
+               | otherwise = "No"
+  f (Baz1 v fn)            = show (fn v)
+</ProgramListing>
+
+</Para>
+
+<Para>
+Operationally, in a dictionary-passing implementation, the
+constructors <Literal>Baz1</Literal> and <Literal>Baz2</Literal> must store the
+dictionaries for <Literal>Eq</Literal> and <Literal>Show</Literal> respectively, and
+extract it on pattern matching.
+</Para>
+
+<Para>
+Notice the way that the syntax fits smoothly with that used for
+universal quantification earlier.
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>Restrictions</Title>
+
+<Para>
+There are several restrictions on the ways in which existentially-quantified
+constructors can be use.
+</Para>
+
+<Para>
+
+<ItemizedList>
+<ListItem>
+
+<Para>
+ When pattern matching, each pattern match introduces a new,
+distinct, type for each existential type variable.  These types cannot
+be unified with any other type, nor can they escape from the scope of
+the pattern match.  For example, these fragments are incorrect:
+
+
+<ProgramListing>
+  f1 (MkFoo a f) = a
+</ProgramListing>
+
+
+Here, the type bound by <Literal>MkFoo</Literal> "escapes", because <Literal>a</Literal>
+is the result of <Literal>f1</Literal>.  One way to see why this is wrong is to
+ask what type <Literal>f1</Literal> has:
+
+
+<ProgramListing>
+  f1 :: Foo -&#62; a             -- Weird!
+</ProgramListing>
+
+
+What is this "<Literal>a</Literal>" in the result type? Clearly we don't mean
+this:
+
+
+<ProgramListing>
+  f1 :: forall a. Foo -&#62; a   -- Wrong!
+</ProgramListing>
+
+
+The original program is just plain wrong.  Here's another sort of error
+
+
+<ProgramListing>
+  f2 (Baz1 a b) (Baz1 p q) = a==q
+</ProgramListing>
+
+
+It's ok to say <Literal>a==b</Literal> or <Literal>p==q</Literal>, but
+<Literal>a==q</Literal> is wrong because it equates the two distinct types arising
+from the two <Literal>Baz1</Literal> constructors.
+
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+You can't pattern-match on an existentially quantified
+constructor in a <Literal>let</Literal> or <Literal>where</Literal> group of
+bindings. So this is illegal:
+
+
+<ProgramListing>
+  f3 x = a==b where { Baz1 a b = x }
+</ProgramListing>
+
+
+You can only pattern-match
+on an existentially-quantified constructor in a <Literal>case</Literal> expression or
+in the patterns of a function definition.
+
+The reason for this restriction is really an implementation one.
+Type-checking binding groups is already a nightmare without
+existentials complicating the picture.  Also an existential pattern
+binding at the top level of a module doesn't make sense, because it's
+not clear how to prevent the existentially-quantified type "escaping".
+So for now, there's a simple-to-state restriction.  We'll see how
+annoying it is.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+You can't use existential quantification for <Literal>newtype</Literal>
+declarations.  So this is illegal:
+
+
+<ProgramListing>
+  newtype T = forall a. Ord a =&#62; MkT a
+</ProgramListing>
+
+
+Reason: a value of type <Literal>T</Literal> must be represented as a pair
+of a dictionary for <Literal>Ord t</Literal> and a value of type <Literal>t</Literal>.
+That contradicts the idea that <Literal>newtype</Literal> should have no
+concrete representation.  You can get just the same efficiency and effect
+by using <Literal>data</Literal> instead of <Literal>newtype</Literal>.  If there is no
+overloading involved, then there is more of a case for allowing
+an existentially-quantified <Literal>newtype</Literal>, because the <Literal>data</Literal>
+because the <Literal>data</Literal> version does carry an implementation cost,
+but single-field existentially quantified constructors aren't much
+use.  So the simple restriction (no existential stuff on <Literal>newtype</Literal>)
+stands, unless there are convincing reasons to change it.
+
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ You can't use <Literal>deriving</Literal> to define instances of a
+data type with existentially quantified data constructors.
+
+Reason: in most cases it would not make sense. For example:&num;
+
+<ProgramListing>
+  data T = forall a. MkT [a] deriving( Eq )
+</ProgramListing>
+
+To derive <Literal>Eq</Literal> in the standard way we would need to have equality
+between the single component of two <Literal>MkT</Literal> constructors:
+
+<ProgramListing>
+  instance Eq T where
+    (MkT a) == (MkT b) = ???
+</ProgramListing>
+
+But <Literal>a</Literal> and <Literal>b</Literal> have distinct types, and so can't be compared.
+It's just about possible to imagine examples in which the derived instance
+would make sense, but it seems altogether simpler simply to prohibit such
+declarations.  Define your own instances!
+</Para>
+</ListItem>
+
+</ItemizedList>
+
+</Para>
+
+</Sect2>
+
+</Sect1>
+
+<Sect1 id="sec-assertions">
+<Title>Assertions
+<IndexTerm><Primary>Assertions</Primary></IndexTerm>
+</Title>
+
+<Para>
+If you want to make use of assertions in your standard Haskell code, you
+could define a function like the following:
+</Para>
+
+<Para>
+
+<ProgramListing>
+assert :: Bool -&#62; a -&#62; a
+assert False x = error "assertion failed!"
+assert _     x = x
+</ProgramListing>
+
+</Para>
+
+<Para>
+which works, but gives you back a less than useful error message --
+an assertion failed, but which and where?
+</Para>
+
+<Para>
+One way out is to define an extended <Literal>assert</Literal> function which also
+takes a descriptive string to include in the error message and
+perhaps combine this with the use of a pre-processor which inserts
+the source location where <Literal>assert</Literal> was used.
+</Para>
+
+<Para>
+Ghc offers a helping hand here, doing all of this for you. For every
+use of <Literal>assert</Literal> in the user's source:
+</Para>
+
+<Para>
+
+<ProgramListing>
+kelvinToC :: Double -&#62; Double
+kelvinToC k = assert (k &amp;gt;= 0.0) (k+273.15)
+</ProgramListing>
+
+</Para>
+
+<Para>
+Ghc will rewrite this to also include the source location where the
+assertion was made,
+</Para>
+
+<Para>
+
+<ProgramListing>
+assert pred val ==&#62; assertError "Main.hs|15" pred val
+</ProgramListing>
+
+</Para>
+
+<Para>
+The rewrite is only performed by the compiler when it spots
+applications of <Literal>Exception.assert</Literal>, so you can still define and
+use your own versions of <Literal>assert</Literal>, should you so wish. If not,
+import <Literal>Exception</Literal> to make use <Literal>assert</Literal> in your code.
+</Para>
+
+<Para>
+To have the compiler ignore uses of assert, use the compiler option
+<Literal>-fignore-asserts</Literal>. <IndexTerm><Primary>-fignore-asserts option</Primary></IndexTerm> That is,
+expressions of the form <Literal>assert pred e</Literal> will be rewritten to <Literal>e</Literal>.
+</Para>
+
+<Para>
+Assertion failures can be caught, see the documentation for the
+Hugs/GHC Exception library for information of how.
+</Para>
+
+</Sect1>
+
+<Sect1 id="scoped-type-variables">
+<Title>Scoped Type Variables
+</Title>
+
+<Para>
+A <Emphasis>pattern type signature</Emphasis> can introduce a <Emphasis>scoped type
+variable</Emphasis>.  For example
+</Para>
+
+<Para>
+
+<ProgramListing>
+f (xs::[a]) = ys ++ ys
+           where
+              ys :: [a]
+              ys = reverse xs
+</ProgramListing>
+
+</Para>
+
+<Para>
+The pattern <Literal>(xs::[a])</Literal> includes a type signature for <Literal>xs</Literal>.
+This brings the type variable <Literal>a</Literal> into scope; it scopes over
+all the patterns and right hand sides for this equation for <Literal>f</Literal>.
+In particular, it is in scope at the type signature for <Literal>y</Literal>.
+</Para>
+
+<Para>
+At ordinary type signatures, such as that for <Literal>ys</Literal>, any type variables
+mentioned in the type signature <Emphasis>that are not in scope</Emphasis> are
+implicitly universally quantified.  (If there are no type variables in
+scope, all type variables mentioned in the signature are universally
+quantified, which is just as in Haskell 98.)  In this case, since <Literal>a</Literal>
+is in scope, it is not universally quantified, so the type of <Literal>ys</Literal> is
+the same as that of <Literal>xs</Literal>.  In Haskell 98 it is not possible to declare
+a type for <Literal>ys</Literal>; a major benefit of scoped type variables is that
+it becomes possible to do so.
+</Para>
+
+<Para>
+Scoped type variables are implemented in both GHC and Hugs.  Where the
+implementations differ from the specification below, those differences
+are noted.
+</Para>
+
+<Para>
+So much for the basic idea.  Here are the details.
+</Para>
+
+<Sect2>
+<Title>Scope and implicit quantification</Title>
+
+<Para>
+
+<ItemizedList>
+<ListItem>
+
+<Para>
+ All the type variables mentioned in the patterns for a single
+function definition equation, that are not already in scope,
+are brought into scope by the patterns.  We describe this set as
+the <Emphasis>type variables bound by the equation</Emphasis>.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ The type variables thus brought into scope may be mentioned
+in ordinary type signatures or pattern type signatures anywhere within
+their scope.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ In ordinary type signatures, any type variable mentioned in the
+signature that is in scope is <Emphasis>not</Emphasis> universally quantified.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ Ordinary type signatures do not bring any new type variables
+into scope (except in the type signature itself!). So this is illegal:
+
+
+<ProgramListing>
+  f :: a -&#62; a
+  f x = x::a
+</ProgramListing>
+
+
+It's illegal because <Literal>a</Literal> is not in scope in the body of <Literal>f</Literal>,
+so the ordinary signature <Literal>x::a</Literal> is equivalent to <Literal>x::forall a.a</Literal>;
+and that is an incorrect typing.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ There is no implicit universal quantification on pattern type
+signatures, nor may one write an explicit <Literal>forall</Literal> type in a pattern
+type signature.  The pattern type signature is a monotype.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+
+The type variables in the head of a <Literal>class</Literal> or <Literal>instance</Literal> declaration
+scope over the methods defined in the <Literal>where</Literal> part.  For example:
+
+
+<ProgramListing>
+  class C a where
+    op :: [a] -&#62; a
+
+    op xs = let ys::[a]
+                ys = reverse xs
+            in
+            head ys
+</ProgramListing>
+
+
+(Not implemented in Hugs yet, Dec 98).
+</Para>
+</ListItem>
+
+</ItemizedList>
+
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>Polymorphism</Title>
+
+<Para>
+
+<ItemizedList>
+<ListItem>
+
+<Para>
+ Pattern type signatures are completely orthogonal to ordinary, separate
+type signatures.  The two can be used independently or together.  There is
+no scoping associated with the names of the type variables in a separate type signature.
+
+
+<ProgramListing>
+   f :: [a] -&#62; [a]
+   f (xs::[b]) = reverse xs
+</ProgramListing>
+
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ The function must be polymorphic in the type variables
+bound by all its equations.  Operationally, the type variables bound
+by one equation must not:
+
+
+<ItemizedList>
+<ListItem>
+
+<Para>
+ Be unified with a type (such as <Literal>Int</Literal>, or <Literal>[a]</Literal>).
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ Be unified with a type variable free in the environment.
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ Be unified with each other.  (They may unify with the type variables
+bound by another equation for the same function, of course.)
+</Para>
+</ListItem>
+
+</ItemizedList>
+
+
+For example, the following all fail to type check:
+
+
+<ProgramListing>
+  f (x::a) (y::b) = [x,y]       -- a unifies with b
+
+  g (x::a) = x + 1::Int         -- a unifies with Int
+
+  h x = let k (y::a) = [x,y]    -- a is free in the
+        in k x                  -- environment
+
+  k (x::a) True    = ...        -- a unifies with Int
+  k (x::Int) False = ...
+
+  w :: [b] -&#62; [b]
+  w (x::a) = x                  -- a unifies with [b]
+</ProgramListing>
+
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ The pattern-bound type variable may, however, be constrained
+by the context of the principal type, thus:
+
+
+<ProgramListing>
+  f (x::a) (y::a) = x+y*2
+</ProgramListing>
+
+
+gets the inferred type: <Literal>forall a. Num a =&gt; a -&gt; a -&gt; a</Literal>.
+</Para>
+</ListItem>
+
+</ItemizedList>
+
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>Result type signatures</Title>
+
+<Para>
+
+<ItemizedList>
+<ListItem>
+
+<Para>
+ The result type of a function can be given a signature,
+thus:
+
+
+<ProgramListing>
+  f (x::a) :: [a] = [x,x,x]
+</ProgramListing>
+
+
+The final <Literal>":: [a]"</Literal> after all the patterns gives a signature to the
+result type.  Sometimes this is the only way of naming the type variable
+you want:
+
+
+<ProgramListing>
+  f :: Int -&#62; [a] -&#62; [a]
+  f n :: ([a] -&#62; [a]) = let g (x::a, y::a) = (y,x)
+                        in \xs -&#62; map g (reverse xs `zip` xs)
+</ProgramListing>
+
+
+</Para>
+</ListItem>
+
+</ItemizedList>
+
+</Para>
+
+<Para>
+Result type signatures are not yet implemented in Hugs.
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>Pattern signatures on other constructs</Title>
+
+<Para>
+
+<ItemizedList>
+<ListItem>
+
+<Para>
+ A pattern type signature can be on an arbitrary sub-pattern, not
+just on a variable:
+
+
+<ProgramListing>
+  f ((x,y)::(a,b)) = (y,x) :: (b,a)
+</ProgramListing>
+
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ Pattern type signatures, including the result part, can be used
+in lambda abstractions:
+
+
+<ProgramListing>
+  (\ (x::a, y) :: a -&#62; x)
+</ProgramListing>
+
+
+Type variables bound by these patterns must be polymorphic in
+the sense defined above.
+For example:
+
+
+<ProgramListing>
+  f1 (x::c) = f1 x      -- ok
+  f2 = \(x::c) -&#62; f2 x  -- not ok
+</ProgramListing>
+
+
+Here, <Literal>f1</Literal> is OK, but <Literal>f2</Literal> is not, because <Literal>c</Literal> gets unified
+with a type variable free in the environment, in this
+case, the type of <Literal>f2</Literal>, which is in the environment when
+the lambda abstraction is checked.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ Pattern type signatures, including the result part, can be used
+in <Literal>case</Literal> expressions:
+
+
+<ProgramListing>
+  case e of { (x::a, y) :: a -&#62; x }
+</ProgramListing>
+
+
+The pattern-bound type variables must, as usual,
+be polymorphic in the following sense: each case alternative,
+considered as a lambda abstraction, must be polymorphic.
+Thus this is OK:
+
+
+<ProgramListing>
+  case (True,False) of { (x::a, y) -&#62; x }
+</ProgramListing>
+
+
+Even though the context is that of a pair of booleans,
+the alternative itself is polymorphic.  Of course, it is
+also OK to say:
+
+
+<ProgramListing>
+  case (True,False) of { (x::Bool, y) -&#62; x }
+</ProgramListing>
+
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+To avoid ambiguity, the type after the ``<Literal>::</Literal>'' in a result
+pattern signature on a lambda or <Literal>case</Literal> must be atomic (i.e. a single
+token or a parenthesised type of some sort).  To see why,
+consider how one would parse this:
+
+
+<ProgramListing>
+  \ x :: a -&#62; b -&#62; x
+</ProgramListing>
+
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ Pattern type signatures that bind new type variables
+may not be used in pattern bindings at all.
+So this is illegal:
+
+
+<ProgramListing>
+  f x = let (y, z::a) = x in ...
+</ProgramListing>
+
+
+But these are OK, because they do not bind fresh type variables:
+
+
+<ProgramListing>
+  f1 x            = let (y, z::Int) = x in ...
+  f2 (x::(Int,a)) = let (y, z::a)   = x in ...
+</ProgramListing>
+
+
+However a single variable is considered a degenerate function binding,
+rather than a degerate pattern binding, so this is permitted, even
+though it binds a type variable:
+
+
+<ProgramListing>
+  f :: (b-&#62;b) = \(x::b) -&#62; x
+</ProgramListing>
+
+
+</Para>
+</ListItem>
+
+</ItemizedList>
+
+Such degnerate function bindings do not fall under the monomorphism
+restriction.  Thus:
+</Para>
+
+<Para>
+
+<ProgramListing>
+  g :: a -&#62; a -&#62; Bool = \x y. x==y
+</ProgramListing>
+
+</Para>
+
+<Para>
+Here <Literal>g</Literal> has type <Literal>forall a. Eq a =&gt; a -&gt; a -&gt; Bool</Literal>, just as if
+<Literal>g</Literal> had a separate type signature.  Lacking a type signature, <Literal>g</Literal>
+would get a monomorphic type.
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>Existentials</Title>
+
+<Para>
+
+<ItemizedList>
+<ListItem>
+
+<Para>
+ Pattern type signatures can bind existential type variables.
+For example:
+
+
+<ProgramListing>
+  data T = forall a. MkT [a]
+
+  f :: T -&#62; T
+  f (MkT [t::a]) = MkT t3
+                 where
+                   t3::[a] = [t,t,t]
+</ProgramListing>
+
+
+</Para>
+</ListItem>
+
+</ItemizedList>
+
+</Para>
+
+</Sect2>
+
+</Sect1>
+
+<Sect1 id="pragmas">
+<Title>Pragmas
+</Title>
+
+<Para>
+GHC supports several pragmas, or instructions to the compiler placed
+in the source code.  Pragmas don't affect the meaning of the program,
+but they might affect the efficiency of the generated code.
+</Para>
+
+<Sect2 id="inline-pragma">
+<Title>INLINE pragma
+
+<IndexTerm><Primary>INLINE pragma</Primary></IndexTerm>
+<IndexTerm><Primary>pragma, INLINE</Primary></IndexTerm></Title>
+
+<Para>
+GHC (with <Literal>-O</Literal>, as always) tries to inline (or ``unfold'')
+functions/values that are ``small enough,'' thus avoiding the call
+overhead and possibly exposing other more-wonderful optimisations.
+</Para>
+
+<Para>
+You will probably see these unfoldings (in Core syntax) in your
+interface files.
+</Para>
+
+<Para>
+Normally, if GHC decides a function is ``too expensive'' to inline, it
+will not do so, nor will it export that unfolding for other modules to
+use.
+</Para>
+
+<Para>
+The sledgehammer you can bring to bear is the
+<Literal>INLINE</Literal><IndexTerm><Primary>INLINE pragma</Primary></IndexTerm> pragma, used thusly:
+
+<ProgramListing>
+key_function :: Int -&#62; String -&#62; (Bool, Double)
+
+#ifdef __GLASGOW_HASKELL__
+{-# INLINE key_function #-}
+#endif
+</ProgramListing>
+
+(You don't need to do the C pre-processor carry-on unless you're going
+to stick the code through HBC&mdash;it doesn't like <Literal>INLINE</Literal> pragmas.)
+</Para>
+
+<Para>
+The major effect of an <Literal>INLINE</Literal> pragma is to declare a function's
+``cost'' to be very low.  The normal unfolding machinery will then be
+very keen to inline it.
+</Para>
+
+<Para>
+An <Literal>INLINE</Literal> pragma for a function can be put anywhere its type
+signature could be put.
+</Para>
+
+<Para>
+<Literal>INLINE</Literal> pragmas are a particularly good idea for the
+<Literal>then</Literal>/<Literal>return</Literal> (or <Literal>bind</Literal>/<Literal>unit</Literal>) functions in a monad.
+For example, in GHC's own <Literal>UniqueSupply</Literal> monad code, we have:
+
+<ProgramListing>
+#ifdef __GLASGOW_HASKELL__
+{-# INLINE thenUs #-}
+{-# INLINE returnUs #-}
+#endif
+</ProgramListing>
+
+</Para>
+
+</Sect2>
+
+<Sect2 id="noinline-pragma">
+<Title>NOINLINE pragma
+</Title>
+
+<Para>
+<IndexTerm><Primary>NOINLINE pragma</Primary></IndexTerm>
+<IndexTerm><Primary>pragma, NOINLINE</Primary></IndexTerm>
+</Para>
+
+<Para>
+The <Literal>NOINLINE</Literal> pragma does exactly what you'd expect: it stops the
+named function from being inlined by the compiler.  You shouldn't ever
+need to do this, unless you're very cautious about code size.
+</Para>
+
+</Sect2>
+
+<Sect2 id="specialize-pragma">
+<Title>SPECIALIZE pragma
+</Title>
+
+<Para>
+<IndexTerm><Primary>SPECIALIZE pragma</Primary></IndexTerm>
+<IndexTerm><Primary>pragma, SPECIALIZE</Primary></IndexTerm>
+<IndexTerm><Primary>overloading, death to</Primary></IndexTerm>
+</Para>
+
+<Para>
+(UK spelling also accepted.)  For key overloaded functions, you can
+create extra versions (NB: more code space) specialised to particular
+types.  Thus, if you have an overloaded function:
+</Para>
+
+<Para>
+
+<ProgramListing>
+hammeredLookup :: Ord key =&#62; [(key, value)] -&#62; key -&#62; value
+</ProgramListing>
+
+</Para>
+
+<Para>
+If it is heavily used on lists with <Literal>Widget</Literal> keys, you could
+specialise it as follows:
+
+<ProgramListing>
+{-# SPECIALIZE hammeredLookup :: [(Widget, value)] -&#62; Widget -&#62; value #-}
+</ProgramListing>
+
+</Para>
+
+<Para>
+To get very fancy, you can also specify a named function to use for
+the specialised value, by adding <Literal>= blah</Literal>, as in:
+
+<ProgramListing>
+{-# SPECIALIZE hammeredLookup :: ...as before... = blah #-}
+</ProgramListing>
+
+It's <Emphasis>Your Responsibility</Emphasis> to make sure that <Literal>blah</Literal> really
+behaves as a specialised version of <Literal>hammeredLookup</Literal>!!!
+</Para>
+
+<Para>
+NOTE: the <Literal>=blah</Literal> feature isn't implemented in GHC 4.xx.
+</Para>
+
+<Para>
+An example in which the <Literal>= blah</Literal> form will Win Big:
+
+<ProgramListing>
+toDouble :: Real a =&#62; a -&#62; Double
+toDouble = fromRational . toRational
+
+{-# SPECIALIZE toDouble :: Int -&#62; Double = i2d #-}
+i2d (I# i) = D# (int2Double# i) -- uses Glasgow prim-op directly
+</ProgramListing>
+
+The <Literal>i2d</Literal> function is virtually one machine instruction; the
+default conversion&mdash;via an intermediate <Literal>Rational</Literal>&mdash;is obscenely
+expensive by comparison.
+</Para>
+
+<Para>
+By using the US spelling, your <Literal>SPECIALIZE</Literal> pragma will work with
+HBC, too.  Note that HBC doesn't support the <Literal>= blah</Literal> form.
+</Para>
+
+<Para>
+A <Literal>SPECIALIZE</Literal> pragma for a function can be put anywhere its type
+signature could be put.
+</Para>
+
+</Sect2>
+
+<Sect2 id="specialize-instance-pragma">
+<Title>SPECIALIZE instance pragma
+</Title>
+
+<Para>
+<IndexTerm><Primary>SPECIALIZE pragma</Primary></IndexTerm>
+<IndexTerm><Primary>overloading, death to</Primary></IndexTerm>
+Same idea, except for instance declarations.  For example:
+
+<ProgramListing>
+instance (Eq a) =&#62; Eq (Foo a) where { ... usual stuff ... }
+
+{-# SPECIALIZE instance Eq (Foo [(Int, Bar)] #-}
+</ProgramListing>
+
+Compatible with HBC, by the way.
+</Para>
+
+</Sect2>
+
+<Sect2 id="line-pragma">
+<Title>LINE pragma
+</Title>
+
+<Para>
+<IndexTerm><Primary>LINE pragma</Primary></IndexTerm>
+<IndexTerm><Primary>pragma, LINE</Primary></IndexTerm>
+</Para>
+
+<Para>
+This pragma is similar to C's <Literal>&num;line</Literal> pragma, and is mainly for use in
+automatically generated Haskell code.  It lets you specify the line
+number and filename of the original code; for example
+</Para>
+
+<Para>
+
+<ProgramListing>
+{-# LINE 42 "Foo.vhs" #-}
+</ProgramListing>
+
+</Para>
+
+<Para>
+if you'd generated the current file from something called <Literal>Foo.vhs</Literal>
+and this line corresponds to line 42 in the original.  GHC will adjust
+its error messages to refer to the line/file named in the <Literal>LINE</Literal>
+pragma.
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>RULES pragma</Title>
+
+<Para>
+The RULES pragma lets you specify rewrite rules.  It is described in
+<XRef LinkEnd="rewrite-rules">.
+</Para>
+
+</Sect2>
+
+</Sect1>
+
+<Sect1 id="rewrite-rules">
+<Title>Rewrite rules
+
+<IndexTerm><Primary>RULES pagma</Primary></IndexTerm>
+<IndexTerm><Primary>pragma, RULES</Primary></IndexTerm>
+<IndexTerm><Primary>rewrite rules</Primary></IndexTerm></Title>
+
+<Para>
+The programmer can specify rewrite rules as part of the source program
+(in a pragma).  GHC applies these rewrite rules wherever it can.
+</Para>
+
+<Para>
+Here is an example:
+
+<ProgramListing>
+  {-# RULES
+        "map/map"       forall f g xs. map f (map g xs) = map (f.g) xs
+  #-}
+</ProgramListing>
+
+</Para>
+
+<Sect2>
+<Title>Syntax</Title>
+
+<Para>
+From a syntactic point of view:
+
+<ItemizedList>
+<ListItem>
+
+<Para>
+ Each rule has a name, enclosed in double quotes.  The name itself has
+no significance at all.  It is only used when reporting how many times the rule fired.
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ There may be zero or more rules in a <Literal>RULES</Literal> pragma.
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ Layout applies in a <Literal>RULES</Literal> pragma.  Currently no new indentation level
+is set, so you must lay out your rules starting in the same column as the
+enclosing definitions.
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ Each variable mentioned in a rule must either be in scope (e.g. <Literal>map</Literal>),
+or bound by the <Literal>forall</Literal> (e.g. <Literal>f</Literal>, <Literal>g</Literal>, <Literal>xs</Literal>).  The variables bound by
+the <Literal>forall</Literal> are called the <Emphasis>pattern</Emphasis> variables.  They are separated
+by spaces, just like in a type <Literal>forall</Literal>.
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ A pattern variable may optionally have a type signature.
+If the type of the pattern variable is polymorphic, it <Emphasis>must</Emphasis> have a type signature.
+For example, here is the <Literal>foldr/build</Literal> rule:
+
+<ProgramListing>
+  "fold/build"  forall k z (g::forall b. (a-&#62;b-&#62;b) -&#62; b -&#62; b) .
+                foldr k z (build g) = g k z
+</ProgramListing>
+
+Since <Literal>g</Literal> has a polymorphic type, it must have a type signature.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ The left hand side of a rule must consist of a top-level variable applied
+to arbitrary expressions.  For example, this is <Emphasis>not</Emphasis> OK:
+
+<ProgramListing>
+  "wrong1"   forall e1 e2.  case True of { True -&#62; e1; False -&#62; e2 } = e1
+  "wrong2"   forall f.      f True = True
+</ProgramListing>
+
+In <Literal>"wrong1"</Literal>, the LHS is not an application; in <Literal>"wrong1"</Literal>, the LHS has a pattern variable
+in the head.
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ A rule does not need to be in the same module as (any of) the
+variables it mentions, though of course they need to be in scope.
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ Rules are automatically exported from a module, just as instance declarations are.
+</Para>
+</ListItem>
+
+</ItemizedList>
+
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>Semantics</Title>
+
+<Para>
+From a semantic point of view:
+
+<ItemizedList>
+<ListItem>
+
+<Para>
+ Rules are only applied if you use the <Literal>-O</Literal> flag.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ Rules are regarded as left-to-right rewrite rules.
+When GHC finds an expression that is a substitution instance of the LHS
+of a rule, it replaces the expression by the (appropriately-substituted) RHS.
+By "a substitution instance" we mean that the LHS can be made equal to the
+expression by substituting for the pattern variables.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ The LHS and RHS of a rule are typechecked, and must have the
+same type.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ GHC makes absolutely no attempt to verify that the LHS and RHS
+of a rule have the same meaning.  That is undecideable in general, and
+infeasible in most interesting cases.  The responsibility is entirely the programmer's!
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ GHC makes no attempt to make sure that the rules are confluent or
+terminating.  For example:
+
+<ProgramListing>
+  "loop"        forall x,y.  f x y = f y x
+</ProgramListing>
+
+This rule will cause the compiler to go into an infinite loop.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ If more than one rule matches a call, GHC will choose one arbitrarily to apply.
+
+</Para>
+</ListItem>
+<ListItem>
+<Para>
+ GHC currently uses a very simple, syntactic, matching algorithm
+for matching a rule LHS with an expression.  It seeks a substitution
+which makes the LHS and expression syntactically equal modulo alpha
+conversion.  The pattern (rule), but not the expression, is eta-expanded if
+necessary.  (Eta-expanding the epression can lead to laziness bugs.)
+But not beta conversion (that's called higher-order matching).
+</Para>
+
+<Para>
+Matching is carried out on GHC's intermediate language, which includes
+type abstractions and applications.  So a rule only matches if the
+types match too.  See <XRef LinkEnd="rule-spec"> below.
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ GHC keeps trying to apply the rules as it optimises the program.
+For example, consider:
+
+<ProgramListing>
+  let s = map f
+      t = map g
+  in
+  s (t xs)
+</ProgramListing>
+
+The expression <Literal>s (t xs)</Literal> does not match the rule <Literal>"map/map"</Literal>, but GHC
+will substitute for <Literal>s</Literal> and <Literal>t</Literal>, giving an expression which does match.
+If <Literal>s</Literal> or <Literal>t</Literal> was (a) used more than once, and (b) large or a redex, then it would
+not be substituted, and the rule would not fire.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ In the earlier phases of compilation, GHC inlines <Emphasis>nothing
+that appears on the LHS of a rule</Emphasis>, because once you have substituted
+for something you can't match against it (given the simple minded
+matching).  So if you write the rule
+
+<ProgramListing>
+        "map/map"       forall f,g.  map f . map g = map (f.g)
+</ProgramListing>
+
+this <Emphasis>won't</Emphasis> match the expression <Literal>map f (map g xs)</Literal>.
+It will only match something written with explicit use of ".".
+Well, not quite.  It <Emphasis>will</Emphasis> match the expression
+
+<ProgramListing>
+        wibble f g xs
+</ProgramListing>
+
+where <Literal>wibble</Literal> is defined:
+
+<ProgramListing>
+        wibble f g = map f . map g
+</ProgramListing>
+
+because <Literal>wibble</Literal> will be inlined (it's small).
+
+Later on in compilation, GHC starts inlining even things on the
+LHS of rules, but still leaves the rules enabled.  This inlining
+policy is controlled by the per-simplification-pass flag <Literal>-finline-phase</Literal>n.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ All rules are implicitly exported from the module, and are therefore
+in force in any module that imports the module that defined the rule, directly
+or indirectly.  (That is, if A imports B, which imports C, then C's rules are
+in force when compiling A.)  The situation is very similar to that for instance
+declarations.
+</Para>
+</ListItem>
+
+</ItemizedList>
+
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>List fusion</Title>
+
+<Para>
+The RULES mechanism is used to implement fusion (deforestation) of common list functions.
+If a "good consumer" consumes an intermediate list constructed by a "good producer", the
+intermediate list should be eliminated entirely.
+</Para>
+
+<Para>
+The following are good producers:
+
+<ItemizedList>
+<ListItem>
+
+<Para>
+ List comprehensions
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ Enumerations of <Literal>Int</Literal> and <Literal>Char</Literal> (e.g. <Literal>['a'..'z']</Literal>).
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ Explicit lists (e.g. <Literal>[True, False]</Literal>)
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ The cons constructor (e.g <Literal>3:4:[]</Literal>)
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ <Literal>++</Literal>
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ <Literal>map</Literal>
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ <Literal>filter</Literal>
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ <Literal>iterate</Literal>, <Literal>repeat</Literal>
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ <Literal>zip</Literal>, <Literal>zipWith</Literal>
+</Para>
+</ListItem>
+
+</ItemizedList>
+
+</Para>
+
+<Para>
+The following are good consumers:
+
+<ItemizedList>
+<ListItem>
+
+<Para>
+ List comprehensions
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ <Literal>array</Literal> (on its second argument)
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ <Literal>length</Literal>
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ <Literal>++</Literal> (on its first argument)
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ <Literal>map</Literal>
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ <Literal>filter</Literal>
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ <Literal>concat</Literal>
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ <Literal>unzip</Literal>, <Literal>unzip2</Literal>, <Literal>unzip3</Literal>, <Literal>unzip4</Literal>
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ <Literal>zip</Literal>, <Literal>zipWith</Literal> (but on one argument only; if both are good producers, <Literal>zip</Literal>
+will fuse with one but not the other)
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ <Literal>partition</Literal>
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ <Literal>head</Literal>
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ <Literal>and</Literal>, <Literal>or</Literal>, <Literal>any</Literal>, <Literal>all</Literal>
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ <Literal>sequence&lowbar;</Literal>
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ <Literal>msum</Literal>
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ <Literal>sortBy</Literal>
+</Para>
+</ListItem>
+
+</ItemizedList>
+
+</Para>
+
+<Para>
+So, for example, the following should generate no intermediate lists:
+
+<ProgramListing>
+        array (1,10) [(i,i*i) | i &#60;- map (+ 1) [0..9]]
+</ProgramListing>
+
+</Para>
+
+<Para>
+This list could readily be extended; if there are Prelude functions that you use
+a lot which are not included, please tell us.
+</Para>
+
+<Para>
+If you want to write your own good consumers or producers, look at the
+Prelude definitions of the above functions to see how to do so.
+</Para>
+
+</Sect2>
+
+<Sect2 id="rule-spec">
+<Title>Specialisation
+</Title>
+
+<Para>
+Rewrite rules can be used to get the same effect as a feature
+present in earlier version of GHC:
+
+<ProgramListing>
+  {-# SPECIALIZE fromIntegral :: Int8 -&#62; Int16 = int8ToInt16 #-}
+</ProgramListing>
+
+This told GHC to use <Literal>int8ToInt16</Literal> instead of <Literal>fromIntegral</Literal> whenever
+the latter was called with type <Literal>Int8 -&gt; Int16</Literal>.  That is, rather than
+specialising the original definition of <Literal>fromIntegral</Literal> the programmer is
+promising that it is safe to use <Literal>int8ToInt16</Literal> instead.
+</Para>
+
+<Para>
+This feature is no longer in GHC.  But rewrite rules let you do the
+same thing:
+
+<ProgramListing>
+  {-# RULES
+    "fromIntegral/Int8/Int16" fromIntegral = int8ToInt16
+  #-}
+</ProgramListing>
+
+This slightly odd-looking rule instructs GHC to replace <Literal>fromIntegral</Literal>
+by <Literal>int8ToInt16</Literal> <Emphasis>whenever the types match</Emphasis>.  Speaking more operationally,
+GHC adds the type and dictionary applications to get the typed rule
+
+<ProgramListing>
+        forall (d1::Integral Int8) (d2::Num Int16) .
+                fromIntegral Int8 Int16 d1 d2 = int8ToInt16
+</ProgramListing>
+
+What is more,
+this rule does not need to be in the same file as fromIntegral,
+unlike the <Literal>SPECIALISE</Literal> pragmas which currently do (so that they
+have an original definition available to specialise).
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>Controlling what's going on</Title>
+
+<Para>
+
+<ItemizedList>
+<ListItem>
+
+<Para>
+ Use <Literal>-ddump-rules</Literal> to see what transformation rules GHC is using.
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ Use <Literal>-ddump-simpl-stats</Literal> to see what rules are being fired.
+If you add <Literal>-dppr-debug</Literal> you get a more detailed listing.
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ The defintion of (say) <Literal>build</Literal> in <Literal>PrelBase.lhs</Literal> looks llike this:
+
+<ProgramListing>
+        build   :: forall a. (forall b. (a -&#62; b -&#62; b) -&#62; b -&#62; b) -&#62; [a]
+        {-# INLINE build #-}
+        build g = g (:) []
+</ProgramListing>
+
+Notice the <Literal>INLINE</Literal>!  That prevents <Literal>(:)</Literal> from being inlined when compiling
+<Literal>PrelBase</Literal>, so that an importing module will ``see'' the <Literal>(:)</Literal>, and can
+match it on the LHS of a rule.  <Literal>INLINE</Literal> prevents any inlining happening
+in the RHS of the <Literal>INLINE</Literal> thing.  I regret the delicacy of this.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ In <Literal>ghc/lib/std/PrelBase.lhs</Literal> look at the rules for <Literal>map</Literal> to
+see how to write rules that will do fusion and yet give an efficient
+program even if fusion doesn't happen.  More rules in <Literal>PrelList.lhs</Literal>.
+</Para>
+</ListItem>
+
+</ItemizedList>
+
+</Para>
+
+</Sect2>
+
+</Sect1>
diff --git a/ghc/docs/users_guide/gone_wrong.sgml b/ghc/docs/users_guide/gone_wrong.sgml
new file mode 100644 (file)
index 0000000..db00204
--- /dev/null
@@ -0,0 +1,462 @@
+<Chapter id="wrong">
+<Title>What to do when something goes wrong
+</Title>
+
+<Para>
+<IndexTerm><Primary>problems</Primary></IndexTerm>
+</Para>
+
+<Para>
+If you still have a problem after consulting this section, then you
+may have found a <Emphasis>bug</Emphasis>&mdash;please report it!  See <XRef LinkEnd="bug-reports"> for a
+list of things we'd like to know about your bug.  If in doubt, send a
+report&mdash;we love mail from irate users :-!
+</Para>
+
+<Para>
+(<XRef LinkEnd="vs-Haskell-defn">, which describes Glasgow
+Haskell's shortcomings vs.&nbsp;the Haskell language definition, may also
+be of interest.)
+</Para>
+
+<Sect1 id="wrong-compiler">
+<Title>When the compiler ``does the wrong thing''
+</Title>
+
+<Para>
+<IndexTerm><Primary>compiler problems</Primary></IndexTerm>
+<IndexTerm><Primary>problems with the compiler</Primary></IndexTerm>
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term>``Help! The compiler crashed (or `panic'd)!''</Term>
+<ListItem>
+<Para>
+These events are <Emphasis>always</Emphasis> bugs in the GHC system&mdash;please report them.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>``The compiler ran out of heap (or stack) when compiling itself!''</Term>
+<ListItem>
+<Para>
+It happens.  We try to supply reasonable <Literal>-H&lt;n&gt;</Literal> flags for
+<Literal>ghc/compiler/</Literal> and <Literal>ghc/lib/</Literal>, but GHC's memory consumption
+can vary by platform (e.g., on a 64-bit machine).
+</Para>
+
+<Para>
+Just say <Literal>make all EXTRA&lowbar;HC&lowbar;OPTS=-H&lt;a reasonable number&gt;</Literal> and see
+how you get along.
+</Para>
+
+<Para>
+Note that this is less likely to happen if you are compiling with GHC
+4.00 or later, since the introduction of the dynamically expanding
+heap.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>``The compiler died with a pattern-matching error.''</Term>
+<ListItem>
+<Para>
+This is a bug just as surely as a ``panic.'' Please report it.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>``This is a terrible error message.''</Term>
+<ListItem>
+<Para>
+If you think that GHC could have produced a better error message,
+please report it as a bug.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>``What about these `trace' messages from GHC?''</Term>
+<ListItem>
+<Para>
+Almost surely not a problem.  About some specific cases&hellip;
+<VariableList>
+
+<VarListEntry>
+<Term>Simplifier still going after N iterations:</Term>
+<ListItem>
+<Para>
+Sad, but harmless.  You can change the number with a
+<Literal>-fmax-simplifier-iterations&lt;N&gt;</Literal><IndexTerm><Primary>-fmax-simplifier-iterations&lt;N&gt; option</Primary></IndexTerm> option (no space);
+and you can see what actions took place in each iteration by
+turning on the <Literal>-fshow-simplifier-progress</Literal>
+<IndexTerm><Primary>-fshow-simplifier-progress option</Primary></IndexTerm> option.
+</Para>
+
+<Para>
+If the simplifier definitely seems to be ``looping,'' please report
+it.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>``What about this warning from the C compiler?''</Term>
+<ListItem>
+<Para>
+For example: ``&hellip;warning: `Foo' declared `static' but never defined.''
+Unsightly, but shouldn't be a problem.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>Sensitivity to <Literal>.hi</Literal> interface files:</Term>
+<ListItem>
+<Para>
+GHC is very sensitive about interface files.  For example, if it picks
+up a non-standard <Literal>Prelude.hi</Literal> file, pretty terrible things will
+happen.  If you turn on
+<Literal>-fno-implicit-prelude</Literal><IndexTerm><Primary>-fno-implicit-prelude option</Primary></IndexTerm>, the
+compiler will almost surely die, unless you know what you are doing.
+</Para>
+
+<Para>
+Furthermore, as sketched below, you may have big problems
+running programs compiled using unstable interfaces.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>``I think GHC is producing incorrect code'':</Term>
+<ListItem>
+<Para>
+Unlikely :-) A useful be-more-paranoid option to give to GHC is
+<Literal>-dcore-lint</Literal><IndexTerm><Primary>-dcore-lint option</Primary></IndexTerm>; this causes a ``lint''
+pass to check for errors (notably type errors) after each Core-to-Core
+transformation pass.  We run with <Literal>-dcore-lint</Literal> on all the time; it
+costs about 5&percnt; in compile time.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>``Why did I get a link error?''</Term>
+<ListItem>
+<Para>
+If the linker complains about not finding <Literal>&lowbar;&lt;something&gt;&lowbar;fast</Literal>, then
+something is inconsistent: you probably didn't compile modules in the
+proper dependency order.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>``What's a `consistency error'?''</Term>
+<ListItem>
+<Para>
+(These are reported just after linking your program.)
+</Para>
+
+<Para>
+You tried to link incompatible object files, e.g., normal ones
+(registerised, Appel garbage-collector) with profiling ones (two-space
+collector).  Or those compiled by a previous version of GHC
+with an incompatible newer version.
+</Para>
+
+<Para>
+If you run <Literal>nm -o *.o &verbar; egrep 't (cc&verbar;hsc)\.'</Literal> (or, on
+unregisterised files: <Literal>what *.o</Literal>), you'll see all the consistency
+tags/strings in your object files.  They must all be the same!
+(ToDo: tell you what they mean&hellip;)
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>``Is this line number right?''</Term>
+<ListItem>
+<Para>
+On this score, GHC usually does pretty well, especially
+if you ``allow'' it to be off by one or two.  In the case of an
+instance or class declaration, the line number
+may only point you to the declaration, not to a specific method.
+</Para>
+
+<Para>
+Please report line-number errors that you find particularly unhelpful.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+</Sect1>
+
+<Sect1 id="wrong-compilee">
+<Title>When your program ``does the wrong thing''
+</Title>
+
+<Para>
+<IndexTerm><Primary>problems running your program</Primary></IndexTerm>
+</Para>
+
+<Para>
+(For advice about overly slow or memory-hungry Haskell programs,
+please see <XRef LinkEnd="sooner-faster-quicker">).
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term>``Help! My program crashed!''</Term>
+<ListItem>
+<Para>
+(e.g., a `segmentation fault' or `core dumped')
+<IndexTerm><Primary>segmentation fault</Primary></IndexTerm>
+</Para>
+
+<Para>
+If your program has no <Literal>&lowbar;ccall&lowbar;</Literal>s/<Literal>&lowbar;casm&lowbar;</Literal>s in it, then a crash is
+always a BUG in the GHC system, except in one case: If your program is
+made of several modules, each module must have been compiled after any
+modules on which it depends (unless you use <Literal>.hi-boot</Literal> files, in which
+case these <Emphasis>must</Emphasis> be correct with respect to the module source). 
+</Para>
+
+<Para>
+For example, if an interface is lying about the type of an imported
+value then GHC may well generate duff code for the importing module.
+<Emphasis>This applies to pragmas inside interfaces too!</Emphasis>  If the pragma is
+lying (e.g., about the ``arity'' of a value), then duff code may result.
+Furthermore, arities may change even if types do not.
+</Para>
+
+<Para>
+In short, if you compile a module and its interface changes, then all
+the modules that import that interface <Emphasis>must</Emphasis> be re-compiled.
+</Para>
+
+<Para>
+A useful option to alert you when interfaces change is
+<Literal>-hi-diffs</Literal><IndexTerm><Primary>-hi-diffs option</Primary></IndexTerm>.  It will run <Literal>diff</Literal> on the
+changed interface file, before and after, when applicable.
+</Para>
+
+<Para>
+If you are using <Literal>make</Literal>, a useful tool to make sure that every module
+<Emphasis>is</Emphasis> up-to-date with respect to its imported interfaces is
+<Literal>mkdependHS</Literal> (which comes with GHC).  Please see <XRef LinkEnd="mkdependHS">.
+</Para>
+
+<Para>
+If you are down to your last-compile-before-a-bug-report, we would
+recommend that you add a <Literal>-dcore-lint</Literal> option (for extra checking) to your compilation options.
+</Para>
+
+<Para>
+So, before you report a bug because of a core dump, you should probably:
+
+<Screen>
+% rm *.o        # scrub your object files
+% make my_prog  # re-make your program; use -hi-diffs to highlight changes;
+                # as mentioned above, use -dcore-lint to be more paranoid
+% ./my_prog ... # retry...
+</Screen>
+
+</Para>
+
+<Para>
+Of course, if you have <Literal>&lowbar;ccall&lowbar;</Literal>s/<Literal>&lowbar;casm&lowbar;</Literal>s in your program then all
+bets are off, because you can trash the heap, the stack, or whatever.
+</Para>
+
+<Para>
+If you are interested in hard-core debugging of a crashing
+GHC-compiled program, please see <XRef LinkEnd="hard-core-debug">.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>``My program entered an `absent' argument.''</Term>
+<ListItem>
+<Para>
+This is definitely caused by a bug in GHC. Please report it.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>``What's with this `arithmetic (or `floating') exception' ''?</Term>
+<ListItem>
+<Para>
+<Literal>Int</Literal>, <Literal>Float</Literal>, and <Literal>Double</Literal> arithmetic is <Emphasis>unchecked</Emphasis>.
+Overflows, underflows and loss of precision are either silent or
+reported as an exception by the operating system (depending on the
+architecture).  Divide-by-zero <Emphasis>may</Emphasis> cause an untrapped
+exception (please report it if it does).
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+</Sect1>
+
+<Sect1 id="bug-reports">
+<Title>How to report a bug in the GHC system
+</Title>
+
+<Para>
+<IndexTerm><Primary>bug reports</Primary></IndexTerm>
+</Para>
+
+<Para>
+Glasgow Haskell is a changing system so there are sure to be bugs in
+it.  Please report them to <ULink
+URL="mailto:glasgow-haskell-bugs@haskell.org"
+>glasgow-haskell-bugs@haskell.org</ULink
+>!  (However, please
+check the earlier part of this section to be sure it's not a known
+not-really-a problem.)
+</Para>
+
+<Para>
+The name of the bug-reporting game is: facts, facts, facts.
+Don't omit them because ``Oh, they won't be interested&hellip;''
+</Para>
+
+<Para>
+
+<OrderedList>
+<ListItem>
+
+<Para>
+ What kind of machine are you running on, and exactly what
+version of the operating system are you using? (<Literal>uname -a</Literal> or <Literal>cat
+/etc/motd</Literal> will show the desired information.)
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ What version of GCC are you using? <Literal>gcc -v</Literal> will tell you.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ Run the sequence of compiles/runs that caused the offending
+behaviour, capturing all the input/output in a ``script'' (a UNIX
+command) or in an Emacs shell window.  We'd prefer to see the whole
+thing.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ Be sure any Haskell compilations are run with a <Literal>-v</Literal> (verbose)
+flag, so we can see exactly what was run, what versions of things you
+have, etc.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ What is the program behaviour that is wrong, in your opinion?
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ If practical, please send enough source files/interface files
+for us to duplicate the problem.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ If you are a Hero and track down the problem in the
+compilation-system sources, please send us patches relative to a known
+released version of GHC, or whole files if you prefer.
+
+</Para>
+</ListItem>
+
+</OrderedList>
+
+</Para>
+
+</Sect1>
+
+<Sect1 id="hard-core-debug">
+<Title>Hard-core debugging of GHC-compiled programs
+</Title>
+
+<Para>
+<IndexTerm><Primary>debugging, hard-core</Primary></IndexTerm>
+</Para>
+
+<Para>
+If your program is crashing, you should almost surely file a bug
+report, as outlined in previous sections.
+</Para>
+
+<Para>
+This section suggests ways to Make Further Progress Anyway.
+</Para>
+
+<Para>
+The first thing to establish is: Is it a garbage-collection (GC) bug?
+Try your program with a very large heap and a <Literal>-Sstderr</Literal> RTS
+flag.
+
+<ItemizedList>
+<ListItem>
+
+<Para>
+If it crashes <Emphasis>without</Emphasis> garbage-collecting, then it is
+definitely <Emphasis>not</Emphasis> a GC bug.
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+If you can make it crash with one heap size but not with another, then
+it <Emphasis>probably is</Emphasis> a GC bug.
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+If it crashes with the normal
+collector, but not when you force two-space collection (<Literal>-F2s</Literal>
+runtime flag), then it <Emphasis>probably is</Emphasis> a GC bug.
+</Para>
+</ListItem>
+
+</ItemizedList>
+
+</Para>
+
+<Para>
+If it <Emphasis>is</Emphasis> a GC bug, you may be able to avoid it by using a
+particular heap size or by using a <Literal>-F2s</Literal> runtime flag.  (But don't
+forget to report the bug!!!)
+</Para>
+
+<Para>
+ToDo: more here?
+</Para>
+
+</Sect1>
+
+</Chapter>
diff --git a/ghc/docs/users_guide/installing.sgml b/ghc/docs/users_guide/installing.sgml
new file mode 100644 (file)
index 0000000..0415c4d
--- /dev/null
@@ -0,0 +1,1979 @@
+<!doctype linuxdoc system>
+<article>
+
+<title>Building and Installing the Glasgow Functional Programming Tools Suite
+Version 4.04
+<author>The GHC Team,
+Department of Computing Science,
+University of Glasgow,
+Glasgow, Scotland,
+G12 8QQ.
+
+Email: <tt>glasgow-haskell-{users,bugs}@dcs.gla.ac.uk</tt>
+<date>April 1998</date>
+
+<abstract>
+
+This guide is intended for people who want to install or modify
+programs from the Glasgow <tt>fptools</tt> suite (as distinct from those
+who merely want to <em/run/ them).
+
+</abstract>
+
+<toc>
+
+<sect>Getting the Glasgow <tt>fptools</tt> suite
+<label id="sec:getting">
+<p>
+
+Building the Glasgow tools <em/can/ be complicated, mostly because
+there are so many permutations of what/why/how, e.g., ``Build Happy
+with HBC, everything else with GHC, leave out profiling, and test it
+all on the `real' NoFib programs.''  Yeeps!
+
+Happily, such complications don't apply to most people.  A few common
+``strategies'' serve most purposes.  Pick one and proceed
+as suggested:
+
+<descrip>
+
+<tag><idx>Binary distribution</idx>.</tag>
+ If your only purpose is to install some of the <tt>fptools</tt> suite
+then the easiest thing to do is to get a binary distribution. In the
+binary distribution everything is pre-compiled for your particular
+machine architecture and operating system, so all you should have to
+do is install the binaries and libraries in suitable places.  Section
+<ref id="sec:installing-bin-distrib" name="Installing a Binary
+Distribution"> describes how to do this.
+
+A binary distribution may not work for you for two reasons.  First, we
+may not have built the suite for the particular architecture/OS
+platform you want. That may be due to lack of time and energy (in
+which case you can get a source distribution and build from it; see
+below).  Alternatively, it may be because we haven't yet ported the
+suite to your architecture, in which case you are considerably worse
+off.
+
+The second reason a binary distribution may not be what you want is
+if you want to read or modify the souce code.
+
+<tag><idx>Source distribution</idx>.</tag> You have a supported
+platform, but (a)~you like the warm fuzzy feeling of compiling things
+yourself; (b)~you want to build something ``extra''---e.g., a set of
+libraries with strictness-analysis turned off; or (c)~you want to hack
+on GHC yourself.
+
+A source distribution contains complete sources for one or more
+projects in the <tt>fptools</tt> suite.  Not only that, but the more awkward
+machine-independent steps are done for you.  For example, if you don't
+have <tt>flex</tt><ncdx/flex/ you'll find it convenient that the source
+distribution contains the result of running <tt>flex</tt> on the lexical
+analyser specification.  If you don't want to alter the lexical
+analyser then this saves you having to find and install <tt>flex</tt>. You
+will still need a working version of GHC on your machine in order to
+compile (most of) the sources, however.
+
+We make source distributions more frequently than binary
+distributions; a release that comes with pre-compiled binaries
+is considered a major release, i.e., a release that we have some
+confidence will work well by having tested it (more) thoroughly.
+
+Source-only distributions are either bugfix releases or snapshots of
+current state of development. The release has undergone some testing.
+Source releases of 4.xx can be compiled up using 2.10 or later.
+
+<tag/Build GHC from intermediate C <tt>.hc</tt> files<nidx/hc files/:/ You
+need a working GHC to use a source distribution. What if you don't
+have a working GHC? Then you have no choice but to ``bootstrap'' up
+from the intermediate C (<tt>.hc</tt>) files that we provide.  Building GHC
+on an unsupported platform falls into this category.  Please see
+Section <ref id="sec:booting-from-C" name="Booting From C">.
+
+Once you have built GHC, you can build the other Glasgow tools with
+it.
+
+In theory, you can (could?) build GHC with another Haskell compiler
+(e.g., HBC). We haven't tried to do this for ages and it almost
+certainly doesn't work any more (for tedious reasons).
+
+<tag/The CVS repository./
+
+We make source distributions slightly more often than binary
+distributions; but still infrequently.  If you want more up-to-the
+minute (but less tested) source code then you need to get access to
+our CVS repository.
+
+All the <tt>fptools</tt> source code is held in a CVS repository. CVS is a
+pretty good source-code control system, and best of all it works over
+the network.
+
+The repository holds source code only. It holds no mechanically
+generated files at all.  So if you check out a source tree from CVS
+you will need to install every utility so that you can build all the
+derived files from scratch.
+
+More information about our CVS repository is available at <url
+name="The Fptools CVS Cheat Sheet"
+url="http://www.dcs.gla.ac.uk/fp/software/ghc/cvs-cheat-sheet.html">.
+</descrip>
+
+If you are going to do any building from sources (either from a source
+distribution or the CVS repository) then you need to read all of this
+manual in detail.
+
+<sect>Things to check before you start typing
+<p>
+
+Here's a list of things to check before you get started.
+<enum>
+<item>
+<idx>Disk space needed</idx>: About 30MB (five hamburgers' worth) of disk space
+for the most basic binary distribution of GHC; more for some
+platforms, e.g., Alphas.  An extra ``bundle'' (e.g., concurrent
+Haskell libraries) might take you to 8--10 hamburgers.
+
+You'll need over 100MB (say, 20 hamburgers' worth) if you need to
+build the basic stuff from scratch.
+
+
+All of the above are <em/estimates/ of disk-space needs.(I don't yet
+know the disk requirements for the non-GHC tools).
+
+<item>
+Use an appropriate machine, compilers, and things.
+
+SPARC boxes, DEC Alphas running OSF/1, and PCs running Linux, FreeBSD,
+or Solaris are all fully supported.  MIPS, AIX, Win32 and HP boxes are
+in pretty good shape.  Section <ref id="sec:port-info" name="Port Info">
+gives the full run-down on ports or lack thereof.
+
+NOTE: as of version 4.00, we lost a few ports.  All of the x86 ports
+are working, as is the Sparc/Solaris port, but the rest will need a
+little work.  Please contact us if you can provide hardware cycles
+and/or porting expertise.
+
+<item> Be sure that the ``pre-supposed'' utilities are installed.
+Section <ref id="sec:pre-supposed" name="Installing Pre-Supposed
+Utilities"> elaborates.
+
+<item> If you have any problem when building or installing the Glasgow
+tools, please check the ``known pitfalls'' (Section <ref
+id="sec:build-pitfalls" name="Building Pitfalls">).  Also check the
+known bugs page: <url
+url="http://www.dcs.gla.ac.uk/fp/software/ghc/ghc-bugs.html">.
+<nidx/known bugs/
+<nidx/bugs, known/
+
+If you feel there is still some shortcoming in our procedure or
+instructions, please report it.
+
+For GHC, please see the bug-reporting section of the User's guide
+(separate document), to maximise the usefulness of your report.
+<nidx/bugs, reporting/
+
+If in doubt, please send a message to <tt>glasgow-haskell-bugs@dcs.gla.ac.uk</tt>.
+<nidx/bugs, mailing list/
+</enum>
+
+
+<sect>What machines the Glasgow tools run on
+<label id="sec:port-info">
+<p>
+<nidx>ports, GHC</nidx>
+<nidx>GHC ports</nidx>
+<nidx>supported platforms</nidx>
+<nidx>platforms, supported</nidx>
+
+The main question is whether or not the Haskell compiler (GHC) runs on
+your platform.
+
+A ``platform'' is a architecture/manufacturer/operating-system
+combination, such as <tt>sparc-sun-solaris2</tt>.  Other common ones are
+<tt>alpha-dec-osf2</tt>, <tt>hppa1.1-hp-hpux9</tt>, <tt>i386-unknown-linux</tt>,
+<tt>i386-unknown-solaris2</tt>, <tt>i386-unknown-freebsd</tt>,
+<tt>i386-unknown-cygwin32</tt>, <tt>m68k-sun-sunos4</tt>, <tt>mips-sgi-irix5</tt>,
+<tt>sparc-sun-sunos4</tt>, <tt>sparc-sun-solaris2</tt>, <tt>powerpc-ibm-aix</tt>.
+
+Bear in mind that certain ``bundles'', e.g. parallel Haskell, may not
+work on all machines for which basic Haskell compiling is supported.
+
+Some libraries may only work on a limited number of platforms; for
+example, a sockets library is of no use unless the operating system
+supports the underlying BSDisms.
+
+<sect1>What platforms the Haskell compiler (GHC) runs on
+<p>
+<nidx>fully-supported platforms</nidx>
+<nidx>native-code generator</nidx>
+<nidx>registerised ports</nidx>
+<nidx>unregisterised ports</nidx>
+
+The GHC hierarchy of Porting Goodness: (a)~Best is a native-code
+generator; (b)~next best is a ``registerised''
+port; (c)~the bare minimum is an ``unregisterised'' port.
+(``Unregisterised'' is so terrible that we won't say more about it).
+
+We use Sparcs running Solaris 2.5, x86 boxes running FreeBSD and
+Linux, and DEC~Alphas running OSF/1~V2.0, so those are the
+``fully-supported'' platforms, unsurprisingly.  All have native-code
+generators, for quicker compilations.  The native-code generator for
+iX86 platforms (e.g., Linux ELF) is <em/nearly/ working; but is not
+turned on by default.
+
+Here's everything that's known about GHC ports.  We identify platforms
+by their ``canonical'' CPU/Manufacturer/OS triple.
+
+Note that some ports are fussy about which GCC version you use; or
+require GAS; or&hellip;
+
+<descrip>
+<tag/alpha-dec-osf1:/
+<nidx>alpha-dec-osf1: fully supported</nidx>
+
+(We have OSF/1 V3.0.) Fully supported, including native-code
+generator.  We recommend GCC 2.6.x or later.
+
+<tag/sparc-sun-sunos4:/
+<nidx>sparc-sun-sunos4: fully supported</nidx>
+
+Fully supported, including native-code generator.
+
+<tag/sparc-sun-solaris2:/ 
+<nidx>sparc-sun-solaris2: fully supported</nidx>
+
+Fully supported, including native-code generator.  A couple of quirks,
+though: (a)~the profiling libraries are bizarrely huge when compiled
+with object splitting; (b)~the default <tt>xargs</tt><ncdx/xargs/ program is
+atrociously bad for building GHC libraries (see Section <ref
+id="sec:pre-supposed" name="Installing Pre-Supposed Utilities"> for
+details).
+
+<tag/HP-PA box running HP/UX 9.x:/
+<nidx>hppa1.1-hp-hpux: registerised port</nidx>
+
+Works registerised.  No native-code generator.  For GCC, you're best
+off with one of the Utah releases of GCC~2.6.3 (`u3' or later), from
+<tt>jaguar.cs.utah.edu</tt>.  We think a straight GCC 2.7.x works,
+too.
+
+Concurrent/Parallel Haskell probably don't work (yet).
+<nidx>hppa1.1-hp-hpux: concurrent---no</nidx>
+<nidx>hppa1.1-hp-hpux: parallel---no</nidx>
+
+<tag/i386-*-linux (PCs running Linux---ELF format):/
+<nidx>i386-*-linux: registerised port</nidx>
+
+GHC works registerised.  You <em/must/ have GCC 2.7.x or later.  The
+iX86 native-code generator is <em/nearly/ there, but it isn't turned
+on by default.
+
+Profiling works, and Concurrent Haskell works.
+<nidx>i386-*-linux: profiling---yes</nidx>
+<nidx>i386-*-linux: concurrent---yes</nidx>
+Parallel Haskell probably works.
+<nidx>i386-*-linux: parallel---maybe</nidx>
+
+On old Linux a.out systems: should be the same.
+<nidx>i386-*-linuxaout: registerised port</nidx>
+
+<tag>i386-*-freebsd (PCs running FreeBSD 2.2 or higher, and
+NetBSD/OpenBSD using FreeBSD emulation):</tag> 
+<nidx>i386-*-freebsd:registerised port</nidx> 
+
+GHC works registerised. Supports same set of bundles as the above.
+
+<nidx>i386-*-freebsd: profiling---yes</nidx>
+<nidx>i386-*-freebsd: concurrent---yes</nidx>
+<nidx>i386-*-freebsd: parallel---maybe</nidx>
+
+<tag/i386-unknown-cygwin32:/
+<nidx>i386-unknown-cygwin32: fully supported</nidx>
+
+Fully supported under Win95/NT, including a native code
+generator. Requires the <tt>cygwin32</tt> compatibility library and a
+healthy collection of GNU tools (i.e., gcc, GNU ld, bash etc.)
+Profiling works, so does Concurrent Haskell.  
+
+<nidx>i386-*-cygwin32: profiling---yes</nidx> 
+<nidx>i386-*-cygwin32: concurrent---yes</nidx>
+
+<tag/mips-sgi-irix5:/
+<nidx>mips-sgi-irix5: registerised port</nidx>
+
+GHC works registerised (no native-code generator).  I suspect any
+GCC~2.6.x (or later) is OK.  The GCC that I used was built with
+<tt>--with-gnu-as</tt>; turns out that is important!
+
+Concurrent/Parallel Haskell probably don't work (yet).
+Profiling might work, but it is untested.
+<nidx>mips-sgi-irix5: concurrent---no</nidx>
+<nidx>mips-sgi-irix5: parallel---no</nidx>
+<nidx>mips-sgi-irix5: profiling---maybe</nidx>
+
+<tag/mips-sgi-irix6:/
+<nidx>mips-sgi-irix6: registerised port</nidx>
+
+Thanks to the fine efforts of Tomasz Cholewo <htmlurl
+url="mailto:tjchol01@mecca.spd.louisville.edu"
+name="tjchol01@mecca.spd.louisville.edu">, GHC works registerised (no
+native code generator) under IRIX 6.2 and 6.3. Depends on having
+specially tweaked version of gcc-2.7.2 around, which can be downloaded
+from <url url="http://mecca.spd.louisville.edu/~tjchol01/software/">.
+
+Profiling works, Concurrent/Parallel Haskell might work (AFAIK, untested).
+<nidx>mips-sgi-irix6: concurrent---maybe</nidx>
+<nidx>mips-sgi-irix6: parallel---maybe</nidx>
+<nidx>mips-sgi-irix6: profiling---yes</nidx>
+
+<tag/powerpc-ibm-aix:/
+<nidx>powerpc-ibm-aix: registerised port</nidx>
+GHC works registerised (no native-code generator..yet).
+I suspect 2.7.x is what you need together with this.
+
+Concurrent/Parallel Haskell probably don't work (yet).
+Profiling might work, but it is untested.
+<nidx>mips-sgi-irix5: concurrent---no</nidx>
+<nidx>mips-sgi-irix5: parallel---no</nidx>
+<nidx>mips-sgi-irix5: profiling---maybe</nidx>
+
+<tag/m68k-apple-macos7 (Mac, using MPW):/
+<nidx>m68k-apple-macos7: historically ported</nidx>
+Once upon a time, David Wright in Tasmania has actually
+gotten GHC to run on a Macintosh.  Ditto James Thomson here at Glasgow.
+You may be able to get Thomson's from here.  (Not sure that it will
+excite you to death, but&hellip;)
+
+No particularly recent GHC is known to work on a Mac.
+
+<tag/m68k-next-nextstep3:/
+<nidx>m68k-next-nextstep3: historically ported</nidx>
+Carsten Schultz succeeded with a ``registerised'' port of GHC~0.29.
+There's probably a little bit-rot since then, but otherwise it should
+still be fine.
+
+Concurrent/Parallel Haskell probably won't work (yet).
+<nidx>m68k-next-nextstep3: concurrent---no</nidx>
+<nidx>m68k-next-nextstep3: parallel---no</nidx>
+
+<tag/m68k-sun-sunos4 (Sun3):/ <nidx>m68k-sun-sunos4: registerised
+port</nidx> GHC 2.0x and 3.0x haven't been tried on a Sun3.  GHC~0.26
+worked registerised.  No native-code generator.
+
+Concurrent/Parallel Haskell probably don't work (yet).
+<nidx>m68k-sun-sunos4: concurrent---no</nidx>
+<nidx>m68k-sun-sunos4: parallel---no</nidx>
+</descrip>
+
+<sect1>What machines the other tools run on
+<p>
+
+Unless you hear otherwise, the other tools work if GHC works.
+
+Haggis requires Concurrent Haskell to work.
+<nidx>Haggis, Concurrent Haskell</nidx>
+
+
+<sect>Installing from binary distributions
+<p>
+<label id="sec:installing-bin-distrib">
+<nidx>binary installations</nidx>
+<nidx>installation, of binaries</nidx>
+
+Installing from binary distributions is easiest, and recommended!
+(Why binaries?  Because GHC is a Haskell compiler written in Haskell,
+so you've got to ``bootstrap'' it, somehow.  We provide
+machine-generated C-files-from-Haskell for this purpose, but it's
+really quite a pain to use them.  If you must build GHC from its
+sources, using a binary-distributed GHC to do so is a sensible way to
+proceed. For the other <tt>fptools</tt> programs, many are written in Haskell,
+so binary distributions allow you to install them without having a Haskell compiler.)
+
+
+<sect1>Bundle structure<p>
+<nidx>bundles of binary stuff</nidx>
+
+Binary distributions come in ``bundles,'' one bundle per file called
+<tt>&lt;bundle&gt;-&lt;platform&gt;.tar.gz</tt>.  (See Section <ref
+id="sec:port-info" name="Porting Information"> for what a platform
+is.)  Suppose that you untar a binary-distribution bundle, thus:
+
+<tscreen><verb>
+  % cd /your/scratch/space
+  % gunzip < ghc-x.xx-sun-sparc-solaris2.tar.gz | tar xvf -
+</verb></tscreen>
+
+Then you should find a single directory, <tt>fptools</tt>, with the following
+structure:
+
+<nidx>binary distribution, layout</nidx>
+<nidx>directory layout (binary distributions)</nidx>
+<descrip>
+
+<tag><tt>Makefile.in</tt></tag> the raw material from which the <tt>Makefile</tt>
+will be made (Section <ref id="sec:install" name="Installation">).
+
+<tag><tt>configure</tt></tag> the configuration script (Section <ref
+id="sec:install" name="Installing">).
+
+<tag><tt>README</tt></tag> Contains this file summary.
+
+<tag><tt>INSTALL</tt></tag> Contains this description of how to install
+the bundle.
+
+<tag><tt>ANNOUNCE</tt></tag> The announcement message for the bundle.
+
+<tag><tt>NEWS</tt></tag> release notes for the bundle -- a longer version
+of <tt>ANNOUNCE</tt>.  For GHC, the release notes are contained in the User
+Guide and this file isn't present.
+
+<tag><tt>bin/&lt;platform&gt;</tt></tag> contains platform-specific executable
+files to be invoked directly by the user.  These are the files that
+must end up in your path.
+
+<tag><tt>lib/&lt;platform&gt;/</tt></tag> contains platform-specific support
+files for the installation.  Typically there is a subdirectory for
+each <tt>fptools</tt> project, whose name is the name of the project with its
+version number.  For example, for GHC there would be a sub-directory
+<tt>ghc-x.xx</tt>/ where <tt>x.xx</tt> is the version number of GHC in the bundle.
+
+These sub-directories have the following general structure:
+
+<descrip>
+<tag><tt>libHS.a</tt> etc:</tag> supporting library archives.
+<tag><tt>ghc-iface.prl</tt> etc:</tag> support scripts.
+<tag><tt>import/</tt></tag> <idx>Interface files</idx> (<tt>.hi</tt>) for the prelude.
+<tag><tt>include/</tt></tag> A few C <tt>&num;include</tt> files.
+</descrip>
+
+<tag><tt>share/</tt></tag> contains platform-independent support files
+for the installation.  Again, there is a sub-directory for each
+<tt>fptools</tt> project.
+
+<tag><tt>info/</tt></tag> contains Emacs info documentation files (one
+sub-directory per project).
+
+<tag><tt>html/</tt></tag> contains HTML documentation files (one
+sub-directory per project).
+
+<tag><tt>man/</tt></tag> contains Unix manual pages.
+
+</descrip>
+
+This structure is designed so that you can unpack multiple bundles
+(including ones from different releases or platforms) into a single
+<tt>fptools</tt> directory<footnote>this doesn't work at the
+moment</footnote>:
+
+<tscreen><verb>
+  % cd /your/scratch/space
+  % gunzip < ghc-x.xx-sun-sparc-solaris2.tar.gz | tar xvf -
+  % gunzip < happy-x.xx-sun-sparc-sunos4.tar.gz | tar xvf -
+</verb></tscreen>
+
+When you do multiple unpacks like this, the top level <tt>Makefile</tt>,
+<tt>README</tt>, and <tt>INSTALL</tt> get overwritten each time.
+That's fine -- they should be the same.  Likewise, the
+<tt>ANNOUNCE-&lt;bundle&gt;</tt> and <tt>NEWS-&lt;bundle&gt;</tt>
+files will be duplicated across multiple platforms, so they will be
+harmlessly overwritten when you do multiple unpacks.  Finally, the
+<tt>share/</tt> stuff will get harmlessly overwritten when you do
+multiple unpacks for one bundle on different platforms.
+
+<sect2>Installing<p>
+<label id="sec:install">
+
+OK, so let's assume that you have unpacked your chosen bundles into a
+scratch directory <tt>fptools</tt>. What next? Well, you will at least need
+to run the <tt>configure</tt><ncdx/configure/ script by changing your
+directory to <tt>fptools</tt> and typing <tt>./configure</tt>.  That should convert
+<tt>Makefile.in</tt> to <tt>Makefile</tt>.
+
+<nidx/installing in-place/
+<nidx/in-place installation/
+
+You can now either start using the tools <em/in-situ/ without going
+through any installation process, just type <tt>make in-place</tt> to set the
+tools up for this. You'll also want to add the path which <tt>make</tt> will
+now echo to your <tt>PATH</tt> environment variable. This option is useful if
+you simply want to try out the package and/or you don't have the
+necessary priviledges (or inclination) to properly install the tools
+locally. Note that if you do decide to install the package `properly'
+at a later date, you have to go through the installation steps that
+follows.
+
+To install an <tt>fptools</tt> package, you'll have to do the following:
+
+<enum>
+<item> Edit the <tt>Makefile</tt> and check the settings of the following variables:
+
+<nidx/directories, installation/
+<nidx/installation directories/
+
+<descrip>
+<tag><tt>platform</tt></tag> the platform you are going to install for.
+
+<tag><tt>bindir</tt></tag> the directory in which to install user-invokable
+binaries.
+
+<tag><tt>libdir</tt></tag> the directory in which to install
+platform-dependent support files.
+
+<tag><tt>datadir</tt></tag> the directory in which to install
+platform-independent support files.
+
+<tag><tt>infodir</tt></tag> the directory in which to install Emacs info
+files.
+
+<tag><tt>htmldir</tt></tag> the directory in which to install HTML
+documentation.
+
+<tag><tt>dvidir</tt></tag> the directory in which to install DVI
+documentation.
+</descrip>
+
+The values for these variables can be set through invocation of the
+<tt>configure</tt><ncdx/configure/ script that comes with the distribution,
+but doing an optical diff to see if the values match your expectations
+is always a Good Idea.
+
+<em>Instead of running <tt>configure</tt>, it is perfectly OK to copy
+<tt>Makefile.in</tt> to <tt>Makefile</tt> and set all these variables
+directly yourself.  But do it right!</em>
+
+<item>Run <tt>make install</tt>.  This <em/ should/ work with ordinary Unix
+<tt>make</tt> -- no need for fancy stuff like GNU <tt>make</tt>. 
+
+<item><tt>rehash</tt> (t?csh or zsh users), so your shell will see the new
+stuff in your bin directory.
+
+<item> Once done, test your ``installation'' as suggested in Section
+<ref id="sec:GHC-test" name="Testing GHC">.  Be sure to use a <tt>-v</tt>
+option, so you can see exactly what pathnames it's using.
+
+If things don't work as expected, check the list of know pitfalls in
+Section <ref id="sec:build-pitfalls" name="Building Pitfalls">.
+</enum>
+
+<nidx/link, installed as ghc/
+When installing the user-invokable binaries, this installation
+procedure will install GHC as <tt>ghc-x.xx</tt> where <tt>x.xx</tt> is the version
+number of GHC.  It will also make a link (in the binary installation
+directory) from <tt>ghc</tt> to <tt>ghc-x.xx</tt>.  If you install multiple versions
+of GHC then the last one ``wins'', and ``<tt>ghc</tt>'' will invoke the last
+one installed.  You can change this manually if you want.  But
+regardless, <tt>ghc-x.xx</tt> should always invoke GHC version <tt>x.xx</tt>.
+
+<sect1>What bundles there are
+<p>
+
+<nidx/bundles, binary/
+There are plenty of ``non-basic'' GHC bundles.  The files for them are
+called <tt>ghc-x.xx-&lt;bundle&gt;-&lt;platform&gt;.tar.gz</tt>, where
+the <tt>&lt;platform&gt;</tt> is as above, and <tt>&lt;bundle&gt;</tt> is one
+of these:
+
+<descrip>
+
+<tag><tt>prof</tt>:</tag>  Profiling with cost-centres.  You probably want this.
+<nidx/profiling bundles/
+<nidx/bundles, profiling/
+
+<tag><tt>conc</tt>:</tag> Concurrent Haskell features.  You may want this.
+<nidx/concurrent bundles/
+<nidx/bundles, concurrent/
+
+<tag><tt>par</tt>:</tag> Parallel Haskell features (sits on top of PVM).
+You'll want this if you're into that kind of thing.
+<nidx/parallel bundles/
+<nidx/bundles, parallel/
+
+<tag><tt>gran</tt>:</tag> The ``GranSim'' parallel-Haskell simulator
+(hmm&hellip; mainly for implementors).
+<nidx/bundles, gransim/
+<nidx/gransim bundles/
+
+<tag><tt>ticky</tt>:</tag> ``Ticky-ticky'' profiling; very detailed
+information about ``what happened when I ran this program''---really
+for implementors.
+<nidx/bundles, ticky-ticky/
+<nidx/ticky-ticky bundles/
+
+<tag><tt>prof-conc</tt>:</tag> Cost-centre profiling for Concurrent Haskell.
+<nidx/bundles, profiled-concurrent/
+<nidx/profiled-concurrent bundles/
+
+<tag><tt>prof-ticky</tt>:</tag>  Ticky-ticky profiling for Concurrent Haskell.
+<nidx/bundles, profiled-ticky/
+<nidx/ticky-concurrent bundles/
+</descrip>
+
+One likely scenario is that you will grab <em/three/ binary
+bundles---basic, profiling, and concurrent.  We don't usually make the
+rest, although you can build them yourself from a source distribution.
+
+<sect1>Testing that GHC seems to be working
+<label id="sec:GHC-test">
+<p>
+<nidx>testing a new GHC</nidx>
+
+The way to do this is, of course, to compile and run <em/this/ program
+(in a file <tt>Main.hs</tt>):
+
+<tscreen><verb>
+main = putStr "Hello, world!\n"
+</verb></tscreen>
+
+Compile the program, using the <tt>-v</tt> (verbose) flag to verify that
+libraries, etc., are being found properly:
+<tscreen><verb>
+% ghc -v -o hello Main.hs
+</verb></tscreen>
+
+Now run it:
+<tscreen><verb>
+% ./hello
+Hello, world!
+</verb></tscreen>
+
+Some simple-but-profitable tests are to compile and run the notorious
+<tt>nfib</tt><ncdx/nfib/ program, using different numeric types.  Start with
+<tt>nfib :: Int -&gt; Int</tt>, and then try <tt>Integer</tt>, <tt>Float</tt>, <tt>Double</tt>,
+<tt>Rational</tt> and perhaps the overloaded version.  Code for this is
+distributed in <tt>ghc/misc/examples/nfib/</tt> in a source distribution.
+
+For more information on how to ``drive'' GHC, either do <tt>ghc -help</tt> or
+consult the User's Guide (distributed in several pre-compiled formats
+with a binary distribution, or in source form in
+<tt>ghc/docs/users_guide</tt> in a source distribution).
+
+<sect>Installing pre-supposed utilities
+<label id="sec:pre-supposed">
+<nidx>pre-supposed utilities</nidx>
+<nidx>utilities, pre-supposed</nidx>
+<p>
+
+Here are the gory details about some utility programs you may need;
+<tt>perl</tt> and <tt>gcc</tt> are the only important ones. (<idx/PVM/ is important
+if you're going for Parallel Haskell.)  The <tt><cdx/configure/</tt>
+script will tell you if you are missing something.
+
+<descrip>
+<tag>Perl:</tag>
+<nidx>pre-supposed: Perl</nidx>
+<nidx>Perl, pre-supposed</nidx>
+<em/You have to have Perl to proceed!/ Perl is a language quite good
+for doing shell-scripty tasks that involve lots of text processing.
+It is pretty easy to install.
+
+Perl~5 is required.  For Win32 platforms, we strongly suggest you pick
+up a port of Perl~5 for <tt>cygwin32</tt>, as the common Hip/ActiveWare port
+of Perl is not Cool Enough for our purposes.
+
+Perl should be put somewhere so that it can be invoked by the <tt>&num;!</tt>
+script-invoking mechanism. (I believe <tt>/usr/bin/perl</tt> is preferred;
+we use <tt>/usr/local/bin/perl</tt> at Glasgow.)  The full pathname should
+be less than 32 characters long.
+
+<tag>GNU C (<tt>gcc</tt>):</tag>
+<nidx>pre-supposed: GCC (GNU C compiler)</nidx>
+<nidx>GCC (GNU C compiler), pre-supposed</nidx>
+
+Versions 2.7.2.x, 2.8.1 and egcs 1.1.2 are known to work.  Use other
+versions at your own risk!
+
+If your GCC dies with ``internal error'' on some GHC source file,
+please let us know, so we can report it and get things improved.
+(Exception: on <tt>iX86</tt> boxes---you may need to fiddle with GHC's
+<tt>-monly-N-regs</tt> option; see the User's Guide)
+
+<tag><tt>xargs</tt> on Solaris2:</tag>
+<nidx>xargs, presupposed (Solaris only)</nidx>
+<nidx>Solaris: alternative xargs</nidx>
+The GHC libraries are put together with something like:
+<tscreen><verb>
+find bunch-of-dirs -name '*.o' -print | xargs ar q ...
+</verb></tscreen>
+Unfortunately the Solaris <tt>xargs</tt> (the shell-script equivalent
+of <tt>map</tt>) only ``bites off'' the <tt>.o</tt> files a few at a
+time---with near-infinite rebuilding of the symbol table in
+the <tt>.a</tt> file.
+
+The best solution is to install a sane <tt>xargs</tt> from the GNU
+findutils distribution.  You can unpack, build, and install the GNU
+version in the time the Solaris <tt>xargs</tt> mangles just one GHC
+library.
+
+<tag>Autoconf:</tag>
+<nidx>pre-supposed: Autoconf</nidx>
+<nidx>Autoconf, pre-supposed</nidx>
+
+GNU Autoconf is needed if you intend to build from the CVS sources, it
+is <em/not/ needed if you just intend to build a standard source
+distribution.
+
+Autoconf builds the <tt>configure</tt> script from <tt>configure.in</tt> and
+<tt>aclocal.m4</tt>.  If you modify either of these files, you'll need
+Autoconf to rebuild <tt>configure</tt>.
+
+<tag><tt>sed</tt></tag>
+<nidx>pre-supposed: sed</nidx>
+<nidx>sed, pre-supposed</nidx>
+
+You need a working <tt>sed</tt> if you are going to build from sources.  The
+build-configuration stuff needs it.  GNU sed version 2.0.4 is no good!
+It has a bug in it that is tickled by the build-configuration.  2.0.5
+is ok. Others are probably ok too (assuming we don't create too
+elaborate configure scripts..)
+</descrip>
+
+One <tt>fptools</tt> project is worth a quick note at this point, because it
+is useful for all the others: <tt>glafp-utils</tt> contains several utilities
+which aren't particularly Glasgow-ish, but Occasionally Indispensable.
+Like <tt>lndir</tt> for creating symbolic link trees.
+
+<sect1> Tools for building parallel GHC (GPH)
+<label id="pre-supposed-gph-tools">
+<p>
+
+<descrip>
+<tag>PVM version 3:</tag>
+<nidx>pre-supposed: PVM3 (Parallel Virtual Machine)</nidx>
+<nidx>PVM3 (Parallel Virtual Machine), pre-supposed</nidx>
+
+PVM is the Parallel Virtual Machine on which Parallel Haskell programs
+run.  (You only need this if you plan to run Parallel Haskell.
+Concurent Haskell, which runs concurrent threads on a uniprocessor
+doesn't need it.)  Underneath PVM, you can have (for example) a
+network of workstations (slow) or a multiprocessor box (faster).
+
+The current version of PVM is 3.3.11; we use 3.3.7.  It is readily
+available on the net; I think I got it from <tt>research.att.com</tt>, in
+<tt>netlib</tt>.
+
+A PVM installation is slightly quirky, but easy to do.  Just follow
+the <tt>Readme</tt> instructions.
+
+<tag><tt>bash</tt>:</tag>
+<nidx>bash, presupposed (Parallel Haskell only)</nidx>
+Sadly, the <tt>gr2ps</tt> script, used to convert ``parallelism profiles''
+to PostScript, is written in Bash (GNU's Bourne Again shell).
+This bug will be fixed (someday).
+</descrip>
+
+<sect1> Tools for building the Documentation
+<label id="pre-supposed-doc-tools">
+<p>
+
+The following additional tools are required if you want to format the
+documentation that comes with the <tt>fptools</tt> projects:
+
+<descrip>
+<tag>SGML-Tools:</tag>
+<nidx>pre-supposed: SGML-Tools</nidx>
+<nidx>SGML-Tools, pre-supposed</nidx>
+
+All our documentation is written in SGML, using the LinuxDoc DTD that
+comes with the SGML-Tools, which is the most shrink-wrapped SGML suite
+that we could find.  Should unpack and build painlessly on most
+architectures, and you can use it to generate HTML, Info, LaTeX (and
+hence DVI and Postscript), Groff, and plain text output from any
+LinuxDoc source file (including this manual).  Sources are available
+from <url name="The SGML-Tools Web Page"
+url="http://www.sgmltools.org/">
+
+<tag>TeX:</tag>
+<nidx>pre-supposed: TeX</nidx>
+<nidx>TeX, pre-supposed</nidx>
+A decent TeX distribution is required if you want to produce printable
+documentation.  We recomment teTeX, which includes just about
+everything you need.
+</descrip>
+
+<sect1> Other useful tools
+<label id="pre-supposed-other-tools">
+<p>
+
+<descrip>
+<tag>Flex:</tag> 
+<nidx>pre-supposed: flex</nidx> 
+<nidx>flex, pre-supposed</nidx>
+
+This is a quite-a-bit-better-than-Lex lexer.  Used to build a couple
+of utilities in <tt>glafp-utils</tt>.  Depending on your operating system,
+the supplied <tt>lex</tt> may or may not work; you should get the GNU
+version.
+</descrip>
+
+<sect>Building from source
+<label id="sec:building-from-source">
+<nidx>Building from source</nidx>
+<nidx>Source, building from</nidx>
+<p>
+
+You've been rash enough to want to build some of
+the Glasgow Functional Programming tools (GHC, Happy,
+nofib, etc) from source.  You've slurped the source,
+from the CVS repository or from a source distribution, and
+now you're sitting looking at a huge mound of bits, wondering
+what to do next.
+
+Gingerly, you type <tt>make</tt>.  Wrong already!
+
+This rest of this guide is intended for duffers like me, who aren't
+really interested in Makefiles and systems configurations, but who
+need a mental model of the interlocking pieces so that they can make
+them work, extend them consistently when adding new software, and lay
+hands on them gently when they don't work.
+
+<sect1>Your source tree
+<label id="sec:source-tree">
+<p>
+
+The source code is held in your <em/source tree/.
+The root directory of your source tree <em/must/
+contain the following directories and files:
+
+<itemize>
+<item> <tt>Makefile</tt>: the root Makefile.
+<item> <tt>mk/</tt>: the directory that contains the
+main Makefile code, shared by all the
+<tt>fptools</tt> software.
+<item> <tt>configure.in</tt>, <tt>config.sub</tt>, <tt>config.guess</tt>:
+these files support the configuration process.
+<item> <tt>install-sh</tt>.
+</itemize>
+
+All the other directories are individual <em/projects/ of the
+<tt>fptools</tt> system --- for example, the Glasgow Haskell Compiler
+(<tt>ghc</tt>), the Happy parser generator (<tt>happy</tt>), the <tt>nofib</tt> benchmark
+suite, and so on.  You can have zero or more of these.  Needless to
+say, some of them are needed to build others.
+
+The important thing to remember is that even if you want only one
+project (<tt>happy</tt>, say), you must have a source tree whose root
+directory contains <tt>Makefile</tt>, <tt>mk/</tt>, <tt>configure.in</tt>, and the
+project(s) you want (<tt>happy/</tt> in this case).  You cannot get by with
+just the <tt>happy/</tt> directory.
+
+<sect1>Build trees
+<nidx/build trees/
+<nidx/link trees, for building/
+<p>
+
+While you can build a system in the source tree, we don't recommend it.
+We often want to build multiple versions of our software
+for different architectures, or with different options (e.g. profiling).
+It's very desirable to share a single copy of the source code among
+all these builds.
+
+So for every source tree we have zero or more <em/build trees/.  Each
+build tree is initially an exact copy of the source tree, except that
+each file is a symbolic link to the source file, rather than being a
+copy of the source file.  There are ``standard'' Unix utilities that
+make such copies, so standard that they go by different names:
+<tt>lndir</tt><ncdx/lndir/, <tt>mkshadowdir</tt><ncdx/mkshadowdir/ are two (If you
+don't have either, the source distribution includes sources for the
+<tt>X11</tt> <tt>lndir</tt> --- check out <tt>fptools/glafp-utils/lndir</tt> ).
+
+The build tree does not need to be anywhere near the source tree in
+the file system.  Indeed, one advantage of separating the build tree
+from the source is that the build tree can be placed in a
+non-backed-up partition, saving your systems support people from
+backing up untold megabytes of easily-regenerated, and
+rapidly-changing, gubbins.  The golden rule is that (with a single
+exception -- Section~<ref id="sec:build-config" name="Build
+Configuration"> <em/absolutely everything in the build tree is either
+a symbolic link to the source tree, or else is mechanically
+generated/.  It should be perfectly OK for your build tree to vanish
+overnight; an hour or two compiling and you're on the road again.
+
+You need to be a bit careful, though, that any new files you create
+(if you do any development work) are in the source tree, not a build tree!
+
+Remember, that the source files in the build tree are <em/symbolic
+links/ to the files in the source tree.  (The build tree soon
+accumulates lots of built files like <tt>Foo.o</tt>, as well.)  You
+can <em/delete/ a source file from the build tree without affecting
+the source tree (though it's an odd thing to do).  On the other hand,
+if you <em/edit/ a source file from the build tree, you'll edit the
+source-tree file directly.  (You can set up Emacs so that if you edit
+a source file from the build tree, Emacs will silently create an
+edited copy of the source file in the build tree, leaving the source
+file unchanged; but the danger is that you think you've edited the
+source file whereas actually all you've done is edit the build-tree
+copy.  More commonly you do want to edit the source file.)
+
+Like the source tree, the top level of your build tree must be (a
+linked copy of) the root directory of the <tt>fptools</tt> suite.  Inside
+Makefiles, the root of your build tree is called
+<tt>&dollar;(FPTOOLS_TOP)</tt><ncdx/FPTOOLS_TOP/.  In the rest of this document path
+names are relative to <tt>&dollar;(FPTOOLS_TOP)</tt> unless otherwise stated.  For
+example, the file <tt>ghc/mk/target.mk</tt> is actually
+<tt>&dollar;(FPTOOLS_TOP)/ghc/mk/target.mk</tt>.
+
+
+<sect1>Getting the build you want
+<label id="sec:build-config">
+<p>
+
+When you build <tt>fptools</tt> you will be compiling code on a particular
+<em/host platform/, to run on a particular <em/target platform/
+(usually the same as the host platform)<nidx>platform</nidx>.  The
+difficulty is that there are minor differences between different
+platforms; minor, but enough that the code needs to be a bit different
+for each.  There are some big differences too: for a different
+architecture we need to build GHC with a different native-code
+generator.
+
+There are also knobs you can turn to control how the <tt>fptools</tt>
+software is built.  For example, you might want to build GHC optimised
+(so that it runs fast) or unoptimised (so that you can compile it fast
+after you've modified it.  Or, you might want to compile it with
+debugging on (so that extra consistency-checking code gets included)
+or off.  And so on.
+
+All of this stuff is called the <em/configuration/ of your build.
+You set the configuration using an exciting three-step process.
+<descrip>
+
+<tag>Step 1: get ready for configuration.</tag> Change directory to
+<tt>&dollar;(FPTOOLS_TOP)</tt> and issue the command <tt>autoconf</tt><ncdx/autoconf/ (with
+no arguments). This GNU program converts <tt>&dollar;(FPTOOLS_TOP)/configure.in</tt>
+to a shell script called <tt>&dollar;(FPTOOLS_TOP)/configure</tt>.
+
+Both these steps are completely platform-independent; they just mean
+that the human-written file (<tt>configure.in</tt>) can be short, although
+the resulting shell script, <tt>configure</tt>, and <tt>mk/config.h.in</tt>, are
+long.
+
+In case you don't have <tt>autoconf</tt> we distribute the results,
+<tt>configure</tt>, and <tt>mk/config.h.in</tt>, with the source distribution.  They
+aren't kept in the repository, though.
+
+<tag>Step 2: system configuration.</tag>
+Runs the newly-created <tt>configure</tt> script, thus:
+<tscreen><verb>
+  ./configure
+</verb></tscreen>
+<tt>configure</tt>'s mission is to scurry round your computer working out
+what architecture it has, what operating system, whether it has the
+<tt>vfork</tt> system call, where <tt>yacc</tt> is kept, whether <tt>gcc</tt> is available,
+where various obscure <tt>&num;include</tt> files are, whether it's a leap year,
+and what the systems manager had for lunch.  It communicates these
+snippets of information in two ways:
+
+<itemize>
+
+<item> It translates <tt>mk/config.mk.in</tt><ncdx/config.mk.in/ to
+<tt>mk/config.mk</tt><ncdx/config.mk/, substituting for things between
+``@@@@}'' brackets.  So, ``@HaveGcc@'' will be replaced by
+``<tt>YES</tt>'' or ``<tt>NO</tt>'' depending on what <tt>configure</tt> finds.
+<tt>mk/config.mk</tt> is included by every Makefile (directly or indirectly),
+so the configuration information is thereby communicated to all
+Makefiles.
+
+<item> It translates <tt>mk/config.h.in</tt><ncdx/config.h.in/ to
+<tt>mk/config.h</tt><ncdx/config.h/.  The latter is <tt>&num;include</tt>d by various C
+programs, which can thereby make use of configuration information.
+
+</itemize>
+
+<tt>configure</tt> caches the results of its run in <tt>config.cache</tt>.  Quite
+often you don't want that; you're running <tt>configure</tt> a second time
+because something has changed.  In that case, simply delete
+<tt>config.cache</tt>.
+
+<tag>Step 3: build configuration.</tag>
+
+ Next, you say how this build of <tt>fptools</tt> is to differ from the
+standard defaults by creating a new file <tt>mk/build.mk</tt><ncdx/build.mk/
+<em/in the build tree/.  This file is the one and only file you edit
+in the build tree, precisely because it says how this build differs
+from the source.  (Just in case your build tree does die, you might
+want to keep a private directory of <tt>build.mk</tt> files, and use a
+symbolic link in each build tree to point to the appropriate one.)  So
+<tt>mk/build.mk</tt> never exists in the source tree --- you create one in
+each build tree from the template.  We'll discuss what to put in it
+shortly.  
+
+</descrip>
+
+And that's it for configuration. Simple, eh?
+
+What do you put in your build-specific configuration file
+<tt>mk/build.mk</tt>?  <em/For almost all purposes all you will do is put
+make variable definitions that override those in/ <tt>mk/config.mk.in</tt>.
+The whole point of <tt>mk/config.mk.in</tt> --- and its derived counterpart
+<tt>mk/config.mk</tt> --- is to define the build configuration. It is heavily
+commented, as you will see if you look at it.  So generally, what you
+do is look at <tt>mk/config.mk.in</tt>, and add definitions in <tt>mk/build.mk</tt>
+that override any of the <tt>config.mk</tt> definitions that you want to
+change.  (The override occurs because the main boilerplate file,
+<tt>mk/boilerplate.mk</tt><ncdx/boilerplate.mk/, includes <tt>build.mk</tt> after
+<tt>config.mk</tt>.)
+
+For example, <tt>config.mk.in</tt> contains the definition:
+
+<tscreen><verb>
+  ProjectsToBuild = glafp-utils ghc
+</verb></tscreen>
+
+The accompanying comment explains that this is the list of enabled
+projects; that is, if (after configuring) you type <tt>gmake all</tt> in
+<tt>FPTOOLS_TOP</tt> four specified projects will be made.  If you want to
+add <tt>green-card</tt>, you can add this line to <tt>build.mk</tt>:
+
+<tscreen><verb>
+  ProjectsToBuild += green-card
+</verb></tscreen>
+
+or, if you prefer,
+
+<tscreen><verb>
+  ProjectsToBuild = glafp-utils ghc green-card
+</verb></tscreen>
+
+(GNU <tt>make</tt> allows existing definitions to have new text appended
+using the ``<tt>+=</tt>'' operator, which is quite a convenient feature.)
+
+When reading <tt>config.mk.in</tt>, remember that anything between
+``@...@'' signs is going to be substituted by <tt>configure</tt>
+later.  You <em/can/ override the resulting definition if you want,
+but you need to be a bit surer what you are doing.  For example,
+there's a line that says: 
+
+<tscreen><verb>
+  YACC = @YaccCmd@
+</verb></tscreen>
+
+This defines the Make variables <tt>YACC</tt> to the pathname for a Yacc that
+<tt>configure</tt> finds somewhere.  If you have your own pet Yacc you want
+to use instead, that's fine. Just add this line to <tt>mk/build.mk</tt>:
+
+<tscreen><verb>
+  YACC = myyacc
+</verb></tscreen>
+
+You do not <em/have/ to have a <tt>mk/build.mk</tt> file at all; if you
+don't, you'll get all the default settings from <tt>mk/config.mk.in</tt>.
+
+You can also use <tt>build.mk</tt> to override anything that <tt>configure</tt> got
+wrong.  One place where this happens often is with the definition of
+<tt>FPTOOLS_TOP_ABS</tt>: this variable is supposed to be the canonical path
+to the top of your source tree, but if your system uses an automounter
+then the correct directory is hard to find automatically.  If you find
+that <tt>configure</tt> has got it wrong, just put the correct definition in
+<tt>build.mk</tt>.
+
+<sect1>The story so far
+<p>
+
+Let's summarise the steps you need to carry to get yourself
+a fully-configured build tree from scratch.
+
+<enum>
+
+<item> Get your source tree from somewhere (CVS repository or source
+distribution).  Say you call the root directory <tt>myfptools</tt> (it
+does not have to be called <tt>fptools</tt>).  Make sure that you have
+the essential files (see Section~<ref id="sec:source-tree"
+name="Source Tree">).
+
+<item> Use <tt>lndir</tt> or <tt>mkshadowdir</tt> to create a build tree.
+<tscreen><verb>
+    cd myfptools
+    mkshadowdir . /scratch/joe-bloggs/myfptools-sun4
+</verb></tscreen>
+You probably want to give the build tree a name that
+suggests its main defining characteristic (in your mind at least),
+in case you later add others.
+
+<item> Change directory to the build tree.  Everything is going
+to happen there now.
+<tscreen><verb>
+    cd /scratch/joe-bloggs/myfptools-sun4
+</verb></tscreen>
+<item> Prepare for system configuration:
+<tscreen><verb>
+    autoconf
+</verb></tscreen>
+(You can skip this step if you are starting from a source distribution,
+and you already have <tt>configure</tt> and <tt>mk/config.h.in</tt>.)
+
+<item> Do system configuration:
+<tscreen><verb>
+    ./configure
+</verb></tscreen>
+
+<item> Create the file <tt>mk/build.mk</tt>, 
+adding definitions for your desired configuration options.
+<tscreen><verb>
+    emacs mk/build.mk
+</verb></tscreen>
+</enum>
+You can make subsequent changes to <tt>mk/build.mk</tt> as often 
+as you like.  You do not have to run any further configuration 
+programs to make these changes take effect.
+In theory you should, however, say <tt>gmake clean</tt>, <tt>gmake all</tt>,
+because configuration option changes could affect anything --- but in practice you are likely to know what's affected.
+
+<sect1>Making things
+<p>
+
+At this point you have made yourself a fully-configured build tree,
+so you are ready to start building real things.
+
+The first thing you need to know is that 
+<em/you must use GNU <tt>make</tt>, usually called <tt>gmake</tt>, not standard Unix <tt>make</tt>/.
+If you use standard Unix <tt>make</tt> you will get all sorts of error messages
+(but no damage) because the <tt>fptools</tt> <tt>Makefiles</tt> use GNU <tt>make</tt>'s facilities
+extensively.
+
+<sect1>Standard Targets
+<label id="sec:standard-targets">
+<nidx/targets, standard makefile/
+<nidx/makefile targets/
+<p>
+
+In any directory you should be able to make the following:
+<descrip>
+
+<tag><tt>boot</tt>:</tag> 
+
+does the one-off preparation required to get ready for the real work.
+Notably, it does <tt>gmake depend</tt> in all directories that contain
+programs.  But <tt>boot</tt> does more.  For example, you can't do <tt>gmake
+depend</tt> in a directory of C program until you have converted the
+literate <tt>.lh</tt> header files into standard <tt>.h</tt> header files.
+Similarly, you can't convert a literate file to illiterate form until
+you have built the <tt>unlit</tt> tool.  <tt>boot</tt> takes care of these
+inter-directory dependencies.
+
+You should say <tt>gmake boot</tt> right after configuring your build tree,
+but note that this is a one-off, i.e., there's no need to re-do
+<tt>gmake boot</tt> if you should re-configure your build tree at a later
+stage (no harm caused if you do though).
+
+<tag><tt>all</tt>:</tag> makes all the final target(s) for this Makefile.
+Depending on which directory you are in a ``final target'' may be an
+executable program, a library archive, a shell script, or a Postscript
+file.  Typing <tt>gmake</tt> alone is generally the same as typing <tt>gmake
+all</tt>.
+
+<tag><tt>install</tt>:</tag> installs the things built by <tt>all</tt>.  Where does it
+install them?  That is specified by <tt>mk/config.mk.in</tt>; you can 
+override it in <tt>mk/build.mk</tt>.
+
+<tag><tt>uninstall</tt>:</tag> reverses the effect of <tt>install</tt>.
+
+<tag><tt>clean</tt>:</tag> remove all easily-rebuilt files.
+
+<tag><tt>veryclean</tt>:</tag> remove all files that can be rebuilt at all.
+There's a danger here that you may remove a file that needs a more
+obscure utility to rebuild it (especially if you started from a source
+distribution).
+
+<tag><tt>check</tt>:</tag> run the test suite.
+
+</descrip>
+
+All of these standard targets automatically recurse into
+sub-directories.  Certain other standard targets do not:
+
+<descrip>
+
+<tag><tt>configure</tt>:</tag> is only available in the root directory
+<tt>&dollar;(FPTOOLS_TOP)</tt>; it has been discussed in Section~<ref
+id="sec:build-config" name="Build Configuration">.
+
+<tag><tt>depend</tt>:</tag> make a <tt>.depend</tt> file in each directory that needs
+it. This <tt>.depend</tt> file contains mechanically-generated dependency
+information; for example, suppose a directory contains a Haskell 
+source module <tt>Foo.lhs</tt> which imports another module <tt>Baz</tt>.
+Then the generated <tt>.depend</tt> file will contain the dependency:
+
+<tscreen><verb>
+  Foo.o : Baz.hi
+</verb></tscreen>
+
+which says that the object file <tt>Foo.o</tt> depends on the interface file
+<tt>Baz.hi</tt> generated by compiling module <tt>Baz</tt>.  The <tt>.depend</tt> file is
+automatically included by every Makefile.
+
+<tag><tt>binary-dist</tt>:</tag> make a binary distribution.  This is the
+target we use to build the binary distributions of GHC and Happy.
+
+<tag><tt>dist</tt>:</tag> make a source distribution.  You must be in a
+linked buid tree to make this target.
+</descrip>
+
+Most <tt>Makefiles</tt> have targets other than these.  You can find
+this out by looking in the <tt>Makefile</tt> itself.
+
+<sect1>Fast Making
+<ncdx/fastmake/
+<nidx/dependencies, omitting/
+<nidx/FAST, makefile variable/
+<p>
+
+Sometimes the dependencies get in the way: if you've made a small
+change to one file, and you're absolutely sure that it won't affect
+anything else, but you know that <tt>make</tt> is going to rebuid everything
+anyway, the following hack may be useful:
+
+<tscreen> <verb>
+gmake FAST=YES
+</verb> </tscreen>
+
+This tells the make system to ignore dependencies and just build what
+you tell it to.  In other words, it's equivalent to temporarily
+removing the <tt>.depend</tt> file in the current directory (where
+<tt>mkdependHS</tt> and friends store their dependency information).
+
+A bit of history: GHC used to come with a <tt>fastmake</tt> script that did
+the above job, but GNU make provides the features we need to do it
+without resorting to a script.  Also, we've found that fastmaking is
+less useful since the advent of GHC's recompilation checker (see the
+User's Guide section on "Separate Compilation").
+
+<sect>The <tt>Makefile</tt> architecture
+<nidx/makefile architecture/
+<p>
+
+<tt>make</tt> is great if everything works --- you type <tt>gmake install</tt> and,
+lo, the right things get compiled and installed in the right places.
+Our goal is to make this happen often, but somehow it often doesn't;
+instead some wierd error message eventually emerges from the bowels of
+a directory you didn't know existed.
+
+The purpose of this section is to give you a road-map to help you figure
+out what is going right and what is going wrong.
+
+<sect1>A small project
+<p>
+
+To get started, let us look at the <tt>Makefile</tt> for an imaginary small
+<tt>fptools</tt> project, <tt>small</tt>.  Each project in <tt>fptools</tt> has its own
+directory in <tt>FPTOOLS_TOP</tt>, so the <tt>small</tt> project will have its own
+directory <tt>FPOOLS_TOP/small/</tt>.  Inside the <tt>small/</tt> directory there
+will be a <tt>Makefile</tt>, looking something like this:
+
+<nidx/Makefile, minimal/
+<tscreen><verb>
+  #     Makefile for fptools project "small"
+
+  TOP = ..
+  include $(TOP)/mk/boilerplate.mk
+
+  SRCS = $(wildcard *.lhs) $(wildcard *.c)
+  HS_PROG = small
+
+  include $(TOP)/target.mk
+</verb></tscreen>
+
+This <tt>Makefile</tt> has three sections:
+
+<enum>
+
+<item> The first section includes<footnote>One of the most important
+features of GNU <tt>make</tt> that we use is the ability for a <tt>Makefile</tt> to
+include another named file, very like <tt>cpp</tt>'s <tt>&num;include</tt>
+directive.</footnote> a file of ``boilerplate'' code from the level
+above (which in this case will be
+<tt>FPTOOLS_TOP/mk/boilerplate.mk</tt><ncdx/boilerplate.mk/).  As its name
+suggests, <tt>boilerplate.mk</tt> consists of a large quantity of standard
+<tt>Makefile</tt> code.  We discuss this boilerplate in more detail in
+Section~<ref id="sec:boiler" name="Boilerplate">.
+<nidx/include, directive in Makefiles/
+<nidx/Makefile inclusion/
+
+Before the <tt>include</tt> statement, you must define the <tt>make</tt> variable
+<tt>TOP</tt><ncdx/TOP/ to be the directory containing the <tt>mk</tt> directory in
+which the <tt>boilerplate.mk</tt> file is.  It is <em/not/ OK to simply say
+
+<tscreen><verb>
+  include ../mk/boilerplate.mk  # NO NO NO
+</verb></tscreen>
+
+Why?  Because the <tt>boilerplate.mk</tt> file needs to know where it is, so
+that it can, in turn, <tt>include</tt> other files.  (Unfortunately, when an
+<tt>include</tt>d file does an <tt>include</tt>, the filename is treated relative to
+the directory in which <tt>gmake</tt> is being run, not the directory in
+which the <tt>included</tt> sits.)  In general, <em>every file <tt>foo.mk</tt>
+assumes that <tt>&dollar;(TOP)/mk/foo.mk</tt> refers to itself.</em> It is up to the
+<tt>Makefile</tt> doing the <tt>include</tt> to ensure this is the case.
+
+Files intended for inclusion in other <tt>Makefile</tt>s are written to have
+the following property: <em/after <tt>foo.mk</tt> is <tt>include</tt>d, it leaves
+<tt>TOP</tt> containing the same value as it had just before the <tt>include</tt>
+statement/.  In our example, this invariant guarantees that the
+<tt>include</tt> for <tt>target.mk</tt> will look in the same directory as that for
+<tt>boilerplate.mk</tt>.
+
+<item> The second section defines the following standard <tt>make</tt>
+variables: <tt>SRCS</tt><ncdx/SRCS/ (the source files from which is to be
+built), and <tt>HS_PROG</tt><ncdx/HS_PROG/ (the executable binary to be
+built).  We will discuss in more detail what the ``standard
+variables'' are, and how they affect what happens, in Section~<ref
+id="sec:targets" name="Targets">.
+
+The definition for <tt>SRCS</tt> uses the useful GNU <tt>make</tt> construct
+<tt>&dollar;(wildcard</tt>~$pat$<tt>)</tt><ncdx/wildcard/, which expands to a list of all
+the files matching the pattern <tt>pat</tt> in the current directory.  In
+this example, <tt>SRCS</tt> is set to the list of all the <tt>.lhs</tt> and <tt>.c</tt>
+files in the directory.  (Let's suppose there is one of each,
+<tt>Foo.lhs</tt> and <tt>Baz.c</tt>.)
+
+<item> The last section includes a second file of standard code,
+called <tt>target.mk</tt><ncdx/target.mk/.  It contains the rules that tell
+<tt>gmake</tt> how to make the standard targets (Section~<ref
+id="sec:standard-targets" name="Standard Targets">).  Why, you ask,
+can't this standard code be part of <tt>boilerplate.mk</tt>?  Good question.
+We discuss the reason later, in Section~<ref id="sec:boiler-arch"
+name="Boilerplate Architecture">.
+
+You do not <em/have/ to <tt>include</tt> the <tt>target.mk</tt> file.  Instead, you
+can write rules of your own for all the standard targets.  Usually,
+though, you will find quite a big payoff from using the canned rules
+in <tt>target.mk</tt>; the price tag is that you have to understand what
+canned rules get enabled, and what they do (Section~<ref
+id="sec:targets" name="Targets">.
+
+</enum>
+
+In our example <tt>Makefile</tt>, most of the work is done by the two
+<tt>include</tt>d files.  When you say <tt>gmake all</tt>, the following things
+happen:
+
+<itemize>
+
+<item> <tt>gmake</tt> figures out that the object files are <tt>Foo.o</tt> and
+<tt>Baz.o</tt>.
+
+<item> It uses a boilerplate pattern rule to compile <tt>Foo.lhs</tt> to
+<tt>Foo.o</tt> using a Haskell compiler.  (Which one?  That is set in the
+build configuration.)
+
+<item> It uses another standard pattern rule to compile <tt>Baz.c</tt> to
+<tt>Baz.o</tt>, using a C compiler.  (Ditto.)
+
+<item> It links the resulting <tt>.o</tt> files together to make <tt>small</tt>,
+using the Haskell compiler to do the link step.  (Why not use <tt>ld</tt>?
+Because the Haskell compiler knows what standard librarise to link in.
+How did <tt>gmake</tt> know to use the Haskell compiler to do the link,
+rather than the C compiler?  Because we set the variable <tt>HS_PROG</tt>
+rather than <tt>C_PROG</tt>.)
+
+</itemize>
+
+All <tt>Makefile</tt>s should follow the above three-section format.
+
+<sect1>A larger project
+<p>
+
+Larger projects are usually structured into a nummber of sub-directories,
+each of which has its own <tt>Makefile</tt>.  (In very large projects, this
+sub-structure might be iterated recursively, though that is rare.)
+To give you the idea, here's part of the directory structure for
+the (rather large) <tt>ghc</tt> project:
+
+<tscreen><verb>
+  $(FPTOOLS_TOP)/ghc/
+    Makefile
+
+    mk/
+      boilerplate.mk
+      rules.mk
+
+    docs/
+      Makefile
+      ...source files for documentation...
+
+    driver/
+      Makefile
+      ...source files for driver...
+
+    compiler/
+      Makefile
+      parser/...source files for parser...
+      renamer/...source files for renamer...
+      ...etc...
+</verb></tscreen>
+
+The sub-directories <tt>docs</tt>, <tt>driver</tt>, <tt>compiler</tt>, and so on, each
+contains a sub-component of <tt>ghc</tt>, and each has its own <tt>Makefile</tt>.
+There must also be a <tt>Makefile</tt> in <tt>&dollar;(FPTOOLS_TOP)/ghc</tt>.  It does most
+of its work by recursively invoking <tt>gmake</tt> on the <tt>Makefile</tt>s in the
+sub-directories.  We say that <tt>ghc/Makefile</tt> is a <em/non-leaf
+<tt>Makefile</tt>/, because it does little except organise its children,
+while the <tt>Makefile</tt>s in the sub-directories are all <em/leaf
+<tt>Makefile</tt>s/.  (In principle the sub-directories might themselves
+contain a non-leaf <tt>Makefile</tt> and several sub-sub-directories, but
+that does not happen in <tt>ghc</tt>.)
+
+The <tt>Makefile</tt> in <tt>ghc/compiler</tt> is considered a leaf <tt>Makefile</tt> even
+though the <tt>ghc/compiler</tt> has sub-directories, because these sub-directories
+do not themselves have <tt>Makefile</tt>s in them.  They are just used to structure
+the collection of modules that make up <tt>ghc</tt>, but all are managed by the
+single <tt>Makefile</tt> in <tt>ghc/compiler</tt>.
+
+You will notice that <tt>ghc/</tt> also contains a directory <tt>ghc/mk/</tt>.  It
+contains <tt>ghc</tt>-specific <tt>Makefile</tt> boilerplate code.  More precisely:
+
+<itemize> 
+
+<item> <tt>ghc/mk/boilerplate.mk</tt> is included at the top of
+<tt>ghc/Makefile</tt>, and of all the leaf <tt>Makefile</tt>s in the
+sub-directories.  It in turn <tt>include</tt>s the main boilerplate file
+<tt>mk/boilerplate.mk</tt>.
+
+
+<item> <tt>ghc/mk/target.mk</tt> is <tt>include</tt>d at the bottom of
+<tt>ghc/Makefile</tt>, and of all the leaf <tt>Makefiles</tt> in the
+sub-directories.  It in turn <tt>include</tt>s the file <tt>mk/target.mk</tt>.
+
+</itemize>
+
+So these two files are the place to look for <tt>ghc</tt>-wide customisation
+of the standard boilerplate.
+
+<sect1>Boilerplate architecture
+<nidx/boilerplate architecture/
+<label id="sec:boiler-arch">
+<p>
+
+Every <tt>Makefile</tt> includes a <tt>boilerplate.mk</tt><ncdx/boilerplate.mk/ file
+at the top, and <tt>target.mk</tt><ncdx/target.mk/ file at the bottom.  In
+this section we discuss what is in these files, and why there have to
+be two of them.  In general:
+
+<itemize>
+
+<item> <tt>boilerplate.mk</tt> consists of:
+<itemize>
+<item> <em/Definitions of millions of <tt>make</tt> variables/ that
+collectively specify the build configuration.  Examples:
+<tt><cdx/HC_OPTS/</tt>, the options to feed to the Haskell compiler;
+<tt><cdx/NoFibSubDirs/</tt>, the sub-directories to enable within the
+<tt>nofib</tt> project; <tt><cdx/GhcWithHc/</tt>, the name of the Haskell
+compiler to use when compiling <tt>GHC</tt> in the <tt>ghc</tt> project.  <item>
+<em/Standard pattern rules/ that tell <tt>gmake</tt> how to construct one
+file from another.
+</itemize>
+
+<tt>boilerplate.mk</tt> needs to be <tt>include</tt>d at the <em/top/
+of each <tt>Makefile</tt>, so that the user can replace the
+boilerplate definitions or pattern rules by simply giving a new
+definition or pattern rule in the <tt>Makefile</tt>.  <tt>gmake</tt>
+simply takes the last definition as the definitive one.
+
+Instead of <em/replacing/ boilerplate definitions, it is also quite
+common to <em/augment/ them. For example, a <tt>Makefile</tt> might say:
+
+<tscreen><verb>
+  SRC_HC_OPTS += -O
+</verb></tscreen>
+
+thereby adding ``<tt>-O</tt>'' to the end of <tt><cdx/SRC_HC_OPTS/</tt>.
+
+<item> <tt>target.mk</tt> contains <tt>make</tt> rules for the standard
+targets described in Section~<ref id="sec:standard-targets"
+name="Standard Targets">.  These rules are selectively included,
+depending on the setting of certain <tt>make</tt> variables.  These
+variables are usually set in the middle section of the
+<tt>Makefile</tt> between the two <tt>include</tt>s.
+
+<tt>target.mk</tt> must be included at the end (rather than being part of
+<tt>boilerplate.mk</tt>) for several tiresome reasons:
+
+<itemize>
+<item> <tt>gmake</tt> commits target and dependency lists earlier than
+it should.  For example, <tt>target.mk</tt> has a rule that looks like
+this: 
+
+<tscreen><verb>
+  $(HS_PROG) : $(OBJS)
+        $(HC) $(LD_OPTS) $< -o $@
+</verb></tscreen>
+
+If this rule was in <tt>boilerplate.mk</tt> then <tt>&dollar;(HS_PROG)</tt><ncdx/HS_PROG/
+and <tt>&dollar;(OBJS)</tt><ncdx/OBJS/ would not have their final values at the
+moment <tt>gmake</tt> encountered the rule.  Alas, <tt>gmake</tt> takes a snapshot
+of their current values, and wires that snapshot into the rule.  (In
+contrast, the commands executed when the rule ``fires'' are only
+substituted at the moment of firing.)  So, the rule must follow the
+definitions given in the <tt>Makefile</tt> itself.
+
+<item> Unlike pattern rules, ordinary rules cannot be overriden or
+replaced by subsequent rules for the same target (at least not without an
+error message).  Including ordinary rules in <tt>boilerplate.mk</tt> would
+prevent the user from writing rules for specific targets in specific cases.
+
+<item> There are a couple of other reasons I've forgotten, but it doesn't
+matter too much.
+</itemize>
+</itemize>
+
+<sect1>The main <tt>mk/boilerplate.mk</tt> file
+<label id="sec:boiler">
+<ncdx/boilerplate.mk/
+<p>
+
+If you look at <tt>&dollar;(FPTOOLS_TOP)/mk/boilerplate.mk</tt> you will find
+that it consists of the following sections, each held in a separate
+file: 
+
+<descrip> 
+
+<tag><tt><cdx/config.mk/</tt></tag> is the build configuration file we
+discussed at length in Section~<ref id="sec:build-config" name="Build
+Configuration">.
+
+<tag><tt><cdx/paths.mk/</tt></tag> defines <tt>make</tt> variables for
+pathnames and file lists.  In particular, it gives definitions for:
+
+<descrip>
+<tag><tt><cdx/SRCS/</tt>:</tag> all source files in the current directory.
+<tag><tt><cdx/HS_SRCS/</tt>:</tag> all Haskell source files in the current directory.
+It is derived from <tt>&dollar;(SRCS)</tt>, so if you override <tt>SRCS</tt> with a new value
+<tt>HS_SRCS</tt> will follow suit.
+<tag><tt><cdx/C_SRCS/</tt>:</tag> similarly for C source files.
+<tag><tt><cdx/HS_OBJS/</tt>:</tag> the <tt>.o</tt> files derived from <tt>&dollar;(HS_SRCS)</tt>.
+<tag><tt><cdx/C_OBJS/</tt>:</tag> similarly for <tt>&dollar;(C_SRCS)</tt>.
+<tag><tt><cdx/OBJS/</tt>:</tag> the concatenation of <tt>&dollar;(HS_OBJS)</tt> and <tt>&dollar;(C_OBJS)</tt>.
+</descrip>
+
+Any or all of these definitions can easily be overriden by giving new
+definitions in your <tt>Makefile</tt>.  For example, if there are things in
+the current directory that look like source files but aren't, then
+you'll need to set <tt>SRCS</tt> manually in your <tt>Makefile</tt>.  The other
+definitions will then work from this new definition.
+
+What, exactly, does <tt>paths.mk</tt> consider a ``source file'' to be.  It's
+based the file's suffix (e.g. <tt>.hs</tt>, <tt>.lhs</tt>, <tt>.c</tt>, <tt>.lc</tt>, etc), but
+this is the kind of detail that changes more rapidly, so rather than
+enumerate the source suffices here the best thing to do is to look in
+<tt>paths.mk</tt>.
+
+<tag><tt><cdx/opts.mk/</tt></tag> defines <tt>make</tt> variables for option
+strings to pass to each program. For example, it defines
+<tt><cdx/HC_OPTS/</tt>, the option strings to pass to the Haskell
+compiler.  See Section~<ref id="sec:suffix" name="Pattern Rules and
+Options">.
+
+<tag><tt><cdx/suffix.mk/</tt></tag> defines standard pattern rules --
+see Section~<ref id="sec:suffix" name="Pattern Rules and Options">.
+</descrip>
+
+Any of the variables and pattern rules defined by the boilerplate file
+can easily be overridden in any particular <tt>Makefile</tt>, because the
+boilerplace <tt>include</tt> comes first.  Definitions after this <tt>include</tt>
+directive simply override the default ones in <tt>boilerplate.mk</tt>.
+
+<sect1>Pattern rules and options
+<label id="sec:suffix">
+<nidx/Pattern rules/
+<p>
+
+The file <tt>suffix.mk</tt><ncdx/suffix.mk/ defines standard <em/pattern
+rules/ that say how to build one kind of file from another, for
+example, how to build a <tt>.o</tt> file from a <tt>.c</tt> file.  (GNU <tt>make</tt>'s
+<em/pattern rules/ are more powerful and easier to use than Unix
+<tt>make</tt>'s <em/suffix rules/.)
+
+Almost all the rules look something like this:
+
+<tscreen><verb>
+%.o : %.c
+        $(RM) $@
+        $(CC) $(CC_OPTS) -c $< -o $@
+</verb></tscreen>
+
+Here's how to understand the rule.  It says that
+<em/something/<tt>.o</tt> (say <tt>Foo.o</tt>) can be built from
+<em/something/<tt>.c</tt> (<tt>Foo.c</tt>), by invoking the C compiler
+(path name held in <tt>&dollar;(CC)</tt>), passing to it the options
+<tt>&dollar;(CC_OPTS)</tt> and the rule's dependent file of the rule
+<tt>&dollar;&lt;</tt> (<tt>Foo.c</tt> in this case), and putting the result in
+the rule's target <tt>&dollar;@</tt> (<tt>Foo.o</tt> in this case).
+
+Every program is held in a <tt>make</tt> variable defined in
+<tt>mk/config.mk</tt> --- look in <tt>mk/config.mk</tt> for the
+complete list.  One important one is the Haskell compiler, which is
+called <tt>&dollar;(HC)</tt>.
+
+Every programs options are are held in a <tt>make</tt> variables called
+<tt>&lt;prog&gt;_OPTS</tt>.  the <tt>&lt;prog&gt;_OPTS</tt> variables are defined in
+<tt>mk/opts.mk</tt>.  Almost all of them are defined like this:
+
+<tscreen><verb>
+  CC_OPTS = $(SRC_CC_OPTS) $(WAY$(_way)_CC_OPTS) $($*_CC_OPTS) $(EXTRA_CC_OPTS)
+</verb></tscreen>
+
+The four variables from which <tt>CC_OPTS</tt> is built have the following meaning:
+
+<descrip>
+
+<tag><tt><cdx/SRC_CC_OPTS/</tt>:</tag> options passed to all C
+compilations.
+
+<tag><tt>WAY_&lt;way&gt;_CC_OPTS</tt>:</tag> options passed to C
+compilations for way <tt>&lt;way&gt;</tt>. For example,
+<tt>WAY_mp_CC_OPTS</tt> gives options to pass to the C compiler when
+compiling way <tt>mp</tt>.  The variable <tt>WAY_CC_OPTS</tt> holds
+options to pass to the C compiler when compiling the standard way.
+(Section~<ref id="sec:ways" name="Ways"> dicusses multi-way
+compilation.)  <tag><tt>&lt;module&gt;_CC_OPTS</tt>:</tag> options to
+pass to the C compiler that are specific to module <tt>&lt;module&gt;</tt>.  For example, <tt>SMap_CC_OPTS</tt> gives the specific options
+to pass to the C compiler when compiling <tt>SMap.c</tt>.
+
+<tag><tt><cdx/EXTRA_CC_OPTS/</tt>:</tag> extra options to pass to all
+C compilations.  This is intended for command line use, thus;
+
+<tscreen><verb>
+  gmake libHS.a EXTRA_CC_OPTS="-v"
+</verb></tscreen>
+</descrip>
+
+<sect1>The main <tt>mk/target.mk</tt> file
+<label id="sec:targets">
+<ncdx/target.mk/
+<p>
+
+<tt>target.mk</tt> contains canned rules for all the standard targets
+described in Section~<ref id="sec:standard-targets" name="Standard
+Targets">.  It is complicated by the fact that you don't want all of
+these rules to be active in every <tt>Makefile</tt>.  Rather than have a
+plethora of tiny files which you can include selectively, there is a
+single file, <tt>target.mk</tt>, which selectively includes rules based on
+whether you have defined certain variables in your <tt>Makefile</tt>.  This
+section explains what rules you get, what variables control them, and
+what the rules do.  Hopefully, you will also get enough of an idea of
+what is supposed to happen that you can read and understand any weird
+special cases yourself.
+
+<descrip>
+<tag><tt><cdx/HS_PROG/</tt>.</tag> If <tt>HS_PROG</tt> is defined, you get
+rules with the following targets:
+<descrip>
+<tag><tt><cdx/HS_PROG/</tt></tag> itself.  This rule links <tt>&dollar;(OBJS)</tt>
+with the Haskell runtime system to get an executable called
+<tt>&dollar;(HS_PROG)</tt>.
+<tag><tt><cdx/install/</tt></tag> installs <tt>&dollar;(HS_PROG)</tt>
+in <tt>&dollar;(bindir)</tt> with the execute bit set.
+</descrip>
+
+<tag><tt><cdx/C_PROG/</tt></tag> is similar to <tt>HS_PROG</tt>, except that
+the link step links <tt>&dollar;(C_OBJS)</tt> with the C runtime system.
+
+<tag><tt><cdx/LIBRARY/</tt></tag> is similar to <tt>HS_PROG</tt>, except that
+it links <tt>&dollar;(LIB_OBJS)</tt> to make the library archive <tt>&dollar;(LIBRARY)</tt>, and
+<tt>install</tt> installs it in <tt>&dollar;(libdir)</tt>, with the execute bit not set.
+
+<tag><tt><cdx/LIB_DATA/</tt></tag> &hellip;
+<tag><tt><cdx/LIB_EXEC/</tt></tag> &hellip;
+
+<tag><tt><cdx/HS_SRCS/</tt>, <tt><cdx/C_SRCS/</tt>.</tag> If <tt>HS_SRCS</tt>
+is defined and non-empty, a rule for the target <tt>depend</tt> is included,
+which generates dependency information for Haskell programs.
+Similarly for <tt>C_SRCS</tt>.
+</descrip>
+
+All of these rules are ``double-colon'' rules, thus
+
+<tscreen><verb>
+  install :: $(HS_PROG)
+        ...how to install it...
+</verb></tscreen>
+
+GNU <tt>make</tt> treats double-colon rules as separate entities.  If there
+are several double-colon rules for the same target it takes each in
+turn and fires it if its dependencies say to do so.  This means that
+you can, for example, define both <tt>HS_PROG</tt> and <tt>LIBRARY</tt>, which will
+generate two rules for <tt>install</tt>.  When you type <tt>gmake install</tt> both
+rules will be fired, and both the program and the library will be
+installed, just as you wanted.
+
+<sect1>Recursion
+<label id="sec:subdirs">
+<nidx/recursion, in makefiles/
+<nidx/Makefile, recursing into subdirectories/
+<p>
+
+In leaf <tt>Makefiles</tt> the variable <tt>SUBDIRS</tt><ncdx/SUBDIRS/ is undefined.
+In non-leaf <tt>Makefiles</tt>, <tt>SUBDIRS</tt> is set to the list of
+sub-directories that contain subordinate <tt>Makefile</tt>s.  <em/It is up to
+you to set <tt>SUBDIRS</tt> in the <tt>Makefile</tt>./ There is no automation here
+--- <tt>SUBDIRS</tt> is too important automate.
+
+When <tt>SUBDIRS</tt> is defined, <tt>target.mk</tt> includes a rather
+neat rule for the standard targets (Section~<ref
+id="sec:standard-targets" name="Standard Targets"> that simply invokes
+<tt>make</tt> recursively in each of the sub-directories.
+
+<em/These recursive invocations are guaranteed to occur in the order
+in which the list of directories is specified in <tt>SUBDIRS</tt>./ This
+guarantee can be important.  For example, when you say <tt>gmake boot</tt> it
+can be important that the recursive invocation of <tt>make boot</tt> is done
+in one sub-directory (the include files, say) before another (the
+source files).  Generally, put the most independent sub-directory
+first, and the most dependent last.
+
+<sect1>Way management
+<label id="sec:ways">
+<nidx/way management/
+<p>
+
+We sometimes want to build essentially the same system in several
+different ``ways''.  For example, we want to build <tt>ghc</tt>'s <tt>Prelude</tt>
+libraries with and without profiling, with and without concurrency,
+and so on, so that there is an appropriately-built library archive to
+link with when the user compiles his program.  It would be possible to
+have a completely separate build tree for each such ``way'', but it
+would be horribly bureaucratic, especially since often only parts of
+the build tree need to be constructed in multiple ways.
+
+Instead, the <tt>target.mk</tt><ncdx/target.mk/ contains some clever magic to
+allow you to build several versions of a system; and to control
+locally how many versions are built and how they differ.  This section
+explains the magic.
+
+The files for a particular way are distinguished by munging the
+suffix.  The ``normal way'' is always built, and its files have the
+standard suffices <tt>.o</tt>, <tt>.hi</tt>, and so on.  In addition, you can build
+one or more extra ways, each distinguished by a <em/way tag/.  The
+object files and interface files for one of these extra ways are
+distinguished by their suffix.  For example, way <tt>mp</tt> has files
+<tt>.mp_o</tt> and <tt>.mp_hi</tt>.  Library archives have their way tag the other
+side of the dot, for boring reasons; thus, <tt>libHS_mp.a</tt>.
+
+A <tt>make</tt> variable called <tt>way</tt> holds the current way tag.  <em/<tt>way</tt>
+is only ever set on the command line of a recursive invocation of
+<tt>gmake</tt>./ It is never set inside a <tt>Makefile</tt>.  So it is a global
+constant for any one invocation of <tt>gmake</tt>.  Two other <tt>make</tt>
+variables, <tt>way_</tt> and <tt>_way</tt> are immediately derived from <tt>&dollar;(way)</tt> and
+never altered.  If <tt>way</tt> is not set, then neither are <tt>way_</tt> and
+<tt>_way</tt>, and the invocation of <tt>make</tt> will build the ``normal way''.
+If <tt>way</tt> is set, then the other two variables are set in sympathy.
+For example, if <tt>&dollar;(way)</tt> is ``<tt>mp</tt>'', then <tt>way_</tt> is set to ``<tt>mp_</tt>''
+and <tt>_way</tt> is set to ``<tt>_mp</tt>''.  These three variables are then used
+when constructing file names.
+
+So how does <tt>make</tt> ever get recursively invoked with <tt>way</tt> set?  There
+are two ways in which this happens:
+
+<itemize>
+
+<item> For some (but not all) of the standard targets, when in a leaf
+sub-directory, <tt>make</tt> is recursively invoked for each way tag in
+<tt>&dollar;(WAYS)</tt>.  You set <tt>WAYS</tt> to the list of way tags you want these
+targets built for.  The mechanism here is very much like the recursive
+invocation of <tt>make</tt> in sub-directories (Section~<ref id="sec:subdirs"
+name="Subdirectories">).
+
+It is up to you to set <tt>WAYS</tt> in your <tt>Makefile</tt>; this is how you
+control what ways will get built.  <item> For a useful collection of
+targets (such as <tt>libHS_mp.a</tt>, <tt>Foo.mp_o</tt>) there is a rule which
+recursively invokes <tt>make</tt> to make the specified target, setting the
+<tt>way</tt> variable.  So if you say <tt>gmake Foo.mp_o</tt> you should see a
+recursive invocation <tt>gmake Foo.mp_o way=mp</tt>, and <em/in this
+recursive invocation the pattern rule for compiling a Haskell file
+into a <tt>.o</tt> file will match/.  The key pattern rules (in <tt>suffix.mk</tt>)
+look like this:
+
+<tscreen><verb>
+  %.$(way_)o : %.lhs
+        $(HC) $(HC_OPTS) $< -o $@
+</verb></tscreen>
+
+Neat, eh?
+</itemize>
+
+
+<sect1>When the canned rule isn't right
+<p>
+
+Sometimes the canned rule just doesn't do the right thing.  For
+example, in the <tt>nofib</tt> suite we want the link step to print out
+timing information.  The thing to do here is <em/not/ to define
+<tt>HS_PROG</tt> or <tt>C_PROG</tt>, and instead define a special purpose rule in
+your own <tt>Makefile</tt>.  By using different variable names you will avoid
+the canned rules being included, and conflicting with yours.
+
+
+<sect>Booting/porting from C (<tt>.hc</tt>) files
+<label id="sec:booting-from-C">
+<nidx>building GHC from .hc files</nidx>
+<nidx>booting GHC from .hc files</nidx>
+<nidx>porting GHC</nidx>
+<p>
+
+This section is for people trying to get GHC going by using the
+supplied intermediate C (<tt>.hc</tt>) files.  This would probably be because
+no binaries have been provided, or because the machine is not ``fully
+supported.''
+
+The intermediate C files are normally made available together with a
+source release, please check the announce message for exact directions
+of where to find them. If we've haven't made them available or you
+can't find them, please ask.
+
+Assuming you've got them, unpack them on top of a fresh source tree.
+Then follow the `normal' instructions in Section~<ref
+id="sec:building-from-source" name="Buiding From Source"> for setting
+up a build tree. When you invoke the configure script, you'll have
+to tell the script about your intentions:
+
+<tscreen><verb>
+foo% ./configure --enable-hc-boot
+</verb></tscreen>
+<ncdx/--enable-hc-boot/
+<ncdx/--disable-hc-boot/
+
+Assuming it configures OK and you don't need to create <tt>mk/build.mk</tt>
+for any other purposes, the next step is to proceed with a <tt>make boot</tt>
+followed by <tt>make all</tt>. At the successful completion of <tt>make all</tt>,
+you should end up with a binary of the compiler proper,
+<tt>ghc/compiler/hsc</tt>, plus archives (but no <tt>.hi</tt> files!) of the prelude
+libraries. To generate the Prelude interface files (and test drive the
+bootstrapped compiler), re-run the <tt>configure</tt> script, but this time
+witout the <tt>--enable-hc-boot</tt> option. After that re-create the
+contents of <tt>ghc/lib</tt>:
+
+<tscreen><verb>
+foo% ./configure
+ ....
+foo% cd ghc/lib
+foo% make clean
+foo% make boot
+foo% make all
+</verb></tscreen>
+
+
+That's the mechanics of the boot process, but, of course, if you're
+trying to boot on a platform that is not supported and significantly
+`different' from any of the supported ones, this is only the start of
+the adventure&hellip;(ToDo: porting tips - stuff to look out for, etc.)
+
+
+<sect>Known pitfalls in building Glasgow Haskell
+<label id="sec:build-pitfalls">
+<nidx>problems, building</nidx>
+<nidx>pitfalls, in building</nidx>
+<nidx>building pitfalls</nidx>
+<p>
+
+WARNINGS about pitfalls and known ``problems'':
+
+<enum>
+
+<item>
+One difficulty that comes up from time to time is running out of space
+in <tt>/tmp</tt>.  (It is impossible for the configuration stuff to
+compensate for the vagaries of different sysadmin approaches re temp
+space.)
+<nidx/tmp, running out of space in/
+
+The quickest way around it is <tt>setenv TMPDIR /usr/tmp</tt><ncdx/TMPDIR/ or
+even <tt>setenv TMPDIR .</tt> (or the equivalent incantation with the shell
+of your choice).
+
+The best way around it is to say
+<tscreen><verb>
+export TMPDIR=<dir>
+</verb></tscreen>
+in your <tt>build.mk</tt> file.
+Then GHC and the other <tt>fptools</tt> programs will use the appropriate directory
+in all cases.
+
+
+<item>
+In compiling some support-code bits, e.g., in <tt>ghc/rts/gmp</tt> and even
+in <tt>ghc/lib</tt>, you may get a few C-compiler warnings.  We think these
+are OK.
+
+<item>
+When compiling via C, you'll sometimes get ``warning: assignment from
+incompatible pointer type'' out of GCC.  Harmless.
+
+<item>
+Similarly, <tt>ar</tt>chiving warning messages like the following are not
+a problem:
+<tscreen><verb>
+ar: filename GlaIOMonad__1_2s.o truncated to GlaIOMonad_
+ar: filename GlaIOMonad__2_2s.o truncated to GlaIOMonad_
+...
+</verb></tscreen>
+
+<item> In compiling the compiler proper (in <tt>compiler/</tt>), you <em/may/
+get an ``Out of heap space'' error message.  These can vary with the
+vagaries of different systems, it seems.  The solution is simple:
+
+<itemize> 
+
+<item> If you're compiling with GHC 4.00 or above, then the
+<em/maximum/ heap size must have been reached.  This is somewhat
+unlikely, since the maximum is set to 64M by default.  Anyway, you can
+raise it with the <tt>-optCrts-M&amp;lt;size&amp;gt;</tt> flag (add this flag to
+<tt>&lt;module&gt;_HC_OPTS</tt> <tt>make</tt> variable in the appropriate <tt>Makefile</tt>).
+
+<item> For GHC < 4.00, add a suitable <tt>-H</tt> flag to the <tt>Makefile</tt>, as
+above.
+
+</itemize>
+
+and try again: <tt>gmake</tt>.  (see Section~<ref id="sec:suffix"
+name="Pattern Rules and Options"> for information about
+<tt>&lt;module&gt;_HC_OPTS</tt>.)
+
+Alternatively, just cut to the chase scene:
+<tscreen><verb>
+% cd ghc/compiler
+% make EXTRA_HC_OPTS=-optCrts-M128M
+</verb></tscreen>
+
+<item>
+If you try to compile some Haskell, and you get errors from GCC about
+lots of things from <tt>/usr/include/math.h</tt>, then your GCC was
+mis-installed.  <tt>fixincludes</tt> wasn't run when it should've been.
+
+As <tt>fixincludes</tt> is now automagically run as part of GCC installation,
+this bug also suggests that you have an old GCC.
+
+
+<item>
+You <em/may/ need to re-<tt>ranlib</tt><ncdx/ranlib/ your libraries (on Sun4s).
+
+<tscreen><verb>
+% cd $(libdir)/ghc-x.xx/sparc-sun-sunos4
+% foreach i ( `find . -name '*.a' -print` ) # or other-shell equiv...
+?    ranlib $i
+?    # or, on some machines: ar s $i
+? end
+</verb></tscreen>
+
+We'd be interested to know if this is still necessary.
+
+
+<item>
+GHC's sources go through <tt>cpp</tt> before being compiled, and <tt>cpp</tt> varies
+a bit from one Unix to another.  One particular gotcha is macro calls
+like this:
+
+<tscreen><verb>
+  SLIT("Hello, world")
+</verb></tscreen>
+
+Some <tt>cpp</tt>s treat the comma inside the string as separating two macro
+arguments, so you get
+
+<tscreen><verb>
+  :731: macro `SLIT' used with too many (2) args
+</verb></tscreen>
+
+Alas, <tt>cpp</tt> doesn't tell you the offending file!
+
+Workaround: don't put wierd things in string args to <tt>cpp</tt> macros.
+</enum>
+
+</article>
diff --git a/ghc/docs/users_guide/intro.sgml b/ghc/docs/users_guide/intro.sgml
new file mode 100644 (file)
index 0000000..553c0c1
--- /dev/null
@@ -0,0 +1,398 @@
+<Chapter id="introduction-GHC">
+<Title>Introduction to GHC
+</Title>
+
+<Para>
+This is a guide to using the Glasgow Haskell compilation (GHC) system. It is
+a batch compiler for the Haskell&nbsp;98 language, with support for various
+Glasgow-only extensions. In this document, we assume that GHC has been
+installed at your site as <Literal>ghc</Literal>.  A separate document,
+``Building and Installing the Glasgow Functional Programming Tools Suite'',
+describes how to install <Literal>ghc</Literal>.
+</Para>
+
+<Para>
+Many people will use GHC very simply: compile some
+modules&mdash;<Literal>ghc -c -O Foo.hs Bar.hs</Literal>; and link them&mdash;
+<Literal>ghc -o wiggle -O Foo.o Bar.o</Literal>.
+</Para>
+
+<Para>
+But if you need to do something more complicated, GHC can do that,
+too:
+
+<Screen>
+ghc -c -O -fno-foldr-build -dcore-lint -fvia-C -ddump-simpl Foo.lhs
+</Screen>
+
+Stay tuned&mdash;all will be revealed!
+</Para>
+
+<Para>
+The rest of this section provide some tutorial information
+on batch-style compilation; if you're familiar with these concepts
+already, then feel free to skip to the next section.
+</Para>
+
+<Sect1 id="batch-system-parts">
+<Title>The (batch) compilation system components</Title>
+
+<Para>
+The Glorious Haskell Compilation System, as with most UNIX (batch)
+compilation systems, has several interacting parts:
+
+<OrderedList>
+<ListItem>
+<Para>
+A <Emphasis>driver</Emphasis><IndexTerm><Primary>driver program</Primary></IndexTerm> 
+<Literal>ghc</Literal><IndexTerm><Primary>ghc</Primary></IndexTerm>&mdash;which
+you usually think of as ``the compiler''&mdash;is a program that merely
+invokes/glues-together the other pieces of the system (listed below),
+passing the right options to each, slurping in the right libraries, etc.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+A <Emphasis>literate pre-processor</Emphasis>
+<IndexTerm><Primary>literate pre-processor</Primary></IndexTerm>
+<IndexTerm><Primary>pre-processor, literate</Primary></IndexTerm>
+<Literal>unlit</Literal><IndexTerm><Primary>unlit</Primary></IndexTerm> that extracts Haskell
+code from a literate script; used if you believe in that sort of
+thing.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+The <Emphasis>Haskellised C pre-processor</Emphasis>
+<IndexTerm><Primary>Haskellised C pre-processor</Primary></IndexTerm>
+<IndexTerm><Primary>C pre-processor, Haskellised</Primary></IndexTerm>
+<IndexTerm><Primary>pre-processor, Haskellised C</Primary></IndexTerm>
+<Literal>hscpp</Literal>,<IndexTerm><Primary>hscpp</Primary></IndexTerm> only needed by people requiring conditional
+compilation, probably for large systems.  The ``Haskellised'' part
+just means that <Literal>&num;line</Literal> directives in the output have been
+converted into proper Haskell <Literal>&lcub;-&num; LINE ... -&rcub;</Literal> pragmas. You must give an explicit <Literal>-cpp</Literal> option 
+<IndexTerm><Primary>-cpp option</Primary></IndexTerm> for the C pre-processor to be invoked.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+The <Emphasis>Haskell compiler</Emphasis>
+<IndexTerm><Primary>Haskell compiler</Primary></IndexTerm>
+<IndexTerm><Primary>compiler, Haskell</Primary></IndexTerm>
+<Literal>hsc</Literal>,<IndexTerm><Primary>hsc</Primary></IndexTerm>
+which&mdash;in normal use&mdash;takes its input from the C pre-processor
+and produces assembly-language output (sometimes: ANSI C output).
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+The <Emphasis>ANSI&nbsp;C Haskell high-level assembler :-)</Emphasis>
+<IndexTerm><Primary>ANSI C compiler</Primary></IndexTerm>
+<IndexTerm><Primary>high-level assembler</Primary></IndexTerm>
+<IndexTerm><Primary>assembler, high-level</Primary></IndexTerm>
+compiles <Literal>hsc</Literal>'s C output into assembly language for a particular
+target architecture.  In fact, the only C compiler we currently
+support is <Literal>gcc</Literal>, because we make use of certain extensions to the
+C language only supported by gcc.  Version 2.x is a must; we recommend
+version 2.7.2.1 for stability (we've heard both good and bad reports
+of later versions).
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+The <Emphasis>assembler</Emphasis><IndexTerm><Primary>assembler</Primary></IndexTerm>&mdash;a standard UNIX one, probably
+<Literal>as</Literal><IndexTerm><Primary>as</Primary></IndexTerm>.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+The <Emphasis>linker</Emphasis><IndexTerm><Primary>linker</Primary></IndexTerm>&mdash;a standard UNIX one, probably
+<Literal>ld</Literal>.<IndexTerm><Primary>ld</Primary></IndexTerm>
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+A <Emphasis>runtime system</Emphasis>,<IndexTerm><Primary>runtime system</Primary></IndexTerm> including (most notably)
+a storage manager; the linker links in the code for this.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+The <Emphasis>Haskell standard prelude</Emphasis><IndexTerm><Primary>standard prelude</Primary></IndexTerm>, a
+large library of standard functions, is linked in as well.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+Parts of other <Emphasis>installed libraries</Emphasis> that you have at your site may be linked in also.
+</Para>
+</ListItem>
+
+</OrderedList>
+</Para>
+
+</Sect1>
+
+<Sect1 id="compile-what-really-happens">
+<Title>What really happens when I ``compile'' a Haskell program?
+</Title>
+
+<Para>
+You invoke the Glasgow Haskell compilation system through the
+driver program <Literal>ghc</Literal>.<IndexTerm><Primary>ghc</Primary></IndexTerm> For example, if you had typed a
+literate ``Hello, world!'' program into <Literal>hello.lhs</Literal>, and you then
+invoked:
+
+<Screen>
+ghc hello.lhs
+</Screen>
+
+</Para>
+
+<Para>
+the following would happen:
+
+<OrderedList>
+<ListItem>
+
+<Para>
+The file <Literal>hello.lhs</Literal> is run through the literate-program
+code extractor <Literal>unlit</Literal><IndexTerm><Primary>unlit</Primary></IndexTerm>, feeding its output to
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+The Haskell compiler proper <Literal>hsc</Literal><IndexTerm><Primary>hsc</Primary></IndexTerm>, which produces
+input for
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+The assembler (or that ubiquitous ``high-level assembler,'' a C
+compiler), which produces an object file and passes it to
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+The linker, which links your code with the appropriate libraries
+(including the standard prelude), producing an executable program in
+the default output file named <Literal>a.out</Literal>.
+</Para>
+</ListItem>
+
+</OrderedList>
+
+</Para>
+
+<Para>
+You have considerable control over the compilation process.  You feed
+command-line arguments (call them ``options,'' for short) to the
+driver, <Literal>ghc</Literal>; the ``types'' of the input files (as encoded in
+their names' suffixes) also matter.
+</Para>
+
+<Para>
+Here's hoping this is enough background so that you can read the rest
+of this guide!
+</Para>
+
+</Sect1>
+
+<Sect1 id="mailing-lists-GHC">
+<Title>Meta-information: Web sites, mailing lists, etc.
+</Title>
+
+<Para>
+<IndexTerm><Primary>mailing lists, Glasgow Haskell</Primary></IndexTerm>
+<IndexTerm><Primary>Glasgow Haskell mailing lists</Primary></IndexTerm>
+</Para>
+
+<Para>
+On the World-Wide Web, there are several URLs of likely interest:
+</Para>
+
+<Para>
+
+<ItemizedList>
+<ListItem>
+
+<Para>
+  <ULink
+URL="http://www.haskell.org/"
+>Haskell home page</ULink
+>
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+  <ULink
+URL="http://www.haskell.org/ghc/"
+>GHC home page</ULink
+>
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+  <ULink
+URL="http://www.dcs.gla.ac.uk/fp/"
+>Glasgow FP group page</ULink
+>
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+  <ULink
+URL="http://www.cs.nott.ac.uk/Department/Staff/mpj/faq.html"
+>comp.lang.functional FAQ</ULink
+>
+</Para>
+</ListItem>
+
+</ItemizedList>
+
+</Para>
+
+<Para>
+We run two mailing lists about Glasgow Haskell.  We encourage you to
+join, as you feel is appropriate.
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term>glasgow-haskell-users:</Term>
+<ListItem>
+<Para>
+This list is for GHC users to chat among themselves.  Subscribe by
+sending mail to <ULink
+URL="mailto:majordomo@haskell.org"
+>majordomo@haskell.org</ULink
+>, with a message body (not
+header) like this:
+</Para>
+
+<Para>
+
+<Screen> 
+subscribe glasgow-haskell-users MyName &#60;m.y.self@bigbucks.com&#62; 
+</Screen>
+</Para>
+
+<Para>
+(The last bit is your all-important e-mail address, of course.)
+</Para>
+
+<Para>
+To communicate with your fellow users, send mail to <ULink
+URL="mailto:glasgow-haskell-users@haskell.org"
+>glasgow-haskell-users@haskell.org</ULink
+>.
+</Para>
+
+<Para>
+To contact the list administrator, send mail to <ULink
+URL="mailto:glasgow-haskell-users-request@haskell.org"
+>glasgow-haskell-users-request@haskell.org</ULink
+>.  An archive
+of the list is available on the Web: <ULink
+URL="http://www.dcs.gla.ac.uk/mail-www/glasgow-haskell-users"
+>glasgow-haskell-users mailing list archive</ULink
+>.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>glasgow-haskell-bugs:</Term>
+<ListItem>
+<Para>
+Send bug reports for GHC to this address!  The sad and lonely people
+who subscribe to this list will muse upon what's wrong and what you
+might do about it.
+</Para>
+
+<Para>
+Subscribe via <ULink
+URL="mailto:majordomo@haskell.org"
+>majordomo@haskell.org</ULink
+> with:
+</Para>
+
+<Para>
+
+<Screen>
+subscribe glasgow-haskell-bugs My Name &#60;m.y.self@hackers.r.us&#62;
+</Screen>
+
+</Para>
+
+<Para>
+Again, you may contact the list administrator at <ULink
+URL="mailto:glasgow-haskell-bugs-request@haskell.org"
+>glasgow-haskell-bugs-request@haskell.org</ULink
+>.
+And, yes, an archive of the list is available on the Web at: : <ULink
+URL="http://www.dcs.gla.ac.uk/mail-www/glasgow-haskell-bugs"
+>glasgow-haskell-bugs mailing list archive</ULink
+>
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+<Para>
+There is also the general Haskell mailing list.  Subscribe by sending
+email to <ULink
+URL="mailto:majordomo@dcs.gla.ac.uk"
+>majordomo@dcs.gla.ac.uk</ULink
+>, with the usual message body:
+</Para>
+
+<Para>
+
+<Screen>
+subscribe haskell My Name &#60;m.y.self@@fp.rules.ok.org&#62;
+</Screen>
+
+</Para>
+
+<Para>
+Some Haskell-related discussion takes place in the Usenet newsgroup
+<Literal>comp.lang.functional</Literal>.  (But note: news is basically dead at Glasgow.
+That's one reason Glaswegians aren't too active in c.f.l.)
+</Para>
+
+<Para>
+The main anonymous-FTP site for Glasgow Haskell is <ULink
+URL="ftp://ftp.dcs.gla.ac.uk/pub/haskell/glasgow"
+>ftp://ftp.dcs.gla.ac.uk/pub/haskell/glasgow</ULink
+>.  ``Important''
+bits are mirrored at other Haskell archive sites (and we have their
+stuff, too).
+</Para>
+
+</Sect1>
+
+&relnotes
+
+</Chapter>
diff --git a/ghc/docs/users_guide/lang.sgml b/ghc/docs/users_guide/lang.sgml
new file mode 100644 (file)
index 0000000..dca6e30
--- /dev/null
@@ -0,0 +1,8 @@
+<Chapter id="ghc-language-features">
+<Title>GHC Language Features</Title>
+
+&glaexts
+&parallel
+&vs-hs
+
+</Chapter>
diff --git a/ghc/docs/users_guide/libmisc.sgml b/ghc/docs/users_guide/libmisc.sgml
new file mode 100644 (file)
index 0000000..530f83e
--- /dev/null
@@ -0,0 +1,1046 @@
+<Sect1 id="GHC-library">
+<Title>Miscellaneous libraries
+</Title>
+
+<Para>
+<IndexTerm><Primary>libraries, miscellaneous</Primary></IndexTerm>
+<IndexTerm><Primary>misc, syslib</Primary></IndexTerm>
+</Para>
+
+<Para>
+This section describes a collection of Haskell libraries we've
+collected over the years.  Access to any of these modules is provided
+by giving the <Literal>-syslib misc</Literal><IndexTerm><Primary>-syslib misc option</Primary></IndexTerm>.
+</Para>
+
+<Sect2 id="Bag">
+<Title>The <Literal>Bag</Literal> type
+</Title>
+
+<Para>
+<IndexTerm><Primary>Bag module (misc syslib)</Primary></IndexTerm>
+</Para>
+
+<Para>
+A <Emphasis>bag</Emphasis> is an unordered collection of elements which may contain
+duplicates.  To use, <Literal>import Bag</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+data Bag elt    -- abstract
+
+emptyBag        :: Bag elt
+unitBag         :: elt -&#62; Bag elt
+
+consBag         :: elt       -&#62; Bag elt -&#62; Bag elt
+snocBag         :: Bag elt   -&#62; elt     -&#62; Bag elt
+
+unionBags       :: Bag elt   -&#62; Bag elt -&#62; Bag elt
+unionManyBags   :: [Bag elt] -&#62; Bag elt
+
+isEmptyBag      :: Bag elt   -&#62; Bool
+elemBag         :: Eq elt =&#62; elt -&#62; Bag elt -&#62; Bool
+
+filterBag       :: (elt -&#62; Bool) -&#62; Bag elt -&#62; Bag elt
+partitionBag    :: (elt -&#62; Bool) -&#62; Bag elt-&#62; (Bag elt, Bag elt)
+        -- returns the elements that do/don't satisfy the predicate
+
+concatBag       :: Bag (Bag a) -&#62; Bag a
+foldBag         :: (r -&#62; r -&#62; r) -&#62; (a -&#62; r) -&#62; r -&#62; Bag a -&#62; r
+mapBag          :: (a -&#62; b) -&#62; Bag a -&#62; Bag b
+
+listToBag       :: [elt] -&#62; Bag elt
+bagToList       :: Bag elt -&#62; [elt]
+</ProgramListing>
+
+</Para>
+
+</Sect2>
+
+<Sect2 id="FiniteMap">
+<Title>The <Literal>FiniteMap</Literal> type
+</Title>
+
+<Para>
+<IndexTerm><Primary>FiniteMap module (misc syslib)</Primary></IndexTerm>
+</Para>
+
+<Para>
+What functional programmers call a <Emphasis>finite map</Emphasis>, everyone else
+calls a <Emphasis>lookup table</Emphasis>.
+</Para>
+
+<Para>
+Out code is derived from that in this paper:
+<QUOTE
+>S Adams
+"Efficient sets: a balancing act"
+Journal of functional programming 3(4) Oct 1993, pages 553-562</QUOTE
+>
+Guess what?  The implementation uses balanced trees.
+</Para>
+
+<Para>
+
+<ProgramListing>
+data FiniteMap key elt  -- abstract
+
+--      BUILDING
+emptyFM         :: FiniteMap key elt
+unitFM          :: key -&#62; elt -&#62; FiniteMap key elt
+listToFM        :: Ord key =&#62; [(key,elt)] -&#62; FiniteMap key elt
+                        -- In the case of duplicates, the last is taken
+
+--      ADDING AND DELETING
+                   -- Throws away any previous binding
+                   -- In the list case, the items are added starting with the
+                   -- first one in the list
+addToFM         :: Ord key =&#62; FiniteMap key elt -&#62; key -&#62; elt  -&#62; FiniteMap key elt
+addListToFM     :: Ord key =&#62; FiniteMap key elt -&#62; [(key,elt)] -&#62; FiniteMap key elt
+
+                 -- Combines with previous binding
+                 -- In the combining function, the first argument is
+                 -- the "old" element, while the second is the "new" one.
+addToFM_C       :: Ord key =&#62; (elt -&#62; elt -&#62; elt)
+                           -&#62; FiniteMap key elt -&#62; key -&#62; elt
+                           -&#62; FiniteMap key elt
+addListToFM_C   :: Ord key =&#62; (elt -&#62; elt -&#62; elt)
+                           -&#62; FiniteMap key elt -&#62; [(key,elt)]
+                           -&#62; FiniteMap key elt
+
+                 -- Deletion doesn't complain if you try to delete something
+                 -- which isn't there
+delFromFM       :: Ord key =&#62; FiniteMap key elt -&#62; key   -&#62; FiniteMap key elt
+delListFromFM   :: Ord key =&#62; FiniteMap key elt -&#62; [key] -&#62; FiniteMap key elt
+
+--      COMBINING
+                 -- Bindings in right argument shadow those in the left
+plusFM          :: Ord key =&#62; FiniteMap key elt -&#62; FiniteMap key elt
+                           -&#62; FiniteMap key elt
+
+                   -- Combines bindings for the same thing with the given function
+plusFM_C        :: Ord key =&#62; (elt -&#62; elt -&#62; elt)
+                           -&#62; FiniteMap key elt -&#62; FiniteMap key elt -&#62; FiniteMap key elt
+
+minusFM         :: Ord key =&#62; FiniteMap key elt -&#62; FiniteMap key elt -&#62; FiniteMap key elt
+                   -- (minusFM a1 a2) deletes from a1 any bindings which are bound in a2
+
+intersectFM     :: Ord key =&#62; FiniteMap key elt -&#62; FiniteMap key elt -&#62; FiniteMap key elt
+intersectFM_C   :: Ord key =&#62; (elt -&#62; elt -&#62; elt)
+                           -&#62; FiniteMap key elt -&#62; FiniteMap key elt -&#62; FiniteMap key elt
+
+--      MAPPING, FOLDING, FILTERING
+foldFM          :: (key -&#62; elt -&#62; a -&#62; a) -&#62; a -&#62; FiniteMap key elt -&#62; a
+mapFM           :: (key -&#62; elt1 -&#62; elt2) -&#62; FiniteMap key elt1 -&#62; FiniteMap key elt2
+filterFM        :: Ord key =&#62; (key -&#62; elt -&#62; Bool)
+                           -&#62; FiniteMap key elt -&#62; FiniteMap key elt
+
+--      INTERROGATING
+sizeFM          :: FiniteMap key elt -&#62; Int
+isEmptyFM       :: FiniteMap key elt -&#62; Bool
+
+elemFM          :: Ord key =&#62; key -&#62; FiniteMap key elt -&#62; Bool
+lookupFM        :: Ord key =&#62; FiniteMap key elt -&#62; key -&#62; Maybe elt
+lookupWithDefaultFM
+                :: Ord key =&#62; FiniteMap key elt -&#62; elt -&#62; key -&#62; elt
+                -- lookupWithDefaultFM supplies a "default" elt
+                -- to return for an unmapped key
+
+--      LISTIFYING
+fmToList        :: FiniteMap key elt -&#62; [(key,elt)]
+keysFM          :: FiniteMap key elt -&#62; [key]
+eltsFM          :: FiniteMap key elt -&#62; [elt]
+</ProgramListing>
+
+</Para>
+
+</Sect2>
+
+<Sect2 id="ListSetOps">
+<Title>The <Literal>ListSetOps</Literal> type
+</Title>
+
+<Para>
+<IndexTerm><Primary>ListSetOps module (misc syslib)</Primary></IndexTerm>
+</Para>
+
+<Para>
+Just a few set-sounding operations on lists.  If you want sets, use
+the <Literal>Set</Literal> module.
+</Para>
+
+<Para>
+
+<ProgramListing>
+unionLists          :: Eq a =&#62; [a] -&#62; [a] -&#62; [a]
+intersectLists      :: Eq a =&#62; [a] -&#62; [a] -&#62; [a]
+minusList           :: Eq a =&#62; [a] -&#62; [a] -&#62; [a]
+disjointLists       :: Eq a =&#62; [a] -&#62; [a] -&#62; Bool
+intersectingLists   :: Eq a =&#62; [a] -&#62; [a] -&#62; Bool
+</ProgramListing>
+
+</Para>
+
+</Sect2>
+
+<Sect2 id="Maybes">
+<Title>The <Literal>Maybes</Literal> type
+</Title>
+
+<Para>
+<IndexTerm><Primary>Maybes module (misc syslib)</Primary></IndexTerm>
+</Para>
+
+<Para>
+The <Literal>Maybe</Literal> type is in the Haskell 1.4 prelude. Moreover, the
+required <Literal>Maybe</Literal> library provides many useful functions on
+<Literal>Maybe</Literal>s. This (pre-1.3) module provides some more:
+</Para>
+
+<Para>
+An <Literal>Either</Literal>-like type called <Literal>MaybeErr</Literal>:
+
+<ProgramListing>
+data MaybeErr val err = Succeeded val | Failed err
+</ProgramListing>
+
+</Para>
+
+<Para>
+Some operations to do with <Literal>Maybe</Literal> (some commentary follows):
+
+<ProgramListing>
+maybeToBool :: Maybe a -&#62; Bool      -- Nothing =&#62; False; Just =&#62; True
+allMaybes   :: [Maybe a] -&#62; Maybe [a]
+firstJust   :: [Maybe a] -&#62; Maybe a
+findJust    :: (a -&#62; Maybe b) -&#62; [a] -&#62; Maybe b
+
+assocMaybe  :: Eq a =&#62; [(a,b)] -&#62; a -&#62; Maybe b
+mkLookupFun :: (key -&#62; key -&#62; Bool) -- Equality predicate
+            -&#62; [(key,val)]          -- The assoc list
+            -&#62; (key -&#62; Maybe val)   -- A lookup fun to use
+mkLookupFunDef :: (key -&#62; key -&#62; Bool)  -- Equality predicate
+               -&#62; [(key,val)]           -- The assoc list
+               -&#62; val                   -- Value to return on failure
+               -&#62; key                   -- The key
+               -&#62; val                   -- The corresponding value
+
+    -- a monad thing
+thenMaybe   :: Maybe a -&#62; (a -&#62; Maybe b) -&#62; Maybe b
+returnMaybe :: a -&#62; Maybe a
+failMaybe   :: Maybe a
+mapMaybe    :: (a -&#62; Maybe b) -&#62; [a] -&#62; Maybe [b]
+</ProgramListing>
+
+</Para>
+
+<Para>
+NB: <Literal>catMaybes</Literal> which used to be here, is now available via the
+standard <Literal>Maybe</Literal> interface (<Literal>Maybe</Literal> is an instance of <Literal>MonadPlus</Literal>).
+</Para>
+
+<Para>
+<Literal>allMaybes</Literal> collects a list of <Literal>Justs</Literal> into a single <Literal>Just</Literal>, returning
+<Literal>Nothing</Literal> if there are any <Literal>Nothings</Literal>.
+</Para>
+
+<Para>
+<Literal>firstJust</Literal> takes a list of <Literal>Maybes</Literal> and returns the
+first <Literal>Just</Literal> if there is one, or <Literal>Nothing</Literal> otherwise.
+</Para>
+
+<Para>
+<Literal>assocMaybe</Literal> looks up in an association list, returning
+<Literal>Nothing</Literal> if it fails.
+</Para>
+
+<Para>
+Now, some operations to do with <Literal>MaybeErr</Literal> (comments follow):
+
+<ProgramListing>
+    -- a monad thing (surprise, surprise)
+thenMaB   :: MaybeErr a err -&#62; (a -&#62; MaybeErr b err) -&#62; MaybeErr b err
+returnMaB :: val -&#62; MaybeErr val err
+failMaB   :: err -&#62; MaybeErr val err
+
+listMaybeErrs :: [MaybeErr val err] -&#62; MaybeErr [val] [err]
+foldlMaybeErrs :: (acc -&#62; input -&#62; MaybeErr acc err)
+               -&#62; acc
+               -&#62; [input]
+               -&#62; MaybeErr acc [err]
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>listMaybeErrs</Literal> takes a list of <Literal>MaybeErrs</Literal> and, if they all succeed,
+returns a <Literal>Succeeded</Literal> of a list of their values.  If any fail, it
+returns a <Literal>Failed</Literal> of the list of all the errors in the list.
+</Para>
+
+<Para>
+<Literal>foldlMaybeErrs</Literal> works along a list, carrying an accumulator; it
+applies the given function to the accumulator and the next list item,
+accumulating any errors that occur.
+</Para>
+
+</Sect2>
+
+<Sect2 id="memo-library">
+<Title>The <Literal>Memo</Literal> library
+</Title>
+
+<Para>
+<IndexTerm><Primary>Memo (misc syslib)</Primary></IndexTerm>
+</Para>
+
+<Para>
+The <Literal>Memo</Literal> library provides fast polymorphic memo functions using hash
+tables.  The interface is:
+</Para>
+
+<Para>
+
+<ProgramListing>
+memo :: (a -&#62; b) -&#62; a -&#62; b
+</ProgramListing>
+
+</Para>
+
+<Para>
+So, for example, <Literal>memo f</Literal> is a version of <Literal>f</Literal> that caches the results
+of previous calls.
+</Para>
+
+<Para>
+The searching is very fast, being based on pointer equality.  One
+consequence of this is that the caching will only be effective if
+<Emphasis>exactly the same argument is passed again to the memoised
+function</Emphasis>.  This means not just a copy of a previous argument, but the
+same instance.  It's not useful to memoise integer functions using
+this interface, because integers are generally copied a lot and two
+instances of '27' are unlikely to refer to the same object.
+</Para>
+
+<Para>
+This memoisation library works well when the keys are large (or even
+infinite).
+</Para>
+
+<Para>
+The memo table implementation uses weak pointers and stable names (see
+the GHC/Hugs library document) to avoid space leaks and allow hashing
+for arbitrary Haskell objects.  NOTE: while individual memo table
+entries will be garbage collected if the associated key becomes
+garbage, the memo table itself will not be collected if the function
+becomes garbage.  We plan to fix this in a future version.
+</Para>
+
+<Para>
+There's another version of <Literal>memo</Literal> if you want to explicitly give a
+size for the hash table (the default size is 1001 buckets):
+</Para>
+
+<Para>
+
+<ProgramListing>
+memo_sized :: Int -&#62; (a -&#62; b) -&#62; a -&#62; b
+</ProgramListing>
+
+</Para>
+
+</Sect2>
+
+<Sect2 id="PackedString">
+<Title>The <Literal>PackedString</Literal> type
+</Title>
+
+<Para>
+<IndexTerm><Primary>PackedString module (misc syslib)</Primary></IndexTerm>
+</Para>
+
+<Para>
+You need to <Literal>import PackedString</Literal> and heave in your
+<Literal>-syslib ghc</Literal> to use <Literal>PackedString</Literal>s.
+</Para>
+
+<Para>
+The basic type and functions available are:
+
+<ProgramListing>
+data PackedString -- abstract
+
+packString          :: [Char] -&#62; PackedString
+packStringST        :: [Char] -&#62; ST s PackedString
+packCBytesST        :: Int -&#62; Addr -&#62; ST s PackedString
+packBytesForCST     :: [Char] -&#62; ST s (ByteArray Int)
+byteArrayToPS       :: ByteArray Int -&#62; PackedString
+unsafeByteArrayToPS :: ByteArray a   -&#62; Int -&#62; PackedString
+psToByteArray       :: PackedString -&#62; ByteArray Int
+psToByteArrayST     :: PackedString -&#62; ST s (ByteArray Int)
+
+unpackPS        :: PackedString -&#62; [Char]
+</ProgramListing>
+
+</Para>
+
+<Para>
+We also provide a wad of list-manipulation-like functions:
+
+<ProgramListing>
+nilPS       :: PackedString
+consPS      :: Char -&#62; PackedString -&#62; PackedString
+
+headPS      :: PackedString -&#62; Char
+tailPS      :: PackedString -&#62; PackedString
+nullPS      :: PackedString -&#62; Bool
+appendPS    :: PackedString -&#62; PackedString -&#62; PackedString
+lengthPS    :: PackedString -&#62; Int
+indexPS     :: PackedString -&#62; Int -&#62; Char
+            -- 0-origin indexing into the string
+mapPS       :: (Char -&#62; Char) -&#62; PackedString -&#62; PackedString
+filterPS    :: (Char -&#62; Bool) -&#62; PackedString -&#62; PackedString
+foldlPS     :: (a -&#62; Char -&#62; a) -&#62; a -&#62; PackedString -&#62; a
+foldrPS     :: (Char -&#62; a -&#62; a) -&#62; a -&#62; PackedString -&#62; a
+takePS      :: Int -&#62; PackedString -&#62; PackedString
+dropPS      :: Int -&#62; PackedString -&#62; PackedString
+splitAtPS   :: Int -&#62; PackedString -&#62; (PackedString, PackedString)
+takeWhilePS :: (Char -&#62; Bool) -&#62; PackedString -&#62; PackedString
+dropWhilePS :: (Char -&#62; Bool) -&#62; PackedString -&#62; PackedString
+spanPS      :: (Char -&#62; Bool) -&#62; PackedString -&#62; (PackedString, PackedString)
+breakPS     :: (Char -&#62; Bool) -&#62; PackedString -&#62; (PackedString, PackedString)
+linesPS     :: PackedString -&#62; [PackedString]
+wordsPS     :: PackedString -&#62; [PackedString]
+reversePS   :: PackedString -&#62; PackedString
+concatPS    :: [PackedString] -&#62; PackedString
+elemPS      :: Char -&#62; PackedString -&#62; Bool
+  -- Perl-style split&amp;join
+splitPS     :: Char -&#62; PackedString -&#62; [PackedString]
+splitWithPS :: (Char -&#62; Bool) -&#62; PackedString -&#62; [PackedString]
+joinPS      :: PackedString -&#62; [PackedString] -&#62; PackedString
+
+substrPS   :: PackedString -&#62; Int -&#62; Int -&#62; PackedString
+           -- pluck out a piece of a PackedString
+           -- start and end chars you want; both 0-origin-specified
+</ProgramListing>
+
+</Para>
+
+</Sect2>
+
+<Sect2 id="Set">
+<Title>The <Literal>Set</Literal> type
+</Title>
+
+<Para>
+<IndexTerm><Primary>Set module (misc syslib)</Primary></IndexTerm>
+</Para>
+
+<Para>
+Our implementation of <Emphasis>sets</Emphasis> (key property: no duplicates) is just
+a variant of the <Literal>FiniteMap</Literal> module.
+</Para>
+
+<Para>
+
+<ProgramListing>
+data Set        -- abstract
+                -- instance of: Eq
+
+emptySet        :: Set a
+mkSet           :: Ord a =&#62; [a]  -&#62; Set a
+setToList       :: Set a -&#62; [a]
+unitSet         :: a -&#62; Set a
+singletonSet    :: a -&#62; Set a  -- deprecated, use unitSet.
+
+union           :: Ord a =&#62; Set a -&#62; Set a -&#62; Set a
+unionManySets   :: Ord a =&#62; [Set a] -&#62; Set a
+minusSet        :: Ord a =&#62; Set a -&#62; Set a -&#62; Set a
+mapSet          :: Ord a =&#62; (b -&#62; a) -&#62; Set b -&#62; Set a
+intersect       :: Ord a =&#62; Set a -&#62; Set a -&#62; Set a
+
+elementOf       :: Ord a =&#62; a -&#62; Set a -&#62; Bool
+isEmptySet      :: Set a -&#62; Bool
+
+cardinality     :: Set a -&#62; Int
+</ProgramListing>
+
+</Para>
+
+</Sect2>
+
+<Sect2 id="BitSet">
+<Title>The <Literal>BitSet</Literal> interface
+</Title>
+
+<Para>
+<IndexTerm><Primary>Bitset interface (misc syslib)</Primary></IndexTerm>
+</Para>
+
+<Para>
+Bit sets are a fast implementation of sets of integers ranging from 0
+to one less than the number of bits in a machine word (typically 31).
+If any element exceeds the maximum value for a particular machine
+architecture, the results of these operations are undefined.  You have
+been warned.
+</Para>
+
+<Para>
+
+<ProgramListing>
+data BitSet   -- abstract
+              -- instance of:
+
+emptyBS       :: BitSet
+mkBS          :: [Int] -&#62; BitSet
+unitBS        :: Int -&#62; BitSet
+unionBS       :: BitSet -&#62; BitSet -&#62; BitSet
+minusBS       :: BitSet -&#62; BitSet -&#62; BitSet
+isEmptyBS     :: BitSet -&#62; Bool
+intersectBS   :: BitSet -&#62; BitSet -&#62; BitSet
+elementBS     :: Int -&#62; BitSet -&#62; Bool
+listBS        :: BitSet -&#62; [Int]
+</ProgramListing>
+
+</Para>
+
+</Sect2>
+
+<Sect2 id="Util">
+<Title>The <Literal>Util</Literal> type
+</Title>
+
+<Para>
+<IndexTerm><Primary>Util module (misc syslib)</Primary></IndexTerm>
+</Para>
+
+<Para>
+Stuff that has been generally useful to use in writing the compiler.
+Don't be too surprised if this stuff moves/gets-renamed/etc.
+</Para>
+
+<Para>
+
+<ProgramListing>
+-- general list processing
+forall          :: (a -&#62; Bool) -&#62; [a] -&#62; Bool
+exists          :: (a -&#62; Bool) -&#62; [a] -&#62; Bool
+
+nOfThem         :: Int -&#62; a -&#62; [a]
+lengthExceeds   :: [a] -&#62; Int -&#62; Bool
+isSingleton     :: [a] -&#62; Bool
+
+--paranoid zip'ing (equal length lists)
+zipEqual        :: [a] -&#62; [b] -&#62; [(a,b)]
+zipWithEqual    :: String -&#62; (a-&#62;b-&#62;c) -&#62; [a]-&#62;[b]-&#62;[c]
+zipWith3Equal   :: String -&#62; (a-&#62;b-&#62;c-&#62;d) -&#62; [a]-&#62;[b]-&#62;[c]-&#62;[d]
+zipWith4Equal   :: String -&#62; (a-&#62;b-&#62;c-&#62;d-&#62;e) -&#62; [a]-&#62;[b]-&#62;[c]-&#62;[d]-&#62;[e]
+-- lazy in second argument
+zipLazy :: [a] -&#62; [b] -&#62; [(a,b)]
+
+mapAndUnzip :: (a -&#62; (b, c)) -&#62; [a] -&#62; ([b], [c])
+mapAndUnzip3 :: (a -&#62; (b, c, d)) -&#62; [a] -&#62; ([b], [c], [d])
+
+-- prefix and suffix matching on lists of characters.
+startsWith :: {-prefix-}String -&#62; String -&#62; Maybe String
+endsWith   :: {-suffix-}String -&#62; String -&#62; Maybe String
+
+-- association lists
+assoc       :: Eq a =&#62; String -&#62; [(a, b)] -&#62; a -&#62; b
+
+-- duplicate handling
+hasNoDups    :: Eq a =&#62; [a] -&#62; Bool
+equivClasses :: (a -&#62; a -&#62; Ordering) -&#62; [a] -&#62; [[a]]
+runs         :: (a -&#62; a -&#62; Bool)     -&#62; [a] -&#62; [[a]]
+removeDups   :: (a -&#62; a -&#62; Ordering) -&#62; [a] -&#62; ([a], [[a]])
+
+-- sorting (don't complain of no choice...)
+quicksort          :: (a -&#62; a -&#62; Bool)     -&#62; [a] -&#62; [a]
+sortLt             :: (a -&#62; a -&#62; Bool)     -&#62; [a] -&#62; [a]
+stableSortLt       :: (a -&#62; a -&#62; Bool)     -&#62; [a] -&#62; [a]
+mergesort          :: (a -&#62; a -&#62; _CMP_TAG) -&#62; [a] -&#62; [a]
+mergeSort          :: Ord a =&#62; [a] -&#62; [a]
+naturalMergeSort   :: Ord a =&#62; [a] -&#62; [a]
+mergeSortLe        :: Ord a =&#62; [a] -&#62; [a]
+naturalMergeSortLe :: Ord a =&#62; [a] -&#62; [a]
+
+-- transitive closures
+transitiveClosure :: (a -&#62; [a])         -- Successor function
+                  -&#62; (a -&#62; a -&#62; Bool)   -- Equality predicate
+                  -&#62; [a]
+                  -&#62; [a]                -- The transitive closure
+
+-- accumulating (Left, Right, Bi-directional)
+mapAccumL :: (acc -&#62; x -&#62; (acc, y))
+                        -- Function of elt of input list and
+                        -- accumulator, returning new accumulator and
+                        -- elt of result list
+          -&#62; acc        -- Initial accumulator
+          -&#62; [x]        -- Input list
+          -&#62; (acc, [y]) -- Final accumulator and result list
+
+mapAccumR :: (acc -&#62; x -&#62; (acc, y)) -&#62; acc -&#62; [x] -&#62; (acc, [y])
+
+mapAccumB :: (accl -&#62; accr -&#62; x -&#62; (accl, accr,y))
+          -&#62; accl -&#62; accr -&#62; [x]
+          -&#62; (accl, accr, [y])
+
+--list comparison with explicit element comparer.
+cmpList :: (a -&#62; a -&#62; Ordering) -&#62; [a] -&#62; [a] -&#62; Ordering
+
+-- pairs
+applyToPair :: ((a -&#62; c), (b -&#62; d)) -&#62; (a, b) -&#62; (c, d)
+applyToFst  :: (a -&#62; c) -&#62; (a, b) -&#62; (c, b)
+applyToSnd  :: (b -&#62; d) -&#62; (a, b) -&#62; (a, d)
+foldPair    :: (a-&#62;a-&#62;a, b-&#62;b-&#62;b) -&#62; (a, b) -&#62; [(a, b)] -&#62; (a, b)
+unzipWith   :: (a -&#62; b -&#62; c) -&#62; [(a, b)] -&#62; [c]
+</ProgramListing>
+
+</Para>
+
+</Sect2>
+
+</Sect1>
+
+<Sect1 id="C-interfaces">
+<Title>Interfaces to C libraries
+</Title>
+
+<Para>
+<IndexTerm><Primary>C library interfaces</Primary></IndexTerm>
+<IndexTerm><Primary>interfaces, C library</Primary></IndexTerm>
+</Para>
+
+<Para>
+The GHC system library (<Literal>-syslib misc</Literal>) also provides interfaces to
+several useful C libraries, mostly from the GNU project.
+</Para>
+
+<Sect2 id="Readline">
+<Title>The <Literal>Readline</Literal> interface
+</Title>
+
+<Para>
+<IndexTerm><Primary>Readline library (misc syslib)</Primary></IndexTerm>
+<IndexTerm><Primary>command-line editing library</Primary></IndexTerm>
+</Para>
+
+<Para>
+(Darren Moffat supplied the <Literal>Readline</Literal> interface.)
+</Para>
+
+<Para>
+The <Literal>Readline</Literal> module is a straightforward interface to the GNU
+Readline library.  As such, you will need to look at the GNU
+documentation (and have a <Literal>libreadline.a</Literal> file around somewhere&hellip;)
+</Para>
+
+<Para>
+You'll need to link any Readlining program with <Literal>-lreadline -ltermcap</Literal>,
+besides the usual <Literal>-syslib ghc</Literal> (and <Literal>-fhaskell-1.3</Literal>).
+</Para>
+
+<Para>
+The main function you'll use is:
+
+<ProgramListing>
+readline :: String{-the prompt-} -&#62; IO String
+</ProgramListing>
+
+</Para>
+
+<Para>
+If you want to mess around with Full Readline G(l)ory, we also
+provide:
+
+<ProgramListing>
+rlInitialize, addHistory,
+
+rlBindKey, rlAddDefun, RlCallbackFunction(..),
+
+rlGetLineBuffer, rlSetLineBuffer, rlGetPoint, rlSetPoint, rlGetEnd,
+rlSetEnd, rlGetMark, rlSetMark, rlSetDone, rlPendingInput,
+
+rlPrompt, rlTerminalName, rlSetReadlineName, rlGetReadlineName
+</ProgramListing>
+
+(All those names are just Haskellised versions of what you
+will see in the GNU readline documentation.)
+</Para>
+
+</Sect2>
+
+<Sect2 id="Regex">
+<Title>The <Literal>Regex</Literal> and <Literal>MatchPS</Literal> interfaces
+</Title>
+
+<Para>
+<IndexTerm><Primary>Regex library (misc syslib)</Primary></IndexTerm>
+<IndexTerm><Primary>MatchPS library (misc syslib)</Primary></IndexTerm>
+<IndexTerm><Primary>regular-expressions library</Primary></IndexTerm>
+</Para>
+
+<Para>
+(Sigbjorn Finne supplied the regular-expressions interface.)
+</Para>
+
+<Para>
+The <Literal>Regex</Literal> library provides quite direct interface to the GNU
+regular-expression library, for doing manipulation on <Literal>PackedString</Literal>s.
+You probably need to see the GNU documentation if you are operating at
+this level.  Alternatively, you can use the simpler and higher-level
+<Literal>RegexString</Literal> interface.
+</Para>
+
+<Para>
+The datatypes and functions that <Literal>Regex</Literal> provides are:
+
+<ProgramListing>
+data PatBuffer  # just a bunch of bytes (mutable)
+
+data REmatch
+ = REmatch (Array Int GroupBounds)  -- for $1, ... $n
+           GroupBounds              -- for $` (everything before match)
+           GroupBounds              -- for $&amp; (entire matched string)
+           GroupBounds              -- for $' (everything after)
+           GroupBounds              -- for $+ (matched by last bracket)
+
+-- GroupBounds hold the interval where a group
+-- matched inside a string, e.g.
+--
+-- matching "reg(exp)" "a regexp" returns the pair (5,7) for the
+-- (exp) group. (PackedString indices start from 0)
+
+type GroupBounds = (Int, Int)
+
+re_compile_pattern
+        :: PackedString         -- pattern to compile
+        -&#62; Bool                 -- True &#60;=&#62; assume single-line mode
+        -&#62; Bool                 -- True &#60;=&#62; case-insensitive
+        -&#62; PrimIO PatBuffer
+
+re_match :: PatBuffer           -- compiled regexp
+         -&#62; PackedString        -- string to match
+         -&#62; Int                 -- start position
+         -&#62; Bool                -- True &#60;=&#62; record results in registers
+         -&#62; PrimIO (Maybe REmatch)
+
+-- Matching on 2 strings is useful when you're dealing with multiple
+-- buffers, which is something that could prove useful for
+-- PackedStrings, as we don't want to stuff the contents of a file
+-- into one massive heap chunk, but load (smaller chunks) on demand.
+
+re_match2 :: PatBuffer          -- 2-string version
+          -&#62; PackedString
+          -&#62; PackedString
+          -&#62; Int
+          -&#62; Int
+          -&#62; Bool
+          -&#62; PrimIO (Maybe REmatch)
+
+re_search :: PatBuffer          -- compiled regexp
+          -&#62; PackedString       -- string to search
+          -&#62; Int                -- start index
+          -&#62; Int                -- stop index
+          -&#62; Bool               -- True &#60;=&#62; record results in registers
+          -&#62; PrimIO (Maybe REmatch)
+
+re_search2 :: PatBuffer         -- Double buffer search
+           -&#62; PackedString
+           -&#62; PackedString
+           -&#62; Int               -- start index
+           -&#62; Int               -- range (?)
+           -&#62; Int               -- stop index
+           -&#62; Bool              -- True &#60;=&#62; results in registers
+           -&#62; PrimIO (Maybe REmatch)
+</ProgramListing>
+
+</Para>
+
+<Para>
+The <Literal>MatchPS</Literal> module provides Perl-like ``higher-level'' facilities
+to operate on <Literal>PackedStrings</Literal>.  The regular expressions in
+question are in Perl syntax.  The ``flags'' on various functions can
+include: <Literal>i</Literal> for case-insensitive, <Literal>s</Literal> for single-line mode, and
+<Literal>g</Literal> for global.  (It's probably worth your time to peruse the
+source code&hellip;)
+</Para>
+
+<Para>
+
+<ProgramListing>
+matchPS :: PackedString    -- regexp
+        -&#62; PackedString    -- string to match
+        -&#62; [Char]          -- flags
+        -&#62; Maybe REmatch   -- info about what matched and where
+
+searchPS :: PackedString    -- regexp
+         -&#62; PackedString    -- string to match
+         -&#62; [Char]          -- flags
+         -&#62; Maybe REmatch
+
+-- Perl-like match-and-substitute:
+substPS :: PackedString     -- regexp
+        -&#62; PackedString     -- replacement
+        -&#62; [Char]           -- flags
+        -&#62; PackedString     -- string
+        -&#62; PackedString
+
+-- same as substPS, but no prefix and suffix:
+replacePS :: PackedString  -- regexp
+          -&#62; PackedString  -- replacement
+          -&#62; [Char]        -- flags
+          -&#62; PackedString  -- string
+          -&#62; PackedString
+
+match2PS :: PackedString   -- regexp
+         -&#62; PackedString   -- string1 to match
+         -&#62; PackedString   -- string2 to match
+         -&#62; [Char]         -- flags
+         -&#62; Maybe REmatch
+
+search2PS :: PackedString  -- regexp
+          -&#62; PackedString  -- string to match
+          -&#62; PackedString  -- string to match
+          -&#62; [Char]        -- flags
+          -&#62; Maybe REmatch
+
+-- functions to pull the matched pieces out of an REmatch:
+
+getMatchesNo    :: REmatch -&#62; Int
+getMatchedGroup :: REmatch -&#62; Int -&#62; PackedString -&#62; PackedString
+getWholeMatch   :: REmatch -&#62; PackedString -&#62; PackedString
+getLastMatch    :: REmatch -&#62; PackedString -&#62; PackedString
+getAfterMatch   :: REmatch -&#62; PackedString -&#62; PackedString
+
+-- (reverse) brute-force string matching;
+-- Perl equivalent is index/rindex:
+findPS, rfindPS :: PackedString -&#62; PackedString -&#62; Maybe Int
+
+-- Equivalent to Perl "chop" (off the last character, if any):
+chopPS :: PackedString -&#62; PackedString
+
+-- matchPrefixPS: tries to match as much as possible of strA starting
+-- from the beginning of strB (handy when matching fancy literals in
+-- parsers):
+matchPrefixPS :: PackedString -&#62; PackedString -&#62; Int
+</ProgramListing>
+
+</Para>
+
+</Sect2>
+
+<Sect2 id="RegexString">
+<Title>The <Literal>RegexString</Literal> interface
+</Title>
+
+<Para>
+<IndexTerm><Primary>RegexString library (misc syslib)</Primary></IndexTerm>
+<IndexTerm><Primary>regular-expressions library</Primary></IndexTerm>
+</Para>
+
+<Para>
+(Simon Marlow supplied the String Regex wrapper.)
+</Para>
+
+<Para>
+For simple regular expression operations, the <Literal>Regex</Literal> library is a
+little heavyweight.  <Literal>RegexString</Literal> permits regex matching on ordinary
+Haskell <Literal>String</Literal>s.
+</Para>
+
+<Para>
+The datatypes and functions that <Literal>RegexString</Literal> provides are:
+
+<ProgramListing>
+data Regex              -- a compiled regular expression
+
+mkRegex
+        :: String       -- regexp to compile
+        -&#62; Regex        -- compiled regexp
+
+matchRegex
+        :: Regex        -- compiled regexp
+        -&#62; String       -- string to match
+        -&#62; Maybe [String] -- text of $1, $2, ... (if matched)
+</ProgramListing>
+
+</Para>
+
+</Sect2>
+
+<Sect2 id="Socket">
+<Title>Network-interface toolkit&mdash;<Literal>Socket</Literal> and <Literal>SocketPrim</Literal>
+</Title>
+
+<Para>
+<IndexTerm><Primary>SocketPrim interface (misc syslib)</Primary></IndexTerm>
+<IndexTerm><Primary>Socket interface (misc syslib)</Primary></IndexTerm>
+<IndexTerm><Primary>network-interface library</Primary></IndexTerm>
+<IndexTerm><Primary>sockets library</Primary></IndexTerm>
+<IndexTerm><Primary>BSD sockets library</Primary></IndexTerm>
+(Darren Moffat supplied the initial version of this library.)
+</Para>
+
+<Para>
+Your best bet for documentation is to look at the code&mdash;really!&mdash;
+normally in
+<Literal>fptools/ghc/lib/misc/&lcub;BSD,Socket,SocketPrim</Literal>.lhs&rcub;.
+</Para>
+
+<Para>
+The <Literal>BSD</Literal> module provides functions to get at
+system-database info; pretty straightforward if you're into this sort of
+thing:
+
+<ProgramListing>
+getHostName         :: IO String
+
+getServiceByName    :: ServiceName -&#62; IO ServiceEntry
+getServicePortNumber:: ServiceName -&#62; IO PortNumber
+getServiceEntry     :: IO ServiceEntry
+setServiceEntry     :: Bool -&#62; IO ()
+endServiceEntry     :: IO ()
+
+getProtocolByName   :: ProtocolName -&#62; IO ProtocolEntry
+getProtocolByNumber :: ProtocolNumber -&#62; IO ProtcolEntry
+getProtocolNumber   :: ProtocolName -&#62; ProtocolNumber
+getProtocolEntry    :: IO ProtocolEntry
+setProtocolEntry    :: Bool -&#62; IO ()
+endProtocolEntry    :: IO ()
+
+getHostByName       :: HostName -&#62; IO HostEntry
+getHostByAddr       :: Family -&#62; HostAddress -&#62; IO HostEntry
+getHostEntry        :: IO HostEntry
+setHostEntry        :: Bool -&#62; IO ()
+endHostEntry        :: IO ()
+</ProgramListing>
+</Para>
+
+<Para>
+The <Literal>SocketPrim</Literal> interface provides quite direct access to
+the socket facilities in a BSD Unix system, including all the
+complications.  We hope you don't need to use it!  See the source if
+needed&hellip;
+</Para>
+
+<Para>
+The <Literal>Socket</Literal> interface is a ``higher-level'' interface to
+sockets, and it is what we recommend.  Please tell us if the facilities it
+offers are inadequate to your task!
+</Para>
+
+<Para>
+The interface is relatively modest:
+
+<ProgramListing>
+connectTo       :: Hostname -&#62; PortID -&#62; IO Handle
+listenOn        :: PortID -&#62; IO Socket
+
+accept          :: Socket -&#62; IO (Handle, HostName)
+sendTo          :: Hostname -&#62; PortID -&#62; String -&#62; IO ()
+
+recvFrom        :: Hostname -&#62; PortID -&#62; IO String
+socketPort      :: Socket -&#62; IO PortID
+
+data PortID     -- PortID is a non-abstract type
+  = Service String        -- Service Name eg "ftp"
+  | PortNumber PortNumber -- User defined Port Number
+  | UnixSocket String     -- Unix family socket in file system
+
+type Hostname = String
+
+ -- 16-bit value (stored in network byte order).
+data PortNumber
+ -- instance of: Eq, Num, Show.
+
+mkPortNumber :: Int -&#62; PortNumber
+</ProgramListing>
+</Para>
+
+<Para>
+Various examples of networking Haskell code are provided in
+</Para>
+
+</Sect2>
+
+<Sect2 id="Select">
+<Title>The <Literal>Select</Literal> interface
+</Title>
+
+<Para>
+<IndexTerm><Primary>Select interface (misc syslib)</Primary></IndexTerm>
+</Para>
+
+<Para>
+The <Literal>Select</Literal> interface provides a Haskell wrapper for the <Literal>select()</Literal>
+OS call supplied by many modern UNIX variants. <Literal>Select</Literal> exports the
+following:
+</Para>
+
+<Para>
+
+<ProgramListing>
+type TimeOut = Maybe Int
+  -- Nothing =&#62; wait indefinitely.
+  -- Just x | x &#62;= 0    =&#62; block waiting for 'x' micro seconds.
+  --        | otherwise =&#62; block waiting for '-x' micro seconds.
+
+hSelect :: [Handle]
+        -&#62; [Handle]
+        -&#62; [Handle]
+        -&#62; TimeOut
+        -&#62; IO SelectResult
+
+type SelectResult
+ = ( [Handle]  -- input  handles ready
+   , [Handle]  -- output handles ready
+   , [Handle]  -- exc.   handles ready
+   )
+</ProgramListing>
+
+</Para>
+
+<Para>
+Here's an example of how it could be used:
+</Para>
+
+<Para>
+
+<ProgramListing>
+module Main(main) where
+
+import Select
+import IO
+
+main :: IO ()
+main = do
+  hSetBuffering stdin NoBuffering
+  putStrLn "waiting for input to appear"
+  hSelect [stdin] [] [] Nothing
+  putStrLn "input ready, let's try reading"
+  x &#60;- getChar
+  print x
+</ProgramListing>
+
+</Para>
+
+<Para>
+where the call to <Literal>hSelect</Literal> makes the process go to sleep
+until there's input available on <Literal>stdin</Literal>.
+</Para>
+
+<Para>
+Notice that this particular use of <Literal>hSelect</Literal> is now really a no-op
+with GHC compiled code, as its implementation of IO will take care to
+avoid blocking the process (i.e., all running Haskell threads), and
+call <Literal>select()</Literal> for you, if needs be. However, <Literal>hSelect</Literal> exposes
+functionality that is useful in other contexts (e.g., you want to
+wait for input on two <Literal>Handles</Literal> for 3 seconds, but no longer.)
+</Para>
+
+</Sect2>
+
+</Sect1>
diff --git a/ghc/docs/users_guide/libraries.sgml b/ghc/docs/users_guide/libraries.sgml
new file mode 100644 (file)
index 0000000..f7fb4d5
--- /dev/null
@@ -0,0 +1,1307 @@
+<Chapter id="ghc-prelude">
+<Title>The GHC prelude and libraries
+</Title>
+
+<Para>
+This document describes GHC's prelude and libraries.  The basic story is that of the Haskell 1.4 Report and Libraries document (which we do not reproduce here), but this document describes in addition:
+</Para>
+
+<Para>
+
+<ItemizedList>
+
+<ListItem>
+<Para>
+GHC's additional non-standard libraries and types, such as state
+transformers, packed strings, foreign objects, stable pointers, and so on.
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+GHC's primitive types and operations.  The standard Haskell functions are
+implemented on top of these, and it is sometimes useful to use them
+directly.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+The organisation of these libraries into directories.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para>
+Short description of programmer interface to the non-standard
+libraries provided in addition to the standard prelude.
+</Para>
+</ListItem>
+
+</ItemizedList>
+</Para>
+
+<Para>
+A number of the libraries that provide access to GHC's language
+extensions are shared by Hugs, and are described in the <ULink
+URL="libs.html">GHC/Hugs Extension Libraries</ULink> document.
+</Para>
+
+<Sect1 id="ghc-prelude-exts">
+<Title>Prelude extensions
+</Title>
+
+<Para>
+GHC's prelude contains the following non-standard extensions:
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>fromInt</Literal> method in class <Literal>Num</Literal>:</Term>
+<ListItem>
+<Para>
+It's there.  Converts from
+an <Literal>Int</Literal> to the type.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>toInt</Literal> method in class <Literal>Integral</Literal>:</Term>
+<ListItem>
+<Para>
+Converts from Integral
+type to an <Literal>Int</Literal>.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+<Para>
+GHC also internally uses a number of modules that begin with the
+string <Literal>Prel</Literal><IndexTerm><Primary>Prel module prefix</Primary></IndexTerm>: for this reason, we
+don't recommend that you use any module names beginning with <Literal>Prel</Literal> in
+your own programs.  The <Literal>Prel</Literal> modules are always available: in fact,
+you can get access to several extensions this way (for some you might
+need to give the <Literal>-fglasgow-exts</Literal><IndexTerm><Primary>-fglasgow-exts option</Primary></IndexTerm>
+flag).
+</Para>
+
+</Sect1>
+
+<Sect1>
+<Title>GHC/Hugs Extension Libraries</Title>
+
+<Para>
+The extension libraries provided by both GHC and Hugs are described in
+the
+<ULink
+URL="http://www.dcs.gla.ac.uk/fp/software/ghc/hg-libs/hg-libs.html"
+>GHC/Hugs Extension Library Document</ULink
+>
+</Para>
+
+</Sect1>
+
+<Sect1>
+<Title>GHC-only Extension Libraries</Title>
+
+<Para>
+<IndexTerm><Primary>libraries, ghc-only</Primary></IndexTerm>
+<IndexTerm><Primary>extension libraries, ghc-only</Primary></IndexTerm>
+</Para>
+
+<Para>
+If you rely on the implicit <Literal>import Prelude</Literal> that GHC normally does
+for you, and if you don't use any weird flags (notably
+<Literal>-fglasgow-exts</Literal>), and if you don't import the Glasgow extensions
+interface, <Literal>GlaExts</Literal>, then GHC should work <Emphasis>exactly</Emphasis> as the
+Haskell report says (modulo a few minor issues, see <XRef LinkEnd="vs-Haskell-defn">).
+</Para>
+
+<Para>
+If you turn on <Literal>-fglasgow-exts</Literal>, a new world opesn up to you and the compiler
+will recognise and parse unboxed values properly, and provide access to the
+various interfaces libraries described here (and piles of other goodies.)
+</Para>
+
+&mutablearray
+&bytearray
+
+<Sect2>
+<Title>The <Literal>CCall</Literal> module</Title>
+
+<Para>
+The <Literal>CCall</Literal> module defines the classes <Literal>CCallable</Literal> and <Literal>CReturnable</Literal>,
+along with instances for the primitive types (<Literal>Int</Literal>, <Literal>Int&num;</Literal>, <Literal>Float</Literal>,
+<Literal>Float&num;</Literal> etc.)  GHC knows to import this module if you use <Literal>&lowbar;ccall&lowbar;</Literal>,
+but if you need to define your own instances of these classes, you
+will need to import <Literal>CCall</Literal> explicitly.
+</Para>
+
+<Para>
+More information on how to use <Literal>&lowbar;ccall&lowbar;</Literal> can be found in <XRef LinkEnd="glasgow-ccalls">.
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>The <Literal>GlaExts</Literal> interface</Title>
+
+<Para>
+<IndexTerm><Primary>GlaExts interface (GHC extensions)</Primary></IndexTerm>
+</Para>
+
+<Para>
+The <Literal>GlaExts</Literal> interface provides access to extensions that only GHC
+implements.  These currently are: unboxed types, including the
+representations of the primitive types (Int, Float, etc.), and the
+GHC primitive operations (<Literal>+&num;</Literal>, <Literal>==&num;</Literal>, etc.).
+</Para>
+
+<Para>
+This module used to provide access to all the Glasgow extensions, but
+these have since been moved into separate libraries for compatibility
+with Hugs (version 2.09: in fact, you can still get at this stuff via
+<Literal>GlaExts</Literal> for compatibility, but this facility will likely be removed
+in the future).
+</Para>
+
+<Para>
+
+<ProgramListing>
+-- the representation of some basic types:
+data Char    = C# Char#
+data Int     = I# Int#
+data Addr    = A# Addr#
+data Word    = W# Word#
+data Float   = F# Float#
+data Double  = D# Double#
+data Integer = S# Int#              -- small integers
+             | J# Int# ByteArray#   -- large integers
+
+module GHC  -- all primops and primitive types.
+</ProgramListing>
+
+</Para>
+
+</Sect2>
+
+</Sect1>
+
+<Sect1 id="ghc-libs-ghc">
+<Title>The module <Literal>PrelGHC</Literal>: really primitive stuff
+</Title>
+
+<Para>
+<IndexTerm><Primary>PrelGHC module</Primary></IndexTerm>
+</Para>
+
+<Para>
+This module defines all the types which are primitive in Glasgow
+Haskell, and the operations provided for them.
+</Para>
+
+<Para>
+A primitive type is one which cannot be defined in Haskell, and which
+is therefore built into the language and compiler.  Primitive types
+are always unlifted; that is, a value of primitive type cannot be
+bottom.  We use the convention that primitive types, values, and
+operations have a <Literal>&num;</Literal> suffix.
+</Para>
+
+<Para>
+Primitive values are often represented by a simple bit-pattern, such
+as <Literal>Int&num;</Literal>, <Literal>Float&num;</Literal>, <Literal>Double&num;</Literal>.  But this is not necessarily the case:
+a primitive value might be represented by a pointer to a
+heap-allocated object.  Examples include <Literal>Array&num;</Literal>, the type of
+primitive arrays.  A primitive array is heap-allocated because it is
+too big a value to fit in a register, and would be too expensive to
+copy around; in a sense, it is accidental that it is represented by a
+pointer.  If a pointer represents a primitive value, then it really
+does point to that value: no unevaluated thunks, no
+indirections&hellip;nothing can be at the other end of the pointer than the
+primitive value.
+</Para>
+
+<Sect2 id="unboxed-tuples">
+<Title>Unboxed Tuples
+</Title>
+
+<Para>
+Unboxed tuples aren't really exported by <Literal>PrelGHC</Literal>, they're available
+by default with <Literal>-fglasgow-exts</Literal>.  An unboxed tuple looks like this:
+</Para>
+
+<Para>
+
+<ProgramListing>
+(# e_1, ..., e_n #)
+</ProgramListing>
+
+</Para>
+
+<Para>
+where <Literal>e&lowbar;1..e&lowbar;n</Literal> are expressions of any type (primitive or
+non-primitive).  The type of an unboxed tuple looks the same.
+</Para>
+
+<Para>
+Unboxed tuples are used for functions that need to return multiple
+values, but they avoid the heap allocation normally associated with
+using fully-fledged tuples.  When an unboxed tuple is returned, the
+components are put directly into registers or on the stack; the
+unboxed tuple itself does not have a composite representation.  Many
+of the primitive operations listed in this section return unboxed
+tuples.
+</Para>
+
+<Para>
+There are some pretty stringent restrictions on the use of unboxed tuples:
+</Para>
+
+<Para>
+
+<ItemizedList>
+<ListItem>
+
+<Para>
+ Unboxed tuple types are subject to the same restrictions as
+other unboxed types; i.e. they may not be stored in polymorphic data
+structures or passed to polymorphic functions.
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ Unboxed tuples may only be constructed as the direct result of
+a function, and may only be deconstructed with a <Literal>case</Literal> expression.
+eg. the following are valid:
+
+
+<ProgramListing>
+f x y = (# x+1, y-1 #)
+g x = case f x x of { (# a, b #) -&#62; a + b }
+</ProgramListing>
+
+
+but the following are invalid:
+
+
+<ProgramListing>
+f x y = g (# x, y #)
+g (# x, y #) = x + y
+</ProgramListing>
+
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ No variable can have an unboxed tuple type.  This is illegal:
+
+
+<ProgramListing>
+f :: (# Int, Int #) -&#62; (# Int, Int #)
+f x = x
+</ProgramListing>
+
+
+because <Literal>x</Literal> has an unboxed tuple type.
+
+</Para>
+</ListItem>
+
+</ItemizedList>
+
+</Para>
+
+<Para>
+Note: we may relax some of these restrictions in the future.
+</Para>
+
+<Para>
+The <Literal>IO</Literal> and <Literal>ST</Literal> monads use unboxed tuples to avoid unnecessary
+allocation during sequences of operations.
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>Character and numeric types</Title>
+
+<Para>
+<IndexTerm><Primary>character types, primitive</Primary></IndexTerm>
+<IndexTerm><Primary>numeric types, primitive</Primary></IndexTerm>
+<IndexTerm><Primary>integer types, primitive</Primary></IndexTerm>
+<IndexTerm><Primary>floating point types, primitive</Primary></IndexTerm>
+</Para>
+
+<Para>
+There are the following obvious primitive types:
+</Para>
+
+<Para>
+
+<ProgramListing>
+type Char#
+type Int#       -- see also Word# and Addr#, later
+type Float#
+type Double#
+</ProgramListing>
+
+<IndexTerm><Primary><literal>Char&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>Int&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>Float&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>Double&num;</literal></Primary></IndexTerm>
+</Para>
+
+<Para>
+If you really want to know their exact equivalents in C, see
+<Literal>ghc/includes/StgTypes.h</Literal> in the GHC source tree.
+</Para>
+
+<Para>
+Literals for these types may be written as follows:
+</Para>
+
+<Para>
+
+<ProgramListing>
+1#              an Int#
+1.2#            a Float#
+1.34##          a Double#
+'a'#            a Char#; for weird characters, use '\o&#60;octal&#62;'#
+"a"#            an Addr# (a `char *')
+</ProgramListing>
+
+<IndexTerm><Primary>literals, primitive</Primary></IndexTerm>
+<IndexTerm><Primary>constants, primitive</Primary></IndexTerm>
+<IndexTerm><Primary>numbers, primitive</Primary></IndexTerm>
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>Comparison operations</Title>
+
+<Para>
+<IndexTerm><Primary>comparisons, primitive</Primary></IndexTerm>
+<IndexTerm><Primary>operators, comparison</Primary></IndexTerm>
+</Para>
+
+<Para>
+
+<ProgramListing>
+{&#62;,&#62;=,==,/=,&#60;,&#60;=}# :: Int# -&#62; Int# -&#62; Bool
+
+{gt,ge,eq,ne,lt,le}Char# :: Char# -&#62; Char# -&#62; Bool
+    -- ditto for Word# and Addr#
+</ProgramListing>
+
+<IndexTerm><Primary><literal>&#62;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>&#62;=&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>==&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>/=&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>&#60;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>&#60;=&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>gt&lcub;Char,Word,Addr&rcub;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>ge&lcub;Char,Word,Addr&rcub;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>eq&lcub;Char,Word,Addr&rcub;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>ne&lcub;Char,Word,Addr&rcub;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>lt&lcub;Char,Word,Addr&rcub;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>le&lcub;Char,Word,Addr&rcub;&num;</literal></Primary></IndexTerm>
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>Primitive-character operations</Title>
+
+<Para>
+<IndexTerm><Primary>characters, primitive operations</Primary></IndexTerm>
+<IndexTerm><Primary>operators, primitive character</Primary></IndexTerm>
+</Para>
+
+<Para>
+
+<ProgramListing>
+ord# :: Char# -&#62; Int#
+chr# :: Int# -&#62; Char#
+</ProgramListing>
+
+<IndexTerm><Primary><literal>ord&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>chr&num;</literal></Primary></IndexTerm>
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>Primitive-<Literal>Int</Literal> operations</Title>
+
+<Para>
+<IndexTerm><Primary>integers, primitive operations</Primary></IndexTerm>
+<IndexTerm><Primary>operators, primitive integer</Primary></IndexTerm>
+</Para>
+
+<Para>
+
+<ProgramListing>
+{+,-,*,quotInt,remInt}# :: Int# -&#62; Int# -&#62; Int#
+negateInt# :: Int# -&#62; Int#
+
+iShiftL#, iShiftRA#, iShiftRL# :: Int# -&#62; Int# -&#62; Int#
+        -- shift left, right arithmetic, right logical
+</ProgramListing>
+
+<IndexTerm><Primary><literal>+&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>-&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>*&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>quotInt&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>remInt&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>iShiftL&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>iShiftRA&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>iShiftRL&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary>shift operations, integer</Primary></IndexTerm>
+</Para>
+
+<Para>
+<Emphasis>Note:</Emphasis> No error/overflow checking!
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>Primitive-<Literal>Double</Literal> and <Literal>Float</Literal> operations</Title>
+
+<Para>
+<IndexTerm><Primary>floating point numbers, primitive</Primary></IndexTerm>
+<IndexTerm><Primary>operators, primitive floating point</Primary></IndexTerm>
+</Para>
+
+<Para>
+
+<ProgramListing>
+{+,-,*,/}##         :: Double# -&#62; Double# -&#62; Double#
+{&#60;,&#60;=,==,/=,&#62;=,&#62;}## :: Double# -&#62; Double# -&#62; Bool
+negateDouble#       :: Double# -&#62; Double#
+double2Int#         :: Double# -&#62; Int#
+int2Double#         :: Int#    -&#62; Double#
+
+{plus,minux,times,divide}Float# :: Float# -&#62; Float# -&#62; Float#
+{gt,ge,eq,ne,lt,le}Float# :: Float# -&#62; Float# -&#62; Bool
+negateFloat#        :: Float# -&#62; Float#
+float2Int#          :: Float# -&#62; Int#
+int2Float#          :: Int#   -&#62; Float#
+</ProgramListing>
+
+</Para>
+
+<Para>
+<IndexTerm><Primary><literal>+&num;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>-&num;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>*&num;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>/&num;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>&#60;&num;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>&#60;=&num;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>==&num;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>=/&num;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>&#62;=&num;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>&#62;&num;&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>negateDouble&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>double2Int&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>int2Double&num;</literal></Primary></IndexTerm>
+</Para>
+
+<Para>
+<IndexTerm><Primary><literal>plusFloat&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>minusFloat&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>timesFloat&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>divideFloat&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>gtFloat&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>geFloat&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>eqFloat&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>neFloat&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>ltFloat&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>leFloat&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>negateFloat&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>float2Int&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>int2Float&num;</literal></Primary></IndexTerm>
+</Para>
+
+<Para>
+And a full complement of trigonometric functions:
+</Para>
+
+<Para>
+
+<ProgramListing>
+ expDouble#      :: Double# -&#62; Double#
+logDouble#      :: Double# -&#62; Double#
+sqrtDouble#     :: Double# -&#62; Double#
+sinDouble#      :: Double# -&#62; Double#
+cosDouble#      :: Double# -&#62; Double#
+tanDouble#      :: Double# -&#62; Double#
+asinDouble#     :: Double# -&#62; Double#
+acosDouble#     :: Double# -&#62; Double#
+atanDouble#     :: Double# -&#62; Double#
+sinhDouble#     :: Double# -&#62; Double#
+coshDouble#     :: Double# -&#62; Double#
+tanhDouble#     :: Double# -&#62; Double#
+powerDouble#    :: Double# -&#62; Double# -&#62; Double#
+</ProgramListing>
+
+<IndexTerm><Primary>trigonometric functions, primitive</Primary></IndexTerm>
+</Para>
+
+<Para>
+similarly for <Literal>Float&num;</Literal>.
+</Para>
+
+<Para>
+There are two coercion functions for <Literal>Float&num;</Literal>/<Literal>Double&num;</Literal>:
+</Para>
+
+<Para>
+
+<ProgramListing>
+float2Double#   :: Float# -&#62; Double#
+double2Float#   :: Double# -&#62; Float#
+</ProgramListing>
+
+<IndexTerm><Primary><literal>float2Double&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>double2Float&num;</literal></Primary></IndexTerm>
+</Para>
+
+<Para>
+The primitive versions of <Literal>encodeDouble</Literal>/<Literal>decodeDouble</Literal>:
+</Para>
+
+<Para>
+
+<ProgramListing>
+encodeDouble#   :: Int# -&#62; Int# -&#62; ByteArray#   -- Integer mantissa
+                -&#62; Int#                         -- Int exponent
+                -&#62; Double#
+
+decodeDouble#   :: Double# -&#62; PrelNum.ReturnIntAndGMP
+</ProgramListing>
+
+<IndexTerm><Primary><literal>encodeDouble&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>decodeDouble&num;</literal></Primary></IndexTerm>
+</Para>
+
+<Para>
+(And the same for <Literal>Float&num;</Literal>s.)
+</Para>
+
+</Sect2>
+
+<Sect2 id="integer-operations">
+<Title>Operations on/for <Literal>Integers</Literal> (interface to GMP)
+</Title>
+
+<Para>
+<IndexTerm><Primary>arbitrary precision integers</Primary></IndexTerm>
+<IndexTerm><Primary>Integer, operations on</Primary></IndexTerm>
+</Para>
+
+<Para>
+We implement <Literal>Integers</Literal> (arbitrary-precision integers) using the GNU
+multiple-precision (GMP) package (version 2.0.2).
+</Para>
+
+<Para>
+The data type for <Literal>Integer</Literal> is either a small integer,
+represented by an <Literal>Int</Literal>, or a large integer represented
+using the pieces requird by GMP's <Literal>MP&lowbar;INT</Literal> in <Literal>gmp.h</Literal>
+(see <Literal>gmp.info</Literal> in <Literal>ghc/includes/runtime/gmp</Literal>).  It comes out as:
+</Para>
+
+<Para>
+
+<ProgramListing>
+data Integer = S# Int#             -- small integers
+             | J# Int# ByteArray#  -- large integers
+</ProgramListing>
+
+<IndexTerm><Primary>Integer type</Primary></IndexTerm>
+The primitive ops to support large <Literal>Integers</Literal> use the ``pieces'' of the
+representation, and are as follows:
+</Para>
+
+<Para>
+
+<ProgramListing>
+negateInteger#  :: Int# -&#62; ByteArray# -&#62; Integer
+
+{plus,minus,times}Integer# :: Int# -&#62; ByteArray#
+                           -&#62; Int# -&#62; ByteArray#
+                           -&#62; Integer
+
+cmpInteger# :: Int# -&#62; ByteArray#
+            -&#62; Int# -&#62; ByteArray#
+            -&#62; Int# -- -1 for &#60;; 0 for ==; +1 for &#62;
+
+divModInteger#, quotRemInteger#
+        :: Int# -&#62; ByteArray#
+        -&#62; Int# -&#62; ByteArray#
+        -&#62; PrelNum.Return2GMPs
+
+integer2Int# :: Int# -&#62; ByteArray# -&#62; Int#
+
+int2Integer#  :: Int#  -&#62; Integer -- NB: no error-checking on these two!
+word2Integer# :: Word# -&#62; Integer
+
+addr2Integer# :: Addr# -&#62; Integer
+        -- the Addr# is taken to be a `char *' string
+        -- to be converted into an Integer.
+</ProgramListing>
+
+<IndexTerm><Primary><literal>negateInteger&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>plusInteger&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>minusInteger&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>timesInteger&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>cmpInteger&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>divModInteger&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>quotRemInteger&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>integer2Int&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>int2Integer&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>word2Integer&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>addr2Integer&num;</literal></Primary></IndexTerm>
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>Words and addresses</Title>
+
+<Para>
+<IndexTerm><Primary>word, primitive type</Primary></IndexTerm>
+<IndexTerm><Primary>address, primitive type</Primary></IndexTerm>
+<IndexTerm><Primary>unsigned integer, primitive type</Primary></IndexTerm>
+<IndexTerm><Primary>pointer, primitive type</Primary></IndexTerm>
+</Para>
+
+<Para>
+A <Literal>Word&num;</Literal> is used for bit-twiddling operations.  It is the same size as
+an <Literal>Int&num;</Literal>, but has no sign nor any arithmetic operations.
+
+<ProgramListing>
+type Word#      -- Same size/etc as Int# but *unsigned*
+type Addr#      -- A pointer from outside the "Haskell world" (from C, probably);
+                -- described under "arrays"
+</ProgramListing>
+
+<IndexTerm><Primary><literal>Word&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>Addr&num;</literal></Primary></IndexTerm>
+</Para>
+
+<Para>
+<Literal>Word&num;</Literal>s and <Literal>Addr&num;</Literal>s have the usual comparison operations.
+Other unboxed-<Literal>Word</Literal> ops (bit-twiddling and coercions):
+</Para>
+
+<Para>
+
+<ProgramListing>
+and#, or#, xor# :: Word# -&#62; Word# -&#62; Word#
+        -- standard bit ops.
+
+quotWord#, remWord# :: Word# -&#62; Word# -&#62; Word#
+        -- word (i.e. unsigned) versions are different from int
+        -- versions, so we have to provide these explicitly.
+
+not# :: Word# -&#62; Word#
+
+shiftL#, shiftRA#, shiftRL# :: Word# -&#62; Int# -&#62; Word#
+        -- shift left, right arithmetic, right logical
+
+int2Word#       :: Int#  -&#62; Word# -- just a cast, really
+word2Int#       :: Word# -&#62; Int#
+</ProgramListing>
+
+<IndexTerm><Primary>bit operations, Word and Addr</Primary></IndexTerm>
+<IndexTerm><Primary><literal>and&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>or&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>xor&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>not&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>quotWord&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>remWord&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>shiftL&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>shiftRA&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>shiftRL&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>int2Word&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>word2Int&num;</literal></Primary></IndexTerm>
+</Para>
+
+<Para>
+Unboxed-<Literal>Addr</Literal> ops (C casts, really):
+
+<ProgramListing>
+int2Addr#       :: Int#  -&#62; Addr#
+addr2Int#       :: Addr# -&#62; Int#
+</ProgramListing>
+
+<IndexTerm><Primary><literal>int2Addr&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>addr2Int&num;</literal></Primary></IndexTerm>
+</Para>
+
+<Para>
+The casts between <Literal>Int&num;</Literal>, <Literal>Word&num;</Literal> and <Literal>Addr&num;</Literal> correspond to null
+operations at the machine level, but are required to keep the Haskell
+type checker happy.
+</Para>
+
+<Para>
+Operations for indexing off of C pointers (<Literal>Addr&num;</Literal>s) to snatch values
+are listed under ``arrays''.
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>Arrays</Title>
+
+<Para>
+<IndexTerm><Primary>arrays, primitive</Primary></IndexTerm>
+</Para>
+
+<Para>
+The type <Literal>Array&num; elt</Literal> is the type of primitive, unpointed arrays of
+values of type <Literal>elt</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+type Array# elt
+</ProgramListing>
+
+<IndexTerm><Primary><literal>Array&num;</literal></Primary></IndexTerm>
+</Para>
+
+<Para>
+<Literal>Array&num;</Literal> is more primitive than a Haskell array&mdash;indeed, the
+Haskell <Literal>Array</Literal> interface is implemented using <Literal>Array&num;</Literal>&mdash;in that an
+<Literal>Array&num;</Literal> is indexed only by <Literal>Int&num;</Literal>s, starting at zero.  It is also
+more primitive by virtue of being unboxed.  That doesn't mean that it
+isn't a heap-allocated object - of course, it is.  Rather, being
+unboxed means that it is represented by a pointer to the array itself,
+and not to a thunk which will evaluate to the array (or to bottom).
+The components of an <Literal>Array&num;</Literal> are themselves boxed.
+</Para>
+
+<Para>
+The type <Literal>ByteArray&num;</Literal> is similar to <Literal>Array&num;</Literal>, except that it contains
+just a string of (non-pointer) bytes.
+</Para>
+
+<Para>
+
+<ProgramListing>
+type ByteArray#
+</ProgramListing>
+
+<IndexTerm><Primary><literal>ByteArray&num;</literal></Primary></IndexTerm>
+</Para>
+
+<Para>
+Arrays of these types are useful when a Haskell program wishes to
+construct a value to pass to a C procedure. It is also possible to
+use them to build (say) arrays of unboxed characters for internal use
+in a Haskell program.  Given these uses, <Literal>ByteArray&num;</Literal> is deliberately
+a bit vague about the type of its components.  Operations are provided
+to extract values of type <Literal>Char&num;</Literal>, <Literal>Int&num;</Literal>, <Literal>Float&num;</Literal>, <Literal>Double&num;</Literal>, and
+<Literal>Addr&num;</Literal> from arbitrary offsets within a <Literal>ByteArray&num;</Literal>.  (For type
+<Literal>Foo&num;</Literal>, the $i$th offset gets you the $i$th <Literal>Foo&num;</Literal>, not the <Literal>Foo&num;</Literal> at
+byte-position $i$.  Mumble.)  (If you want a <Literal>Word&num;</Literal>, grab an <Literal>Int&num;</Literal>,
+then coerce it.)
+</Para>
+
+<Para>
+Lastly, we have static byte-arrays, of type <Literal>Addr&num;</Literal> &lsqb;mentioned
+previously].  (Remember the duality between arrays and pointers in C.)
+Arrays of this types are represented by a pointer to an array in the
+world outside Haskell, so this pointer is not followed by the garbage
+collector.  In other respects they are just like <Literal>ByteArray&num;</Literal>.  They
+are only needed in order to pass values from C to Haskell.
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>Reading and writing</Title>
+
+<Para>
+Primitive arrays are linear, and indexed starting at zero.
+</Para>
+
+<Para>
+The size and indices of a <Literal>ByteArray&num;</Literal>, <Literal>Addr&num;</Literal>, and
+<Literal>MutableByteArray&num;</Literal> are all in bytes.  It's up to the program to
+calculate the correct byte offset from the start of the array.  This
+allows a <Literal>ByteArray&num;</Literal> to contain a mixture of values of different
+type, which is often needed when preparing data for and unpicking
+results from C.  (Umm&hellip;not true of indices&hellip;WDP 95/09)
+</Para>
+
+<Para>
+<Emphasis>Should we provide some <Literal>sizeOfDouble&num;</Literal> constants?</Emphasis>
+</Para>
+
+<Para>
+Out-of-range errors on indexing should be caught by the code which
+uses the primitive operation; the primitive operations themselves do
+<Emphasis>not</Emphasis> check for out-of-range indexes. The intention is that the
+primitive ops compile to one machine instruction or thereabouts.
+</Para>
+
+<Para>
+We use the terms ``reading'' and ``writing'' to refer to accessing
+<Emphasis>mutable</Emphasis> arrays (see <XRef LinkEnd="sect-mutable">), and
+``indexing'' to refer to reading a value from an <Emphasis>immutable</Emphasis>
+array.
+</Para>
+
+<Para>
+Immutable byte arrays are straightforward to index (all indices in bytes):
+
+<ProgramListing>
+indexCharArray#   :: ByteArray# -&#62; Int# -&#62; Char#
+indexIntArray#    :: ByteArray# -&#62; Int# -&#62; Int#
+indexAddrArray#   :: ByteArray# -&#62; Int# -&#62; Addr#
+indexFloatArray#  :: ByteArray# -&#62; Int# -&#62; Float#
+indexDoubleArray# :: ByteArray# -&#62; Int# -&#62; Double#
+
+indexCharOffAddr#   :: Addr# -&#62; Int# -&#62; Char#
+indexIntOffAddr#    :: Addr# -&#62; Int# -&#62; Int#
+indexFloatOffAddr#  :: Addr# -&#62; Int# -&#62; Float#
+indexDoubleOffAddr# :: Addr# -&#62; Int# -&#62; Double#
+indexAddrOffAddr#   :: Addr# -&#62; Int# -&#62; Addr#
+ -- Get an Addr# from an Addr# offset
+</ProgramListing>
+
+<IndexTerm><Primary><literal>indexCharArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>indexIntArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>indexAddrArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>indexFloatArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>indexDoubleArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>indexCharOffAddr&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>indexIntOffAddr&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>indexFloatOffAddr&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>indexDoubleOffAddr&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>indexAddrOffAddr&num;</literal></Primary></IndexTerm>
+</Para>
+
+<Para>
+The last of these, <Literal>indexAddrOffAddr&num;</Literal>, extracts an <Literal>Addr&num;</Literal> using an offset
+from another <Literal>Addr&num;</Literal>, thereby providing the ability to follow a chain of
+C pointers.
+</Para>
+
+<Para>
+Something a bit more interesting goes on when indexing arrays of boxed
+objects, because the result is simply the boxed object. So presumably
+it should be entered&mdash;we never usually return an unevaluated
+object!  This is a pain: primitive ops aren't supposed to do
+complicated things like enter objects.  The current solution is to
+return a single element unboxed tuple (see <XRef LinkEnd="unboxed-tuples">).
+</Para>
+
+<Para>
+
+<ProgramListing>
+indexArray#       :: Array# elt -&#62; Int# -&#62; (# elt #)
+</ProgramListing>
+
+<IndexTerm><Primary><literal>indexArray&num;</literal></Primary></IndexTerm>
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>The state type</Title>
+
+<Para>
+<IndexTerm><Primary><literal>state, primitive type</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>State&num;</literal></Primary></IndexTerm>
+</Para>
+
+<Para>
+The primitive type <Literal>State&num;</Literal> represents the state of a state
+transformer.  It is parameterised on the desired type of state, which
+serves to keep states from distinct threads distinct from one another.
+But the <Emphasis>only</Emphasis> effect of this parameterisation is in the type
+system: all values of type <Literal>State&num;</Literal> are represented in the same way.
+Indeed, they are all represented by nothing at all!  The code
+generator ``knows'' to generate no code, and allocate no registers
+etc, for primitive states.
+</Para>
+
+<Para>
+
+<ProgramListing>
+type State# s
+</ProgramListing>
+
+</Para>
+
+<Para>
+The type <Literal>GHC.RealWorld</Literal> is truly opaque: there are no values defined
+of this type, and no operations over it.  It is ``primitive'' in that
+sense - but it is <Emphasis>not unlifted!</Emphasis> Its only role in life is to be
+the type which distinguishes the <Literal>IO</Literal> state transformer.
+</Para>
+
+<Para>
+
+<ProgramListing>
+data RealWorld
+</ProgramListing>
+
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>State of the world</Title>
+
+<Para>
+A single, primitive, value of type <Literal>State&num; RealWorld</Literal> is provided.
+</Para>
+
+<Para>
+
+<ProgramListing>
+realWorld# :: State# RealWorld
+</ProgramListing>
+
+<IndexTerm><Primary>realWorld&num; state object</Primary></IndexTerm>
+</Para>
+
+<Para>
+(Note: in the compiler, not a <Literal>PrimOp</Literal>; just a mucho magic
+<Literal>Id</Literal>. Exported from <Literal>GHC</Literal>, though).
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>Mutable arrays</Title>
+
+<Para>
+<Anchor id="sect-mutable">
+<IndexTerm><Primary>mutable arrays</Primary></IndexTerm>
+<IndexTerm><Primary>arrays, mutable</Primary></IndexTerm>
+</Para>
+
+<Para>
+Corresponding to <Literal>Array&num;</Literal> and <Literal>ByteArray&num;</Literal>, we have the types of
+mutable versions of each.  In each case, the representation is a
+pointer to a suitable block of (mutable) heap-allocated storage.
+</Para>
+
+<Para>
+
+<ProgramListing>
+type MutableArray# s elt
+type MutableByteArray# s
+</ProgramListing>
+
+<IndexTerm><Primary><literal>MutableArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>MutableByteArray&num;</literal></Primary></IndexTerm>
+</Para>
+
+<Sect3>
+<Title>Allocation</Title>
+
+<Para>
+<IndexTerm><Primary>mutable arrays, allocation</Primary></IndexTerm>
+<IndexTerm><Primary>arrays, allocation</Primary></IndexTerm>
+<IndexTerm><Primary>allocation, of mutable arrays</Primary></IndexTerm>
+</Para>
+
+<Para>
+Mutable arrays can be allocated. Only pointer-arrays are initialised;
+arrays of non-pointers are filled in by ``user code'' rather than by
+the array-allocation primitive.  Reason: only the pointer case has to
+worry about GC striking with a partly-initialised array.
+</Para>
+
+<Para>
+
+<ProgramListing>
+newArray#       :: Int# -&#62; elt -&#62; State# s -&#62; (# State# s, MutableArray# s elt #)
+
+newCharArray#   :: Int# -&#62; State# s -&#62; (# State# s, MutableByteArray# s elt #)
+newIntArray#    :: Int# -&#62; State# s -&#62; (# State# s, MutableByteArray# s elt #)
+newAddrArray#   :: Int# -&#62; State# s -&#62; (# State# s, MutableByteArray# s elt #)
+newFloatArray#  :: Int# -&#62; State# s -&#62; (# State# s, MutableByteArray# s elt #)
+newDoubleArray# :: Int# -&#62; State# s -&#62; (# State# s, MutableByteArray# s elt #)
+</ProgramListing>
+
+<IndexTerm><Primary><literal>newArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>newCharArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>newIntArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>newAddrArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>newFloatArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>newDoubleArray&num;</literal></Primary></IndexTerm>
+</Para>
+
+<Para>
+The size of a <Literal>ByteArray&num;</Literal> is given in bytes.
+</Para>
+
+</Sect3>
+
+<Sect3>
+<Title>Reading and writing</Title>
+
+<Para>
+<IndexTerm><Primary>arrays, reading and writing</Primary></IndexTerm>
+</Para>
+
+<Para>
+
+<ProgramListing>
+readArray#       :: MutableArray# s elt -&#62; Int# -&#62; State# s -&#62; (# State# s, elt #)
+readCharArray#   :: MutableByteArray# s -&#62; Int# -&#62; State# s -&#62; (# State# s, Char# #)
+readIntArray#    :: MutableByteArray# s -&#62; Int# -&#62; State# s -&#62; (# State# s, Int# #)
+readAddrArray#   :: MutableByteArray# s -&#62; Int# -&#62; State# s -&#62; (# State# s, Addr# #)
+readFloatArray#  :: MutableByteArray# s -&#62; Int# -&#62; State# s -&#62; (# State# s, Float# #)
+readDoubleArray# :: MutableByteArray# s -&#62; Int# -&#62; State# s -&#62; (# State# s, Double# #)
+
+writeArray#       :: MutableArray# s elt -&#62; Int# -&#62; elt     -&#62; State# s -&#62; State# s
+writeCharArray#   :: MutableByteArray# s -&#62; Int# -&#62; Char#   -&#62; State# s -&#62; State# s
+writeIntArray#    :: MutableByteArray# s -&#62; Int# -&#62; Int#    -&#62; State# s -&#62; State# s
+writeAddrArray#   :: MutableByteArray# s -&#62; Int# -&#62; Addr#   -&#62; State# s -&#62; State# s
+writeFloatArray#  :: MutableByteArray# s -&#62; Int# -&#62; Float#  -&#62; State# s -&#62; State# s
+writeDoubleArray# :: MutableByteArray# s -&#62; Int# -&#62; Double# -&#62; State# s -&#62; State# s
+</ProgramListing>
+
+<IndexTerm><Primary><literal>readArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>readCharArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>readIntArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>readAddrArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>readFloatArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>readDoubleArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>writeArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>writeCharArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>writeIntArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>writeAddrArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>writeFloatArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>writeDoubleArray&num;</literal></Primary></IndexTerm>
+</Para>
+
+</Sect3>
+
+<Sect3>
+<Title>Equality</Title>
+
+<Para>
+<IndexTerm><Primary>arrays, testing for equality</Primary></IndexTerm>
+</Para>
+
+<Para>
+One can take ``equality'' of mutable arrays.  What is compared is the
+<Emphasis>name</Emphasis> or reference to the mutable array, not its contents.
+</Para>
+
+<Para>
+
+<ProgramListing>
+sameMutableArray#     :: MutableArray# s elt -&#62; MutableArray# s elt -&#62; Bool
+sameMutableByteArray# :: MutableByteArray# s -&#62; MutableByteArray# s -&#62; Bool
+</ProgramListing>
+
+<IndexTerm><Primary><literal>sameMutableArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>sameMutableByteArray&num;</literal></Primary></IndexTerm>
+</Para>
+
+</Sect3>
+
+<Sect3>
+<Title>Freezing mutable arrays</Title>
+
+<Para>
+<IndexTerm><Primary>arrays, freezing mutable</Primary></IndexTerm>
+<IndexTerm><Primary>freezing mutable arrays</Primary></IndexTerm>
+<IndexTerm><Primary>mutable arrays, freezing</Primary></IndexTerm>
+</Para>
+
+<Para>
+Only unsafe-freeze has a primitive.  (Safe freeze is done directly in Haskell
+by copying the array and then using <Literal>unsafeFreeze</Literal>.)
+</Para>
+
+<Para>
+
+<ProgramListing>
+unsafeFreezeArray#     :: MutableArray# s elt -&#62; State# s -&#62; (# State# s, Array# s elt #)
+unsafeFreezeByteArray# :: MutableByteArray# s -&#62; State# s -&#62; (# State# s, ByteArray# #)
+</ProgramListing>
+
+<IndexTerm><Primary><literal>unsafeFreezeArray&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>unsafeFreezeByteArray&num;</literal></Primary></IndexTerm>
+</Para>
+
+</Sect3>
+
+</Sect2>
+
+<Sect2>
+<Title>Stable pointers</Title>
+
+<Para>
+<IndexTerm><Primary>stable pointers</Primary></IndexTerm>
+<IndexTerm><Primary>pointers, stable</Primary></IndexTerm>
+</Para>
+
+<Para>
+A stable pointer is a name for a Haskell object which can be passed to
+the external world.  It is ``stable'' in the sense that the name does
+not change when the Haskell garbage collector runs&mdash;in contrast to
+the address of the object which may well change.
+</Para>
+
+<Para>
+The stable pointer type is parameterised by the type of the thing
+which is named.
+</Para>
+
+<Para>
+
+<ProgramListing>
+type StablePtr# a
+</ProgramListing>
+
+<IndexTerm><Primary><literal>StablePtr&num;</literal></Primary></IndexTerm>
+</Para>
+
+<Para>
+A stable pointer is represented by an index into the (static)
+<Literal>StablePointerTable</Literal>.  The Haskell garbage collector treats the
+<Literal>StablePointerTable</Literal> as a source of roots for GC.
+</Para>
+
+<Para>
+The <Literal>makeStablePointer</Literal> function converts a value into a stable
+pointer.  It is part of the <Literal>IO</Literal> monad, because we want to be sure
+we don't allocate one twice by accident, and then only free one of the
+copies.
+</Para>
+
+<Para>
+
+<ProgramListing>
+makeStablePointer#  :: a -&#62; State# RealWorld -&#62; (# State# RealWord, StablePtr# a #)
+freeStablePointer#  :: StablePtr# a -&#62; State# RealWorld -&#62; State# RealWorld
+deRefStablePointer# :: StablePtr# a -&#62; State# RealWorld -&#62; (# State# RealWorld, a #)
+</ProgramListing>
+
+<IndexTerm><Primary><literal>makeStablePointer&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>freeStablePointer&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>deRefStablePointer&num;</literal></Primary></IndexTerm>
+</Para>
+
+<Para>
+There is also a C procedure <Literal>FreeStablePtr</Literal> which frees a stable pointer.
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>Foreign objects</Title>
+
+<Para>
+<IndexTerm><Primary>Foreign objects</Primary></IndexTerm>
+</Para>
+
+<Para>
+A <Literal>ForeignObj&num;</Literal> is a reference to an object outside the Haskell world
+(i.e., from the C world, or a reference to an object on another
+machine completely.), where the Haskell world has been told ``Let me
+know when you're finished with this&hellip;''.
+</Para>
+
+<Para>
+
+<ProgramListing>
+type ForeignObj#
+</ProgramListing>
+
+<IndexTerm><Primary><literal>ForeignObj&num;</literal></Primary></IndexTerm>
+</Para>
+
+<Para>
+GHC provides two primitives on <Literal>ForeignObj&num;</Literal>:
+</Para>
+
+<Para>
+
+<ProgramListing>
+makeForeignObj#
+        :: Addr# -- foreign reference
+        -&#62; Addr# -- pointer to finalisation routine
+        -&#62; (# State# RealWorld, ForeignObj# )
+writeForeignObj
+        :: ForeignObj#        -- foreign object
+        -&#62; Addr#              -- datum
+        -&#62; State# RealWorld
+        -&#62; State# RealWorld
+</ProgramListing>
+
+<IndexTerm><Primary><literal>makeForeignObj&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>writeForeignObj&num;</literal></Primary></IndexTerm>
+</Para>
+
+<Para>
+The module <Literal>Foreign</Literal> (see library documentation) provides a more
+programmer-friendly interface to foreign objects.
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>Synchronizing variables (M-vars)</Title>
+
+<Para>
+<IndexTerm><Primary>synchronising variables (M-vars)</Primary></IndexTerm>
+<IndexTerm><Primary>M-Vars</Primary></IndexTerm>
+</Para>
+
+<Para>
+Synchronising variables are the primitive type used to implement
+Concurrent Haskell's MVars (see the Concurrent Haskell paper for
+the operational behaviour of these operations).
+</Para>
+
+<Para>
+
+<ProgramListing>
+type MVar# s elt        -- primitive
+
+newMVar#    :: State# s -&#62; (# State# s, MVar# s elt #)
+takeMVar#   :: SynchVar# s elt -&#62; State# s -&#62; (# State# s, elt #)
+putMVar#    :: SynchVar# s elt -&#62; State# s -&#62; State# s
+</ProgramListing>
+
+<IndexTerm><Primary><literal>SynchVar&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>newSynchVar&num;</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>takeMVar</literal></Primary></IndexTerm>
+<IndexTerm><Primary><literal>putMVar</literal></Primary></IndexTerm>
+</Para>
+
+</Sect2>
+
+</Sect1>
+
+&posix
+&libmisc
+
+</Chapter>
diff --git a/ghc/docs/users_guide/license.sgml b/ghc/docs/users_guide/license.sgml
new file mode 100644 (file)
index 0000000..d41466f
--- /dev/null
@@ -0,0 +1,58 @@
+<Preface>
+<Title>The Glasgow Haskell Compiler License</Title>
+
+<Para>
+Copyright 1999, The University Court of the University of Glasgow. 
+All rights reserved.
+</Para>
+
+<Para>
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+</Para>
+
+<Para>
+<ItemizedList>
+
+<ListItem>
+<Para>
+Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para> 
+Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+</Para>
+</ListItem>
+
+<ListItem>
+<Para> 
+Neither name of the University nor the names of its contributors may be
+used to endorse or promote products derived from this software without
+specific prior written permission.
+</Para>
+</ListItem>
+
+</ItemizedList>
+</Para>
+
+<Para>
+THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF
+GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+UNIVERSITY COURT OF THE UNIVERSITY OF GLASGOW OR THE CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+</Para>
+
+</Preface>
diff --git a/ghc/docs/users_guide/parallel.sgml b/ghc/docs/users_guide/parallel.sgml
new file mode 100644 (file)
index 0000000..a36d005
--- /dev/null
@@ -0,0 +1,188 @@
+<Sect1 id="concurrent-and-parallel">
+<Title>Concurrent and Parallel Haskell
+</Title>
+
+<Para>
+<IndexTerm><Primary>Concurrent Haskell</Primary></IndexTerm>
+<IndexTerm><Primary>Parallel Haskell</Primary></IndexTerm>
+</Para>
+
+<Para>
+Concurrent and Parallel Haskell are Glasgow extensions to Haskell
+which let you structure your program as a group of independent
+`threads'.
+</Para>
+
+<Para>
+Concurrent and Parallel Haskell have very different purposes.
+</Para>
+
+<Para>
+Concurrent Haskell is for applications which have an inherent
+structure of interacting, concurrent tasks (i.e. `threads').  Threads
+in such programs may be <Emphasis>required</Emphasis>.  For example, if a concurrent thread has been spawned to handle a mouse click, it isn't
+optional&mdash;the user wants something done!
+</Para>
+
+<Para>
+A Concurrent Haskell program implies multiple `threads' running within
+a single Unix process on a single processor.
+</Para>
+
+<Para>
+You will find at least one paper about Concurrent Haskell hanging off
+of <ULink URL="http://www.dcs.gla.ac.uk/~simonpj/">Simon Peyton Jones's Web page</ULink>.
+</Para>
+
+<Para>
+Parallel Haskell is about <Emphasis>speed</Emphasis>&mdash;spawning threads onto multiple
+processors so that your program will run faster.  The `threads'
+are always <Emphasis>advisory</Emphasis>&mdash;if the runtime system thinks it can
+get the job done more quickly by sequential execution, then fine.
+</Para>
+
+<Para>
+A Parallel Haskell program implies multiple processes running on
+multiple processors, under a PVM (Parallel Virtual Machine) framework.
+</Para>
+
+<Para>
+Parallel Haskell is still relatively new; it is more about ``research
+fun'' than about ``speed.'' That will change.
+</Para>
+
+<Para>
+Again, check Simon's Web page for publications about Parallel Haskell
+(including ``GUM'', the key bits of the runtime system).
+</Para>
+
+<Para>
+Some details about Parallel Haskell follow.  For more information
+about concurrent Haskell, see the Concurrent section in the <ULink
+URL="libs.html"
+>GHC/Hugs Extension Libraries</ULink
+> documentation.
+</Para>
+
+<Sect2>
+<Title>Features specific to Parallel Haskell
+<IndexTerm><Primary>Parallel Haskell&mdash;features</Primary></IndexTerm></Title>
+
+<Sect3>
+<Title>The <Literal>Parallel</Literal> interface (recommended)
+<IndexTerm><Primary>Parallel interface</Primary></IndexTerm></Title>
+
+<Para>
+GHC provides two functions for controlling parallel execution, through
+the <Literal>Parallel</Literal> interface:
+</Para>
+
+<Para>
+
+<ProgramListing>
+interface Parallel where
+infixr 0 `par`
+infixr 1 `seq`
+
+par :: a -&#62; b -&#62; b
+seq :: a -&#62; b -&#62; b
+</ProgramListing>
+
+</Para>
+
+<Para>
+The expression <Literal>(x `par` y)</Literal> <Emphasis>sparks</Emphasis> the evaluation of <Literal>x</Literal>
+(to weak head normal form) and returns <Literal>y</Literal>.  Sparks are queued for
+execution in FIFO order, but are not executed immediately.  At the
+next heap allocation, the currently executing thread will yield
+control to the scheduler, and the scheduler will start a new thread
+(until reaching the active thread limit) for each spark which has not
+already been evaluated to WHNF.
+</Para>
+
+<Para>
+The expression <Literal>(x `seq` y)</Literal> evaluates <Literal>x</Literal> to weak head normal
+form and then returns <Literal>y</Literal>.  The <Literal>seq</Literal> primitive can be used to
+force evaluation of an expression beyond WHNF, or to impose a desired
+execution sequence for the evaluation of an expression.
+</Para>
+
+<Para>
+For example, consider the following parallel version of our old
+nemesis, <Literal>nfib</Literal>:
+</Para>
+
+<Para>
+
+<ProgramListing>
+import Parallel
+
+nfib :: Int -&#62; Int
+nfib n | n &#60;= 1 = 1
+       | otherwise = par n1 (seq n2 (n1 + n2 + 1))
+                     where n1 = nfib (n-1)
+                           n2 = nfib (n-2)
+</ProgramListing>
+
+</Para>
+
+<Para>
+For values of <Literal>n</Literal> greater than 1, we use <Literal>par</Literal> to spark a thread
+to evaluate <Literal>nfib (n-1)</Literal>, and then we use <Literal>seq</Literal> to force the
+parent thread to evaluate <Literal>nfib (n-2)</Literal> before going on to add
+together these two subexpressions.  In this divide-and-conquer
+approach, we only spark a new thread for one branch of the computation
+(leaving the parent to evaluate the other branch).  Also, we must use
+<Literal>seq</Literal> to ensure that the parent will evaluate <Literal>n2</Literal> <Emphasis>before</Emphasis>
+<Literal>n1</Literal> in the expression <Literal>(n1 + n2 + 1)</Literal>.  It is not sufficient to
+reorder the expression as <Literal>(n2 + n1 + 1)</Literal>, because the compiler may
+not generate code to evaluate the addends from left to right.
+</Para>
+
+</Sect3>
+
+<Sect3>
+<Title>Underlying functions and primitives
+<IndexTerm><Primary>parallelism primitives</Primary></IndexTerm>
+<IndexTerm><Primary>primitives for parallelism</Primary></IndexTerm></Title>
+
+<Para>
+The functions <Literal>par</Literal> and <Literal>seq</Literal> are wired into GHC, and unfold
+into uses of the <Literal>par&num;</Literal> and <Literal>seq&num;</Literal> primitives, respectively.  If
+you'd like to see this with your very own eyes, just run GHC with the
+<Literal>-ddump-simpl</Literal> option.  (Anything for a good time&hellip;)
+</Para>
+
+</Sect3>
+
+<Sect3>
+<Title>Scheduling policy for concurrent/parallel threads
+<IndexTerm><Primary>Scheduling&mdash;concurrent/parallel</Primary></IndexTerm>
+<IndexTerm><Primary>Concurrent/parallel scheduling</Primary></IndexTerm></Title>
+
+<Para>
+Runnable threads are scheduled in round-robin fashion.  Context
+switches are signalled by the generation of new sparks or by the
+expiry of a virtual timer (the timer interval is configurable with the
+<Literal>-C[&lt;num&gt;]</Literal><IndexTerm><Primary>-C&lt;num&gt; RTS option (concurrent,
+parallel)</Primary></IndexTerm> RTS option).  However, a context switch doesn't
+really happen until the current heap block is full.  You can't get any
+faster context switching than this.
+</Para>
+
+<Para>
+When a context switch occurs, pending sparks which have not already
+been reduced to weak head normal form are turned into new threads.
+However, there is a limit to the number of active threads (runnable or
+blocked) which are allowed at any given time.  This limit can be
+adjusted with the <Literal>-t&lt;num&gt;</Literal><IndexTerm><Primary>-t &lt;num&gt; RTS option (concurrent, parallel)</Primary></IndexTerm>
+RTS option (the default is 32).  Once the
+thread limit is reached, any remaining sparks are deferred until some
+of the currently active threads are completed.
+</Para>
+
+</Sect3>
+
+</Sect2>
+
+</Sect1>
diff --git a/ghc/docs/users_guide/posix.sgml b/ghc/docs/users_guide/posix.sgml
new file mode 100644 (file)
index 0000000..10a7b72
--- /dev/null
@@ -0,0 +1,2369 @@
+<Sect1 id="Posix-library">
+<Title>The Posix library
+</Title>
+
+<Para>
+<IndexTerm><Primary>Posix library</Primary></IndexTerm>
+<IndexTerm><Primary>libraries, Posix</Primary></IndexTerm>
+</Para>
+
+<Para>
+The <Literal>Posix</Literal> interface gives you access to the set of OS
+services standardised by POSIX 1003.1b (or the <Emphasis>IEEE Portable
+Operating System Interface for Computing Environments</Emphasis> - IEEE Std.
+1003.1). The interface is accessed by <Literal>import Posix</Literal> and
+adding <Literal>-syslib posix</Literal> on your command-line.
+</Para>
+
+<Sect2 id="Posix-data-types">
+<Title>Posix data types
+</Title>
+
+<Para>
+<IndexTerm><Primary>Posix, data types</Primary></IndexTerm>
+</Para>
+
+<Para>
+
+<ProgramListing>
+data ByteCount  -- instances of : Eq Ord Num Real Integral Ix Enum Show
+</ProgramListing>
+
+</Para>
+
+<Para>
+A <Literal>ByteCount</Literal> is a primitive of type <Literal>unsigned</Literal>. At a minimum,
+an conforming implementation must support values in the range
+<Literal>[0, UINT&lowbar;MAX]</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+data ClockTick  -- instances of : Eq Ord Num Real Integral Ix Enum Show
+</ProgramListing>
+
+</Para>
+
+<Para>
+A <Literal>ClockTick</Literal> is a primitive of type <Literal>clock&lowbar;t</Literal>, which
+is used to measure intervals of time in fractions of a second.  The 
+resolution is determined by <Literal>getSysVar ClockTick</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+data DeviceID  -- instances of : Eq Ord Num Real Integral Ix Enum Show
+</ProgramListing>
+
+</Para>
+
+<Para>
+A <Literal>DeviceID</Literal> is a primitive of type <Literal>dev&lowbar;t</Literal>.  It must
+be an arithmetic type.
+</Para>
+
+<Para>
+
+<ProgramListing>
+data EpochTime -- instances of : Eq Ord Num Real Integral Ix Enum Show
+</ProgramListing>
+
+</Para>
+
+<Para>
+A <Literal>EpochTime</Literal> is a primitive of type <Literal>time&lowbar;t</Literal>, which is
+used to measure seconds since the Epoch.  At a minimum, the implementation 
+must support values in the range <Literal>[0, INT&lowbar;MAX]</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+data FileID -- instances of : Eq Ord Num Real Integral Ix Enum Show
+</ProgramListing>
+
+</Para>
+
+<Para>
+A <Literal>FileID</Literal> is a primitive of type <Literal>ino&lowbar;t</Literal>.  It must
+be an arithmetic type.
+</Para>
+
+<Para>
+
+<ProgramListing>
+data FileMode -- instances of : Eq Ord Num Real Integral Ix Enum Show
+</ProgramListing>
+
+</Para>
+
+<Para>
+A <Literal>FileMode</Literal> is a primitive of type <Literal>mode&lowbar;t</Literal>.
+It must be an arithmetic type.
+</Para>
+
+<Para>
+
+<ProgramListing>
+data FileOffset -- instances of : Eq Ord Num Real Integral Ix Enum Show
+</ProgramListing>
+
+</Para>
+
+<Para>
+A <Literal>FileOffset</Literal> is a primitive of type <Literal>off&lowbar;t</Literal>.  It must
+be an arithmetic type.
+</Para>
+
+<Para>
+
+<ProgramListing>
+data GroupID -- instances of : Eq Ord Num Real Integral Ix Enum Show
+</ProgramListing>
+
+</Para>
+
+<Para>
+A <Literal>GroupID</Literal> is a primitive of type <Literal>gid&lowbar;t</Literal>.  It must
+be an arithmetic type.
+
+<ProgramListing>
+data Limit -- instances of : Eq Ord Num Real Integral Ix Enum Show
+</ProgramListing>
+
+</Para>
+
+<Para>
+A <Literal>Limit</Literal> is a primitive of type <Literal>long</Literal>.
+At a minimum, the implementation must support values in the range 
+<Literal>[LONG&lowbar;MIN, LONG&lowbar;MAX]</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+data LinkCount -- instances of : Eq Ord Num Real Integral Ix Enum Show
+</ProgramListing>
+
+</Para>
+
+<Para>
+A <Literal>LinkCount</Literal> is a primitive of type <Literal>nlink&lowbar;t</Literal>.  It must
+be an arithmetic type.
+</Para>
+
+<Para>
+
+<ProgramListing>
+data ProcessID -- instances of : Eq Ord Num Real Integral Ix Enum Show
+type ProcessGroupID = ProcessID
+</ProgramListing>
+
+</Para>
+
+<Para>
+A <Literal>ProcessID</Literal> is a primitive of type <Literal>pid&lowbar;t</Literal>.  It
+must be a signed arithmetic type.
+
+<ProgramListing>
+data UserID -- instances of : Eq Ord Num Real Integral Ix Enum Show
+</ProgramListing>
+
+</Para>
+
+<Para>
+A <Literal>UserID</Literal> is a primitive of type <Literal>uid&lowbar;t</Literal>.  It
+must be an arithmetic type.
+</Para>
+
+<Para>
+
+<ProgramListing>
+data DirStream
+</ProgramListing>
+
+A <Literal>DirStream</Literal> is a primitive of type <Literal>DIR *</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+data FileStatus
+</ProgramListing>
+
+A <Literal>FileStatus</Literal> is a primitive of type <Literal>struct stat</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+data GroupEntry
+</ProgramListing>
+
+</Para>
+
+<Para>
+A <Literal>GroupEntry</Literal> is a primitive of type <Literal>struct group</Literal>.
+
+<ProgramListing>
+data ProcessTimes
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>ProcessTimes</Literal> is a primitive structure containing a
+<Literal>clock&lowbar;t</Literal> and a <Literal>struct tms</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+data SignalSet
+</ProgramListing>
+
+</Para>
+
+<Para>
+An <Literal>SignalSet</Literal> is a primitive of type <Literal>sigset&lowbar;t</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+data SystemID
+</ProgramListing>
+
+</Para>
+
+<Para>
+A <Literal>SystemID</Literal> is a primitive of type <Literal>struct utsname</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+data TerminalAttributes
+</ProgramListing>
+
+<Literal>TerminalAttributes</Literal> is a primitive of type <Literal>struct termios</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+data UserEntry
+</ProgramListing>
+
+</Para>
+
+<Para>
+A <Literal>UserEntry</Literal> is a primitive of type <Literal>struct passwd</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+data BaudRate = B0 | B50 | B75 | B110 | B134 | B150 | B200 | B300 | B600
+              | B1200 | B1800 | B2400 | B4800 | B9600 | B19200 | B38400
+              deriving (Eq, Show)
+
+data Fd 
+
+intToFd :: Int -&#62; Fd -- use with care.
+
+data FdOption = AppendOnWrite
+              | CloseOnExec
+              | NonBlockingRead
+
+data ControlCharacter = EndOfFile
+                      | EndOfLine
+                      | Erase
+                      | Interrupt
+                      | Kill
+                      | Quit
+                      | Suspend
+                      | Start
+                      | Stop
+
+type ErrorCode = Int
+
+type FileLock = (LockRequest, SeekMode, FileOffset, FileOffset)
+--                            whence    start       length
+
+data FlowAction = SuspendOutput | RestartOutput | TransmitStop | TransmitStart
+
+data Handler = Default | Ignore | Catch (IO ())
+
+data LockRequest = ReadLock | WriteLock | Unlock
+                 deriving (Eq, Show)
+
+data OpenMode = ReadOnly | WriteOnly | ReadWrite
+
+data PathVar = LinkLimit
+             | InputLineLimit
+             | InputQueueLimit
+             | FileNameLimit
+             | PathNameLimit
+             | PipeBufferLimit
+             | SetOwnerAndGroupIsRestricted
+             | FileNamesAreNotTruncated
+
+data QueueSelector = InputQueue | OutputQueue | BothQueues
+
+type Signal = Int
+
+data SysVar = ArgumentLimit
+            | ChildLimit
+            | ClockTick
+            | GroupLimit
+            | OpenFileLimit
+            | PosixVersion
+            | HasSavedIDs
+            | HasJobControl
+
+data TerminalMode = InterruptOnBreak       -- BRKINT
+                | MapCRtoLF                -- ICRNL
+                | IgnoreBreak              -- IGNBRK
+                | IgnoreCR                 -- IGNCR
+                | IgnoreParityErrors       -- IGNPAR
+                | MapLFtoCR                -- INLCR
+                | CheckParity              -- INPCK
+                | StripHighBit             -- ISTRIP
+                | StartStopInput           -- IXOFF
+                | StartStopOutput          -- IXON
+                | MarkParityErrors         -- PARMRK
+                | ProcessOutput            -- OPOST
+                | LocalMode                -- CLOCAL
+                | ReadEnable               -- CREAD
+                | TwoStopBits              -- CSTOPB
+                | HangupOnClose            -- HUPCL
+                | EnableParity             -- PARENB
+                | OddParity                -- PARODD
+                | EnableEcho               -- ECHO
+                | EchoErase                -- ECHOE
+                | EchoKill                 -- ECHOK
+                | EchoLF                   -- ECHONL
+                | ProcessInput             -- ICANON
+                | ExtendedFunctions        -- IEXTEN
+                | KeyboardInterrupts       -- ISIG
+                | NoFlushOnInterrupt       -- NOFLSH
+                | BackgroundWriteInterrupt -- TOSTOP
+
+data TerminalState = Immediately | WhenDrained | WhenFlushed
+
+data ProcessStatus = Exited ExitCode 
+                   | Terminated Signal 
+                   | Stopped Signal
+                   deriving (Eq, Show)
+</ProgramListing>
+
+</Para>
+
+</Sect2>
+
+<Sect2 id="Process-Primitives">
+<Title>Posix Process Primitives
+</Title>
+
+<Para>
+
+<ProgramListing>
+forkProcess :: IO (Maybe ProcessID)
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>forkProcess</Literal> calls <Literal>fork</Literal>, returning
+<Literal>Just pid</Literal> to the parent, where <Literal>pid</Literal> is the
+ProcessID of the child, and returning <Literal>Nothing</Literal> to the
+child.
+</Para>
+
+<Para>
+
+<ProgramListing>
+executeFile :: FilePath                   -- Command
+            -&#62; Bool                       -- Search PATH?
+            -&#62; [String]                   -- Arguments
+            -&#62; Maybe [(String, String)]   -- Environment
+            -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>executeFile cmd args env</Literal> calls one of the
+<Literal>execv*</Literal> family, depending on whether or not the current
+PATH is to be searched for the command, and whether or not an
+environment is provided to supersede the process's current
+environment.  The basename (leading directory names suppressed) of
+the command is passed to <Literal>execv*</Literal> as <Literal>arg[0]</Literal>;
+the argument list passed to <Literal>executeFile</Literal> therefore begins 
+with <Literal>arg[1]</Literal>.
+</Para>
+
+<Para>
+
+<Screen>
+Search PATH?    Supersede environ?      Call
+~~~~~~~~~~~~    ~~~~~~~~~~~~~~~~~~      ~~~~~~~
+False           False                   execv
+False           True                    execve
+True            False                   execvp
+True            True                    execvpe*
+</Screen>
+
+</Para>
+
+<Para>
+Note that <Literal>execvpe</Literal> is not provided by the POSIX standard, and must
+be written by hand.  Care must be taken to ensure that the search path
+is extracted from the original environment, and not from the
+environment to be passed on to the new image.
+</Para>
+
+<Para>
+NOTE: In general, sharing open files between parent and child
+processes is potential bug farm, and should be avoided unless you
+really depend on this `feature' of POSIX' <Literal>fork()</Literal> semantics. Using
+Haskell, there's the extra complication that arguments to
+<Literal>executeFile</Literal> might come from files that are read lazily (using
+<Literal>hGetContents</Literal>, or some such.) If this is the case, then for your own
+sanity, please ensure that the arguments to <Literal>executeFile</Literal> have been
+fully evaluated before calling <Literal>forkProcess</Literal> (followed by
+<Literal>executeFile</Literal>.) Consider yourself warned :-)
+</Para>
+
+<Para>
+A successful <Literal>executeFile</Literal> overlays the current process image with 
+a new one, so it only returns on failure.
+</Para>
+
+<Para>
+
+<ProgramListing>
+runProcess :: FilePath                    -- Command
+           -&#62; [String]                    -- Arguments
+           -&#62; Maybe [(String, String)]    -- Environment (Nothing -&#62; Inherited)
+           -&#62; Maybe FilePath              -- Working directory (Nothing -&#62; inherited)
+           -&#62; Maybe Handle                -- stdin  (Nothing -&#62; inherited)
+           -&#62; Maybe Handle                -- stdout (Nothing -&#62; inherited)
+           -&#62; Maybe Handle                -- stderr (Nothing -&#62; inherited)
+           -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>runProcess</Literal> is our candidate for the high-level OS-independent
+primitive.
+</Para>
+
+<Para>
+<Literal>runProcess cmd args env wd inhdl outhdl errhdl</Literal> runs <Literal>cmd</Literal>
+(searching the current <Literal>PATH</Literal>) with arguments <Literal>args</Literal>.  If
+<Literal>env</Literal> is <Literal>Just pairs</Literal>, the command is executed with the
+environment specified by <Literal>pairs</Literal> of variables and values;
+otherwise, the command is executed with the current environment.  If
+<Literal>wd</Literal> is <Literal>Just dir</Literal>, the command is executed with working
+directory <Literal>dir</Literal>; otherwise, the command is executed in the current
+working directory.  If <Literal>&lcub;in,out,err</Literal>hdl&rcub; is <Literal>Just handle</Literal>, the
+command is executed with the <Literal>Fd</Literal> for <Literal>std&lcub;in,out,err</Literal>&rcub;
+attached to the specified <Literal>handle</Literal>; otherwise, the <Literal>Fd</Literal> for
+<Literal>std&lcub;in,out,err</Literal>&rcub; is left unchanged.
+</Para>
+
+<Para>
+
+<ProgramListing>
+getProcessStatus :: Bool              -- Block?
+                 -&#62; Bool              -- Stopped processes?
+                 -&#62; ProcessID 
+                 -&#62; IO (Maybe ProcessStatus)
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getProcessStatus blk stopped pid</Literal> calls <Literal>waitpid</Literal>, returning
+<Literal>Just tc</Literal>, the <Literal>ProcessStatus</Literal> for process <Literal>pid</Literal> if it is
+available, <Literal>Nothing</Literal> otherwise.  If <Literal>blk</Literal> is <Literal>False</Literal>, then
+<Literal>WNOHANG</Literal> is set in the options for <Literal>waitpid</Literal>, otherwise not.
+If <Literal>stopped</Literal> is <Literal>True</Literal>, then <Literal>WUNTRACED</Literal> is set in the
+options for <Literal>waitpid</Literal>, otherwise not.
+</Para>
+
+<Para>
+
+<ProgramListing>
+getGroupProcessStatus :: Bool         -- Block?
+                      -&#62; Bool         -- Stopped processes?
+                      -&#62; ProcessGroupID 
+                      -&#62; IO (Maybe (ProcessID, ProcessStatus))
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getGroupProcessStatus blk stopped pgid</Literal> calls <Literal>waitpid</Literal>,
+returning <Literal>Just (pid, tc)</Literal>, the <Literal>ProcessID</Literal> and
+<Literal>ProcessStatus</Literal> for any process in group <Literal>pgid</Literal> if one is
+available, <Literal>Nothing</Literal> otherwise.  If <Literal>blk</Literal> is <Literal>False</Literal>, then
+<Literal>WNOHANG</Literal> is set in the options for <Literal>waitpid</Literal>, otherwise not.
+If <Literal>stopped</Literal> is <Literal>True</Literal>, then <Literal>WUNTRACED</Literal> is set in the
+options for <Literal>waitpid</Literal>, otherwise not.
+</Para>
+
+<Para>
+
+<ProgramListing>
+getAnyProcessStatus :: Bool           -- Block?
+                    -&#62; Bool           -- Stopped processes?
+                    -&#62; IO (Maybe (ProcessID, ProcessStatus))
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getAnyProcessStatus blk stopped</Literal> calls <Literal>waitpid</Literal>, returning
+<Literal>Just (pid, tc)</Literal>, the <Literal>ProcessID</Literal> and <Literal>ProcessStatus</Literal> for any
+child process if one is available, <Literal>Nothing</Literal> otherwise.  If
+<Literal>blk</Literal> is <Literal>False</Literal>, then <Literal>WNOHANG</Literal> is set in the options for
+<Literal>waitpid</Literal>, otherwise not.  If <Literal>stopped</Literal> is <Literal>True</Literal>, then
+<Literal>WUNTRACED</Literal> is set in the options for <Literal>waitpid</Literal>, otherwise not.
+</Para>
+
+<Para>
+
+<ProgramListing>
+exitImmediately :: ExitCode -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>exitImmediately status</Literal> calls <Literal>&lowbar;exit</Literal> to terminate the process
+with the indicated exit <Literal>status</Literal>.
+The operation never returns.
+</Para>
+
+<Para>
+
+<ProgramListing>
+getEnvironment :: IO [(String, String)]
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getEnvironment</Literal> parses the environment variable mapping provided by
+<Literal>environ</Literal>, returning <Literal>(variable, value)</Literal> pairs. 
+The operation never fails.
+</Para>
+
+<Para>
+
+<ProgramListing>
+setEnvironment :: [(String, String)] -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>setEnvironment</Literal> replaces the process environment with the provided
+mapping of <Literal>(variable, value)</Literal> pairs. 
+</Para>
+
+<Para>
+
+<ProgramListing>
+getEnvVar :: String -&#62; IO String
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getEnvVar var</Literal> returns the value associated with variable <Literal>var</Literal> 
+in the current environment (identical functionality provided through
+standard Haskell library function <Literal>System.getEnv</Literal>).
+</Para>
+
+<Para>
+The operation may fail with:
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>NoSuchThing</Literal></Term>
+<ListItem>
+<Para>
+The variable has no mapping in the current environment.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+<Para>
+
+<ProgramListing>
+setEnvVar :: String -&#62; String -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>setEnvVar var val</Literal> sets the value associated with variable <Literal>var</Literal> 
+in the current environment to be <Literal>val</Literal>.  Any previous mapping is 
+superseded.
+</Para>
+
+<Para>
+
+<ProgramListing>
+removeEnvVar :: String -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>removeEnvVar var</Literal> removes any value associated with variable <Literal>var</Literal> 
+in the current environment.  Deleting a variable for which there is no mapping
+does not generate an error.
+</Para>
+
+<Para>
+
+<ProgramListing>
+nullSignal :: Signal
+nullSignal = 0
+
+backgroundRead, sigTTIN        :: Signal
+backgroundWrite, sigTTOU       :: Signal
+continueProcess, sigCONT       :: Signal
+floatingPointException, sigFPE :: Signal
+illegalInstruction, sigILL     :: Signal
+internalAbort, sigABRT         :: Signal
+keyboardSignal, sigINT         :: Signal
+keyboardStop, sigTSTP          :: Signal
+keyboardTermination, sigQUIT   :: Signal
+killProcess, sigKILL           :: Signal
+lostConnection, sigHUP         :: Signal
+openEndedPipe, sigPIPE         :: Signal
+processStatusChanged, sigCHLD  :: Signal
+realTimeAlarm, sigALRM         :: Signal
+segmentationViolation, sigSEGV :: Signal
+softwareStop, sigSTOP          :: Signal
+softwareTermination, sigTERM   :: Signal
+userDefinedSignal1, sigUSR1    :: Signal
+userDefinedSignal2, sigUSR2    :: Signal
+
+signalProcess :: Signal -&#62; ProcessID -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>signalProcess int pid</Literal> calls <Literal>kill</Literal> to signal 
+process <Literal>pid</Literal> with interrupt signal <Literal>int</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+raiseSignal :: Signal -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>raiseSignal int</Literal> calls <Literal>kill</Literal> to signal the current process
+with interrupt signal <Literal>int</Literal>. 
+</Para>
+
+<Para>
+
+<ProgramListing>
+signalProcessGroup :: Signal -&#62; ProcessGroupID -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>signalProcessGroup int pgid</Literal> calls <Literal>kill</Literal> to signal 
+all processes in group <Literal>pgid</Literal> with interrupt signal <Literal>int</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+setStoppedChildFlag :: Bool -&#62; IO Bool
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>setStoppedChildFlag bool</Literal> sets a flag which controls whether or
+not the <Literal>NOCLDSTOP</Literal> option will be used the next time a signal
+handler is installed for <Literal>SIGCHLD</Literal>.  If <Literal>bool</Literal> is <Literal>True</Literal> (the
+default), <Literal>NOCLDSTOP</Literal> will not be used; otherwise it will be.  The
+operation never fails.
+</Para>
+
+<Para>
+
+<ProgramListing>
+queryStoppedChildFlag :: IO Bool
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>queryStoppedChildFlag</Literal> queries the flag which
+controls whether or not the <Literal>NOCLDSTOP</Literal> option will be used
+the next time a signal handler is installed for <Literal>SIGCHLD</Literal>.
+If <Literal>NOCLDSTOP</Literal> will be used, it returns <Literal>False</Literal>; 
+otherwise (the default) it returns <Literal>True</Literal>.  
+The operation never fails.
+</Para>
+
+<Para>
+
+<ProgramListing>
+emptySignalSet :: SignalSet
+fullSignalSet  :: SignalSet
+addSignal      :: Signal -&#62; SignalSet -&#62; SignalSet
+deleteSignal   :: Signal -&#62; SignalSet -&#62; SignalSet
+inSignalSet    :: Signal -&#62; SignalSet -&#62; Bool
+
+installHandler :: Signal
+               -&#62; Handler 
+               -&#62; Maybe SignalSet       -- other signals to block
+               -&#62; IO Handler            -- old handler
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>installHandler int handler iset</Literal> calls <Literal>sigaction</Literal> to install an
+interrupt handler for signal <Literal>int</Literal>.  If <Literal>handler</Literal> is <Literal>Default</Literal>,
+<Literal>SIG&lowbar;DFL</Literal> is installed; if <Literal>handler</Literal> is <Literal>Ignore</Literal>, <Literal>SIG&lowbar;IGN</Literal> is
+installed; if <Literal>handler</Literal> is <Literal>Catch action</Literal>, a handler is installed
+which will invoke <Literal>action</Literal> in a new thread when (or shortly after) the
+signal is received.  See <XRef LinkEnd="concurrent-haskell"> for details on how to communicate between
+threads.
+</Para>
+
+<Para>
+If <Literal>iset</Literal> is <Literal>Just s</Literal>, then the <Literal>sa&lowbar;mask</Literal> of the <Literal>sigaction</Literal> structure
+is set to <Literal>s</Literal>; otherwise it is cleared.  The previously installed
+signal handler for <Literal>int</Literal> is returned.
+</Para>
+
+<Para>
+
+<ProgramListing>
+getSignalMask :: IO SignalSet
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getSignalMask</Literal> calls <Literal>sigprocmask</Literal> to determine the
+set of interrupts which are currently being blocked.
+</Para>
+
+<Para>
+
+<ProgramListing>
+setSignalMask :: SignalSet -&#62; IO SignalSet
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>setSignalMask mask</Literal> calls <Literal>sigprocmask</Literal> with
+<Literal>SIG&lowbar;SETMASK</Literal> to block all interrupts in <Literal>mask</Literal>.  The
+previous set of blocked interrupts is returned.
+</Para>
+
+<Para>
+
+<ProgramListing>
+blockSignals :: SignalSet -&#62; IO SignalSet
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>setSignalMask mask</Literal> calls <Literal>sigprocmask</Literal> with
+<Literal>SIG&lowbar;BLOCK</Literal> to add all interrupts in <Literal>mask</Literal> to the
+set of blocked interrupts.  The previous set of blocked interrupts is returned.
+</Para>
+
+<Para>
+
+<ProgramListing>
+unBlockSignals :: SignalSet -&#62; IO SignalSet
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>setSignalMask mask</Literal> calls <Literal>sigprocmask</Literal> with
+<Literal>SIG&lowbar;UNBLOCK</Literal> to remove all interrupts in <Literal>mask</Literal> from the
+set of blocked interrupts.  The previous set of blocked interrupts is returned.
+</Para>
+
+<Para>
+
+<ProgramListing>
+getPendingSignals :: IO SignalSet
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getPendingSignals</Literal> calls <Literal>sigpending</Literal> to obtain
+the set of interrupts which have been received but are currently blocked.
+</Para>
+
+<Para>
+
+<ProgramListing>
+awaitSignal :: Maybe SignalSet -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>awaitSignal iset</Literal> suspends execution until an interrupt is received.
+If <Literal>iset</Literal> is <Literal>Just s</Literal>, <Literal>awaitSignal</Literal> calls <Literal>sigsuspend</Literal>, installing
+<Literal>s</Literal> as the new signal mask before suspending execution; otherwise, it
+calls <Literal>pause</Literal>.  <Literal>awaitSignal</Literal> returns on receipt of a signal.  If you
+have installed any signal handlers with <Literal>installHandler</Literal>, it may be
+wise to call <Literal>yield</Literal> directly after <Literal>awaitSignal</Literal> to ensure that the
+signal handler runs as promptly.
+</Para>
+
+<Para>
+
+<ProgramListing>
+scheduleAlarm :: Int -&#62; IO Int
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>scheduleAlarm i</Literal> calls <Literal>alarm</Literal> to schedule a real time
+alarm at least <Literal>i</Literal> seconds in the future.
+</Para>
+
+<Para>
+
+<ProgramListing>
+sleep :: Int -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>sleep i</Literal> calls <Literal>sleep</Literal> to suspend execution of the
+program until at least <Literal>i</Literal> seconds have elapsed or a signal is
+received.
+</Para>
+
+</Sect2>
+
+<Sect2 id="Process-Environment">
+<Title>Posix Process Environment
+</Title>
+
+<Para>
+<IndexTerm><Primary>Posix, process environment</Primary></IndexTerm>
+</Para>
+
+<Para>
+
+<ProgramListing>
+getProcessID :: IO ProcessID
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getProcessID</Literal> calls <Literal>getpid</Literal> to obtain the <Literal>ProcessID</Literal> for
+the current process.
+</Para>
+
+<Para>
+
+<ProgramListing>
+getParentProcessID :: IO ProcessID
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getProcessID</Literal> calls <Literal>getppid</Literal> to obtain the <Literal>ProcessID</Literal> for
+the parent of the current process.
+</Para>
+
+<Para>
+
+<ProgramListing>
+getRealUserID :: IO UserID
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getRealUserID</Literal> calls <Literal>getuid</Literal> to obtain the real <Literal>UserID</Literal>
+associated with the current process.
+</Para>
+
+<Para>
+
+<ProgramListing>
+getEffectiveUserID :: IO UserID
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getRealUserID</Literal> calls <Literal>geteuid</Literal> to obtain the effective
+<Literal>UserID</Literal> associated with the current process.
+</Para>
+
+<Para>
+
+<ProgramListing>
+setUserID :: UserID -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>setUserID uid</Literal> calls <Literal>setuid</Literal> to set the real, effective, and
+saved set-user-id associated with the current process to <Literal>uid</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+getLoginName :: IO String
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getLoginName</Literal> calls <Literal>getlogin</Literal> to obtain the login name
+associated with the current process.
+</Para>
+
+<Para>
+
+<ProgramListing>
+getRealGroupID :: IO GroupID
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getRealGroupID</Literal> calls <Literal>getgid</Literal> to obtain the real <Literal>GroupID</Literal>
+associated with the current process.
+</Para>
+
+<Para>
+
+<ProgramListing>
+getEffectiveGroupID :: IO GroupID
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getEffectiveGroupID</Literal> calls <Literal>getegid</Literal> to obtain the effective
+<Literal>GroupID</Literal> associated with the current process.
+</Para>
+
+<Para>
+
+<ProgramListing>
+setGroupID :: GroupID -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>setGroupID gid</Literal> calls <Literal>setgid</Literal> to set the real, effective, and
+saved set-group-id associated with the current process to <Literal>gid</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+getGroups :: IO [GroupID]
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getGroups</Literal> calls <Literal>getgroups</Literal> to obtain the list of
+supplementary <Literal>GroupID</Literal>s associated with the current process.
+</Para>
+
+<Para>
+
+<ProgramListing>
+getEffectiveUserName :: IO String
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getEffectiveUserName</Literal> calls <Literal>cuserid</Literal> to obtain a name
+associated with the effective <Literal>UserID</Literal> of the process.
+</Para>
+
+<Para>
+
+<ProgramListing>
+getProcessGroupID :: IO ProcessGroupID
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getProcessGroupID</Literal> calls <Literal>getpgrp</Literal> to obtain the
+<Literal>ProcessGroupID</Literal> for the current process.
+</Para>
+
+<Para>
+
+<ProgramListing>
+createProcessGroup :: ProcessID -&#62; IO ProcessGroupID
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>createProcessGroup pid</Literal> calls <Literal>setpgid</Literal> to make
+process <Literal>pid</Literal> a new process group leader.
+</Para>
+
+<Para>
+
+<ProgramListing>
+joinProcessGroup :: ProcessGroupID -&#62; IO ProcessGroupID
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>joinProcessGroup pgid</Literal> calls <Literal>setpgid</Literal> to set the
+<Literal>ProcessGroupID</Literal> of the current process to <Literal>pgid</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+setProcessGroupID :: ProcessID -&#62; ProcessGroupID -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>setProcessGroupID pid pgid</Literal> calls <Literal>setpgid</Literal> to set the
+<Literal>ProcessGroupID</Literal> for process <Literal>pid</Literal> to <Literal>pgid</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+createSession :: IO ProcessGroupID
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>createSession</Literal> calls <Literal>setsid</Literal> to create a new session
+with the current process as session leader.
+</Para>
+
+<Para>
+
+<ProgramListing>
+systemName :: SystemID -&#62; String
+nodeName :: SystemID -&#62; String
+release :: SystemID -&#62; String
+version :: SystemID -&#62; String
+machine :: SystemID -&#62; String
+
+getSystemID :: IO SystemID
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getSystemID</Literal> calls <Literal>uname</Literal> to obtain information
+about the current operating system.
+</Para>
+
+<Para>
+
+<ProgramListing>
+&#62; epochTime :: IO EpochTime
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>epochTime</Literal> calls <Literal>time</Literal> to obtain the number of 
+seconds that have elapsed since the epoch (Jan 01 00:00:00 GMT 1970).
+</Para>
+
+<Para>
+
+<ProgramListing>
+elapsedTime     :: ProcessTimes -&#62; ClockTick
+userTime        :: ProcessTimes -&#62; ClockTick
+systemTime      :: ProcessTimes -&#62; ClockTick
+childUserTime   :: ProcessTimes -&#62; ClockTick
+childSystemTime :: ProcessTimes -&#62; ClockTick
+
+getProcessTimes :: IO ProcessTimes
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getProcessTimes</Literal> calls <Literal>times</Literal> to obtain time-accounting
+information for the current process and its children.
+</Para>
+
+<Para>
+
+<ProgramListing>
+getControllingTerminalName :: IO FilePath
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getControllingTerminalName</Literal> calls <Literal>ctermid</Literal> to obtain
+a name associated with the controlling terminal for the process.  If a
+controlling terminal exists,
+<Literal>getControllingTerminalName</Literal> returns the name of the
+controlling terminal.
+</Para>
+
+<Para>
+The operation may fail with:
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>NoSuchThing</Literal></Term>
+<ListItem>
+<Para>
+There is no controlling terminal, or its name cannot be determined.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>SystemError</Literal></Term>
+<ListItem>
+<Para>
+Various other causes.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+<Para>
+
+<ProgramListing>
+getTerminalName :: Fd -&#62; IO FilePath
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getTerminalName fd</Literal> calls <Literal>ttyname</Literal> to obtain a name associated
+with the terminal for <Literal>Fd</Literal> <Literal>fd</Literal>. If <Literal>fd</Literal> is associated
+with a terminal, <Literal>getTerminalName</Literal> returns the name of the
+terminal.
+</Para>
+
+<Para>
+The operation may fail with:
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>InappropriateType</Literal></Term>
+<ListItem>
+<Para>
+The channel is not associated with a terminal.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>NoSuchThing</Literal></Term>
+<ListItem>
+<Para>
+The channel is associated with a terminal, but it has no name.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>SystemError</Literal></Term>
+<ListItem>
+<Para>
+Various other causes.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+<Para>
+
+<ProgramListing>
+queryTerminal :: Fd -&#62; IO Bool
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>queryTerminal fd</Literal> calls <Literal>isatty</Literal> to determine whether or
+not <Literal>Fd</Literal> <Literal>fd</Literal> is associated with a terminal.
+</Para>
+
+<Para>
+
+<ProgramListing>
+getSysVar :: SysVar -&#62; IO Limit
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getSysVar var</Literal> calls <Literal>sysconf</Literal> to obtain the
+dynamic value of the requested configurable system limit or option.
+For defined system limits, <Literal>getSysVar</Literal> returns the associated
+value.  For defined system options, the result of <Literal>getSysVar</Literal>
+is undefined, but not failure.
+</Para>
+
+<Para>
+The operation may fail with:
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>NoSuchThing</Literal></Term>
+<ListItem>
+<Para>
+The requested system limit or option is undefined.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+</Sect2>
+
+<Sect2 id="Files-and-Directories">
+<Title>Posix operations on files and directories
+</Title>
+
+<Para>
+<IndexTerm><Primary>Posix, files and directories</Primary></IndexTerm>
+</Para>
+
+<Para>
+
+<ProgramListing>
+openDirStream :: FilePath -&#62; IO DirStream
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>openDirStream dir</Literal> calls <Literal>opendir</Literal> to obtain a
+directory stream for <Literal>dir</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+readDirStream :: DirStream -&#62; IO String
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>readDirStream dp</Literal> calls <Literal>readdir</Literal> to obtain the
+next directory entry (<Literal>struct dirent</Literal>) for the open directory
+stream <Literal>dp</Literal>, and returns the <Literal>d&lowbar;name</Literal> member of that
+structure.
+</Para>
+
+<Para>
+The operation may fail with:
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>EOF</Literal></Term>
+<ListItem>
+<Para>
+End of file has been reached.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>SystemError</Literal></Term>
+<ListItem>
+<Para>
+Various other causes.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+<Para>
+
+<ProgramListing>
+rewindDirStream :: DirStream -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>rewindDirStream dp</Literal> calls <Literal>rewinddir</Literal> to reposition
+the directory stream <Literal>dp</Literal> at the beginning of the directory.
+</Para>
+
+<Para>
+
+<ProgramListing>
+closeDirStream :: DirStream -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>closeDirStream dp</Literal> calls <Literal>closedir</Literal> to close
+the directory stream <Literal>dp</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+getWorkingDirectory :: IO FilePath
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getWorkingDirectory</Literal> calls <Literal>getcwd</Literal> to obtain the name
+of the current working directory.
+</Para>
+
+<Para>
+
+<ProgramListing>
+changeWorkingDirectory :: FilePath -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>changeWorkingDirectory dir</Literal> calls <Literal>chdir</Literal> to change
+the current working directory to <Literal>dir</Literal>.
+</Para>
+
+<Para>
+<ProgramListing>
+nullFileMode       :: FileMode       -- ---------
+ownerReadMode      :: FileMode       -- r--------
+ownerWriteMode     :: FileMode       -- -w-------
+ownerExecuteMode   :: FileMode       -- --x------
+groupReadMode      :: FileMode       -- ---r-----
+groupWriteMode     :: FileMode       -- ----w----
+groupExecuteMode   :: FileMode       -- -----x---
+otherReadMode      :: FileMode       -- ------r--
+otherWriteMode     :: FileMode       -- -------w-
+otherExecuteMode   :: FileMode       -- --------x
+setUserIDMode      :: FileMode       -- --S------
+setGroupIDMode     :: FileMode       -- -----S---
+                               
+stdFileMode        :: FileMode       -- rw-rw-rw-
+                               
+ownerModes         :: FileMode       -- rwx------
+groupModes         :: FileMode       -- ---rwx---
+otherModes         :: FileMode       -- ------rwx
+accessModes        :: FileMode       -- rwxrwxrwx
+
+unionFileModes     :: FileMode -&#62; FileMode -&#62; FileMode
+intersectFileModes :: FileMode -&#62; FileMode -&#62; FileMode
+
+stdInput  :: Fd
+stdInput  = intToFd 0
+
+stdOutput :: Fd
+stdOutput = intToFd 1
+
+stdError  :: Fd
+stdError  = intToFd 2
+
+data OpenFileFlags =
+ OpenFileFlags {
+    append    :: Bool,
+    exclusive :: Bool,
+    noctty    :: Bool,
+    nonBlock  :: Bool,
+    trunc     :: Bool
+ }
+
+openFd :: FilePath
+       -&#62; OpenMode
+       -&#62; Maybe FileMode  -- Just x =&#62; O_CREAT, Nothing =&#62; must exist
+       -&#62; OpenFileFlags
+       -&#62; IO Fd
+</ProgramListing>
+</Para>
+
+<Para>
+<Literal>openFd path acc mode (OpenFileFlags app excl noctty nonblock trunc)</Literal> calls
+<Literal>open</Literal> to obtain a <Literal>Fd</Literal> for the file <Literal>path</Literal> with access
+mode <Literal>acc</Literal>.  If <Literal>mode</Literal> is <Literal>Just m</Literal>, the <Literal>O&lowbar;CREAT</Literal> flag is
+set and the file's permissions will be based on <Literal>m</Literal> if it does not
+already exist; otherwise, the <Literal>O&lowbar;CREAT</Literal> flag is not set.  The
+arguments <Literal>app</Literal>, <Literal>excl</Literal>, <Literal>noctty</Literal>, <Literal>nonblock</Literal>, and
+<Literal>trunc</Literal> control whether or not the flags <Literal>O&lowbar;APPEND</Literal>,
+<Literal>O&lowbar;EXCL</Literal>, <Literal>O&lowbar;NOCTTY</Literal>, <Literal>O&lowbar;NONBLOCK</Literal>, and <Literal>O&lowbar;TRUNC</Literal> are set,
+respectively.
+</Para>
+
+<Para>
+
+<ProgramListing>
+createFile :: FilePath -&#62; FileMode -&#62; IO Fd
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>createFile path mode</Literal> calls <Literal>creat</Literal> to obtain a <Literal>Fd</Literal>
+for file <Literal>path</Literal>, which will be created with permissions based on
+<Literal>mode</Literal> if it does not already exist.
+</Para>
+
+<Para>
+
+<ProgramListing>
+setFileCreationMask :: FileMode -&#62; IO FileMode
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>setFileCreationMask mode</Literal> calls <Literal>umask</Literal> to set
+the process's file creation mask to <Literal>mode</Literal>.  The previous file
+creation mask is returned.
+</Para>
+
+<Para>
+
+<ProgramListing>
+createLink :: FilePath -&#62; FilePath -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>createLink old new</Literal> calls <Literal>link</Literal> to create a 
+new path, <Literal>new</Literal>, linked to an existing file, <Literal>old</Literal>.
+
+<ProgramListing>
+createDirectory :: FilePath -&#62; FileMode -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>createDirectory dir mode</Literal> calls <Literal>mkdir</Literal> to 
+create a new directory, <Literal>dir</Literal>, with permissions based on
+<Literal>mode</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+createNamedPipe :: FilePath -&#62; FileMode -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>createNamedPipe fifo mode</Literal> calls <Literal>mkfifo</Literal> to 
+create a new named pipe, <Literal>fifo</Literal>, with permissions based on
+<Literal>mode</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+removeLink :: FilePath -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>removeLink path</Literal> calls <Literal>unlink</Literal> to remove the link
+named <Literal>path</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+removeDirectory :: FilePath -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>removeDirectory dir</Literal> calls <Literal>rmdir</Literal> to remove the 
+directory named <Literal>dir</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+rename :: FilePath -&#62; FilePath -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>rename old new</Literal> calls <Literal>rename</Literal> to rename a 
+file or directory from <Literal>old</Literal> to <Literal>new</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+fileMode          :: FileStatus -&#62; FileMode
+                   
+fileID            :: FileStatus -&#62; FileID
+deviceID          :: FileStatus -&#62; DeviceID
+                   
+linkCount         :: FileStatus -&#62; LinkCount
+                   
+fileOwner         :: FileStatus -&#62; UserID
+fileGroup         :: FileStatus -&#62; GroupID
+fileSize          :: FileStatus -&#62; FileOffset
+
+accessTime        :: FileStatus -&#62; EpochTime
+modificationTime  :: FileStatus -&#62; EpochTime
+statusChangeTime  :: FileStatus -&#62; EpochTime
+
+isDirectory       :: FileStatus -&#62; Bool
+isCharacterDevice :: FileStatus -&#62; Bool
+isBlockDevice     :: FileStatus -&#62; Bool
+isRegularFile     :: FileStatus -&#62; Bool
+isNamedPipe       :: FileStatus -&#62; Bool
+
+getFileStatus     :: FilePath -&#62; IO FileStatus
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getFileStatus path</Literal> calls <Literal>stat</Literal> to get the
+<Literal>FileStatus</Literal> information for the file <Literal>path</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+getFdStatus :: Fd -&#62; IO FileStatus
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getFdStatus fd</Literal> calls <Literal>fstat</Literal> to get the
+<Literal>FileStatus</Literal> information for the file associated with
+<Literal>Fd</Literal> <Literal>fd</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+queryAccess :: FilePath -&#62; Bool -&#62; Bool -&#62; Bool -&#62; IO Bool
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>queryAccess path r w x</Literal> calls <Literal>access</Literal> to test the access
+permissions for file <Literal>path</Literal>.  The three arguments, <Literal>r</Literal>, <Literal>w</Literal>,
+and <Literal>x</Literal> control whether or not <Literal>access</Literal> is called with
+<Literal>R&lowbar;OK</Literal>, <Literal>W&lowbar;OK</Literal>, and <Literal>X&lowbar;OK</Literal> respectively.
+</Para>
+
+<Para>
+
+<ProgramListing>
+queryFile :: FilePath -&#62; IO Bool
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>queryFile path</Literal> calls <Literal>access</Literal> with <Literal>F&lowbar;OK</Literal> to test for the
+existence for file <Literal>path</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+setFileMode :: FilePath -&#62; FileMode -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>setFileMode path mode</Literal> calls <Literal>chmod</Literal> to set the
+permission bits associated with file <Literal>path</Literal> to <Literal>mode</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+setOwnerAndGroup :: FilePath -&#62; UserID -&#62; GroupID -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>setOwnerAndGroup path uid gid</Literal> calls <Literal>chown</Literal> to
+set the <Literal>UserID</Literal> and <Literal>GroupID</Literal> associated with file
+<Literal>path</Literal> to <Literal>uid</Literal> and <Literal>gid</Literal>, respectively.
+</Para>
+
+<Para>
+
+<ProgramListing>
+setFileTimes :: FilePath -&#62; EpochTime -&#62; EpochTime -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>setFileTimes path atime mtime</Literal> calls <Literal>utime</Literal> to
+set the access and modification times associated with file
+<Literal>path</Literal> to <Literal>atime</Literal> and <Literal>mtime</Literal>, respectively.
+</Para>
+
+<Para>
+
+<ProgramListing>
+touchFile :: FilePath -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>touchFile path</Literal> calls <Literal>utime</Literal> to
+set the access and modification times associated with file
+<Literal>path</Literal> to the current time.
+</Para>
+
+<Para>
+
+<ProgramListing>
+getPathVar :: PathVar -&#62; FilePath -&#62; IO Limit
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getPathVar var path</Literal> calls <Literal>pathconf</Literal> to obtain the
+dynamic value of the requested configurable file limit or option associated
+with file or directory <Literal>path</Literal>.  For
+defined file limits, <Literal>getPathVar</Literal> returns the associated
+value.  For defined file options, the result of <Literal>getPathVar</Literal>
+is undefined, but not failure.
+The operation may fail with:
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>NoSuchThing</Literal></Term>
+<ListItem>
+<Para>
+The requested file limit or option is undefined.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>SystemError</Literal></Term>
+<ListItem>
+<Para>
+Various other causes.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+<Para>
+
+<ProgramListing>
+getFdVar :: PathVar -&#62; Fd -&#62; IO Limit
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getFdVar var fd</Literal> calls <Literal>fpathconf</Literal> to obtain the
+dynamic value of the requested configurable file limit or option associated
+with the file or directory attached to the open channel <Literal>fd</Literal>.
+For defined file limits, <Literal>getFdVar</Literal> returns the associated
+value.  For defined file options, the result of <Literal>getFdVar</Literal>
+is undefined, but not failure.
+</Para>
+
+<Para>
+The operation may fail with:
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>NoSuchThing</Literal></Term>
+<ListItem>
+<Para>
+The requested file limit or option is undefined.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>SystemError</Literal></Term>
+<ListItem>
+<Para>
+Various other causes.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+</Sect2>
+
+<Sect2 id="Input-Output">
+<Title>Posix Input and Output Primitives
+</Title>
+
+<Para>
+<IndexTerm><Primary>Posix, input/output</Primary></IndexTerm>
+</Para>
+
+<Para>
+
+<ProgramListing>
+createPipe :: IO (Fd, Fd)
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>createPipe</Literal> calls <Literal>pipe</Literal> to create a pipe and returns a pair of
+<Literal>Fd</Literal>s, the first for reading and the second for writing.
+</Para>
+
+<Para>
+
+<ProgramListing>
+dup :: Fd -&#62; IO Fd
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>dup fd</Literal> calls <Literal>dup</Literal> to duplicate <Literal>Fd</Literal> <Literal>fd</Literal> to
+another <Literal>Fd</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+dupTo :: Fd -&#62; Fd -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>dupTo src dst</Literal> calls <Literal>dup2</Literal> to duplicate <Literal>Fd</Literal>
+<Literal>src</Literal> to <Literal>Fd</Literal> <Literal>dst</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+fdClose :: Fd -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>fdClose fd</Literal> calls <Literal>close</Literal> to close <Literal>Fd</Literal> <Literal>fd</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+fdRead :: Fd -&#62; ByteCount -&#62; IO (String, ByteCount)
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>fdRead fd nbytes</Literal> calls <Literal>read</Literal> to read at most <Literal>nbytes</Literal>
+bytes from <Literal>Fd</Literal> <Literal>fd</Literal>, and returns the result as a string
+paired with the number of bytes actually read.
+</Para>
+
+<Para>
+The operation may fail with:
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>EOF</Literal></Term>
+<ListItem>
+<Para>
+End of file has been reached.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>SystemError</Literal></Term>
+<ListItem>
+<Para>
+Various other causes.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+<Para>
+
+<ProgramListing>
+fdWrite :: Fd -&#62; String -&#62; IO ByteCount
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>fdWrite fd s</Literal> calls <Literal>write</Literal> to write
+the string <Literal>s</Literal> to <Literal>Fd</Literal> <Literal>fd</Literal> as a
+contiguous sequence of bytes.  It returns the number of bytes successfully
+written.
+</Para>
+
+<Para>
+
+<ProgramListing>
+queryFdOption :: FdOption -&#62; Fd -&#62; IO Bool
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getFdOption opt fd</Literal> calls <Literal>fcntl</Literal> to determine whether or
+not the flag associated with <Literal>FdOption</Literal> <Literal>opt</Literal> is set for
+<Literal>Fd</Literal> <Literal>fd</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+setFdOption :: Fd -&#62; FdOption -&#62; Bool -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>setFdOption fd opt val</Literal> calls <Literal>fcntl</Literal> to set the flag
+associated with <Literal>FdOption</Literal> <Literal>opt</Literal> on <Literal>Fd</Literal> <Literal>fd</Literal> to
+<Literal>val</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+getLock :: Fd -&#62; FileLock -&#62; IO (Maybe (ProcessID, FileLock))
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getLock fd lock</Literal> calls <Literal>fcntl</Literal> to get the first <Literal>FileLock</Literal>
+for <Literal>Fd</Literal> <Literal>fd</Literal> which blocks the <Literal>FileLock</Literal> <Literal>lock</Literal>.  If
+no such <Literal>FileLock</Literal> exists, <Literal>getLock</Literal> returns <Literal>Nothing</Literal>.
+Otherwise, it returns <Literal>Just (pid, block)</Literal>, where <Literal>block</Literal> is the
+blocking <Literal>FileLock</Literal> and <Literal>pid</Literal> is the <Literal>ProcessID</Literal> of the
+process holding the blocking <Literal>FileLock</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+setLock :: Fd -&#62; FileLock -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>setLock fd lock</Literal> calls <Literal>fcntl</Literal> with <Literal>F&lowbar;SETLK</Literal> to set or
+clear a lock segment for <Literal>Fd</Literal> <Literal>fd</Literal> as indicated by the
+<Literal>FileLock</Literal> <Literal>lock</Literal>.  <Literal>setLock</Literal> does not block, but fails with
+<Literal>SystemError</Literal> if the request cannot be satisfied immediately.
+</Para>
+
+<Para>
+
+<ProgramListing>
+waitToSetLock :: Fd -&#62; FileLock -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>waitToSetLock fd lock</Literal> calls <Literal>fcntl</Literal> with <Literal>F&lowbar;SETLKW</Literal> to set
+or clear a lock segment for <Literal>Fd</Literal> <Literal>fd</Literal> as indicated by the
+<Literal>FileLock</Literal> <Literal>lock</Literal>. If the request cannot be satisfied
+immediately, <Literal>waitToSetLock</Literal> blocks until the request can be
+satisfied.
+</Para>
+
+<Para>
+
+<ProgramListing>
+fdSeek :: Fd -&#62; SeekMode -&#62; FileOffset -&#62; IO FileOffset
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>fdSeek fd whence offset</Literal> calls <Literal>lseek</Literal> to position the
+<Literal>Fd</Literal> <Literal>fd</Literal> at the given <Literal>offset</Literal> from the starting location
+indicated by <Literal>whence</Literal>.  It returns the resulting offset from the
+start of the file in bytes.
+</Para>
+
+</Sect2>
+
+<Sect2 id="Device-Specific-Functions">
+<Title>Posix, Device- and Class-Specific Functions
+</Title>
+
+<Para>
+<IndexTerm><Primary>Posix, device and class-specific functions</Primary></IndexTerm>
+</Para>
+
+<Para>
+
+<ProgramListing>
+terminalMode    :: TerminalMode -&#62; TerminalAttributes -&#62; Bool
+withMode        :: TerminalAttributes -&#62; TerminalMode -&#62; TerminalAttributes
+withoutMode     :: TerminalAttributes -&#62; TerminalMode -&#62; TerminalAttributes
+
+bitsPerByte     :: TerminalAttributes -&#62; Int
+withBits        :: TerminalAttributes -&#62; Int -&#62; TerminalAttributes
+
+controlChar     :: TerminalAttributes -&#62; ControlCharacter -&#62; Maybe Char
+withCC          :: TerminalAttributes
+                -&#62; (ControlCharacter, Char)
+                -&#62; TerminalAttributes 
+withoutCC       :: TerminalAttributes 
+                -&#62; ControlCharacter 
+                -&#62; TerminalAttributes
+                  
+inputTime       :: TerminalAttributes -&#62; Int
+withTime        :: TerminalAttributes -&#62; Int -&#62; TerminalAttributes
+                  
+minInput        :: TerminalAttributes -&#62; Int
+withMinInput    :: TerminalAttributes -&#62; Int -&#62; TerminalAttributes
+                  
+inputSpeed      :: TerminalAttributes -&#62; BaudRate
+withInputSpeed  :: TerminalAttributes -&#62; BaudRate -&#62; TerminalAttributes
+                  
+outputSpeed     :: TerminalAttributes -&#62; BaudRate
+withOutputSpeed :: TerminalAttributes -&#62; BaudRate -&#62; TerminalAttributes
+
+getTerminalAttributes :: Fd -&#62; IO TerminalAttributes
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getTerminalAttributes fd</Literal> calls <Literal>tcgetattr</Literal> to obtain
+the <Literal>TerminalAttributes</Literal> associated with <Literal>Fd</Literal> <Literal>fd</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+setTerminalAttributes :: Fd
+                      -&#62; TerminalAttributes 
+                      -&#62; TerminalState
+                      -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>setTerminalAttributes fd attr ts</Literal> calls <Literal>tcsetattr</Literal> to change
+the <Literal>TerminalAttributes</Literal> associated with <Literal>Fd</Literal> <Literal>fd</Literal> to
+<Literal>attr</Literal>, when the terminal is in the state indicated by <Literal>ts</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+sendBreak :: Fd -&#62; Int -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>sendBreak fd duration</Literal> calls <Literal>tcsendbreak</Literal> to transmit a
+continuous stream of zero-valued bits on <Literal>Fd</Literal> <Literal>fd</Literal> for the
+specified implementation-dependent <Literal>duration</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+drainOutput :: Fd -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>drainOutput fd</Literal> calls <Literal>tcdrain</Literal> to block until all output
+written to <Literal>Fd</Literal> <Literal>fd</Literal> has been transmitted.
+</Para>
+
+<Para>
+
+<ProgramListing>
+discardData :: Fd -&#62; QueueSelector -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>discardData fd queues</Literal> calls <Literal>tcflush</Literal> to discard
+pending input and/or output for <Literal>Fd</Literal> <Literal>fd</Literal>,
+as indicated by the <Literal>QueueSelector</Literal> <Literal>queues</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+controlFlow :: Fd -&#62; FlowAction -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>controlFlow fd action</Literal> calls <Literal>tcflow</Literal> to control the 
+flow of data on <Literal>Fd</Literal> <Literal>fd</Literal>, as indicated by
+<Literal>action</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+getTerminalProcessGroupID :: Fd -&#62; IO ProcessGroupID
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getTerminalProcessGroupID fd</Literal> calls <Literal>tcgetpgrp</Literal> to
+obtain the <Literal>ProcessGroupID</Literal> of the foreground process group 
+associated with the terminal attached to <Literal>Fd</Literal> <Literal>fd</Literal>.
+</Para>
+
+<Para>
+
+<ProgramListing>
+setTerminalProcessGroupID :: Fd -&#62; ProcessGroupID -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>setTerminalProcessGroupID fd pgid</Literal> calls <Literal>tcsetpgrp</Literal> to
+set the <Literal>ProcessGroupID</Literal> of the foreground process group 
+associated with the terminal attached to <Literal>Fd</Literal> 
+<Literal>fd</Literal> to <Literal>pgid</Literal>.
+</Para>
+
+</Sect2>
+
+<Sect2 id="System-Database">
+<Title>Posix System Databases
+</Title>
+
+<Para>
+<IndexTerm><Primary>Posix, system databases</Primary></IndexTerm>
+</Para>
+
+<Para>
+
+<ProgramListing>
+groupName    :: GroupEntry -&#62; String
+groupID      :: GroupEntry -&#62; GroupID
+groupMembers :: GroupEntry -&#62; [String]
+
+getGroupEntryForID :: GroupID -&#62; IO GroupEntry
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getGroupEntryForID gid</Literal> calls <Literal>getgrgid</Literal> to obtain
+the <Literal>GroupEntry</Literal> information associated with <Literal>GroupID</Literal>
+<Literal>gid</Literal>.
+</Para>
+
+<Para>
+The operation may fail with:
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>NoSuchThing</Literal></Term>
+<ListItem>
+<Para>
+There is no group entry for the GroupID.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+<Para>
+
+<ProgramListing>
+getGroupEntryForName :: String -&#62; IO GroupEntry
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getGroupEntryForName name</Literal> calls <Literal>getgrnam</Literal> to obtain
+the <Literal>GroupEntry</Literal> information associated with the group called
+<Literal>name</Literal>.
+</Para>
+
+<Para>
+The operation may fail with:
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>NoSuchThing</Literal></Term>
+<ListItem>
+<Para>
+There is no group entry for the name.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+<Para>
+
+<ProgramListing>
+userName      :: UserEntry -&#62; String
+userID        :: UserEntry -&#62; UserID
+userGroupID   :: UserEntry -&#62; GroupID
+homeDirectory :: UserEntry -&#62; String
+userShell     :: UserEntry -&#62; String
+
+getUserEntryForID :: UserID -&#62; IO UserEntry
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getUserEntryForID gid</Literal> calls <Literal>getpwuid</Literal> to obtain
+the <Literal>UserEntry</Literal> information associated with <Literal>UserID</Literal>
+<Literal>uid</Literal>.
+The operation may fail with:
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>NoSuchThing</Literal></Term>
+<ListItem>
+<Para>
+There is no user entry for the UserID.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+<Para>
+
+<ProgramListing>
+getUserEntryForName :: String -&#62; IO UserEntry
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getUserEntryForName name</Literal> calls <Literal>getpwnam</Literal> to obtain
+the <Literal>UserEntry</Literal> information associated with the user login
+<Literal>name</Literal>.
+</Para>
+
+<Para>
+The operation may fail with:
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>NoSuchThing</Literal></Term>
+<ListItem>
+<Para>
+There is no user entry for the name.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+</Sect2>
+
+<Sect2 id="Error-reporting-and-handling">
+<Title>POSIX Errors
+</Title>
+
+<Para>
+<IndexTerm><Primary>Posix, errors</Primary></IndexTerm>
+</Para>
+
+<Para>
+
+<ProgramListing>
+getErrorCode :: IO ErrorCode
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>getErrorCode</Literal> returns the current value of the external
+variable <Literal>errno</Literal>.  It never fails.
+</Para>
+
+<Para>
+
+<ProgramListing>
+setErrorCode :: ErrorCode -&#62; IO ()
+</ProgramListing>
+
+</Para>
+
+<Para>
+<Literal>setErrorCode err</Literal> sets the external
+variable <Literal>errno</Literal> to <Literal>err</Literal>.  It never fails.
+</Para>
+
+<Para>
+
+<ProgramListing>
+noError :: ErrorCode
+noError = 0
+
+argumentListTooLong, e2BIG              :: ErrorCode
+badFd, eBADF                            :: ErrorCode
+brokenPipe, ePIPE                       :: ErrorCode
+directoryNotEmpty, eNOTEMPTY            :: ErrorCode
+execFormatError, eNOEXEC                :: ErrorCode
+fileAlreadyExists, eEXIST               :: ErrorCode
+fileTooLarge, eFBIG                     :: ErrorCode
+filenameTooLong, eNAMETOOLONG           :: ErrorCode
+improperLink, eXDEV                     :: ErrorCode
+inappropriateIOControlOperation, eNOTTY :: ErrorCode
+inputOutputError, eIO                   :: ErrorCode
+interruptedOperation, eINTR             :: ErrorCode
+invalidArgument, eINVAL                 :: ErrorCode
+invalidSeek, eSPIPE                     :: ErrorCode
+isADirectory, eISDIR                    :: ErrorCode
+noChildProcess, eCHILD                  :: ErrorCode
+noLocksAvailable, eNOLCK                :: ErrorCode
+noSpaceLeftOnDevice, eNOSPC             :: ErrorCode
+noSuchOperationOnDevice, eNODEV         :: ErrorCode
+noSuchDeviceOrAddress, eNXIO            :: ErrorCode
+noSuchFileOrDirectory, eNOENT           :: ErrorCode
+noSuchProcess, eSRCH                    :: ErrorCode
+notADirectory, eNOTDIR                  :: ErrorCode
+notEnoughMemory, eNOMEM                 :: ErrorCode
+operationNotImplemented, eNOSYS         :: ErrorCode
+operationNotPermitted, ePERM            :: ErrorCode
+permissionDenied, eACCES                :: ErrorCode
+readOnlyFileSystem, eROFS               :: ErrorCode
+resourceBusy, eBUSY                     :: ErrorCode
+resourceDeadlockAvoided, eDEADLK        :: ErrorCode
+resourceTemporarilyUnavailable, eAGAIN  :: ErrorCode
+tooManyLinks, eMLINK                    :: ErrorCode
+tooManyOpenFiles, eMFILE                :: ErrorCode
+tooManyOpenFilesInSystem, eNFILE        :: ErrorCode
+</ProgramListing>
+
+</Para>
+
+</Sect2>
+
+</Sect1>
diff --git a/ghc/docs/users_guide/profiling.sgml b/ghc/docs/users_guide/profiling.sgml
new file mode 100644 (file)
index 0000000..a0bd4f6
--- /dev/null
@@ -0,0 +1,1012 @@
+<Chapter id="profiling">
+<Title>Profiling
+</Title>
+
+<Para>
+<IndexTerm><Primary>profiling, with cost-centres</Primary></IndexTerm>
+<IndexTerm><Primary>cost-centre profiling</Primary></IndexTerm>
+</Para>
+
+<Para>
+Glasgow Haskell comes with a time and space profiling system. Its
+purpose is to help you improve your understanding of your program's
+execution behaviour, so you can improve it.
+</Para>
+
+<Para>
+Any comments, suggestions and/or improvements you have are welcome.
+Recommended ``profiling tricks'' would be especially cool!
+</Para>
+
+<Sect1 id="profiling-intro">
+<Title>How to profile a Haskell program
+</Title>
+
+<Para>
+The GHC approach to profiling is very simple: annotate the expressions
+you consider ``interesting'' with <Emphasis>cost centre</Emphasis> labels (strings);
+so, for example, you might have:
+</Para>
+
+<Para>
+
+<ProgramListing>
+f x y
+  = let
+        output1 = _scc_ "Pass1" ( pass1 x )
+        output2 = _scc_ "Pass2" ( pass2 output1 y )
+        output3 = _scc_ "Pass3" ( pass3 (output2 `zip` [1 .. ]) )
+    in concat output3
+</ProgramListing>
+
+</Para>
+
+<Para>
+The costs of the evaluating the expressions bound to <Literal>output1</Literal>,
+<Literal>output2</Literal> and <Literal>output3</Literal> will be attributed to the ``cost
+centres'' <Literal>Pass1</Literal>, <Literal>Pass2</Literal> and <Literal>Pass3</Literal>, respectively.
+</Para>
+
+<Para>
+The costs of evaluating other expressions, e.g., <Literal>concat output4</Literal>,
+will be inherited by the scope which referenced the function <Literal>f</Literal>.
+</Para>
+
+<Para>
+You can put in cost-centres via <Literal>&lowbar;scc&lowbar;</Literal> constructs by hand, as in the
+example above.  Perfectly cool.  That's probably what you
+<Emphasis>would</Emphasis> do if your program divided into obvious ``passes'' or
+``phases'', or whatever.
+</Para>
+
+<Para>
+If your program is large or you have no clue what might be gobbling
+all the time, you can get GHC to mark all functions with <Literal>&lowbar;scc&lowbar;</Literal>
+constructs, automagically.  Add an <Literal>-auto</Literal> compilation flag to the
+usual <Literal>-prof</Literal> option.
+</Para>
+
+<Para>
+Once you start homing in on the Guilty Suspects, you may well switch
+from automagically-inserted cost-centres to a few well-chosen ones of
+your own.
+</Para>
+
+<Para>
+To use profiling, you must <Emphasis>compile</Emphasis> and <Emphasis>run</Emphasis> with special
+options.  (We usually forget the ``run'' magic!&mdash;Do as we say, not as
+we do&hellip;) Details follow.
+</Para>
+
+<Para>
+If you're serious about this profiling game, you should probably read
+one or more of the Sansom/Peyton Jones papers about the GHC profiling
+system.  Just visit the <ULink URL="http://www.dcs.gla.ac.uk/fp/">Glasgow FP group web page</ULink>&hellip;
+</Para>
+
+</Sect1>
+
+<Sect1 id="prof-compiler-options">
+<Title>Compiling programs for profiling
+</Title>
+
+<Para>
+<IndexTerm><Primary>profiling options</Primary></IndexTerm>
+<IndexTerm><Primary>options, for profiling</Primary></IndexTerm>
+</Para>
+
+<Para>
+To make use of the cost centre profiling system <Emphasis>all</Emphasis> modules must
+be compiled and linked with the <Literal>-prof</Literal> option.<IndexTerm><Primary>-prof option</Primary></IndexTerm>
+Any <Literal>&lowbar;scc&lowbar;</Literal> constructs you've put in your source will spring to life.
+</Para>
+
+<Para>
+Without a <Literal>-prof</Literal> option, your <Literal>&lowbar;scc&lowbar;</Literal>s are ignored; so you can
+compiled <Literal>&lowbar;scc&lowbar;</Literal>-laden code without changing it.
+</Para>
+
+<Para>
+There are a few other profiling-related compilation options.  Use them
+<Emphasis>in addition to</Emphasis> <Literal>-prof</Literal>.  These do not have to be used
+consistently for all modules in a program.
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>-auto</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-auto option</Primary></IndexTerm>
+<IndexTerm><Primary>cost centres, automatically inserting</Primary></IndexTerm>
+GHC will automatically add <Literal>&lowbar;scc&lowbar;</Literal> constructs for
+all top-level, exported functions.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-auto-all</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-auto-all option</Primary></IndexTerm>
+<Emphasis>All</Emphasis> top-level functions, exported or not, will be automatically
+<Literal>&lowbar;scc&lowbar;</Literal>'d.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-caf-all</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-caf-all option</Primary></IndexTerm>
+The costs of all CAFs in a module are usually attributed to one
+``big'' CAF cost-centre. With this option, all CAFs get their own cost-centre.
+An ``if all else fails'' option&hellip;
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-ignore-scc</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-ignore-scc option</Primary></IndexTerm>
+Ignore any <Literal>&lowbar;scc&lowbar;</Literal> constructs,
+so a module which already has <Literal>&lowbar;scc&lowbar;</Literal>s can be
+compiled for profiling with the annotations ignored.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-G&lt;group&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-G&lt;group&gt; option</Primary></IndexTerm>
+Specifies the <Literal>&lt;group&gt;</Literal> to be attached to all the cost-centres
+declared in the module. If no group is specified it defaults to the
+module name.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+<Para>
+In addition to the <Literal>-prof</Literal> option your system might be setup to enable
+you to compile and link with the <Literal>-prof-details</Literal> <IndexTerm><Primary>-prof-details
+option</Primary></IndexTerm> option instead. This enables additional detailed counts
+to be reported with the <Literal>-P</Literal> RTS option.
+</Para>
+
+</Sect1>
+
+<Sect1 id="prof-rts-options">
+<Title>How to control your profiled program at runtime
+</Title>
+
+<Para>
+<IndexTerm><Primary>profiling RTS options</Primary></IndexTerm>
+<IndexTerm><Primary>RTS options, for profiling</Primary></IndexTerm>
+</Para>
+
+<Para>
+It isn't enough to compile your program for profiling with <Literal>-prof</Literal>!
+</Para>
+
+<Para>
+When you <Emphasis>run</Emphasis> your profiled program, you must tell the runtime
+system (RTS) what you want to profile (e.g., time and/or space), and
+how you wish the collected data to be reported.  You also may wish to
+set the sampling interval used in time profiling.
+</Para>
+
+<Para>
+Executive summary: <Literal>./a.out +RTS -pT</Literal> produces a time profile in
+<Literal>a.out.prof</Literal>; <Literal>./a.out +RTS -hC</Literal> produces space-profiling
+info which can be mangled by <Literal>hp2ps</Literal> and viewed with <Literal>ghostview</Literal>
+(or equivalent).
+</Para>
+
+<Para>
+Profiling runtime flags are passed to your program between the usual
+<Literal>+RTS</Literal> and <Literal>-RTS</Literal> options.
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>-p&lt;sort&gt;</Literal> or <Literal>-P&lt;sort&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-p&lt;sort&gt; RTS option (profiling)</Primary></IndexTerm>
+<IndexTerm><Primary>-P&lt;sort&gt; RTS option (profiling)</Primary></IndexTerm>
+<IndexTerm><Primary>time profile</Primary></IndexTerm>
+<IndexTerm><Primary>serial time profile</Primary></IndexTerm>
+The <Literal>-p?</Literal> option produces a standard <Emphasis>time profile</Emphasis> report.
+It is written into the file <Literal>&lt;program&gt;@.prof</Literal>.
+</Para>
+
+<Para>
+The <Literal>-P?</Literal> option produces a more detailed report containing the
+actual time and allocation data as well.  (Not used much.)
+</Para>
+
+<Para>
+The <Literal>&lt;sort&gt;</Literal> indicates how the cost centres are to be sorted in the
+report. Valid <Literal>&lt;sort&gt;</Literal> options are:
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>T</Literal>:</Term>
+<ListItem>
+<Para>
+by time, largest first (the default);
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>A</Literal>:</Term>
+<ListItem>
+<Para>
+by bytes allocated, largest first;
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>C</Literal>:</Term>
+<ListItem>
+<Para>
+alphabetically by group, module and cost centre.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-i&lt;secs&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-i&lt;secs&gt; RTS option
+(profiling)</Primary></IndexTerm> Set the profiling (sampling) interval to <Literal>&lt;secs&gt;</Literal>
+seconds (the default is 1&nbsp;second).  Fractions are allowed: for example
+<Literal>-i0.2</Literal> will get 5 samples per second.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-h&lt;break-down&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-h&lt;break-down&gt; RTS option (profiling)</Primary></IndexTerm>
+<IndexTerm><Primary>heap profile</Primary></IndexTerm>
+</Para>
+
+<Para>
+Produce a detailed <Emphasis>space profile</Emphasis> of the heap occupied by live
+closures. The profile is written to the file <Literal>&lt;program&gt;@.hp</Literal> from
+which a PostScript graph can be produced using <Literal>hp2ps</Literal> (see 
+<XRef LinkEnd="hp2ps">).
+</Para>
+
+<Para>
+The heap space profile may be broken down by different criteria:
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>-hC</Literal>:</Term>
+<ListItem>
+<Para>
+cost centre which produced the closure (the default).
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-hM</Literal>:</Term>
+<ListItem>
+<Para>
+cost centre module which produced the closure.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-hG</Literal>:</Term>
+<ListItem>
+<Para>
+cost centre group which produced the closure.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-hD</Literal>:</Term>
+<ListItem>
+<Para>
+closure description&mdash;a string describing the closure.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-hY</Literal>:</Term>
+<ListItem>
+<Para>
+closure type&mdash;a string describing the closure's type.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+By default all live closures in the heap are profiled, but particular
+closures of interest can be selected (see below).
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+<Para>
+Heap (space) profiling uses hash tables. If these tables
+should fill the run will abort. The
+<Literal>-z&lt;tbl&gt;&lt;size&gt;</Literal><IndexTerm><Primary>-z&lt;tbl&gt;&lt;size&gt; RTS option (profiling)</Primary></IndexTerm> option is used to
+increase the size of the relevant hash table (<Literal>C</Literal>, <Literal>M</Literal>,
+<Literal>G</Literal>, <Literal>D</Literal> or <Literal>Y</Literal>, defined as for <Literal>&lt;break-down&gt;</Literal> above). The
+actual size used is the next largest power of 2.
+</Para>
+
+<Para>
+The heap profile can be restricted to particular closures of interest.
+The closures of interest can selected by the attached cost centre
+(module:label, module and group), closure category (description, type,
+and kind) using the following options:
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>-c&lcub;&lt;mod&gt;:&lt;lab&gt;,&lt;mod&gt;:&lt;lab&gt;...</Literal>&rcub;:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-c&lcub;&lt;lab&gt;</Primary></IndexTerm> RTS option (profiling)&rcub;
+Selects individual cost centre(s).
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-m&lcub;&lt;mod&gt;,&lt;mod&gt;...</Literal>&rcub;:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-m&lcub;&lt;mod&gt;</Primary></IndexTerm> RTS option (profiling)&rcub;
+Selects all cost centres from the module(s) specified.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-g&lcub;&lt;grp&gt;,&lt;grp&gt;...</Literal>&rcub;:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-g&lcub;&lt;grp&gt;</Primary></IndexTerm> RTS option (profiling)&rcub;
+Selects all cost centres from the groups(s) specified.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-d&lcub;&lt;des&gt;,&lt;des&gt;...</Literal>&rcub;:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-d&lcub;&lt;des&gt;</Primary></IndexTerm> RTS option (profiling)&rcub;
+Selects closures which have one of the specified descriptions.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-y&lcub;&lt;typ&gt;,&lt;typ&gt;...</Literal>&rcub;:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-y&lcub;&lt;typ&gt;</Primary></IndexTerm> RTS option (profiling)&rcub;
+Selects closures which have one of the specified type descriptions.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-k&lcub;&lt;knd&gt;,&lt;knd&gt;...</Literal>&rcub;:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-k&lcub;&lt;knd&gt;</Primary></IndexTerm> RTS option (profiling)&rcub;
+Selects closures which are of one of the specified closure kinds.
+Valid closure kinds are <Literal>CON</Literal> (constructor), <Literal>FN</Literal> (manifest
+function), <Literal>PAP</Literal> (partial application), <Literal>BH</Literal> (black hole) and
+<Literal>THK</Literal> (thunk).
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+<Para>
+The space occupied by a closure will be reported in the heap profile
+if the closure satisfies the following logical expression:
+</Para>
+
+<Para>
+<Quote>(&lsqb;-c&rsqb; or &lsqb;-m&rsqb; or &lsqb;-g&rsqb;) and (&lsqb;-d&rsqb; or &lsqb;-y&rsqb; or &lsqb;-k&rsqb;)</Quote>
+</Para>
+
+<Para>
+where a particular option is true if the closure (or its attached cost
+centre) is selected by the option (or the option is not specified).
+</Para>
+
+</Sect1>
+
+<Sect1 id="prof-output">
+<Title>What's in a profiling report?
+</Title>
+
+<Para>
+<IndexTerm><Primary>profiling report, meaning thereof</Primary></IndexTerm>
+</Para>
+
+<Para>
+When you run your profiled program with the <Literal>-p</Literal> RTS option <IndexTerm><Primary>-p
+RTS option</Primary></IndexTerm>, you get the following information about your ``cost
+centres'':
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>COST CENTRE</Literal>:</Term>
+<ListItem>
+<Para>
+The cost-centre's name.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>MODULE</Literal>:</Term>
+<ListItem>
+<Para>
+The module associated with the cost-centre;
+important mostly if you have identically-named cost-centres in
+different modules.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>scc</Literal>:</Term>
+<ListItem>
+<Para>
+How many times this cost-centre was entered; think
+of it as ``I got to the <Literal>&lowbar;scc&lowbar;</Literal> construct this many times&hellip;''
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>&percnt;time</Literal>:</Term>
+<ListItem>
+<Para>
+What part of the time was spent in this cost-centre (see also ``ticks,''
+below).
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>&percnt;alloc</Literal>:</Term>
+<ListItem>
+<Para>
+What part of the memory allocation was done in this cost-centre
+(see also ``bytes,'' below).
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>inner</Literal>:</Term>
+<ListItem>
+<Para>
+How many times this cost-centre ``passed control'' to an inner
+cost-centre; for example, <Literal>scc=4</Literal> plus <Literal>subscc=8</Literal> means
+``This <Literal>&lowbar;scc&lowbar;</Literal> was entered four times, but went out to
+other <Literal>&lowbar;scc&lowbar;s</Literal> eight times.''
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>cafs</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>CAF, profiling</Primary></IndexTerm>
+How many CAFs this cost centre evaluated.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>dicts</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>Dictionaries, profiling</Primary></IndexTerm>
+How many dictionaries this cost centre evaluated.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+<Para>
+In addition you can use the <Literal>-P</Literal> RTS option <IndexTerm><Primary></Primary></IndexTerm> to get the following additional information:
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>ticks</Literal>:</Term>
+<ListItem>
+<Para>
+The raw number of time ``ticks'' which were
+attributed to this cost-centre; from this, we get the <Literal>&percnt;time</Literal>
+figure mentioned above.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>bytes</Literal>:</Term>
+<ListItem>
+<Para>
+Number of bytes allocated in the heap while in
+this cost-centre; again, this is the raw number from which we
+get the <Literal>&percnt;alloc</Literal> figure mentioned above.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+<Para>
+Finally if you built your program with <Literal>-prof-details</Literal>
+<IndexTerm><Primary></Primary></IndexTerm> the <Literal>-P</Literal> RTS option will also
+produce the following information:
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>closures</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>closures, profiling</Primary></IndexTerm>
+How many heap objects were allocated; these objects may be of varying
+size.  If you divide the number of bytes (mentioned below) by this
+number of ``closures'', then you will get the average object size.
+(Not too interesting, but still&hellip;)
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>thunks</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>thunks, profiling</Primary></IndexTerm>
+How many times we entered (evaluated) a thunk&mdash;an unevaluated
+object in the heap&mdash;while we were in this cost-centre.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>funcs</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>functions, profiling</Primary></IndexTerm>
+How many times we entered (evaluated) a function while we we in this
+cost-centre.  (In Haskell, functions are first-class values and may be
+passed as arguments, returned as results, evaluated, and generally
+manipulated just like data values)
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>PAPs</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>partial applications, profiling</Primary></IndexTerm>
+How many times we entered (evaluated) a partial application (PAP), i.e.,
+a function applied to fewer arguments than it needs.  For example, <Literal>Int</Literal>
+addition applied to one argument would be a PAP.  A PAP is really
+just a particular form for a function.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+</Sect1>
+
+<Sect1 id="prof-graphs">
+<Title>Producing graphical heap profiles
+</Title>
+
+<Para>
+<IndexTerm><Primary>heap profiles, producing</Primary></IndexTerm>
+</Para>
+
+<Para>
+Utility programs which produce graphical profiles.
+</Para>
+
+<Sect2 id="hp2ps">
+<Title><Literal>hp2ps</Literal>--heap profile to PostScript
+</Title>
+
+<Para>
+<IndexTerm><Primary>hp2ps (utility)</Primary></IndexTerm>
+<IndexTerm><Primary>heap profiles</Primary></IndexTerm>
+<IndexTerm><Primary>PostScript, from heap profiles</Primary></IndexTerm>
+</Para>
+
+<Para>
+Usage:
+</Para>
+
+<Para>
+
+<Screen>
+hp2ps [flags] [&#60;file&#62;[.stat]]
+</Screen>
+
+</Para>
+
+<Para>
+The program <Literal>hp2ps</Literal><IndexTerm><Primary>hp2ps program</Primary></IndexTerm> converts a heap profile
+as produced by the <Literal>-h&lt;break-down&gt;</Literal><IndexTerm><Primary>-h&lt;break-down&gt; RTS
+option</Primary></IndexTerm> runtime option into a PostScript graph of the heap
+profile. By convention, the file to be processed by <Literal>hp2ps</Literal> has a
+<Literal>.hp</Literal> extension. The PostScript output is written to <Literal>&lt;file&gt;@.ps</Literal>. If
+<Literal>&lt;file&gt;</Literal> is omitted entirely, then the program behaves as a filter.
+</Para>
+
+<Para>
+<Literal>hp2ps</Literal> is distributed in <Literal>ghc/utils/hp2ps</Literal> in a GHC source
+distribution. It was originally developed by Dave Wakeling as part of
+the HBC/LML heap profiler.
+</Para>
+
+<Para>
+The flags are:
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>-d</Literal></Term>
+<ListItem>
+<Para>
+In order to make graphs more readable, <Literal>hp2ps</Literal> sorts the shaded
+bands for each identifier. The default sort ordering is for the bands
+with the largest area to be stacked on top of the smaller ones.  The
+<Literal>-d</Literal> option causes rougher bands (those representing series of
+values with the largest standard deviations) to be stacked on top of
+smoother ones.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-b</Literal></Term>
+<ListItem>
+<Para>
+Normally, <Literal>hp2ps</Literal> puts the title of the graph in a small box at the
+top of the page. However, if the JOB string is too long to fit in a
+small box (more than 35 characters), then
+<Literal>hp2ps</Literal> will choose to use a big box instead.  The <Literal>-b</Literal>
+option forces <Literal>hp2ps</Literal> to use a big box.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-e&lt;float&gt;[in&verbar;mm&verbar;pt]</Literal></Term>
+<ListItem>
+<Para>
+Generate encapsulated PostScript suitable for inclusion in LaTeX
+documents.  Usually, the PostScript graph is drawn in landscape mode
+in an area 9 inches wide by 6 inches high, and <Literal>hp2ps</Literal> arranges
+for this area to be approximately centred on a sheet of a4 paper.
+This format is convenient of studying the graph in detail, but it is
+unsuitable for inclusion in LaTeX documents.  The <Literal>-e</Literal> option
+causes the graph to be drawn in portrait mode, with float specifying
+the width in inches, millimetres or points (the default).  The
+resulting PostScript file conforms to the Encapsulated PostScript
+(EPS) convention, and it can be included in a LaTeX document using
+Rokicki's dvi-to-PostScript converter <Literal>dvips</Literal>.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-g</Literal></Term>
+<ListItem>
+<Para>
+Create output suitable for the <Literal>gs</Literal> PostScript previewer (or
+similar). In this case the graph is printed in portrait mode without
+scaling. The output is unsuitable for a laser printer.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-l</Literal></Term>
+<ListItem>
+<Para>
+Normally a profile is limited to 20 bands with additional identifiers
+being grouped into an <Literal>OTHER</Literal> band. The <Literal>-l</Literal> flag removes this
+20 band and limit, producing as many bands as necessary. No key is
+produced as it won't fit!. It is useful for creation time profiles
+with many bands.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-m&lt;int&gt;</Literal></Term>
+<ListItem>
+<Para>
+Normally a profile is limited to 20 bands with additional identifiers
+being grouped into an <Literal>OTHER</Literal> band. The <Literal>-m</Literal> flag specifies an
+alternative band limit (the maximum is 20).
+</Para>
+
+<Para>
+<Literal>-m0</Literal> requests the band limit to be removed. As many bands as
+necessary are produced. However no key is produced as it won't fit! It
+is useful for displaying creation time profiles with many bands.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-p</Literal></Term>
+<ListItem>
+<Para>
+Use previous parameters. By default, the PostScript graph is
+automatically scaled both horizontally and vertically so that it fills
+the page.  However, when preparing a series of graphs for use in a
+presentation, it is often useful to draw a new graph using the same
+scale, shading and ordering as a previous one. The <Literal>-p</Literal> flag causes
+the graph to be drawn using the parameters determined by a previous
+run of <Literal>hp2ps</Literal> on <Literal>file</Literal>. These are extracted from
+<Literal>file@.aux</Literal>.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-s</Literal></Term>
+<ListItem>
+<Para>
+Use a small box for the title.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-t&lt;float&gt;</Literal></Term>
+<ListItem>
+<Para>
+Normally trace elements which sum to a total of less than 1&percnt; of the
+profile are removed from the profile. The <Literal>-t</Literal> option allows this
+percentage to be modified (maximum 5&percnt;).
+</Para>
+
+<Para>
+<Literal>-t0</Literal> requests no trace elements to be removed from the profile,
+ensuring that all the data will be displayed.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-?</Literal></Term>
+<ListItem>
+<Para>
+Print out usage information.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+</Sect2>
+
+<Sect2 id="stat2resid">
+<Title><Literal>stat2resid</Literal>&mdash;residency info from GC stats
+</Title>
+
+<Para>
+<IndexTerm><Primary>stat2resid (utility)</Primary></IndexTerm>
+<IndexTerm><Primary>GC stats&mdash;residency info</Primary></IndexTerm>
+<IndexTerm><Primary>residency, from GC stats</Primary></IndexTerm>
+</Para>
+
+<Para>
+Usage:
+</Para>
+
+<Para>
+
+<Screen>
+stat2resid [&#60;file&#62;[.stat] [&#60;outfile&#62;]]
+</Screen>
+
+</Para>
+
+<Para>
+The program <Literal>stat2resid</Literal><IndexTerm><Primary>stat2resid</Primary></IndexTerm> converts a detailed
+garbage collection statistics file produced by the
+<Literal>-S</Literal><IndexTerm><Primary>-S RTS option</Primary></IndexTerm> runtime option into a PostScript heap
+residency graph. The garbage collection statistics file can be
+produced without compiling your program for profiling.
+</Para>
+
+<Para>
+By convention, the file to be processed by <Literal>stat2resid</Literal> has a
+<Literal>.stat</Literal> extension. If the <Literal>&lt;outfile&gt;</Literal> is not specified the
+PostScript will be written to <Literal>&lt;file&gt;@.resid.ps</Literal>. If
+<Literal>&lt;file&gt;</Literal> is omitted entirely, then the program behaves as a filter.
+</Para>
+
+<Para>
+The plot can not be produced from the statistics file for a
+generational collector, though a suitable stats file can be produced
+using the <Literal>-F2s</Literal><IndexTerm><Primary>-F2s RTS option</Primary></IndexTerm> runtime option when the
+program has been compiled for generational garbage collection (the
+default).
+</Para>
+
+<Para>
+<Literal>stat2resid</Literal> is distributed in <Literal>ghc/utils/stat2resid</Literal> in a GHC source
+distribution.
+</Para>
+
+</Sect2>
+
+</Sect1>
+
+<Sect1 id="ticky-ticky">
+<Title>Using ``ticky-ticky'' profiling (for implementors)
+</Title>
+
+<Para>
+<IndexTerm><Primary>ticky-ticky profiling (implementors)</Primary></IndexTerm>
+</Para>
+
+<Para>
+(ToDo: document properly.)
+</Para>
+
+<Para>
+It is possible to compile Glasgow Haskell programs so that they will
+count lots and lots of interesting things, e.g., number of updates,
+number of data constructors entered, etc., etc.  We call this
+``ticky-ticky'' profiling,<IndexTerm><Primary>ticky-ticky profiling</Primary></IndexTerm>
+<IndexTerm><Primary>profiling, ticky-ticky</Primary></IndexTerm> because that's the sound a Sun4 makes
+when it is running up all those counters (<Emphasis>slowly</Emphasis>).
+</Para>
+
+<Para>
+Ticky-ticky profiling is mainly intended for implementors; it is quite
+separate from the main ``cost-centre'' profiling system, intended for
+all users everywhere.
+</Para>
+
+<Para>
+To be able to use ticky-ticky profiling, you will need to have built
+appropriate libraries and things when you made the system.  See
+``Customising what libraries to build,'' in the installation guide.
+</Para>
+
+<Para>
+To get your compiled program to spit out the ticky-ticky numbers, use
+a <Literal>-r</Literal> RTS option<IndexTerm><Primary>-r RTS option</Primary></IndexTerm>.  See <XRef LinkEnd="runtime-control">.
+</Para>
+
+<Para>
+Compiling your program with the <Literal>-ticky</Literal> switch yields an executable
+that performs these counts.  Here is a sample ticky-ticky statistics
+file, generated by the invocation <Literal>foo +RTS -rfoo.ticky</Literal>.
+</Para>
+
+<Para>
+
+<Screen>
+ foo +RTS -rfoo.ticky
+
+
+ALLOCATIONS: 3964631 (11330900 words total: 3999476 admin, 6098829 goods, 1232595 slop)
+                                total words:        2     3     4     5    6+
+  69647 (  1.8%) function values                 50.0  50.0   0.0   0.0   0.0
+2382937 ( 60.1%) thunks                           0.0  83.9  16.1   0.0   0.0
+1477218 ( 37.3%) data values                     66.8  33.2   0.0   0.0   0.0
+      0 (  0.0%) big tuples
+      2 (  0.0%) black holes                      0.0 100.0   0.0   0.0   0.0
+      0 (  0.0%) prim things
+  34825 (  0.9%) partial applications             0.0   0.0   0.0 100.0   0.0
+      2 (  0.0%) thread state objects             0.0   0.0   0.0   0.0 100.0
+
+Total storage-manager allocations: 3647137 (11882004 words)
+        [551104 words lost to speculative heap-checks]
+
+STACK USAGE:
+
+ENTERS: 9400092  of which 2005772 (21.3%) direct to the entry code
+                  [the rest indirected via Node's info ptr]
+1860318 ( 19.8%) thunks
+3733184 ( 39.7%) data values
+3149544 ( 33.5%) function values
+                  [of which 1999880 (63.5%) bypassed arg-satisfaction chk]
+ 348140 (  3.7%) partial applications
+ 308906 (  3.3%) normal indirections
+      0 (  0.0%) permanent indirections
+
+RETURNS: 5870443
+2137257 ( 36.4%) from entering a new constructor
+                  [the rest from entering an existing constructor]
+2349219 ( 40.0%) vectored [the rest unvectored]
+
+RET_NEW:         2137257:  32.5% 46.2% 21.3%  0.0%  0.0%  0.0%  0.0%  0.0%  0.0%
+RET_OLD:         3733184:   2.8% 67.9% 29.3%  0.0%  0.0%  0.0%  0.0%  0.0%  0.0%
+RET_UNBOXED_TUP:       2:   0.0%  0.0%100.0%  0.0%  0.0%  0.0%  0.0%  0.0%  0.0%
+
+RET_VEC_RETURN : 2349219:   0.0%  0.0%100.0%  0.0%  0.0%  0.0%  0.0%  0.0%  0.0%
+
+UPDATE FRAMES: 2241725 (0 omitted from thunks)
+SEQ FRAMES:    1
+CATCH FRAMES:  1
+UPDATES: 2241725
+      0 (  0.0%) data values
+  34827 (  1.6%) partial applications
+                  [2 in place, 34825 allocated new space]
+2206898 ( 98.4%) updates to existing heap objects (46 by squeezing)
+UPD_CON_IN_NEW:         0:       0      0      0      0      0      0      0      0      0
+UPD_PAP_IN_NEW:     34825:       0      0      0  34825      0      0      0      0      0
+
+NEW GEN UPDATES: 2274700 ( 99.9%)
+
+OLD GEN UPDATES: 1852 (  0.1%)
+
+Total bytes copied during GC: 190096
+
+**************************************************
+3647137 ALLOC_HEAP_ctr
+11882004 ALLOC_HEAP_tot
+  69647 ALLOC_FUN_ctr
+  69647 ALLOC_FUN_adm
+  69644 ALLOC_FUN_gds
+  34819 ALLOC_FUN_slp
+  34831 ALLOC_FUN_hst_0
+  34816 ALLOC_FUN_hst_1
+      0 ALLOC_FUN_hst_2
+      0 ALLOC_FUN_hst_3
+      0 ALLOC_FUN_hst_4
+2382937 ALLOC_UP_THK_ctr
+      0 ALLOC_SE_THK_ctr
+ 308906 ENT_IND_ctr
+      0 E!NT_PERM_IND_ctr requires +RTS -Z
+[... lots more info omitted ...]
+      0 GC_SEL_ABANDONED_ctr
+      0 GC_SEL_MINOR_ctr
+      0 GC_SEL_MAJOR_ctr
+      0 GC_FAILED_PROMOTION_ctr
+  47524 GC_WORDS_COPIED_ctr
+</Screen>
+
+</Para>
+
+<Para>
+The formatting of the information above the row of asterisks is
+subject to change, but hopefully provides a useful human-readable
+summary.  Below the asterisks <Emphasis>all counters</Emphasis> maintained by the
+ticky-ticky system are dumped, in a format intended to be
+machine-readable: zero or more spaces, an integer, a space, the
+counter name, and a newline.
+</Para>
+
+<Para>
+In fact, not <Emphasis>all</Emphasis> counters are necessarily dumped; compile- or
+run-time flags can render certain counters invalid.  In this case,
+either the counter will simply not appear, or it will appear with a
+modified counter name, possibly along with an explanation for the
+omission (notice <Literal>ENT&lowbar;PERM&lowbar;IND&lowbar;ctr</Literal> appears with an inserted <Literal>!</Literal>
+above).  Software analysing this output should always check that it
+has the counters it expects.  Also, beware: some of the counters can
+have <Emphasis>large</Emphasis> values!
+</Para>
+
+</Sect1>
+
+</Chapter>
diff --git a/ghc/docs/users_guide/runtime_control.sgml b/ghc/docs/users_guide/runtime_control.sgml
new file mode 100644 (file)
index 0000000..b566fa7
--- /dev/null
@@ -0,0 +1,570 @@
+<Sect1 id="runtime-control">
+<Title>Running a compiled program
+</Title>
+
+<Para>
+<IndexTerm><Primary>runtime control of Haskell programs</Primary></IndexTerm>
+<IndexTerm><Primary>running, compiled program</Primary></IndexTerm>
+<IndexTerm><Primary>RTS options</Primary></IndexTerm>
+</Para>
+
+<Para>
+To make an executable program, the GHC system compiles your code and
+then links it with a non-trivial runtime system (RTS), which handles
+storage management, profiling, etc.
+</Para>
+
+<Para>
+You have some control over the behaviour of the RTS, by giving special
+command-line arguments to your program.
+</Para>
+
+<Para>
+When your Haskell program starts up, its RTS extracts command-line
+arguments bracketed between <Literal>+RTS</Literal><IndexTerm><Primary>+RTS option</Primary></IndexTerm> and
+<Literal>-RTS</Literal><IndexTerm><Primary>-RTS option</Primary></IndexTerm> as its own.  For example:
+</Para>
+
+<Para>
+
+<Screen>
+% ./a.out -f +RTS -p -S -RTS -h foo bar
+</Screen>
+
+</Para>
+
+<Para>
+The RTS will snaffle <Literal>-p -S</Literal> for itself, and the remaining arguments
+<Literal>-f -h foo bar</Literal> will be handed to your program if/when it calls
+<Literal>System.getArgs</Literal>.
+</Para>
+
+<Para>
+No <Literal>-RTS</Literal> option is required if the runtime-system options extend to
+the end of the command line, as in this example:
+</Para>
+
+<Para>
+
+<Screen>
+% hls -ltr /usr/etc +RTS -A5m
+</Screen>
+
+</Para>
+
+<Para>
+If you absolutely positively want all the rest of the options in a
+command line to go to the program (and not the RTS), use a
+<Literal>--RTS</Literal><IndexTerm><Primary>--RTS option</Primary></IndexTerm>.
+</Para>
+
+<Para>
+As always, for RTS options that take <Literal>&lt;size&gt;</Literal>s: If the last
+character of <Literal>size</Literal> is a K or k, multiply by 1000; if an M or m, by
+1,000,000; if a G or G, by 1,000,000,000.  (And any wraparound in the
+counters is <Emphasis>your</Emphasis> fault!)
+</Para>
+
+<Para>
+Giving a <Literal>+RTS -f</Literal><IndexTerm><Primary>-f RTS option</Primary></IndexTerm> option will print out the
+RTS options actually available in your program (which vary, depending
+on how you compiled).
+</Para>
+
+<Para>
+NOTE: to send RTS options to the compiler itself, you need to prefix
+the option with <Literal>-optCrts</Literal>, eg. to increase the maximum heap size for
+a compilation to 128M, you would add <Literal>-optCrts-M128m</Literal> to the command
+line.  The compiler understands some options directly without needing
+<Literal>-optCrts</Literal>: these are <Literal>-H</Literal> and <Literal>-K</Literal>.
+</Para>
+
+<Sect2 id="rts-options-gc">
+<Title>RTS options to control the garbage-collector
+</Title>
+
+<Para>
+<IndexTerm><Primary>RTS options, garbage-collection</Primary></IndexTerm>
+</Para>
+
+<Para>
+There are several options to give you precise control over garbage
+collection.  Hopefully, you won't need any of these in normal
+operation, but there are several things that can be tweaked for
+maximum performance.
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>-A&lt;size&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-A&lt;size&gt; RTS option</Primary></IndexTerm>
+<IndexTerm><Primary>allocation area, size</Primary></IndexTerm>
+</Para>
+
+<Para>
+&lsqb;Default: 256k&rsqb; Set the allocation area size used by the garbage
+collector.  The allocation area (actually generation 0 step 0) is
+fixed and is never resized (unless you use <Literal>-H</Literal>, below).
+</Para>
+
+<Para>
+Increasing the allocation area size may or may not give better
+performance (a bigger allocation area means worse cache behaviour but
+fewer garbage collections and less promotion).
+</Para>
+
+<Para>
+With only 1 generation (<Literal>-G1</Literal>) the <Literal>-A</Literal> option specifies the
+minimum allocation area, since the actual size of the allocation area
+will be resized according to the amount of data in the heap (see
+<Literal>-F</Literal>, below).
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-F&lt;factor&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-F&lt;factor&gt; RTS option</Primary></IndexTerm>
+<IndexTerm><Primary>heap size, factor</Primary></IndexTerm>
+</Para>
+
+<Para>
+&lsqb;Default: 2&rsqb; This option controls the amount of memory reserved for
+the older generations (and in the case of a two space collector the
+size of the allocation area) as a factor of the amount of live data.
+For example, if there was 2M of live data in the oldest generation
+when we last collected it, then by default we'll wait until it grows
+to 4M before collecting it again.
+</Para>
+
+<Para>
+The default seems to work well here.  If you have plenty of memory, it
+is usually better to use <Literal>-H&lt;size&gt;</Literal> than to increase
+<Literal>-F&lt;factor&gt;</Literal>.
+</Para>
+
+<Para>
+The <Literal>-F</Literal> setting will be automatically reduced by the garbage
+collector when the maximum heap size (the <Literal>-M&lt;size&gt;</Literal> setting)
+is approaching.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-G&lt;generations&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-G&lt;generations&gt; RTS option</Primary></IndexTerm>
+<IndexTerm><Primary>generations, number of</Primary></IndexTerm>
+</Para>
+
+<Para>
+&lsqb;Default: 2&rsqb; Set the number of generations used by the garbage
+collector.  The default of 2 seems to be good, but the garbage
+collector can support any number of generations.  Anything larger than
+about 4 is probably not a good idea unless your program runs for a
+<Emphasis>long</Emphasis> time, because the oldest generation will never get
+collected.
+</Para>
+
+<Para>
+Specifying 1 generation with <Literal>+RTS -G1</Literal> gives you a simple 2-space
+collector, as you would expect.  In a 2-space collector, the <Literal>-A</Literal>
+option (see above) specifies the <Emphasis>minimum</Emphasis> allocation area size,
+since the allocation area will grow with the amount of live data in
+the heap.  In a multi-generational collector the allocation area is a
+fixed size (unless you use the <Literal>-H</Literal> option, see below).
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-H&lt;size&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-H&lt;size&gt; RTS option</Primary></IndexTerm>
+<IndexTerm><Primary>heap size, suggested</Primary></IndexTerm>
+</Para>
+
+<Para>
+&lsqb;Default: 0&rsqb; This option provides a "suggested heap size" for the
+garbage collector.  The garbage collector will use about this much
+memory until the program residency grows and the heap size needs to be
+expanded to retain reasonable performance.
+</Para>
+
+<Para>
+By default, the heap will start small, and grow and shrink as
+necessary.  This can be bad for performance, so if you have plenty of
+memory it's worthwhile supplying a big <Literal>-H&lt;size&gt;</Literal>.  For
+improving GC performance, using <Literal>-H&lt;size&gt;</Literal> is usually a better
+bet than <Literal>-A&lt;size&gt;</Literal>.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-k&lt;size&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-k&lt;size&gt; RTS option</Primary></IndexTerm>
+<IndexTerm><Primary>stack, minimum size</Primary></IndexTerm>
+</Para>
+
+<Para>
+&lsqb;Default: 1k&rsqb; Set the initial stack size for new threads.  Thread
+stacks (including the main thread's stack) live on the heap, and grow
+as required.  The default value is good for concurrent applications
+with lots of small threads; if your program doesn't fit this model
+then increasing this option may help performance.
+</Para>
+
+<Para>
+The main thread is normally started with a slightly larger heap to cut
+down on unnecessary stack growth while the program is starting up.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-K&lt;size&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-K&lt;size&gt; RTS option</Primary></IndexTerm>
+<IndexTerm><Primary>stack, maximum size</Primary></IndexTerm>
+</Para>
+
+<Para>
+&lsqb;Default: 1M&rsqb; Set the maximum stack size for an individual thread to
+<Literal>&lt;size&gt;</Literal> bytes.  This option is there purely to stop the program
+eating up all the available memory in the machine if it gets into an
+infinite loop.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-m&lt;n&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-m&lt;n&gt; RTS option</Primary></IndexTerm>
+Minimum &percnt; <Literal>&lt;n&gt;</Literal> of heap which must be available for allocation.
+The default is 3&percnt;.
+<IndexTerm><Primary>heap, minimum free</Primary></IndexTerm>
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-M&lt;size&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-M&lt;size&gt; RTS option</Primary></IndexTerm>
+<IndexTerm><Primary>heap size, maximum</Primary></IndexTerm>
+</Para>
+
+<Para>
+&lsqb;Default: 64M&rsqb; Set the maximum heap size to <Literal>&lt;size&gt;</Literal> bytes.  The heap
+normally grows and shrinks according to the memory requirements of the
+program.  The only reason for having this option is to stop the heap
+growing without bound and filling up all the available swap space,
+which at the least will result in the program being summarily killed
+by the operating system.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-s&lt;file&gt;</Literal> or <Literal>-S&lt;file&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-S&lt;file&gt; RTS option</Primary></IndexTerm>
+<IndexTerm><Primary>-s&lt;file&gt; RTS option</Primary></IndexTerm>
+Write modest (<Literal>-s</Literal>) or verbose (<Literal>-S</Literal>) garbage-collector
+statistics into file <Literal>&lt;file&gt;</Literal>. The default <Literal>&lt;file&gt;</Literal> is
+<Literal>&lt;program&gt;@.stat</Literal>. The <Literal>&lt;file&gt;</Literal> <Literal>stderr</Literal> is treated
+specially, with the output really being sent to <Literal>stderr</Literal>.
+</Para>
+
+<Para>
+This option is useful for watching how the storage manager adjusts the
+heap size based on the current amount of live data.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>RTS options for profiling and Concurrent/Parallel Haskell</Title>
+
+<Para>
+The RTS options related to profiling are described in <XRef LinkEnd="prof-rts-options">; and those for concurrent/parallel stuff, in
+<XRef LinkEnd="parallel-rts-opts">.
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>RTS options for hackers, debuggers, and over-interested souls</Title>
+
+<Para>
+<IndexTerm><Primary>RTS options, hacking/debugging</Primary></IndexTerm>
+</Para>
+
+<Para>
+These RTS options might be used (a)&nbsp;to avoid a GHC bug, (b)&nbsp;to see
+``what's really happening'', or (c)&nbsp;because you feel like it.  Not
+recommended for everyday use!
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>-B</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-B RTS option</Primary></IndexTerm>
+Sound the bell at the start of each (major) garbage collection.
+</Para>
+
+<Para>
+Oddly enough, people really do use this option!  Our pal in Durham
+(England), Paul Callaghan, writes: ``Some people here use it for a
+variety of purposes&mdash;honestly!&mdash;e.g., confirmation that the
+code/machine is doing something, infinite loop detection, gauging cost
+of recently added code. Certain people can even tell what stage &lsqb;the
+program&rsqb; is in by the beep pattern. But the major use is for annoying
+others in the same office&hellip;''
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-r&lt;file&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-r &lt;file&gt; RTS option</Primary></IndexTerm>
+<IndexTerm><Primary>ticky ticky profiling</Primary></IndexTerm>
+Produce ``ticky-ticky'' statistics at the end of the program run.
+The <Literal>&lt;file&gt;</Literal> business works just like on the <Literal>-S</Literal> RTS option (above).
+</Para>
+
+<Para>
+``Ticky-ticky'' statistics are counts of various program actions
+(updates, enters, etc.)  The program must have been compiled using
+<Literal>-ticky</Literal><IndexTerm><Primary>-ticky option</Primary></IndexTerm> (a.k.a. ``ticky-ticky profiling''),
+and, for it to be really useful, linked with suitable system
+libraries.  Not a trivial undertaking: consult the installation guide
+on how to set things up for easy ``ticky-ticky'' profiling.  For more
+information, see <XRef LinkEnd="ticky-ticky">.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-D&lt;num&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-D RTS option</Primary></IndexTerm>
+An RTS debugging flag; varying quantities of output depending on which
+bits are set in <Literal>&lt;num&gt;</Literal>.  Only works if the RTS was compiled with the
+<Literal>DEBUG</Literal> option.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-Z</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-Z RTS option</Primary></IndexTerm>
+Turn <Emphasis>off</Emphasis> ``update-frame squeezing'' at garbage-collection
+time.  (There's no particularly good reason to turn it off, except to
+ensure the accuracy of certain data collected regarding thunk entry
+counts.)
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+</Sect2>
+
+<Sect2 id="rts-hooks">
+<Title>``Hooks'' to change RTS behaviour
+</Title>
+
+<Para>
+<IndexTerm><Primary>hooks, RTS</Primary></IndexTerm>
+<IndexTerm><Primary>RTS hooks</Primary></IndexTerm>
+<IndexTerm><Primary>RTS behaviour, changing</Primary></IndexTerm>
+</Para>
+
+<Para>
+GHC lets you exercise rudimentary control over the RTS settings for
+any given program, by compiling in a ``hook'' that is called by the
+run-time system.  The RTS contains stub definitions for all these
+hooks, but by writing your own version and linking it on the GHC
+command line, you can override the defaults.
+</Para>
+
+<Para>
+The function <Literal>defaultsHook</Literal><IndexTerm><Primary>defaultHook</Primary></IndexTerm> lets you change various
+RTS options.  The commonest use for this is to give your program a
+default heap and/or stack size that is greater than the default.  For
+example, to set <Literal>-H8m -K1m</Literal>:
+</Para>
+
+<Para>
+
+<ProgramListing>
+#include "Rts.h"
+#include "RtsFlags.h"
+void defaultsHook (void) {
+   RTSflags.GcFlags.stksSize =  1000002 / sizeof(W_);
+   RTSflags.GcFlags.heapSize =  8000002 / sizeof(W_);
+}
+</ProgramListing>
+
+</Para>
+
+<Para>
+Don't use powers of two for heap/stack sizes: these are more likely to
+interact badly with direct-mapped caches.  The full set of flags is
+defined in <Literal>ghc/rts/RtsFlags.h</Literal> the the GHC source tree.
+</Para>
+
+<Para>
+You can also change the messages printed when the runtime system
+``blows up,'' e.g., on stack overflow.  The hooks for these are as
+follows:
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>void ErrorHdrHook (FILE *)</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>ErrorHdrHook</Primary></IndexTerm>
+What's printed out before the message from <Literal>error</Literal>.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>void OutOfHeapHook (unsigned long, unsigned long)</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>OutOfHeapHook</Primary></IndexTerm>
+The heap-overflow message.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>void StackOverflowHook (long int)</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>StackOverflowHook</Primary></IndexTerm>
+The stack-overflow message.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>void MallocFailHook (long int)</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>MallocFailHook</Primary></IndexTerm>
+The message printed if <Literal>malloc</Literal> fails.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>void PatErrorHdrHook (FILE *)</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>PatErrorHdrHook</Primary></IndexTerm>
+The message printed if a pattern-match fails (the failures
+that were not handled by the Haskell programmer).
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>void PreTraceHook (FILE *)</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>PreTraceHook</Primary></IndexTerm>
+What's printed out before a <Literal>trace</Literal> message.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>void PostTraceHook (FILE *)</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>PostTraceHook</Primary></IndexTerm>
+What's printed out after a <Literal>trace</Literal> message.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+<Para>
+For example, here is the ``hooks'' code used by GHC itself:
+
+<ProgramListing>
+#include &#60;stdio.h&#62;
+#define W_ unsigned long int
+#define I_ long int
+
+void
+ErrorHdrHook (FILE *where)
+{
+    fprintf(where, "\n"); /* no "Fail: " */
+}
+
+void
+OutOfHeapHook (W_ request_size, W_ heap_size) /* both sizes in bytes */
+{
+    fprintf(stderr, "GHC's heap exhausted;\nwhile trying to 
+        allocate %lu bytes in a %lu-byte heap;\nuse the `-H&#60;size&#62;'
+        option to increase the total heap size.\n",
+        request_size,
+        heap_size);
+}
+
+void
+StackOverflowHook (I_ stack_size)    /* in bytes */
+{
+    fprintf(stderr, "GHC stack-space overflow: current size
+        %ld bytes.\nUse the `-K&#60;size&#62;' option to increase it.\n",
+        stack_size);
+}
+
+void
+PatErrorHdrHook (FILE *where)
+{
+    fprintf(where, "\n*** Pattern-matching error within GHC!\n\n
+        This is a compiler bug; please report it to
+        glasgow-haskell-bugs@haskell.org.\n\nFail: ");
+}
+
+void
+PreTraceHook (FILE *where)
+{
+    fprintf(where, "\n"); /* not "Trace On" */
+}
+
+void
+PostTraceHook (FILE *where)
+{
+    fprintf(where, "\n"); /* not "Trace Off" */
+}
+</ProgramListing>
+
+</Para>
+
+</Sect2>
+
+</Sect1>
diff --git a/ghc/docs/users_guide/sooner.sgml b/ghc/docs/users_guide/sooner.sgml
new file mode 100644 (file)
index 0000000..63ede49
--- /dev/null
@@ -0,0 +1,575 @@
+<Chapter id="sooner-faster-quicker">
+<Title>Advice on: sooner, faster, smaller, stingier
+</Title>
+
+<Para>
+Please advise us of other ``helpful hints'' that should go here!
+</Para>
+
+<Sect1 id="sooner">
+<Title>Sooner: producing a program more quickly
+</Title>
+
+<Para>
+<IndexTerm><Primary>compiling faster</Primary></IndexTerm>
+<IndexTerm><Primary>faster compiling</Primary></IndexTerm>
+<VariableList>
+
+<VarListEntry>
+<Term>Don't use <Literal>-O</Literal> or (especially) <Literal>-O2</Literal>:</Term>
+<ListItem>
+<Para>
+By using them, you are telling GHC that you are willing to suffer
+longer compilation times for better-quality code.
+</Para>
+
+<Para>
+GHC is surprisingly zippy for normal compilations without <Literal>-O</Literal>!
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>Use more memory:</Term>
+<ListItem>
+<Para>
+Within reason, more memory for heap space means less garbage
+collection for GHC, which means less compilation time.  If you use
+the <Literal>-Rgc-stats</Literal> option, you'll get a garbage-collector report.
+(Again, you can use the cheap-and-nasty <Literal>-optCrts-Sstderr</Literal> option to
+send the GC stats straight to standard error.)
+</Para>
+
+<Para>
+If it says you're using more than 20&percnt; of total time in garbage
+collecting, then more memory would help.
+</Para>
+
+<Para>
+If the heap size is approaching the maximum (64M by default), and you
+have lots of memory, try increasing the maximum with the
+<Literal>-M&lt;size&gt;</Literal><IndexTerm><Primary>-M&lt;size&gt; option</Primary></IndexTerm> option, e.g.: <Literal>ghc -c -O
+-M1024m Foo.hs</Literal>.
+</Para>
+
+<Para>
+Increasing the default allocation area size used by the compiler's RTS
+might also help: use the <Literal>-A&lt;size&gt;</Literal><IndexTerm><Primary>-A&lt;size&gt; option</Primary></IndexTerm>
+option.
+</Para>
+
+<Para>
+If GHC persists in being a bad memory citizen, please report it as a
+bug.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>Don't use too much memory!</Term>
+<ListItem>
+<Para>
+As soon as GHC plus its ``fellow citizens'' (other processes on your
+machine) start using more than the <Emphasis>real memory</Emphasis> on your
+machine, and the machine starts ``thrashing,'' <Emphasis>the party is
+over</Emphasis>.  Compile times will be worse than terrible!  Use something
+like the csh-builtin <Literal>time</Literal> command to get a report on how many page
+faults you're getting.
+</Para>
+
+<Para>
+If you don't know what virtual memory, thrashing, and page faults are,
+or you don't know the memory configuration of your machine,
+<Emphasis>don't</Emphasis> try to be clever about memory use: you'll just make
+your life a misery (and for other people, too, probably).
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>Try to use local disks when linking:</Term>
+<ListItem>
+<Para>
+Because Haskell objects and libraries tend to be large, it can take
+many real seconds to slurp the bits to/from a remote filesystem.
+</Para>
+
+<Para>
+It would be quite sensible to <Emphasis>compile</Emphasis> on a fast machine using
+remotely-mounted disks; then <Emphasis>link</Emphasis> on a slow machine that had
+your disks directly mounted.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>Don't derive/use <Literal>Read</Literal> unnecessarily:</Term>
+<ListItem>
+<Para>
+It's ugly and slow.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>GHC compiles some program constructs slowly:</Term>
+<ListItem>
+<Para>
+Deeply-nested list comprehensions seem to be one such; in the past,
+very large constant tables were bad, too.
+</Para>
+
+<Para>
+We'd rather you reported such behaviour as a bug, so that we can try
+to correct it.
+</Para>
+
+<Para>
+The parts of the compiler that seem most prone to wandering off for a
+long time are the abstract interpreters (strictness and update
+analysers).  You can turn these off individually with
+<Literal>-fno-strictness</Literal><IndexTerm><Primary>-fno-strictness anti-option</Primary></IndexTerm> and
+<Literal>-fno-update-analysis</Literal>.<IndexTerm><Primary>-fno-update-analysis anti-option</Primary></IndexTerm>
+</Para>
+
+<Para>
+To figure out which part of the compiler is badly behaved, the
+<Literal>-dshow-passes</Literal><IndexTerm><Primary>-dshow-passes option</Primary></IndexTerm> option is your
+friend.
+</Para>
+
+<Para>
+If your module has big wads of constant data, GHC may produce a huge
+basic block that will cause the native-code generator's register
+allocator to founder.  Bring on <Literal>-fvia-C</Literal><IndexTerm><Primary>-fvia-C option</Primary></IndexTerm>
+(not that GCC will be that quick about it, either).
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>Avoid the consistency-check on linking:</Term>
+<ListItem>
+<Para>
+Use <Literal>-no-link-chk</Literal><IndexTerm><Primary>-no-link-chk</Primary></IndexTerm>; saves effort.  This is
+probably safe in a I-only-compile-things-one-way setup.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>Explicit <Literal>import</Literal> declarations:</Term>
+<ListItem>
+<Para>
+Instead of saying <Literal>import Foo</Literal>, say <Literal>import Foo (...stuff I want...)</Literal>.
+</Para>
+
+<Para>
+Truthfully, the reduction on compilation time will be very small.
+However, judicious use of <Literal>import</Literal> declarations can make a
+program easier to understand, so it may be a good idea anyway.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+</Sect1>
+
+<Sect1 id="faster">
+<Title>Faster: producing a program that runs quicker
+</Title>
+
+<Para>
+<IndexTerm><Primary>faster programs, how to produce</Primary></IndexTerm>
+</Para>
+
+<Para>
+The key tool to use in making your Haskell program run faster are
+GHC's profiling facilities, described separately in <XRef LinkEnd="profiling">.  There is <Emphasis>no substitute</Emphasis> for
+finding where your program's time/space is <Emphasis>really</Emphasis> going, as
+opposed to where you imagine it is going.
+</Para>
+
+<Para>
+Another point to bear in mind: By far the best way to improve a
+program's performance <Emphasis>dramatically</Emphasis> is to use better
+algorithms.  Once profiling has thrown the spotlight on the guilty
+time-consumer(s), it may be better to re-think your program than to
+try all the tweaks listed below.
+</Para>
+
+<Para>
+Another extremely efficient way to make your program snappy is to use
+library code that has been Seriously Tuned By Someone Else.  You
+<Emphasis>might</Emphasis> be able to write a better quicksort than the one in the
+HBC library, but it will take you much longer than typing <Literal>import
+QSort</Literal>.  (Incidentally, it doesn't hurt if the Someone Else is Lennart
+Augustsson.)
+</Para>
+
+<Para>
+Please report any overly-slow GHC-compiled programs.  The current
+definition of ``overly-slow'' is ``the HBC-compiled version ran
+faster''&hellip;
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term>Optimise, using <Literal>-O</Literal> or <Literal>-O2</Literal>:</Term>
+<ListItem>
+<Para>
+This is the most basic way
+to make your program go faster.  Compilation time will be slower,
+especially with <Literal>-O2</Literal>.
+</Para>
+
+<Para>
+At present, <Literal>-O2</Literal> is nearly indistinguishable from <Literal>-O</Literal>.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>Compile via C and crank up GCC:</Term>
+<ListItem>
+<Para>
+Even with <Literal>-O</Literal>, GHC tries to
+use a native-code generator, if available.  But the native
+code-generator is designed to be quick, not mind-bogglingly clever.
+Better to let GCC have a go, as it tries much harder on register
+allocation, etc.
+</Para>
+
+<Para>
+So, when we want very fast code, we use: <Literal>-O -fvia-C -O2-for-C</Literal>.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>Overloaded functions are not your friend:</Term>
+<ListItem>
+<Para>
+Haskell's overloading (using type classes) is elegant, neat, etc.,
+etc., but it is death to performance if left to linger in an inner
+loop.  How can you squash it?
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term>Give explicit type signatures:</Term>
+<ListItem>
+<Para>
+Signatures are the basic trick; putting them on exported, top-level
+functions is good software-engineering practice, anyway.  (Tip: using
+<Literal>-fwarn-missing-signatures</Literal><IndexTerm><Primary>-fwarn-missing-signatures
+option</Primary></IndexTerm> can help enforce good signature-practice).
+</Para>
+
+<Para>
+The automatic specialisation of overloaded functions (with <Literal>-O</Literal>)
+should take care of overloaded local and/or unexported functions.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>Use <Literal>SPECIALIZE</Literal> pragmas:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>SPECIALIZE pragma</Primary></IndexTerm>
+<IndexTerm><Primary>overloading, death to</Primary></IndexTerm>
+</Para>
+
+<Para>
+Specialize the overloading on key functions in your program.  See
+<XRef LinkEnd="specialize-pragma"> and
+<XRef LinkEnd="specialize-instance-pragma">.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>``But how do I know where overloading is creeping in?'':</Term>
+<ListItem>
+<Para>
+A low-tech way: grep (search) your interface files for overloaded
+type signatures; e.g.,:
+
+<ProgramListing>
+% egrep '^[a-z].*::.*=&#62;' *.hi
+</ProgramListing>
+
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>Strict functions are your dear friends:</Term>
+<ListItem>
+<Para>
+and, among other things, lazy pattern-matching is your enemy.
+</Para>
+
+<Para>
+(If you don't know what a ``strict function'' is, please consult a
+functional-programming textbook.  A sentence or two of
+explanation here probably would not do much good.)
+</Para>
+
+<Para>
+Consider these two code fragments:
+
+<ProgramListing>
+f (Wibble x y) =  ... # strict
+
+f arg = let { (Wibble x y) = arg } in ... # lazy
+</ProgramListing>
+
+The former will result in far better code.
+</Para>
+
+<Para>
+A less contrived example shows the use of <Literal>cases</Literal> instead
+of <Literal>lets</Literal> to get stricter code (a good thing):
+
+<ProgramListing>
+f (Wibble x y)  # beautiful but slow
+  = let
+        (a1, b1, c1) = unpackFoo x
+        (a2, b2, c2) = unpackFoo y
+    in ...
+
+f (Wibble x y)  # ugly, and proud of it
+  = case (unpackFoo x) of { (a1, b1, c1) -&#62;
+    case (unpackFoo y) of { (a2, b2, c2) -&#62;
+    ...
+    }}
+</ProgramListing>
+
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>GHC loves single-constructor data-types:</Term>
+<ListItem>
+<Para>
+It's all the better if a function is strict in a single-constructor
+type (a type with only one data-constructor; for example, tuples are
+single-constructor types).
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>Newtypes are better than datatypes:</Term>
+<ListItem>
+<Para>
+If your datatype has a single constructor with a single field, use a
+<Literal>newtype</Literal> declaration instead of a <Literal>data</Literal> declaration.  The <Literal>newtype</Literal>
+will be optimised away in most cases.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>``How do I find out a function's strictness?''</Term>
+<ListItem>
+<Para>
+Don't guess&mdash;look it up.
+</Para>
+
+<Para>
+Look for your function in the interface file, then for the third field
+in the pragma; it should say <Literal>&lowbar;S&lowbar; &lt;string&gt;</Literal>.  The <Literal>&lt;string&gt;</Literal>
+gives the strictness of the function's arguments.  <Literal>L</Literal> is lazy
+(bad), <Literal>S</Literal> and <Literal>E</Literal> are strict (good), <Literal>P</Literal> is ``primitive'' (good),
+<Literal>U(...)</Literal> is strict and
+``unpackable'' (very good), and <Literal>A</Literal> is absent (very good).
+</Para>
+
+<Para>
+For an ``unpackable'' <Literal>U(...)</Literal> argument, the info inside
+tells the strictness of its components.  So, if the argument is a
+pair, and it says <Literal>U(AU(LSS))</Literal>, that means ``the first component of the
+pair isn't used; the second component is itself unpackable, with three
+components (lazy in the first, strict in the second \&#38; third).''
+</Para>
+
+<Para>
+If the function isn't exported, just compile with the extra flag <Literal>-ddump-simpl</Literal>;
+next to the signature for any binder, it will print the self-same
+pragmatic information as would be put in an interface file.
+(Besides, Core syntax is fun to look at!)
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>Force key functions to be <Literal>INLINE</Literal>d (esp. monads):</Term>
+<ListItem>
+<Para>
+Placing <Literal>INLINE</Literal> pragmas on certain functions that are used a lot can
+have a dramatic effect.  See <XRef LinkEnd="inline-pragma">.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>Explicit <Literal>export</Literal> list:</Term>
+<ListItem>
+<Para>
+If you do not have an explicit export list in a module, GHC must
+assume that everything in that module will be exported.  This has
+various pessimising effects.  For example, if a bit of code is actually
+<Emphasis>unused</Emphasis> (perhaps because of unfolding effects), GHC will not be
+able to throw it away, because it is exported and some other module
+may be relying on its existence.
+</Para>
+
+<Para>
+GHC can be quite a bit more aggressive with pieces of code if it knows
+they are not exported.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>Look at the Core syntax!</Term>
+<ListItem>
+<Para>
+(The form in which GHC manipulates your code.)  Just run your
+compilation with <Literal>-ddump-simpl</Literal> (don't forget the <Literal>-O</Literal>).
+</Para>
+
+<Para>
+If profiling has pointed the finger at particular functions, look at
+their Core code.  <Literal>lets</Literal> are bad, <Literal>cases</Literal> are good, dictionaries
+(<Literal>d.&lt;Class&gt;.&lt;Unique&gt;</Literal>) &lsqb;or anything overloading-ish&rsqb; are bad,
+nested lambdas are bad, explicit data constructors are good, primitive
+operations (e.g., <Literal>eqInt&num;</Literal>) are good,&hellip;
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>Use unboxed types (a GHC extension):</Term>
+<ListItem>
+<Para>
+When you are <Emphasis>really</Emphasis> desperate for speed, and you want to get
+right down to the ``raw bits.''  Please see <XRef LinkEnd="glasgow-unboxed"> for some information about using unboxed
+types.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>Use <Literal>&lowbar;ccall&lowbar;s</Literal> (a GHC extension) to plug into fast libraries:</Term>
+<ListItem>
+<Para>
+This may take real work, but&hellip; There exist piles of
+massively-tuned library code, and the best thing is not
+to compete with it, but link with it.
+</Para>
+
+<Para>
+<XRef LinkEnd="glasgow-ccalls"> says a little about how to use C calls.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>Don't use <Literal>Float</Literal>s:</Term>
+<ListItem>
+<Para>
+We don't provide specialisations of Prelude functions for <Literal>Float</Literal>
+(but we do for <Literal>Double</Literal>).  If you end up executing overloaded
+code, you will lose on performance, perhaps badly.
+</Para>
+
+<Para>
+<Literal>Floats</Literal> (probably 32-bits) are almost always a bad idea, anyway,
+unless you Really Know What You Are Doing.  Use Doubles.  There's
+rarely a speed disadvantage&mdash;modern machines will use the same
+floating-point unit for both.  With <Literal>Doubles</Literal>, you are much less
+likely to hang yourself with numerical errors.
+</Para>
+
+<Para>
+One time when <Literal>Float</Literal> might be a good idea is if you have a
+<Emphasis>lot</Emphasis> of them, say a giant array of <Literal>Float</Literal>s.  They take up
+half the space in the heap compared to <Literal>Doubles</Literal>.  However, this isn't
+true on a 64-bit machine.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>Use a bigger heap!</Term>
+<ListItem>
+<Para>
+If your program's GC stats (<Literal>-S</Literal><IndexTerm><Primary>-S RTS option</Primary></IndexTerm> RTS option)
+indicate that it's doing lots of garbage-collection (say, more than
+20&percnt; of execution time), more memory might help&mdash;with the
+<Literal>-M&lt;size&gt;</Literal><IndexTerm><Primary>-M&lt;size&gt; RTS option</Primary></IndexTerm> or
+<Literal>-A&lt;size&gt;</Literal><IndexTerm><Primary>-A&lt;size&gt; RTS option</Primary></IndexTerm> RTS options (see
+<XRef LinkEnd="rts-options-gc">).
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+</Sect1>
+
+<Sect1 id="smaller">
+<Title>Smaller: producing a program that is smaller
+</Title>
+
+<Para>
+<IndexTerm><Primary>smaller programs, how to produce</Primary></IndexTerm>
+</Para>
+
+<Para>
+Decrease the ``go-for-it'' threshold for unfolding smallish
+expressions.  Give a
+<Literal>-funfolding-use-threshold0</Literal><IndexTerm><Primary>-funfolding-use-threshold0
+option</Primary></IndexTerm> option for the extreme case. (``Only unfoldings with
+zero cost should proceed.'')  Warning: except in certain specialiised
+cases (like Happy parsers) this is likely to actually
+<Emphasis>increase</Emphasis> the size of your program, because unfolding
+generally enables extra simplifying optimisations to be performed.
+</Para>
+
+<Para>
+Avoid <Literal>Read</Literal>.
+</Para>
+
+<Para>
+Use <Literal>strip</Literal> on your executables.
+</Para>
+
+</Sect1>
+
+<Sect1 id="stingier">
+<Title>Stingier: producing a program that gobbles less heap space
+</Title>
+
+<Para>
+<IndexTerm><Primary>memory, using less heap</Primary></IndexTerm>
+<IndexTerm><Primary>space-leaks, avoiding</Primary></IndexTerm>
+<IndexTerm><Primary>heap space, using less</Primary></IndexTerm>
+</Para>
+
+<Para>
+``I think I have a space leak&hellip;''  Re-run your program with
+<Literal>+RTS -Sstderr</Literal>,<IndexTerm><Primary>-Sstderr RTS option</Primary></IndexTerm> and remove all doubt!
+(You'll see the heap usage get bigger and bigger&hellip;)  &lsqb;Hmmm&hellip;this
+might be even easier with the <Literal>-F2s</Literal><IndexTerm><Primary>-F2s RTS option</Primary></IndexTerm> RTS
+option; so&hellip; <Literal>./a.out +RTS -Sstderr -F2s</Literal>...]
+</Para>
+
+<Para>
+Once again, the profiling facilities (<XRef LinkEnd="profiling">) are the basic tool for demystifying the space
+behaviour of your program.
+</Para>
+
+<Para>
+Strict functions are good for space usage, as they are for time, as
+discussed in the previous section.  Strict functions get right down to
+business, rather than filling up the heap with closures (the system's
+notes to itself about how to evaluate something, should it eventually
+be required).
+</Para>
+
+</Sect1>
+
+</Chapter>
diff --git a/ghc/docs/users_guide/users_guide.sgml b/ghc/docs/users_guide/users_guide.sgml
new file mode 100644 (file)
index 0000000..2c6e285
--- /dev/null
@@ -0,0 +1,44 @@
+<!DOCTYPE BOOK PUBLIC "-//Davenport//DTD DocBook V3.0//EN" [
+        <!ENTITY license        SYSTEM "license.sgml">
+        <!ENTITY intro          SYSTEM "intro.sgml" >
+        <!ENTITY relnotes       SYSTEM "4-04-notes.sgml" >
+        <!ENTITY using          SYSTEM "using.sgml" >
+        <!ENTITY runtime        SYSTEM "runtime_control.sgml" >
+        <!ENTITY prof           SYSTEM "profiling.sgml" >
+        <!ENTITY debug          SYSTEM "debugging.sgml" >
+        <!ENTITY sooner         SYSTEM "sooner.sgml" >
+        <!ENTITY lang           SYSTEM "lang.sgml" >
+        <!ENTITY glaexts        SYSTEM "glasgow_exts.sgml" >
+        <!ENTITY parallel       SYSTEM "parallel.sgml" >
+        <!ENTITY vs-hs          SYSTEM "vs_haskell.sgml" >
+        <!ENTITY libs           SYSTEM "libraries.sgml" >
+        <!ENTITY posix          SYSTEM "posix.sgml" >
+        <!ENTITY libmisc        SYSTEM "libmisc.sgml" >
+        <!ENTITY wrong          SYSTEM "gone_wrong.sgml" >
+        <!ENTITY utils          SYSTEM "utils.sgml" >
+        <!ENTITY mutablearray   SYSTEM "MutableArray.sgml">
+        <!ENTITY bytearray      SYSTEM "ByteArray.sgml">
+        <!ENTITY win32-dll      SYSTEM "win32-dlls.sgml">
+]>
+<Book>
+
+<BookInfo>
+<Title>The Glasgow Haskell Compiler User's Guide, Version&nbsp;4.04</Title>
+<Author><OtherName>The GHC Team</OtherName></Author>
+<Address>
+<Email>glasgow-haskell-&lcub;bugs,users&rcub;-request@haskell.org</Email>
+</Address>
+</BookInfo>
+
+&license
+&intro
+&using
+&prof
+&sooner
+&lang
+&libs
+&wrong
+&utils
+&win32-dll
+
+</Book>
diff --git a/ghc/docs/users_guide/using.sgml b/ghc/docs/users_guide/using.sgml
new file mode 100644 (file)
index 0000000..4653494
--- /dev/null
@@ -0,0 +1,2529 @@
+<Chapter id="using-GHC">
+<Title>Using GHC
+</Title>
+
+<Para>
+<IndexTerm><Primary>GHC, using</Primary></IndexTerm>
+<IndexTerm><Primary>using GHC</Primary></IndexTerm>
+</Para>
+
+<Para>
+GHC is a command-line compiler: in order to compile a Haskell program,
+GHC must be invoked on the source file(s) by typing a command to the
+shell.  The steps involved in compiling a program can be automated
+using the <Literal>make</Literal> tool (this is especially useful if the program
+consists of multiple source files which depend on each other).  This
+section describes how to use GHC from the command-line.
+</Para>
+
+<Sect1 id="command-line-structure">
+<Title>Overall command-line structure
+</Title>
+
+<Para>
+<IndexTerm><Primary>structure, command-line</Primary></IndexTerm>
+<IndexTerm><Primary>command-line structure</Primary></IndexTerm>
+</Para>
+
+<Para>
+An invocation of GHC takes the following form:
+</Para>
+
+<Para>
+
+<Screen>
+ghc [argument...]
+</Screen>
+
+</Para>
+
+<Para>
+Command-line arguments are either options or file names.
+</Para>
+
+<Para>
+Command-line options begin with <Literal>-</Literal>.  They may <Emphasis>not</Emphasis> be
+grouped: <Literal>-vO</Literal> is different from <Literal>-v -O</Literal>.  Options need not
+precede filenames: e.g., <Literal>ghc *.o -o foo</Literal>.  All options are
+processed and then applied to all files; you cannot, for example, invoke
+<Literal>ghc -c -O1 Foo.hs -O2 Bar.hs</Literal> to apply different optimisation
+levels to the files <Literal>Foo.hs</Literal> and <Literal>Bar.hs</Literal>.  For conflicting
+options, e.g., <Literal>-c -S</Literal>, we reserve the right to do anything we
+want.  (Usually, the last one applies.)
+</Para>
+
+</Sect1>
+
+<Sect1 id="file-suffixes">
+<Title>Meaningful file suffixes
+</Title>
+
+<Para>
+<IndexTerm><Primary>suffixes, file</Primary></IndexTerm>
+<IndexTerm><Primary>file suffixes for GHC</Primary></IndexTerm>
+</Para>
+
+<Para>
+File names with ``meaningful'' suffixes (e.g., <Literal>.lhs</Literal> or <Literal>.o</Literal>)
+cause the ``right thing'' to happen to those files.
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>.lhs</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>lhs suffix</Primary></IndexTerm>
+A ``literate Haskell'' module.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>.hs</Literal>:</Term>
+<ListItem>
+<Para>
+A not-so-literate Haskell module.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>.hi</Literal>:</Term>
+<ListItem>
+<Para>
+A Haskell interface file, probably compiler-generated.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>.hc</Literal>:</Term>
+<ListItem>
+<Para>
+Intermediate C file produced by the Haskell compiler.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>.c</Literal>:</Term>
+<ListItem>
+<Para>
+A C&nbsp;file not produced by the Haskell compiler.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>.s</Literal>:</Term>
+<ListItem>
+<Para>
+An assembly-language source file, usually
+produced by the compiler.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>.o</Literal>:</Term>
+<ListItem>
+<Para>
+An object file, produced by an assembler.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+<Para>
+Files with other suffixes (or without suffixes) are passed straight
+to the linker.
+</Para>
+
+</Sect1>
+
+<Sect1 id="options-help">
+<Title>Help and verbosity options
+</Title>
+
+<Para>
+<IndexTerm><Primary>help options (GHC)</Primary></IndexTerm>
+<IndexTerm><Primary>verbose option (GHC)</Primary></IndexTerm>
+</Para>
+
+<Para>
+A good option to start with is the <Literal>-help</Literal> (or <Literal>-?</Literal>) option.
+<IndexTerm><Primary>-help option</Primary></IndexTerm>
+<IndexTerm><Primary>-? option</Primary></IndexTerm>
+GHC spews a long message to standard output and then exits.
+</Para>
+
+<Para>
+The <Literal>-v</Literal><IndexTerm><Primary>-v option</Primary></IndexTerm> option makes GHC <Emphasis>verbose</Emphasis>: it
+reports its version number and shows (on stderr) exactly how it invokes each
+phase of the compilation system.  Moreover, it passes
+the <Literal>-v</Literal> flag to most phases; each reports
+its version number (and possibly some other information).
+</Para>
+
+<Para>
+Please, oh please, use the <Literal>-v</Literal> option when reporting bugs!
+Knowing that you ran the right bits in the right order is always the
+first thing we want to verify.
+</Para>
+
+<Para>
+If you're just interested in the compiler version number, the
+<Literal>--version</Literal><IndexTerm><Primary>--version option</Primary></IndexTerm> option prints out a
+one-line string containing the requested info.
+</Para>
+
+</Sect1>
+
+<Sect1 id="options-order">
+<Title>Running the right phases in the right order
+</Title>
+
+<Para>
+<IndexTerm><Primary>order of passes in GHC</Primary></IndexTerm>
+<IndexTerm><Primary>pass ordering in GHC</Primary></IndexTerm>
+The basic task of the <Literal>ghc</Literal> driver is to run each input file
+through the right phases (compiling, linking, etc.).
+</Para>
+
+<Para>
+The first phase to run is determined by the input-file suffix, and the
+last phase is determined by a flag.  If no relevant flag is present,
+then go all the way through linking.  This table summarises:
+</Para>
+
+<Para>
+<InformalTable>
+<TGroup Cols="4">
+<ColSpec Align="Left">
+<ColSpec Align="Left">
+<ColSpec Align="Left">
+<ColSpec Align="Left">
+<TBody>
+
+<Row>
+<Entry>Phase of the compilation system</Entry>
+<Entry>Suffix saying ``start here''</Entry>
+<Entry>Flag saying ``stop after''</Entry>
+<Entry>(suffix of) output file</Entry>
+</Row>
+
+<Row>
+<Entry>
+literate pre-processor </Entry>
+<Entry> .lhs </Entry>
+<Entry> - </Entry>
+<Entry> - </Entry>
+</Row>
+<Row>
+<Entry>
+C pre-processor (opt.) </Entry>
+<Entry> - </Entry>
+<Entry> - </Entry>
+<Entry> - </Entry>
+</Row>
+<Row>
+<Entry>
+Haskell compiler </Entry>
+<Entry> .hs </Entry>
+<Entry> -C, -S </Entry>
+<Entry> .hc, .s </Entry>
+</Row>
+<Row>
+<Entry>
+C compiler (opt.) </Entry>
+<Entry> .hc or .c </Entry>
+<Entry> -S </Entry>
+<Entry> .s </Entry>
+</Row>
+<Row>
+<Entry>
+assembler </Entry>
+<Entry> .s </Entry>
+<Entry> -c </Entry>
+<Entry> .o </Entry>
+</Row>
+<Row>
+<Entry>
+linker </Entry>
+<Entry> other </Entry>
+<Entry> - </Entry>
+<Entry> a.out </Entry>
+</Row>
+</TBody>
+</TGroup>
+</InformalTable>
+
+<IndexTerm><Primary>-C option</Primary></IndexTerm>
+<IndexTerm><Primary>-S option</Primary></IndexTerm>
+<IndexTerm><Primary>-c option</Primary></IndexTerm>
+</Para>
+
+<Para>
+Thus, a common invocation would be: <Literal>ghc -c Foo.hs</Literal>
+</Para>
+
+<Para>
+Note: What the Haskell compiler proper produces depends on whether a
+native-code generator is used (producing assembly language) or not
+(producing C).
+</Para>
+
+<Para>
+The option <Literal>-cpp</Literal><IndexTerm><Primary>-cpp option</Primary></IndexTerm> must be given for the C
+pre-processor phase to be run, that is, the pre-processor will be run
+over your Haskell source file before continuing.
+</Para>
+
+<Para>
+The option <Literal>-E</Literal><IndexTerm><Primary>-E option</Primary></IndexTerm> runs just the pre-processing
+passes of the compiler, outputting the result on stdout before
+stopping. If used in conjunction with -cpp, the output is the
+code blocks of the original (literal) source after having put it
+through the grinder that is the C pre-processor. Sans <Literal>-cpp</Literal>, the
+output is the de-litted version of the original source.
+</Para>
+
+<Para>
+The option <Literal>-optcpp-E</Literal><IndexTerm><Primary>-optcpp-E option</Primary></IndexTerm> runs just the
+pre-processing stage of the C-compiling phase, sending the result to
+stdout.  (For debugging or obfuscation contests, usually.)
+</Para>
+
+</Sect1>
+
+<Sect1 id="options-output">
+<Title>Re-directing the compilation output(s)
+</Title>
+
+<Para>
+<IndexTerm><Primary>output-directing options</Primary></IndexTerm>
+</Para>
+
+<Para>
+GHC's compiled output normally goes into a <Literal>.hc</Literal>, <Literal>.o</Literal>, etc., file,
+depending on the last-run compilation phase.  The option <Literal>-o
+foo</Literal><IndexTerm><Primary>-o option</Primary></IndexTerm> re-directs the output of that last-run
+phase to file <Literal>foo</Literal>.
+</Para>
+
+<Para>
+Note: this ``feature'' can be counterintuitive:
+<Literal>ghc -C -o foo.o foo.hs</Literal> will put the intermediate C code in the
+file <Literal>foo.o</Literal>, name notwithstanding!
+</Para>
+
+<Para>
+EXOTICA: But the <Literal>-o</Literal> option isn't of much use if you have
+<Emphasis>several</Emphasis> input files&hellip; Non-interface output files are
+normally put in the same directory as their corresponding input file
+came from.  You may specify that they be put in another directory
+using the <Literal>-odir &lt;dir&gt;</Literal><IndexTerm><Primary>-odir &lt;dir&gt; option</Primary></IndexTerm> (the
+``Oh, dear'' option).  For example:
+</Para>
+
+<Para>
+
+<Screen>
+% ghc -c parse/Foo.hs parse/Bar.hs gurgle/Bumble.hs -odir `arch`
+</Screen>
+
+</Para>
+
+<Para>
+The output files, <Literal>Foo.o</Literal>, <Literal>Bar.o</Literal>, and <Literal>Bumble.o</Literal> would be
+put into a subdirectory named after the architecture of the executing
+machine (<Literal>sun4</Literal>, <Literal>mips</Literal>, etc).  The directory must already
+exist; it won't be created.
+</Para>
+
+<Para>
+Note that the <Literal>-odir</Literal> option does <Emphasis>not</Emphasis> affect where the
+interface files are put.  In the above example, they would still be
+put in <Literal>parse/Foo.hi</Literal>, <Literal>parse/Bar.hi</Literal>, and <Literal>gurgle/Bumble.hi</Literal>.
+</Para>
+
+<Para>
+MORE EXOTICA: The <Literal>-osuf &lt;suffix&gt;</Literal><IndexTerm><Primary>-osuf &lt;suffix&gt;
+option</Primary></IndexTerm> will change the <Literal>.o</Literal> file suffix for object files to
+whatever you specify.  (We use this in compiling the prelude.).
+Similarly, the <Literal>-hisuf &lt;suffix&gt;</Literal><IndexTerm><Primary>-hisuf &lt;suffix&gt;
+option</Primary></IndexTerm> will change the <Literal>.hi</Literal> file suffix for non-system
+interface files (see <XRef LinkEnd="hi-options">).
+</Para>
+
+<Para>
+The <Literal>-hisuf</Literal>/<Literal>-osuf</Literal> game is useful if you want to compile a program
+with both GHC and HBC (say) in the same directory.  Let HBC use the
+standard <Literal>.hi</Literal>/<Literal>.o</Literal> suffixes; add <Literal>-hisuf g&lowbar;hi -osuf g&lowbar;o</Literal> to your
+<Literal>make</Literal> rule for GHC compiling&hellip;
+</Para>
+
+<Para>
+FURTHER EXOTICA: If you are doing a normal <Literal>.hs</Literal>-to-<Literal>.o</Literal> compilation
+but would like to hang onto the intermediate <Literal>.hc</Literal> C file, just
+throw in a <Literal>-keep-hc-file-too</Literal> option<IndexTerm><Primary>-keep-hc-file-too option</Primary></IndexTerm>.
+If you would like to look at the assembler output, toss in a
+<Literal>-keep-s-file-too</Literal>,<IndexTerm><Primary>-keep-s-file-too option</Primary></IndexTerm> too.
+</Para>
+
+<Sect2 id="saving-ghc-stderr">
+<Title>Saving GHC's standard error output
+</Title>
+
+<Para>
+<IndexTerm><Primary>standard error, saving</Primary></IndexTerm>
+</Para>
+
+<Para>
+Sometimes, you may cause GHC to be rather chatty on standard error;
+with <Literal>-v</Literal>, for example.  You can instruct GHC to <Emphasis>append</Emphasis> this
+output to a particular log file with a <Literal>-odump &lt;blah&gt;</Literal><IndexTerm><Primary>-odump
+&lt;blah&gt; option</Primary></IndexTerm> option.
+</Para>
+
+</Sect2>
+
+<Sect2 id="temp-files">
+<Title>Redirecting temporary files
+</Title>
+
+<Para>
+<IndexTerm><Primary>temporary files, redirecting</Primary></IndexTerm>
+</Para>
+
+<Para>
+If you have trouble because of running out of space in <Literal>/tmp</Literal> (or
+wherever your installation thinks temporary files should go), you may
+use the <Literal>-tmpdir &lt;dir&gt;</Literal><IndexTerm><Primary>-tmpdir &lt;dir&gt; option</Primary></IndexTerm> option
+to specify an alternate directory.  For example, <Literal>-tmpdir .</Literal> says to
+put temporary files in the current working directory.
+</Para>
+
+<Para>
+Alternatively, use your <Literal>TMPDIR</Literal> environment variable.<IndexTerm><Primary>TMPDIR
+environment variable</Primary></IndexTerm> Set it to the name of the directory where
+temporary files should be put.  GCC and other programs will honour the
+<Literal>TMPDIR</Literal> variable as well.
+</Para>
+
+<Para>
+Even better idea: Set the <Literal>TMPDIR</Literal> variable when building GHC, and
+never worry about <Literal>TMPDIR</Literal> again. (see the build documentation).
+</Para>
+
+</Sect2>
+
+</Sect1>
+
+<Sect1 id="options-sanity">
+<Title>Warnings and sanity-checking
+</Title>
+
+<Para>
+<IndexTerm><Primary>sanity-checking options</Primary></IndexTerm>
+<IndexTerm><Primary>warnings</Primary></IndexTerm>
+GHC has a number of options that select which types of non-fatal error
+messages, otherwise known as warnings, can be generated during
+compilation.  By default, you get a standard set of warnings which are
+generally likely to indicate bugs in your program.  These are:
+<Literal>-fwarn-overlpapping-patterns</Literal>, <Literal>-fwarn-duplicate-exports</Literal>, and
+<Literal>-fwarn-missing-methods</Literal>.  The following flags are simple ways to
+select standard ``packages'' of warnings:
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>-Wnot</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-Wnot option</Primary></IndexTerm>
+Turns off all warnings, including the standard ones.
+</Para>
+</ListItem>
+</VarListEntry>
+
+<VarListEntry>
+<Term><Literal>-w</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-w option</Primary></IndexTerm>
+Synonym for <Literal>-Wnot</Literal>.
+</Para>
+</ListItem>
+</VarListEntry>
+
+<VarListEntry>
+<Term><Literal>-W</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-W option</Primary></IndexTerm>
+Provides the standard warnings plus <Literal>-fwarn-incomplete-patterns</Literal>,
+<Literal>-fwarn-unused-imports</Literal> and <Literal>-fwarn-unused-binds</Literal>.
+</Para>
+</ListItem>
+</VarListEntry>
+
+<VarListEntry>
+<Term><Literal>-Wall</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-Wall option</Primary></IndexTerm>
+Turns on all warning options.
+</Para>
+</ListItem>
+</VarListEntry>
+
+</VariableList>
+</Para>
+
+<Para>
+The full set of warning options is described below.  To turn off any
+warning, simply give the corresponding <Literal>-fno-warn-...</Literal> option on
+the command line.
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>-fwarn-name-shadowing</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-fwarn-name-shadowing option</Primary></IndexTerm>
+<IndexTerm><Primary>shadowing, warning</Primary></IndexTerm>This option causes a warning to be emitted whenever an inner-scope
+value has the same name as an outer-scope value, i.e. the inner value
+shadows the outer one.  This can catch typographical errors that turn
+into hard-to-find bugs, e.g., in the inadvertent cyclic definition
+<Literal>let x = ... x ... in</Literal>.
+</Para>
+
+<Para>
+Consequently, this option does <Emphasis>not</Emphasis> allow cyclic recursive
+definitions.
+</Para>
+</ListItem>
+</VarListEntry>
+
+<VarListEntry>
+<Term><Literal>-fwarn-overlapping-patterns</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-fwarn-overlapping-patterns option</Primary></IndexTerm>
+<IndexTerm><Primary>overlapping patterns, warning</Primary></IndexTerm>
+<IndexTerm><Primary>patterns, overlapping</Primary></IndexTerm>
+By default, the compiler will warn you if a set of patterns are
+overlapping, i.e.,
+</Para>
+
+<Para>
+<ProgramListing>
+f :: String -&#62; Int
+f []     = 0
+f (_:xs) = 1
+f "2"    = 2
+</ProgramListing>
+</Para>
+
+<Para>
+where the last pattern match in <Literal>f</Literal> won't ever be reached, as the
+second pattern overlaps it. More often than not, redundant patterns
+is a programmer mistake/error, so this option is enabled by default.
+</Para>
+</ListItem>
+</VarListEntry>
+
+<VarListEntry>
+<Term><Literal>-fwarn-incomplete-patterns</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-fwarn-incomplete-patterns option</Primary></IndexTerm>
+<IndexTerm><Primary>incomplete patterns, warning</Primary></IndexTerm>
+<IndexTerm><Primary>patterns, incomplete</Primary></IndexTerm>
+Similarly for incomplete patterns, the function <Literal>g</Literal> below will fail
+when applied to non-empty lists, so the compiler will emit a warning
+about this when <Literal>-fwarn-incomplete-patterns</Literal> is enabled.
+</Para>
+
+<Para>
+<ProgramListing>
+g [] = 2
+</ProgramListing>
+</Para>
+
+<Para>
+This option isn't enabled be default because it can be a bit noisy,
+and it doesn't always indicate a bug in the program.  However, it's
+generally considered good practice to cover all the cases in your
+functions.
+</Para>
+</ListItem>
+</VarListEntry>
+
+<VarListEntry>
+<Term><Literal>-fwarn-missing-methods</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-fwarn-missing-methods option</Primary></IndexTerm>
+<IndexTerm><Primary>missing methods, warning</Primary></IndexTerm>
+<IndexTerm><Primary>methods, missing</Primary></IndexTerm>
+This option is on by default, and warns you whenever an instance
+declaration is missing one or more methods, and the corresponding
+class declaration has no default declaration for them.
+</Para>
+</ListItem>
+</VarListEntry>
+
+<VarListEntry>
+<Term><Literal>-fwarn-missing-fields</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-fwarn-missing-fields option</Primary></IndexTerm>
+<IndexTerm><Primary>missing fields, warning</Primary></IndexTerm>
+<IndexTerm><Primary>fields, missing</Primary></IndexTerm>
+This option is on by default, and warns you whenever the construction
+of a labelled field constructor isn't complete, missing initializers
+for one or more fields. While not an error (the missing fields are
+initialised with bottoms), it is often an indication of a programmer
+error.
+</Para>
+</ListItem>
+</VarListEntry>
+
+<VarListEntry>
+<Term><Literal>-fwarn-unused-imports</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-fwarn-unused-imports option</Primary></IndexTerm>
+<IndexTerm><Primary>unused imports, warning</Primary></IndexTerm>
+<IndexTerm><Primary>imports, unused</Primary></IndexTerm>
+Report any objects that are explicitly imported but never used.
+</Para>
+</ListItem>
+</VarListEntry>
+
+<VarListEntry>
+<Term><Literal>-fwarn-unused-binds</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-fwarn-unused-binds option</Primary></IndexTerm>
+<IndexTerm><Primary>unused binds, warning</Primary></IndexTerm>
+<IndexTerm><Primary>binds, unused</Primary></IndexTerm>
+Report any function definitions (and local bindings) which are unused.
+For top-level functions, the warning is only given if the binding is
+not exported.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-fwarn-unused-matches</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-fwarn-unused-matches option</Primary></IndexTerm>
+<IndexTerm><Primary>unused matches, warning</Primary></IndexTerm>
+<IndexTerm><Primary>matches, unused</Primary></IndexTerm>
+Report all unused variables which arise from pattern matches,
+including patterns consisting of a single variable.  For instance <Literal>f x
+y = []</Literal> would report <Literal>x</Literal> and <Literal>y</Literal> as unused.  To eliminate the warning,
+all unused variables can be replaced with wildcards.
+</Para>
+</ListItem>
+</VarListEntry>
+
+<VarListEntry>
+<Term><Literal>-fwarn-duplicate-exports</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-fwarn-duplicate-exports option</Primary></IndexTerm>
+<IndexTerm><Primary>duplicate exports, warning</Primary></IndexTerm>
+<IndexTerm><Primary>export lists, duplicates</Primary></IndexTerm>
+Have the compiler warn about duplicate entries in export lists. This
+is useful information if you maintain large export lists, and want to
+avoid the continued export of a definition after you've deleted (one)
+mention of it in the export list.
+</Para>
+
+<Para>
+This option is on by default.
+</Para>
+</ListItem>
+</VarListEntry>
+
+<VarListEntry>
+<Term><Literal>-fwarn-type-defaults</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-fwarn-type-defaults option</Primary></IndexTerm>
+<IndexTerm><Primary>defaulting mechanism, warning</Primary></IndexTerm>
+Have the compiler warn/inform you where in your source the Haskell
+defaulting mechanism for numeric types kicks in. This is useful
+information when converting code from a context that assumed one
+default into one with another, e.g., the `default default' for Haskell
+1.4 caused the otherwise unconstrained value <Literal>1</Literal> to be given
+the type <Literal>Int</Literal>, whereas Haskell 98 defaults it to
+<Literal>Integer</Literal>.  This may lead to differences in performance and
+behaviour, hence the usefulness of being non-silent about this.
+</Para>
+
+<Para>
+This warning is off by default.
+</Para>
+</ListItem>
+</VarListEntry>
+
+<VarListEntry>
+<Term><Literal>-fwarn-missing-signatures</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-fwarn-missing-signatures option</Primary></IndexTerm>
+<IndexTerm><Primary>type signatures, missing</Primary></IndexTerm>
+If you would like GHC to check that every top-level function/value has
+a type signature, use the <Literal>-fwarn-missing-signatures</Literal> option.  This
+option is off by default.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+<Para>
+If you're feeling really paranoid, the <Literal>-dcore-lint</Literal>
+option<IndexTerm><Primary>-dcore-lint option</Primary></IndexTerm> is a good choice.  It turns on
+heavyweight intra-pass sanity-checking within GHC.  (It checks GHC's
+sanity, not yours.)
+</Para>
+
+</Sect1>
+
+<Sect1 id="separate-compilation">
+<Title>Separate compilation
+</Title>
+
+<Para>
+<IndexTerm><Primary>separate compilation</Primary></IndexTerm>
+<IndexTerm><Primary>recompilation checker</Primary></IndexTerm>
+<IndexTerm><Primary>make and recompilation</Primary></IndexTerm>
+</Para>
+
+<Para>
+This section describes how GHC supports separate compilation.
+</Para>
+
+<Sect2 id="hi-files">
+<Title>Interface files
+</Title>
+
+<Para>
+<IndexTerm><Primary>interface files</Primary></IndexTerm>
+<IndexTerm><Primary>.hi files</Primary></IndexTerm>
+</Para>
+
+<Para>
+When GHC compiles a source file <Literal>F</Literal> which contains a module <Literal>A</Literal>, say,
+it generates an object <Literal>F.o</Literal>, <Emphasis>and</Emphasis> a companion <Emphasis>interface
+file</Emphasis> <Literal>A.hi</Literal>.  The interface file is not intended for human
+consumption, as you'll see if you take a look at one.  It's merely
+there to help the compiler compile other modules in the same program.
+</Para>
+
+<Para>
+NOTE: Having the name of the interface file follow the module name and
+not the file name, means that working with tools such as <Literal>make(1)</Literal>
+become harder. <Literal>make</Literal> implicitly assumes that any output files
+produced by processing a translation unit will have file names that
+can be derived from the file name of the translation unit.  For
+instance, pattern rules becomes unusable.  For this reason, we
+recommend you stick to using the same file name as the module name.
+</Para>
+
+<Para>
+The interface file for <Literal>A</Literal> contains information needed by the compiler
+when it compiles any module <Literal>B</Literal> that imports <Literal>A</Literal>, whether directly or
+indirectly.  When compiling <Literal>B</Literal>, GHC will read <Literal>A.hi</Literal> to find the
+details that it needs to know about things defined in <Literal>A</Literal>.
+</Para>
+
+<Para>
+Furthermore, when compiling module <Literal>C</Literal> which imports <Literal>B</Literal>, GHC may
+decide that it needs to know something about <Literal>A</Literal>&mdash;for example, <Literal>B</Literal>
+might export a function that involves a type defined in <Literal>A</Literal>.  In this
+case, GHC will go and read <Literal>A.hi</Literal> even though <Literal>C</Literal> does not explicitly
+import <Literal>A</Literal> at all.
+</Para>
+
+<Para>
+The interface file may contain all sorts of things that aren't
+explicitly exported from <Literal>A</Literal> by the programmer.  For example, even
+though a data type is exported abstractly, <Literal>A.hi</Literal> will contain the
+full data type definition.  For small function definitions, <Literal>A.hi</Literal>
+will contain the complete definition of the function.  For bigger
+functions, <Literal>A.hi</Literal> will contain strictness information about the
+function.  And so on.  GHC puts much more information into <Literal>.hi</Literal> files
+when optimisation is turned on with the <Literal>-O</Literal> flag.  Without <Literal>-O</Literal> it
+puts in just the minimum; with <Literal>-O</Literal> it lobs in a whole pile of stuff.
+<IndexTerm><Primary>optimsation, effect on .hi files</Primary></IndexTerm>
+</Para>
+
+<Para>
+<Literal>A.hi</Literal> should really be thought of as a compiler-readable version of
+<Literal>A.o</Literal>.  If you use a <Literal>.hi</Literal> file that wasn't generated by the same
+compilation run that generates the <Literal>.o</Literal> file the compiler may assume
+all sorts of incorrect things about <Literal>A</Literal>, resulting in core dumps and
+other unpleasant happenings.
+</Para>
+
+</Sect2>
+
+<Sect2 id="options-finding-imports">
+<Title>Finding interface files
+</Title>
+
+<Para>
+<IndexTerm><Primary>interface files, finding them</Primary></IndexTerm>
+<IndexTerm><Primary>finding interface files</Primary></IndexTerm>
+</Para>
+
+<Para>
+In your program, you import a module <Literal>Foo</Literal> by saying
+<Literal>import Foo</Literal>.  GHC goes looking for an interface file, <Literal>Foo.hi</Literal>.
+It has a builtin list of directories (notably including <Literal>.</Literal>) where
+it looks.
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>-i&lt;dirs&gt;</Literal></Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-i&lt;dirs&gt; option</Primary></IndexTerm>This flag
+prepends a colon-separated list of <Literal>dirs</Literal> to the ``import
+directories'' list.
+See also <XRef LinkEnd="recomp"> for the significance of using
+relative and absolute pathnames in the <Literal>-i</Literal> list.
+</Para>
+</ListItem>
+</VarListEntry>
+
+<VarListEntry>
+<Term><Literal>-i</Literal></Term>
+<ListItem>
+<Para>
+resets the ``import directories'' list back to nothing.
+</Para>
+</ListItem>
+</VarListEntry>
+
+<VarListEntry>
+<Term><Literal>-fno-implicit-prelude</Literal></Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-fno-implicit-prelude option</Primary></IndexTerm>
+GHC normally imports <Literal>Prelude.hi</Literal> files for you.  If you'd rather it
+didn't, then give it a <Literal>-fno-implicit-prelude</Literal> option.  You are
+unlikely to get very far without a Prelude, but, hey, it's a free
+country.
+</Para>
+</ListItem>
+</VarListEntry>
+
+<VarListEntry>
+<Term><Literal>-syslib &lt;lib&gt;</Literal></Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-syslib &lt;lib&gt; option</Primary></IndexTerm>
+If you are using a system-supplied non-Prelude library (e.g., the
+POSIX library), just use a <Literal>-syslib posix</Literal> option (for example).  The
+right interface files should then be available.  <XRef LinkEnd="ghc-prelude"> lists the
+libraries available by this mechanism.
+</Para>
+</ListItem>
+</VarListEntry>
+
+<VarListEntry>
+<Term><Literal>-I&lt;dir&gt;</Literal></Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-I&lt;dir&gt; option</Primary></IndexTerm>
+Once a Haskell module has been compiled to C (<Literal>.hc</Literal> file), you may
+wish to specify where GHC tells the C compiler to look for <Literal>.h</Literal> files.
+(Or, if you are using the <Literal>-cpp</Literal> option<IndexTerm><Primary>-cpp option</Primary></IndexTerm>, where
+it tells the C pre-processor to look&hellip;)  For this purpose, use a <Literal>-I</Literal>
+option in the usual C-ish way.
+</Para>
+</ListItem>
+</VarListEntry>
+
+</VariableList>
+</Para>
+
+</Sect2>
+
+<Sect2 id="hi-options">
+<Title>Other options related to interface files
+</Title>
+
+<Para>
+<IndexTerm><Primary>interface files, options</Primary></IndexTerm>
+The interface output may be directed to another file
+<Literal>bar2/Wurble.iface</Literal> with the option <Literal>-ohi bar2/Wurble.iface</Literal><IndexTerm><Primary>-ohi
+&lt;file&gt; option</Primary></IndexTerm> (not recommended).
+</Para>
+
+<Para>
+To avoid generating an interface file at all, use a <Literal>-nohi</Literal>
+option.<IndexTerm><Primary>-nohi option</Primary></IndexTerm>
+</Para>
+
+<Para>
+The compiler does not overwrite an existing <Literal>.hi</Literal> interface file if
+the new one is byte-for-byte the same as the old one; this is friendly
+to <Literal>make</Literal>.  When an interface does change, it is often enlightening to
+be informed.  The <Literal>-hi-diffs</Literal><IndexTerm><Primary>-hi-diffs option</Primary></IndexTerm> option will
+make <Literal>ghc</Literal> run <Literal>diff</Literal> on the old and new <Literal>.hi</Literal> files. You can also
+record the difference in the interface file itself, the
+<Literal>-keep-hi-diffs</Literal><IndexTerm><Primary>-keep-hi-diffs</Primary></IndexTerm> option takes care of that.
+</Para>
+
+<Para>
+The <Literal>.hi</Literal> files from GHC contain ``usage'' information which changes
+often and uninterestingly.  If you really want to see these changes
+reported, you need to use the
+<Literal>-hi-diffs-with-usages</Literal><IndexTerm><Primary>-hi-diffs-with-usages option</Primary></IndexTerm>
+option.
+</Para>
+
+<Para>
+Interface files are normally jammed full of compiler-produced
+<Emphasis>pragmas</Emphasis>, which record arities, strictness info, etc.  If you
+think these pragmas are messing you up (or you are doing some kind of
+weird experiment), you can tell GHC to ignore them with the
+<Literal>-fignore-interface-pragmas</Literal><IndexTerm><Primary>-fignore-interface-pragmas
+option</Primary></IndexTerm> option.
+</Para>
+
+<Para>
+When compiling without optimisations on, the compiler is extra-careful
+about not slurping in data constructors and instance declarations that
+it will not need. If you believe it is getting it wrong and not
+importing stuff which you think it should, this optimisation can be
+turned off with <Literal>-fno-prune-tydecls</Literal> and <Literal>-fno-prune-instdecls</Literal>.
+<IndexTerm><Primary>-fno-prune-tydecls option</Primary></IndexTerm><IndexTerm><Primary>-fno-prune-instdecls
+option</Primary></IndexTerm>
+</Para>
+
+<Para>
+See also <XRef LinkEnd="options-linker">, which describes how the linker finds standard
+Haskell libraries.
+</Para>
+
+</Sect2>
+
+<Sect2 id="recomp">
+<Title>The recompilation checker
+</Title>
+
+<Para>
+<IndexTerm><Primary>recompilation checker</Primary></IndexTerm>
+</Para>
+
+<Para>
+In the olden days, GHC compared the newly-generated <Literal>.hi</Literal> file with
+the previous version; if they were identical, it left the old one
+alone and didn't change its modification date.  In consequence,
+importers of a module with an unchanged output <Literal>.hi</Literal> file were not
+recompiled.
+</Para>
+
+<Para>
+This doesn't work any more.  In our earlier example, module <Literal>C</Literal> does
+not import module <Literal>A</Literal> directly, yet changes to <Literal>A.hi</Literal> should force a
+recompilation of <Literal>C</Literal>.  And some changes to <Literal>A</Literal> (changing the
+definition of a function that appears in an inlining of a function
+exported by <Literal>B</Literal>, say) may conceivably not change <Literal>B.hi</Literal> one jot.  So
+now&hellip;
+</Para>
+
+<Para>
+GHC keeps a version number on each interface file, and on each type
+signature within the interface file.  It also keeps in every interface
+file a list of the version numbers of everything it used when it last
+compiled the file.  If the source file's modification date is earlier
+than the <Literal>.o</Literal> file's date (i.e. the source hasn't changed since the
+file was last compiled), GHC will be clever.  It compares the version
+numbers on the things it needs this time with the version numbers on
+the things it needed last time (gleaned from the interface file of the
+module being compiled); if they are all the same it stops compiling
+rather early in the process saying ``Compilation IS NOT required''.
+What a beautiful sight!
+</Para>
+
+<Para>
+GHC <Emphasis>only</Emphasis> keeps detailed dependency information for ``user'' modules,
+not for ``library'' modules.  It distinguishes the two by a hack: a module
+whose <Literal>.hi</Literal> file has an absolute path name is considered a library module,
+while a relative path name indicates a user module.  So if you have a
+multi-directory application, use <Emphasis>relative</Emphasis> path names in your
+<Literal>-i</Literal> path, to force GHC to record detailed dependency information.
+Use absolute path names only for directories containing slowly-changing
+library modules.
+</Para>
+
+<Para>
+A path is considered ``absolute'' if it starts with ``<Literal>/</Literal>'', or
+``<Literal>A:/</Literal>'', or ``<Literal>A:\</Literal>'' (or ``<Literal>B:/</Literal>'', ``<Literal>B:\</Literal>'' etc).
+</Para>
+
+<Para>
+Patrick Sansom had a workshop paper about how all this is done (though
+the details have changed quite a bit).  Ask
+him (email: <ULink
+URL="mailto:sansom@dcs.gla.ac.uk"
+>sansom@dcs.gla.ac.uk</ULink
+>) if you want a copy.
+</Para>
+
+</Sect2>
+
+<Sect2 id="using-make">
+<Title>Using <Literal>make</Literal>
+</Title>
+
+<Para>
+<IndexTerm><Primary><literal>make</literal></Primary></IndexTerm>
+</Para>
+
+<Para>
+It is reasonably straightforward to set up a <Literal>Makefile</Literal> to use with
+GHC, assuming you name your source files the same as your modules.
+Thus:
+</Para>
+
+<Para>
+
+<ProgramListing>
+HC      = ghc
+HC_OPTS = -cpp $(EXTRA_HC_OPTS)
+
+SRCS = Main.lhs Foo.lhs Bar.lhs
+OBJS = Main.o   Foo.o   Bar.o
+
+.SUFFIXES : .o .hi .lhs .hc .s
+
+cool_pgm : $(OBJS)
+        rm $@
+        $(HC) -o $@ $(HC_OPTS) $(OBJS)
+
+# Standard suffix rules
+.o.hi:
+        @:
+
+.lhs.o:
+        $(HC) -c $&#60; $(HC_OPTS)
+
+.hs.o:
+        $(HC) -c $&#60; $(HC_OPTS)
+
+# Inter-module dependencies
+Foo.o Foo.hc Foo.s    : Baz.hi          # Foo imports Baz
+Main.o Main.hc Main.s : Foo.hi Baz.hi   # Main imports Foo and Baz
+</ProgramListing>
+
+</Para>
+
+<Para>
+(Sophisticated <Literal>make</Literal> variants may achieve some of the above more
+elegantly.  Notably, <Literal>gmake</Literal>'s pattern rules let you write the more
+comprehensible:
+</Para>
+
+<Para>
+
+<ProgramListing>
+%.o : %.lhs
+        $(HC) -c $&#60; $(HC_OPTS)
+</ProgramListing>
+
+</Para>
+
+<Para>
+What we've shown should work with any <Literal>make</Literal>.)
+</Para>
+
+<Para>
+Note the cheesy <Literal>.o.hi</Literal> rule: It records the dependency of the
+interface (<Literal>.hi</Literal>) file on the source.  The rule says a <Literal>.hi</Literal> file can
+be made from a <Literal>.o</Literal> file by doing&hellip;nothing.  Which is true.
+</Para>
+
+<Para>
+Note the inter-module dependencies at the end of the Makefile, which
+take the form
+</Para>
+
+<Para>
+
+<ProgramListing>
+Foo.o Foo.hc Foo.s    : Baz.hi          # Foo imports Baz
+</ProgramListing>
+
+</Para>
+
+<Para>
+They tell <Literal>make</Literal> that if any of <Literal>Foo.o</Literal>, <Literal>Foo.hc</Literal> or <Literal>Foo.s</Literal> have an
+earlier modification date than <Literal>Baz.hi</Literal>, then the out-of-date file
+must be brought up to date.  To bring it up to date, <Literal>make</Literal> looks for
+a rule to do so; one of the preceding suffix rules does the job
+nicely.
+</Para>
+
+<Para>
+Putting inter-dependencies of the form <Literal>Foo.o : Bar.hi</Literal> into your
+<Literal>Makefile</Literal> by hand is rather error-prone.  Don't worry&mdash;never fear,
+<Literal>mkdependHS</Literal> is here! (and is distributed as part of GHC) Add the
+following to your <Literal>Makefile</Literal>:
+</Para>
+
+<Para>
+
+<ProgramListing>
+depend :
+        mkdependHS -- $(HC_OPTS) -- $(SRCS)
+</ProgramListing>
+
+</Para>
+
+<Para>
+Now, before you start compiling, and any time you change the <Literal>imports</Literal>
+in your program, do <Literal>make depend</Literal> before you do <Literal>make cool&lowbar;pgm</Literal>.
+<Literal>mkdependHS</Literal> will append the needed dependencies to your <Literal>Makefile</Literal>.
+<Literal>mkdependHS</Literal> is fully described in <XRef LinkEnd="mkdependHS">.
+</Para>
+
+<Para>
+A few caveats about this simple scheme:
+</Para>
+
+<Para>
+
+<ItemizedList>
+<ListItem>
+
+<Para>
+ You may need to compile some modules explicitly to create their
+interfaces in the first place (e.g., <Literal>make Bar.o</Literal> to create <Literal>Bar.hi</Literal>).
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ You may have to type <Literal>make</Literal> more than once for the dependencies
+to have full effect.  However, a <Literal>make</Literal> run that does nothing
+<Emphasis>does</Emphasis> mean ``everything's up-to-date.''
+
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+ This scheme will work with mutually-recursive modules but,
+again, it may take multiple iterations to ``settle.''
+
+</Para>
+</ListItem>
+
+</ItemizedList>
+
+</Para>
+
+</Sect2>
+
+<Sect2 id="mutual-recursion">
+<Title>How to compile mutually recursive modules
+</Title>
+
+<Para>
+<IndexTerm><Primary>module system, recursion</Primary></IndexTerm>
+<IndexTerm><Primary>recursion, between modules</Primary></IndexTerm>
+</Para>
+
+<Para>
+Currently, the compiler does not have proper support for dealing with
+mutually recursive modules:
+</Para>
+
+<Para>
+
+<ProgramListing>
+module A where
+
+import B
+
+newtype TA = MkTA Int
+
+f :: TB -&#62; TA
+f (MkTB x) = MkTA x
+--------
+module B where
+
+import A
+
+data TB = MkTB !Int
+
+g :: TA -&#62; TB
+g (MkTA x) = MkTB x
+</ProgramListing>
+
+</Para>
+
+<Para>
+When compiling either module A and B, the compiler will try (in vain)
+to look for the interface file of the other. So, to get mutually
+recursive modules off the ground, you need to hand write an interface
+file for A or B, so as to break the loop.  These hand-written
+interface files are called <Literal>hi-boot</Literal> files, and are placed in a file
+called <Literal>&lt;module&gt;.hi-boot</Literal>.  To import from an <Literal>hi-boot</Literal> file instead
+of the standard <Literal>.hi</Literal> file, use the following syntax in the importing module:
+<IndexTerm><Primary>hi-boot files</Primary></IndexTerm>
+<IndexTerm><Primary>importing, hi-boot files</Primary></IndexTerm>
+</Para>
+
+<Para>
+
+<ProgramListing>
+import {-# SOURCE #-} A
+</ProgramListing>
+
+</Para>
+
+<Para>
+The hand-written interface need only contain the bare minimum of
+information needed to get the bootstrapping process started.  For
+example, it doesn't need to contain declarations for <Emphasis>everything</Emphasis>
+that module <Literal>A</Literal> exports, only the things required by the module that
+imports <Literal>A</Literal> recursively.
+</Para>
+
+<Para>
+For the example at hand, the boot interface file for A would look like
+the following:
+</Para>
+
+<Para>
+
+<ProgramListing>
+__interface A 1 404 where
+__export A TA{MkTA} ;
+1 newtype TA = MkTA PrelBase.Int ;
+</ProgramListing>
+
+</Para>
+
+<Para>
+The syntax is essentially the same as a normal <Literal>.hi</Literal> file
+(unfortunately), but you can usually tailor an existing <Literal>.hi</Literal> file to
+make a <Literal>.hi-boot</Literal> file.
+</Para>
+
+<Para>
+Notice that we only put the declaration for the newtype <Literal>TA</Literal> in the
+<Literal>hi-boot</Literal> file, not the signature for <Literal>f</Literal>, since <Literal>f</Literal> isn't used by
+<Literal>B</Literal>.
+</Para>
+
+<Para>
+The number ``1'' after ``&lowbar;&lowbar;interface A'' gives the version number of module A;
+it is incremented whenever anything in A's interface file changes.  The ``404'' is
+the version number of the interface file <Emphasis>syntax</Emphasis>; we change it when
+we change the syntax of interface files so that you get a better error message when
+you try to read an old-format file with a new-format compiler.
+</Para>
+
+<Para>
+The number ``1'' at the beginning of a declaration is the <Emphasis>version
+number</Emphasis> of that declaration: for the purposes of <Literal>.hi-boot</Literal> files
+these can all be set to 1.  All names must be fully qualified with the
+<Emphasis>original</Emphasis> module that an object comes from: for example, the
+reference to <Literal>Int</Literal> in the interface for <Literal>A</Literal> comes from <Literal>PrelBase</Literal>,
+which is a module internal to GHC's prelude.  It's a pain, but that's
+the way it is.
+</Para>
+
+<Para>
+If you want an hi-boot file to export a data type, but you don't want to give its constructors
+(because the constructors aren't used by the SOURCE-importing module), you can write simply:
+</Para>
+
+<Para>
+
+<ProgramListing>
+__interface A 1 404 where
+__export A TA;
+1 data TA
+</ProgramListing>
+
+</Para>
+
+<Para>
+(You must write all the type parameters, but leave out the '=' and everything that follows it.)
+</Para>
+
+<Para>
+<Emphasis>Note:</Emphasis> This is all a temporary solution, a version of the
+compiler that handles mutually recursive modules properly without the manual
+construction of interface files, is (allegedly) in the works.
+</Para>
+
+</Sect2>
+
+</Sect1>
+
+<Sect1 id="options-optimise">
+<Title>Optimisation (code improvement)
+</Title>
+
+<Para>
+<IndexTerm><Primary>optimisation (GHC)</Primary></IndexTerm>
+<IndexTerm><Primary>improvement, code (GHC)</Primary></IndexTerm>
+</Para>
+
+<Para>
+The <Literal>-O*</Literal> options specify convenient ``packages'' of optimisation
+flags; the <Literal>-f*</Literal> options described later on specify
+<Emphasis>individual</Emphasis> optimisations to be turned on/off; the <Literal>-m*</Literal>
+options specify <Emphasis>machine-specific</Emphasis> optimisations to be turned
+on/off.
+</Para>
+
+<Sect2 id="optimise-pkgs">
+<Title><Literal>-O*</Literal>: convenient ``packages'' of optimisation flags.
+</Title>
+
+<Para>
+<IndexTerm><Primary>-O options</Primary></IndexTerm>
+</Para>
+
+<Para>
+There are <Emphasis>many</Emphasis> options that affect the quality of code
+produced by GHC.  Most people only have a general goal, something like
+``Compile quickly'' or ``Make my program run like greased lightning.''
+The following ``packages'' of optimisations (or lack thereof) should
+suffice.
+</Para>
+
+<Para>
+Once you choose a <Literal>-O*</Literal> ``package,'' stick with it&mdash;don't chop and
+change.  Modules' interfaces <Emphasis>will</Emphasis> change with a shift to a new
+<Literal>-O*</Literal> option, and you may have to recompile a large chunk of all
+importing modules before your program can again be run
+safely (see <XRef LinkEnd="recomp">).
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term>No <Literal>-O*</Literal>-type option specified:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-O* not specified</Primary></IndexTerm>
+This is taken to mean: ``Please compile quickly; I'm not over-bothered
+about compiled-code quality.''  So, for example: <Literal>ghc -c Foo.hs</Literal>
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-O</Literal> or <Literal>-O1</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-O option</Primary></IndexTerm>
+<IndexTerm><Primary>-O1 option</Primary></IndexTerm>
+<IndexTerm><Primary>optimise normally</Primary></IndexTerm>
+Means: ``Generate good-quality code without taking too long about it.''
+Thus, for example: <Literal>ghc -c -O Main.lhs</Literal>
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-O2</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-O2 option</Primary></IndexTerm>
+<IndexTerm><Primary>optimise aggressively</Primary></IndexTerm>
+Means: ``Apply every non-dangerous optimisation, even if it means
+significantly longer compile times.''
+</Para>
+
+<Para>
+The avoided ``dangerous'' optimisations are those that can make
+runtime or space <Emphasis>worse</Emphasis> if you're unlucky.  They are
+normally turned on or off individually.
+</Para>
+
+<Para>
+At the moment, <Literal>-O2</Literal> is <Emphasis>unlikely</Emphasis> to produce
+better code than <Literal>-O</Literal>.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-O2-for-C</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-O2-for-C option</Primary></IndexTerm>
+<IndexTerm><Primary>gcc, invoking with -O2</Primary></IndexTerm>
+</Para>
+
+<Para>
+Says to run GCC with <Literal>-O2</Literal>, which may be worth a few percent in
+execution speed.  Don't forget <Literal>-fvia-C</Literal>, lest you use the native-code
+generator and bypass GCC altogether!
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-Onot</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-Onot option</Primary></IndexTerm>
+<IndexTerm><Primary>optimising, reset</Primary></IndexTerm>
+</Para>
+
+<Para>
+This option will make GHC ``forget'' any <Literal>-O</Literal>ish options it has seen so
+far.  Sometimes useful; for example: <Literal>make all EXTRA&lowbar;HC&lowbar;OPTS=-Onot</Literal>.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-Ofile &lt;file&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-Ofile &lt;file&gt; option</Primary></IndexTerm>
+<IndexTerm><Primary>optimising, customised</Primary></IndexTerm>
+</Para>
+
+<Para>
+For those who need <Emphasis>absolute</Emphasis> control over <Emphasis>exactly</Emphasis>
+what options are used (e.g., compiler writers, sometimes :-), a list
+of options can be put in a file and then slurped in with <Literal>-Ofile</Literal>.
+</Para>
+
+<Para>
+In that file, comments are of the <Literal>&num;</Literal>-to-end-of-line variety; blank
+lines and most whitespace is ignored.
+</Para>
+
+<Para>
+Please ask if you are baffled and would like an example of <Literal>-Ofile</Literal>!
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+<Para>
+At Glasgow, we don't use a <Literal>-O*</Literal> flag for day-to-day work.  We use
+<Literal>-O</Literal> to get respectable speed; e.g., when we want to measure
+something.  When we want to go for broke, we tend to use <Literal>-O -fvia-C
+-O2-for-C</Literal> (and we go for lots of coffee breaks).
+</Para>
+
+<Para>
+The easiest way to see what <Literal>-O</Literal> (etc.) ``really mean'' is to run with
+<Literal>-v</Literal>, then stand back in amazement.  Alternatively, just look at the
+<Literal>HsC&lowbar;minus&lt;blah&gt;</Literal> lists in the <Literal>ghc</Literal> driver script.
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title><Literal>-f*</Literal>: platform-independent flags</Title>
+
+<Para>
+<IndexTerm><Primary>-f* options (GHC)</Primary></IndexTerm>
+<IndexTerm><Primary>-fno-* options (GHC)</Primary></IndexTerm>
+</Para>
+
+<Para>
+Flags can be turned <Emphasis>off</Emphasis> individually.  (NB: I hope you have a
+good reason for doing this&hellip;) To turn off the <Literal>-ffoo</Literal> flag, just use
+the <Literal>-fno-foo</Literal> flag.<IndexTerm><Primary>-fno-&lt;opt&gt; anti-option</Primary></IndexTerm> So, for
+example, you can say <Literal>-O2 -fno-strictness</Literal>, which will then drop out
+any running of the strictness analyser.
+</Para>
+
+<Para>
+The options you are most likely to want to turn off are:
+
+<ItemizedList>
+<ListItem>
+
+<Para>
+<Literal>-fno-strictness</Literal><IndexTerm><Primary>-fno-strictness option</Primary></IndexTerm> (strictness
+analyser, because it is sometimes slow),
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+<Literal>-fno-specialise</Literal><IndexTerm><Primary>-fno-specialise option</Primary></IndexTerm> (automatic
+specialisation of overloaded functions, because it can make your code
+bigger) (US spelling also accepted), and
+</Para>
+</ListItem>
+<ListItem>
+
+<Para>
+<Literal>-fno-cpr-analyse</Literal><IndexTerm><Primary>-fno-cpr-analyse option</Primary></IndexTerm> switches off the CPR (constructed product
+result) analyser.
+</Para>
+</ListItem>
+
+</ItemizedList>
+
+</Para>
+
+<Para>
+Should you wish to turn individual flags <Emphasis>on</Emphasis>, you are advised
+to use the <Literal>-Ofile</Literal> option, described above.  Because the order in
+which optimisation passes are run is sometimes crucial, it's quite
+hard to do with command-line options.
+</Para>
+
+<Para>
+Here are some ``dangerous'' optimisations you <Emphasis>might</Emphasis> want to try:
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>-fvia-C</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-fvia-C option</Primary></IndexTerm>
+<IndexTerm><Primary>native code generator, turning off</Primary></IndexTerm>
+</Para>
+
+<Para>
+Compile via C, and don't use the native-code generator.  (There are
+many cases when GHC does this on its own.)  You might pick up a little
+bit of speed by compiling via C.  If you use <Literal>&lowbar;ccall&lowbar;gc&lowbar;</Literal>s or
+<Literal>&lowbar;casm&lowbar;</Literal>s, you probably <Emphasis>have</Emphasis> to use <Literal>-fvia-C</Literal>.
+</Para>
+
+<Para>
+The lower-case incantation, <Literal>-fvia-c</Literal>, is synonymous.
+</Para>
+
+<Para>
+Compiling via C will probably be slower (in compilation time) than
+using GHC's native code generator.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-funfolding-interface-threshold&lt;n&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-funfolding-interface-threshold option</Primary></IndexTerm>
+<IndexTerm><Primary>inlining, controlling</Primary></IndexTerm>
+<IndexTerm><Primary>unfolding, controlling</Primary></IndexTerm>
+(Default: 30) By raising or lowering this number, you can raise or
+lower the amount of pragmatic junk that gets spewed into interface
+files.  (An unfolding has a ``size'' that reflects the cost in terms
+of ``code bloat'' of expanding that unfolding in another module.  A
+bigger function would be assigned a bigger cost.)
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-funfolding-creation-threshold&lt;n&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-funfolding-creation-threshold option</Primary></IndexTerm>
+<IndexTerm><Primary>inlining, controlling</Primary></IndexTerm>
+<IndexTerm><Primary>unfolding, controlling</Primary></IndexTerm>
+(Default: 30) This option is similar to
+<Literal>-funfolding-interface-threshold</Literal>, except that it governs unfoldings
+within a single module.  Increasing this figure is more likely to
+result in longer compile times than faster code.  The next option is
+more useful:
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-funfolding-use-threshold&lt;n&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-funfolding-use-threshold option</Primary></IndexTerm>
+<IndexTerm><Primary>inlining, controlling</Primary></IndexTerm>
+<IndexTerm><Primary>unfolding, controlling</Primary></IndexTerm>
+(Default: 8) This is the magic cut-off figure for unfolding: below
+this size, a function definition will be unfolded at the call-site,
+any bigger and it won't.  The size computed for a function depends on
+two things: the actual size of the expression minus any discounts that
+apply (see <Literal>-funfolding-con-discount</Literal>).
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-funfolding-con-discount&lt;n&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-funfolding-con-discount option</Primary></IndexTerm>
+<IndexTerm><Primary>inlining, controlling</Primary></IndexTerm>
+<IndexTerm><Primary>unfolding, controlling</Primary></IndexTerm>
+(Default: 2) If the compiler decides that it can eliminate some
+computation by performing an unfolding, then this is a discount factor
+that it applies to the funciton size before deciding whether to unfold
+it or not.
+</Para>
+
+<Para>
+OK, folks, these magic numbers `30', `8', and '2' are mildly
+arbitrary; they are of the ``seem to be OK'' variety.  The `8' is the
+more critical one; it's what determines how eager GHC is about
+expanding unfoldings.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-funbox-strict-fields</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-funbox-strict-fields option</Primary></IndexTerm>
+<IndexTerm><Primary>strict constructor fields</Primary></IndexTerm>
+<IndexTerm><Primary>constructor fields, strict</Primary></IndexTerm>
+</Para>
+
+<Para>
+This option causes all constructor fields which are marked strict
+(i.e. ``!'') to be unboxed or unpacked if possible.  For example:
+</Para>
+
+<Para>
+
+<ProgramListing>
+data T = T !Float !Float
+</ProgramListing>
+
+</Para>
+
+<Para>
+will create a constructor <Literal>T</Literal> containing two unboxed floats if the
+<Literal>-funbox-strict-fields</Literal> flag is given.  This may not always be an
+optimisation: if the <Literal>T</Literal> constructor is scrutinised and the floats
+passed to a non-strict function for example, they will have to be
+reboxed (this is done automatically by the compiler).
+</Para>
+
+<Para>
+This option should only be used in conjunction with <Literal>-O</Literal>, in order to
+expose unfoldings to the compiler so the reboxing can be removed as
+often as possible.  For example:
+</Para>
+
+<Para>
+
+<ProgramListing>
+f :: T -&#62; Float
+f (T f1 f2) = f1 + f2
+</ProgramListing>
+
+</Para>
+
+<Para>
+The compiler will avoid reboxing <Literal>f1</Literal> and <Literal>f2</Literal> by inlining <Literal>+</Literal> on
+floats, but only when <Literal>-O</Literal> is on.
+</Para>
+
+<Para>
+Any single-constructor data is eligible for unpacking; for example
+</Para>
+
+<Para>
+
+<ProgramListing>
+data T = T !(Int,Int)
+</ProgramListing>
+
+</Para>
+
+<Para>
+will store the two <Literal>Int</Literal>s directly in the <Literal>T</Literal> constructor, by flattening
+the pair.  Multi-level unpacking is also supported:
+</Para>
+
+<Para>
+
+<ProgramListing>
+data T = T !S
+data S = S !Int !Int
+</ProgramListing>
+
+</Para>
+
+<Para>
+will store two unboxed <Literal>Int&num;</Literal>s directly in the <Literal>T</Literal> constructor.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-fsemi-tagging</Literal>:</Term>
+<ListItem>
+<Para>
+This option (which <Emphasis>does not work</Emphasis> with the native-code generator)
+tells the compiler to add extra code to test for already-evaluated
+values.  You win if you have lots of such values during a run of your
+program, you lose otherwise.  (And you pay in extra code space.)
+</Para>
+
+<Para>
+We have not played with <Literal>-fsemi-tagging</Literal> enough to recommend it.
+(For all we know, it doesn't even work anymore&hellip; Sigh.)
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title><Literal>-m*</Literal>: platform-specific flags</Title>
+
+<Para>
+<IndexTerm><Primary>-m* options (GHC)</Primary></IndexTerm>
+<IndexTerm><Primary>platform-specific options</Primary></IndexTerm>
+<IndexTerm><Primary>machine-specific options</Primary></IndexTerm>
+</Para>
+
+<Para>
+Some flags only make sense for particular target platforms.
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>-mv8</Literal>:</Term>
+<ListItem>
+<Para>
+(SPARC machines)<IndexTerm><Primary>-mv8 option (SPARC only)</Primary></IndexTerm>
+Means to pass the like-named option to GCC; it says to use the
+Version 8 SPARC instructions, notably integer multiply and divide.
+The similiar <Literal>-m*</Literal> GCC options for SPARC also work, actually.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-mlong-calls</Literal>:</Term>
+<ListItem>
+<Para>
+(HPPA machines)<IndexTerm><Primary>-mlong-calls option (HPPA only)</Primary></IndexTerm>
+Means to pass the like-named option to GCC.  Required for Very Big
+modules, maybe.  (Probably means you're in trouble&hellip;)
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-monly-[32]-regs</Literal>:</Term>
+<ListItem>
+<Para>
+(iX86 machines)<IndexTerm><Primary>-monly-N-regs option (iX86 only)</Primary></IndexTerm>
+GHC tries to ``steal'' four registers from GCC, for performance
+reasons; it almost always works.  However, when GCC is compiling some
+modules with four stolen registers, it will crash, probably saying:
+
+<Screen>
+Foo.hc:533: fixed or forbidden register was spilled.
+This may be due to a compiler bug or to impossible asm
+statements or clauses.
+</Screen>
+
+Just give some registers back with <Literal>-monly-N-regs</Literal>.  Try `3' first,
+then `2'.  If `2' doesn't work, please report the bug to us.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+</Sect2>
+
+<Sect2 id="optimise-C-compiler">
+<Title>Code improvement by the C compiler.
+</Title>
+
+<Para>
+<IndexTerm><Primary>optimisation by GCC</Primary></IndexTerm>
+<IndexTerm><Primary>GCC optimisation</Primary></IndexTerm>
+</Para>
+
+<Para>
+The C&nbsp;compiler (GCC) is run with <Literal>-O</Literal> turned on.  (It has
+to be, actually).
+</Para>
+
+<Para>
+If you want to run GCC with <Literal>-O2</Literal>&mdash;which may be worth a few
+percent in execution speed&mdash;you can give a
+<Literal>-O2-for-C</Literal><IndexTerm><Primary>-O2-for-C option</Primary></IndexTerm> option.
+</Para>
+
+</Sect2>
+
+</Sect1>
+
+<Sect1 id="options-phases">
+<Title>Options related to a particular phase
+</Title>
+
+<Sect2 id="c-pre-processor">
+<Title>The C pre-processor
+</Title>
+
+<Para>
+<IndexTerm><Primary>pre-processing: cpp</Primary></IndexTerm>
+<IndexTerm><Primary>C pre-processor options</Primary></IndexTerm>
+<IndexTerm><Primary>cpp, pre-processing with</Primary></IndexTerm>
+</Para>
+
+<Para>
+The C pre-processor <Literal>cpp</Literal> is run over your Haskell code only if the
+<Literal>-cpp</Literal> option <IndexTerm><Primary>-cpp option</Primary></IndexTerm> is given.  Unless you are
+building a large system with significant doses of conditional
+compilation, you really shouldn't need it.
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>-D&lt;foo&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-D&lt;name&gt; option</Primary></IndexTerm>
+Define macro <Literal>&lt;foo&gt;</Literal> in the usual way.  NB: does <Emphasis>not</Emphasis> affect
+<Literal>-D</Literal> macros passed to the C&nbsp;compiler when compiling via C!  For those,
+use the <Literal>-optc-Dfoo</Literal> hack&hellip; (see <XRef LinkEnd="forcing-options-through">).
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-U&lt;foo&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-U&lt;name&gt; option</Primary></IndexTerm>
+Undefine macro <Literal>&lt;foo&gt;</Literal> in the usual way.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-I&lt;dir&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-I&lt;dir&gt; option</Primary></IndexTerm>
+Specify a directory in which to look for <Literal>&num;include</Literal> files, in
+the usual C way.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+<Para>
+The <Literal>ghc</Literal> driver pre-defines several macros when processing Haskell
+source code (<Literal>.hs</Literal> or <Literal>.lhs</Literal> files):
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>&lowbar;&lowbar;HASKELL98&lowbar;&lowbar;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>&lowbar;&lowbar;HASKELL98&lowbar;&lowbar;</Primary></IndexTerm>
+If defined, this means that GHC supports the language defined by the
+Haskell 98 report.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>&lowbar;&lowbar;HASKELL&lowbar;&lowbar;=98</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>&lowbar;&lowbar;HASKELL&lowbar;&lowbar;</Primary></IndexTerm>
+In GHC 4.04 and later, the <Literal>&lowbar;&lowbar;HASKELL&lowbar;&lowbar;</Literal> macro is defined as having
+the value <Literal>98</Literal>.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>&lowbar;&lowbar;HASKELL1&lowbar;&lowbar;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>&lowbar;&lowbar;HASKELL1&lowbar;&lowbar; macro</Primary></IndexTerm>
+If defined to <Emphasis>n</Emphasis>, that means GHC supports the Haskell language
+defined in the Haskell report version <Emphasis>1.n</Emphasis>.  Currently 5.  This
+macro is deprecated, and will probably disappear in future versions.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>&lowbar;&lowbar;GLASGOW&lowbar;HASKELL&lowbar;&lowbar;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>&lowbar;&lowbar;GLASGOW&lowbar;HASKELL&lowbar;&lowbar; macro</Primary></IndexTerm>
+For version <Emphasis>n</Emphasis> of the GHC system, this will be <Literal>&num;define</Literal>d to
+<Emphasis>100n</Emphasis>.  So, for version 4.00, it is 400.
+</Para>
+
+<Para>
+With any luck, <Literal>&lowbar;&lowbar;GLASGOW&lowbar;HASKELL&lowbar;&lowbar;</Literal> will be undefined in all other
+implementations that support C-style pre-processing.
+</Para>
+
+<Para>
+(For reference: the comparable symbols for other systems are:
+<Literal>&lowbar;&lowbar;HUGS&lowbar;&lowbar;</Literal> for Hugs and <Literal>&lowbar;&lowbar;HBC&lowbar;&lowbar;</Literal> for Chalmers.)
+</Para>
+
+<Para>
+NB. This macro is set when pre-processing both Haskell source and C
+source, including the C source generated from a Haskell module
+(ie. <Literal>.hs</Literal>, <Literal>.lhs</Literal>, <Literal>.c</Literal> and <Literal>.hc</Literal> files).
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>&lowbar;&lowbar;CONCURRENT&lowbar;HASKELL&lowbar;&lowbar;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>&lowbar;&lowbar;CONCURRENT&lowbar;HASKELL&lowbar;&lowbar; macro</Primary></IndexTerm>
+This symbol is defined when pre-processing Haskell (input) and
+pre-processing C (GHC output).  Since GHC from verion 4.00 now
+supports concurrent haskell by default, this symbol is always defined.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>&lowbar;&lowbar;PARALLEL&lowbar;HASKELL&lowbar;&lowbar;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>&lowbar;&lowbar;PARALLEL&lowbar;HASKELL&lowbar;&lowbar; macro</Primary></IndexTerm>
+Only defined when <Literal>-parallel</Literal> is in use!  This symbol is defined when
+pre-processing Haskell (input) and pre-processing C (GHC output).
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+<Para>
+Options other than the above can be forced through to the C
+pre-processor with the <Literal>-opt</Literal> flags (see
+<XRef LinkEnd="forcing-options-through">).
+</Para>
+
+<Para>
+A small word of warning: <Literal>-cpp</Literal> is not friendly to ``string
+gaps''.<IndexTerm><Primary>-cpp vs string gaps</Primary></IndexTerm><IndexTerm><Primary>string gaps vs
+-cpp</Primary></IndexTerm>.  In other words, strings such as the following:
+</Para>
+
+<Para>
+
+<ProgramListing>
+strmod = "\
+\ p \
+\ "
+</ProgramListing>
+
+</Para>
+
+<Para>
+don't work with <Literal>-cpp</Literal>; <Literal>/usr/bin/cpp</Literal> elides the
+backslash-newline pairs.
+</Para>
+
+<Para>
+However, it appears that if you add a space at the end of the line,
+then <Literal>cpp</Literal> (at least GNU <Literal>cpp</Literal> and possibly other <Literal>cpp</Literal>s)
+leaves the backslash-space pairs alone and the string gap works as
+expected.
+</Para>
+
+</Sect2>
+
+<Sect2 id="options-C-compiler">
+<Title>Options affecting the C compiler (if applicable)
+</Title>
+
+<Para>
+<IndexTerm><Primary>include-file options</Primary></IndexTerm>
+<IndexTerm><Primary>C compiler options</Primary></IndexTerm>
+<IndexTerm><Primary>GCC options</Primary></IndexTerm>
+</Para>
+
+<Para>
+At the moment, quite a few common C-compiler options are passed on
+quietly to the C compilation of Haskell-compiler-generated C files.
+THIS MAY CHANGE.  Meanwhile, options so sent are:
+</Para>
+
+<Para>
+
+<InformalTable>
+<TGroup Cols="2">
+<ColSpec Align="Left" Colsep="0">
+<ColSpec Align="Left" Colsep="0">
+<TBody>
+<Row>
+<Entry><Literal>-ansi</Literal> </Entry>
+<Entry> do ANSI C (not K&amp;R) </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>-pedantic</Literal> </Entry>
+<Entry> be so</Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>-dgcc-lint</Literal> </Entry>
+<Entry> (hack) short for ``make GCC very paranoid''</Entry>
+</Row>
+
+</TBody>
+
+</TGroup>
+</InformalTable>
+
+<IndexTerm><Primary>-ansi option (for GCC)</Primary></IndexTerm>
+<IndexTerm><Primary>-pedantic option (for GCC)</Primary></IndexTerm>
+<IndexTerm><Primary>-dgcc-lint option (GCC paranoia)</Primary></IndexTerm>
+</Para>
+
+<Para>
+If you are compiling with lots of <Literal>ccalls</Literal>, etc., you may need to
+tell the C&nbsp;compiler about some <Literal>&num;include</Literal> files.  There is no real
+pretty way to do this, but you can use this hack from the
+command-line:
+</Para>
+
+<Para>
+
+<Screen>
+% ghc -c '-#include &#60;X/Xlib.h&#62;' Xstuff.lhs
+</Screen>
+
+</Para>
+
+</Sect2>
+
+<Sect2 id="options-linker">
+<Title>Linking and consistency-checking
+</Title>
+
+<Para>
+<IndexTerm><Primary>linker options</Primary></IndexTerm>
+<IndexTerm><Primary>ld options</Primary></IndexTerm>
+</Para>
+
+<Para>
+GHC has to link your code with various libraries, possibly including:
+user-supplied, GHC-supplied, and system-supplied (<Literal>-lm</Literal> math
+library, for example).
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>-l&lt;FOO&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-l&lt;lib&gt; option</Primary></IndexTerm>
+Link in a library named <Literal>lib&lt;FOO&gt;.a</Literal> which resides somewhere on the
+library directories path.
+</Para>
+
+<Para>
+Because of the sad state of most UNIX linkers, the order of such
+options does matter.  Thus: <Literal>ghc -lbar *.o</Literal> is almost certainly
+wrong, because it will search <Literal>libbar.a</Literal> <Emphasis>before</Emphasis> it has
+collected unresolved symbols from the <Literal>*.o</Literal> files.
+<Literal>ghc *.o -lbar</Literal> is probably better.
+</Para>
+
+<Para>
+The linker will of course be informed about some GHC-supplied
+libraries automatically; these are:
+</Para>
+
+<Para>
+
+<InformalTable>
+<TGroup Cols="2">
+<ColSpec Align="Left" Colsep="0">
+<ColSpec Align="Left" Colsep="0">
+<TBody>
+<Row>
+<Entry><Emphasis>-l equivalent</Emphasis> </Entry>
+<Entry> <Emphasis>description</Emphasis> </Entry>
+</Row>
+
+<Row>
+<Entry>
+<Literal>-lHSrts,-lHSclib</Literal> </Entry>
+<Entry> basic runtime libraries </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>-lHS</Literal> </Entry>
+<Entry> standard Prelude library </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>-lHS&lowbar;cbits</Literal> </Entry>
+<Entry> C support code for standard Prelude library </Entry>
+</Row>
+<Row>
+<Entry>
+<Literal>-lgmp</Literal> </Entry>
+<Entry> GNU multi-precision library (for Integers)</Entry>
+</Row>
+
+</TBody>
+
+</TGroup>
+</InformalTable>
+
+</Para>
+
+<Para>
+<IndexTerm><Primary>-lHS library</Primary></IndexTerm>
+<IndexTerm><Primary>-lHS&lowbar;cbits library</Primary></IndexTerm>
+<IndexTerm><Primary>-lHSrts library</Primary></IndexTerm>
+<IndexTerm><Primary>-lgmp library</Primary></IndexTerm>
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-syslib &lt;name&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-syslib &lt;name&gt; option</Primary></IndexTerm>
+</Para>
+
+<Para>
+If you are using a Haskell ``system library'' (e.g., the POSIX
+library), just use the <Literal>-syslib posix</Literal> option, and the correct code
+should be linked in.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-L&lt;dir&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-L&lt;dir&gt; option</Primary></IndexTerm>
+Where to find user-supplied libraries&hellip;  Prepend the directory
+<Literal>&lt;dir&gt;</Literal> to the library directories path.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-static</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-static option</Primary></IndexTerm>
+Tell the linker to avoid shared libraries.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-no-link-chk</Literal> and <Literal>-link-chk</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-no-link-chk option</Primary></IndexTerm>
+<IndexTerm><Primary>-link-chk option</Primary></IndexTerm>
+<IndexTerm><Primary>consistency checking of executables</Primary></IndexTerm>
+By default, immediately after linking an executable, GHC verifies that
+the pieces that went into it were compiled with compatible flags; a
+``consistency check''.
+(This is to avoid mysterious failures caused by non-meshing of
+incompatibly-compiled programs; e.g., if one <Literal>.o</Literal> file was compiled
+for a parallel machine and the others weren't.)  You may turn off this
+check with <Literal>-no-link-chk</Literal>.  You can turn it (back) on with
+<Literal>-link-chk</Literal> (the default).
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-no-hs-main</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-no-hs-main option</Primary></IndexTerm>
+<IndexTerm><Primary>linking Haskell libraries with foreign code</Primary></IndexTerm>
+</Para>
+
+<Para>
+In the event you want to include ghc-compiled code as part of another
+(non-Haskell) program, the RTS will not be supplying its definition of
+<Literal>main()</Literal> at link-time, you will have to. To signal that to the
+driver script when linking, use <Literal>-no-hs-main</Literal>.
+</Para>
+
+<Para>
+Notice that since the command-line passed to the linker is rather
+involved, you probably want to use the ghc driver script to do the
+final link of your `mixed-language' application. This is not a
+requirement though, just try linking once with <Literal>-v</Literal> on to see what
+options the driver passes through to the linker.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+</Sect2>
+
+</Sect1>
+
+<Sect1>
+<Title>Using Concurrent Haskell</Title>
+
+<Para>
+<IndexTerm><Primary>Concurrent Haskell&mdash;use</Primary></IndexTerm>
+</Para>
+
+<Para>
+GHC (as of version 4.00) supports Concurrent Haskell by default,
+without requiring a special option or libraries compiled in a certain
+way.  To get access to the support libraries for Concurrent Haskell
+(ie. <Literal>Concurrent</Literal> and friends), use the <Literal>-syslib concurrent</Literal> option.
+</Para>
+
+<Para>
+Three RTS options are provided for modifying the behaviour of the
+threaded runtime system.  See the descriptions of <Literal>-C[&lt;us&gt;]</Literal>, <Literal>-q</Literal>,
+and <Literal>-t&lt;num&gt;</Literal> in <XRef LinkEnd="parallel-rts-opts">.
+</Para>
+
+<Para>
+Concurrent Haskell is described in more detail in <XRef LinkEnd="concurrent-and-parallel">.
+</Para>
+
+</Sect1>
+
+<Sect1>
+<Title>Using Parallel Haskell</Title>
+
+<Para>
+<IndexTerm><Primary>Parallel Haskell&mdash;use</Primary></IndexTerm>
+</Para>
+
+<Para>
+&lsqb;You won't be able to execute parallel Haskell programs unless PVM3
+(Parallel Virtual Machine, version 3) is installed at your site.]
+</Para>
+
+<Para>
+To compile a Haskell program for parallel execution under PVM, use the
+<Literal>-parallel</Literal> option,<IndexTerm><Primary>-parallel option</Primary></IndexTerm> both when compiling
+<Emphasis>and linking</Emphasis>.  You will probably want to <Literal>import Parallel</Literal>
+into your Haskell modules.
+</Para>
+
+<Para>
+To run your parallel program, once PVM is going, just invoke it ``as
+normal''.  The main extra RTS option is <Literal>-N&lt;n&gt;</Literal>, to say how many
+PVM ``processors'' your program to run on.  (For more details of
+all relevant RTS options, please see <XRef LinkEnd="parallel-rts-opts">.)
+</Para>
+
+<Para>
+In truth, running Parallel Haskell programs and getting information
+out of them (e.g., parallelism profiles) is a battle with the vagaries of
+PVM, detailed in the following sections.
+</Para>
+
+<Sect2>
+<Title>Dummy's guide to using PVM</Title>
+
+<Para>
+<IndexTerm><Primary>PVM, how to use</Primary></IndexTerm>
+<IndexTerm><Primary>Parallel Haskell&mdash;PVM use</Primary></IndexTerm>
+Before you can run a parallel program under PVM, you must set the
+required environment variables (PVM's idea, not ours); something like,
+probably in your <Literal>.cshrc</Literal> or equivalent:
+
+<ProgramListing>
+setenv PVM_ROOT /wherever/you/put/it
+setenv PVM_ARCH `$PVM_ROOT/lib/pvmgetarch`
+setenv PVM_DPATH $PVM_ROOT/lib/pvmd
+</ProgramListing>
+
+</Para>
+
+<Para>
+Creating and/or controlling your ``parallel machine'' is a purely-PVM
+business; nothing specific to Parallel Haskell.
+</Para>
+
+<Para>
+You use the <Literal>pvm</Literal><IndexTerm><Primary>pvm command</Primary></IndexTerm> command to start PVM on your
+machine.  You can then do various things to control/monitor your
+``parallel machine;'' the most useful being:
+</Para>
+
+<Para>
+<InformalTable>
+<TGroup Cols=2>
+<ColSpec Align="Left">
+<TBody>
+
+<Row>
+<Entry><Literal>Control-D</Literal></Entry>
+<Entry>exit <Literal>pvm</Literal>, leaving it running</Entry>
+</Row>
+
+<Row>
+<Entry><Literal>halt</Literal></Entry>
+<Entry>kill off this ``parallel machine'' &amp; exit</Entry>
+</Row>
+
+<Row>
+<Entry><Literal>add &lt;host&gt;</Literal></Entry>
+<Entry>add <Literal>&lt;host&gt;</Literal> as a processor</Entry>
+</Row>
+
+<Row>
+<Entry><Literal>delete &lt;host&gt;</Literal></Entry>
+<Entry>delete <Literal>&lt;host&gt;</Literal></Entry>
+</Row>
+
+<Row>
+<Entry><Literal>reset</Literal></Entry>
+<Entry>kill what's going, but leave PVM up</Entry>
+</Row>
+
+<Row>
+<Entry><Literal>conf</Literal></Entry>
+<Entry>list the current configuration</Entry>
+</Row>
+
+<Row>
+<Entry><Literal>ps</Literal></Entry>
+<Entry>report processes' status</Entry>
+</Row>
+
+<Row>
+<Entry><Literal>pstat &lt;pid&gt;</Literal></Entry>
+<Entry>status of a particular process</Entry>
+</Row>
+
+</TBody>
+</TGroup>
+</InformalTable>
+</Para>
+
+<Para>
+The PVM documentation can tell you much, much more about <Literal>pvm</Literal>!
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>Parallelism profiles</Title>
+
+<Para>
+<IndexTerm><Primary>parallelism profiles</Primary></IndexTerm>
+<IndexTerm><Primary>profiles, parallelism</Primary></IndexTerm>
+<IndexTerm><Primary>visualisation tools</Primary></IndexTerm>
+</Para>
+
+<Para>
+With Parallel Haskell programs, we usually don't care about the
+results&mdash;only with ``how parallel'' it was!  We want pretty pictures.
+</Para>
+
+<Para>
+Parallelism profiles (&agrave; la <Literal>hbcpp</Literal>) can be generated with the
+<Literal>-q</Literal><IndexTerm><Primary>-q RTS option (concurrent, parallel)</Primary></IndexTerm> RTS option.  The
+per-processor profiling info is dumped into files named
+<Literal>&lt;full-path&gt;&lt;program&gt;.gr</Literal>.  These are then munged into a PostScript picture,
+which you can then display.  For example, to run your program
+<Literal>a.out</Literal> on 8 processors, then view the parallelism profile, do:
+</Para>
+
+<Para>
+
+<Screen>
+% ./a.out +RTS -N8 -q
+% grs2gr *.???.gr &#62; temp.gr     # combine the 8 .gr files into one
+% gr2ps -O temp.gr              # cvt to .ps; output in temp.ps
+% ghostview -seascape temp.ps   # look at it!
+</Screen>
+
+</Para>
+
+<Para>
+The scripts for processing the parallelism profiles are distributed
+in <Literal>ghc/utils/parallel/</Literal>.
+</Para>
+
+</Sect2>
+
+<Sect2>
+<Title>Other useful info about running parallel programs</Title>
+
+<Para>
+The ``garbage-collection statistics'' RTS options can be useful for
+seeing what parallel programs are doing.  If you do either
+<Literal>+RTS -Sstderr</Literal><IndexTerm><Primary>-Sstderr RTS option</Primary></IndexTerm> or <Literal>+RTS -sstderr</Literal>, then
+you'll get mutator, garbage-collection, etc., times on standard
+error. The standard error of all PE's other than the `main thread'
+appears in <Literal>/tmp/pvml.nnn</Literal>, courtesy of PVM.
+</Para>
+
+<Para>
+Whether doing <Literal>+RTS -Sstderr</Literal> or not, a handy way to watch
+what's happening overall is: <Literal>tail -f /tmp/pvml.nnn</Literal>.
+</Para>
+
+</Sect2>
+
+<Sect2 id="parallel-rts-opts">
+<Title>RTS options for Concurrent/Parallel Haskell
+</Title>
+
+<Para>
+<IndexTerm><Primary>RTS options, concurrent</Primary></IndexTerm>
+<IndexTerm><Primary>RTS options, parallel</Primary></IndexTerm>
+<IndexTerm><Primary>Concurrent Haskell&mdash;RTS options</Primary></IndexTerm>
+<IndexTerm><Primary>Parallel Haskell&mdash;RTS options</Primary></IndexTerm>
+</Para>
+
+<Para>
+Besides the usual runtime system (RTS) options
+(<XRef LinkEnd="runtime-control">), there are a few options particularly
+for concurrent/parallel execution.
+</Para>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>-N&lt;N&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-N&lt;N&gt; RTS option (parallel)</Primary></IndexTerm>
+(PARALLEL ONLY) Use <Literal>&lt;N&gt;</Literal> PVM processors to run this program;
+the default is 2.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-C[&lt;us&gt;]</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-C&lt;us&gt; RTS option</Primary></IndexTerm>
+Sets the context switch interval to <Literal>&lt;us&gt;</Literal> microseconds.  A context
+switch will occur at the next heap allocation after the timer expires.
+With <Literal>-C0</Literal> or <Literal>-C</Literal>, context switches will occur as often as
+possible (at every heap allocation).  By default, context switches
+occur every 10 milliseconds.  Note that many interval timers are only
+capable of 10 millisecond granularity, so the default setting may be
+the finest granularity possible, short of a context switch at every
+heap allocation.
+</Para>
+
+<Para>
+&lsqb;NOTE: this option currently has no effect (version 4.00).  Context
+switches happen when the current heap block is full, i.e. every 4k of
+allocation].
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-q[v]</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-q RTS option</Primary></IndexTerm>
+(PARALLEL ONLY) Produce a quasi-parallel profile of thread activity,
+in the file <Literal>&lt;program&gt;.qp</Literal>.  In the style of <Literal>hbcpp</Literal>, this profile
+records the movement of threads between the green (runnable) and red
+(blocked) queues.  If you specify the verbose suboption (<Literal>-qv</Literal>), the
+green queue is split into green (for the currently running thread
+only) and amber (for other runnable threads).  We do not recommend
+that you use the verbose suboption if you are planning to use the
+<Literal>hbcpp</Literal> profiling tools or if you are context switching at every heap
+check (with <Literal>-C</Literal>).
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-t&lt;num&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-t&lt;num&gt; RTS option</Primary></IndexTerm>
+(PARALLEL ONLY) Limit the number of concurrent threads per processor
+to <Literal>&lt;num&gt;</Literal>.  The default is 32.  Each thread requires slightly over 1K
+<Emphasis>words</Emphasis> in the heap for thread state and stack objects.  (For
+32-bit machines, this translates to 4K bytes, and for 64-bit machines,
+8K bytes.)
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-d</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-d RTS option (parallel)</Primary></IndexTerm>
+(PARALLEL ONLY) Turn on debugging.  It pops up one xterm (or GDB, or
+something&hellip;) per PVM processor.  We use the standard <Literal>debugger</Literal>
+script that comes with PVM3, but we sometimes meddle with the
+<Literal>debugger2</Literal> script.  We include ours in the GHC distribution,
+in <Literal>ghc/utils/pvm/</Literal>.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-e&lt;num&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-e&lt;num&gt; RTS option (parallel)</Primary></IndexTerm>
+(PARALLEL ONLY) Limit the number of pending sparks per processor to
+<Literal>&lt;num&gt;</Literal>. The default is 100. A larger number may be appropriate if
+your program generates large amounts of parallelism initially.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-Q&lt;num&gt;</Literal>:</Term>
+<ListItem>
+<Para>
+<IndexTerm><Primary>-Q&lt;num&gt; RTS option (parallel)</Primary></IndexTerm>
+(PARALLEL ONLY) Set the size of packets transmitted between processors
+to <Literal>&lt;num&gt;</Literal>. The default is 1024 words. A larger number may be
+appropriate if your machine has a high communication cost relative to
+computation speed.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+</Sect2>
+
+</Sect1>
+
+&runtime
+&debug
+
+</Chapter>
diff --git a/ghc/docs/users_guide/utils.sgml b/ghc/docs/users_guide/utils.sgml
new file mode 100644 (file)
index 0000000..da61187
--- /dev/null
@@ -0,0 +1,369 @@
+<Chapter id="utils">
+<Title>Other Haskell utility programs
+</Title>
+
+<IndexTerm><Primary>utilities, Haskell</Primary></IndexTerm>
+
+<Para>
+This section describes other program(s) which we distribute, that help
+with the Great Haskell Programming Task.
+</Para>
+
+<Sect1 id="mkdependHS">
+<Title>Makefile dependencies in Haskell: using <Literal>mkdependHS</Literal>
+</Title>
+
+<Para>
+<IndexTerm><Primary>mkdependHS</Primary></IndexTerm>
+<IndexTerm><Primary>Makefile dependencies</Primary></IndexTerm>
+<IndexTerm><Primary>dependencies in Makefiles</Primary></IndexTerm>
+</Para>
+
+<Para>
+You run <Literal>mkdependHS</Literal> like this:
+
+<Screen>
+mkdependHS [mkdependHS options] [-- GHC options --] srcfile1 [srcfile2 ...]
+</Screen>
+
+or
+
+<Screen>
+ghc -M [mkdependHS options(prefix with -optdep)] [ GHC options ] srcfile1 [srcfile2 ...]
+</Screen>
+
+To see <Literal>mkdependHS</Literal>'s command-line flags, give it a duff flag,
+e.g., <Literal>mkdependHS -help</Literal>.
+</Para>
+
+<Para>
+In general, if module <Literal>A</Literal> contains the line
+
+<ProgramListing>
+import B ...blah...
+</ProgramListing>
+
+then <Literal>mkdependHS</Literal> will generate a dependency line of the form:
+
+<ProgramListing>
+A.o : B.hi
+</ProgramListing>
+
+If module <Literal>A</Literal> contains the line 
+
+<ProgramListing>
+import {-# SOURCE #-} B ...blah...
+</ProgramListing>
+
+then <Literal>mkdependHS</Literal> will generate a dependency line of the form:
+
+<ProgramListing>
+A.o : B.hi-boot
+</ProgramListing>
+
+(See <XRef LinkEnd="hi-files"> for details of interface files.)
+If <Literal>A</Literal> imports multiple modules, then there will be multiple lines with <Literal>A.o</Literal> as the
+target.
+</Para>
+
+<Para>
+By default, <Literal>mkdependHS</Literal> generates all the dependencies, and then
+concatenates them onto the end of
+<Literal>makefile</Literal> (or <Literal>Makefile</Literal> if <Literal>makefile</Literal> doesn't exist) bracketed by
+the lines "<Literal>&num; DO NOT DELETE: Beginning of Haskell dependencies</Literal>" and
+"<Literal>&num; DO NOT DELETE: End of Haskell dependencies</Literal>".  If these lines
+already exist in the <Literal>makefile</Literal>, <Literal>mkdependHS</Literal> deletes the old
+dependencies first.
+</Para>
+
+<Para>
+<Literal>mkdependHS</Literal> takes GHC options between <Literal>--</Literal> brackets.
+It understands the following ones. Any options between <Literal>--</Literal> brackets
+that it doesn't understand are simply ignored; this way you can feed your
+Makefile's standard GHC options to <Literal>mkdependHS</Literal> un-filtered.
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>-cpp</Literal></Term>
+<ListItem>
+<Para>
+Run the C pre-processor over the input files. The
+default is not to.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-D&lt;blah&gt;</Literal></Term>
+<ListItem>
+<Para>
+A cpp <Literal>&num;define</Literal>; usual meaning.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-i&lt;dirs&gt;</Literal></Term>
+<ListItem>
+<Para>
+Add <Literal>&lt;dirs&gt;</Literal> (colon-separated) to list of directories
+to search for "import"ed modules.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-I&lt;dir&gt;</Literal></Term>
+<ListItem>
+<Para>
+Add <Literal>&lt;dir&gt;</Literal> to list of directories to search for
+.h files (i.e., usual meaning).
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-syslib &lt;blah&gt;</Literal></Term>
+<ListItem>
+<Para>
+This program uses this GHC system library; take
+appropriate action (e.g., recognise when they are
+"import"ing a module from that library).
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+<Para>
+Here are the <Literal>mkdependHS</Literal>-specific options (not between <Literal>--</Literal>'s):
+<VariableList>
+
+<VarListEntry>
+<Term><Literal>-v</Literal></Term>
+<ListItem>
+<Para>
+Be verbose.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-v -v</Literal></Term>
+<ListItem>
+<Para>
+Be very verbose.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-w</Literal></Term>
+<ListItem>
+<Para>
+Turn off warnings about interface file shadowing.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-f blah</Literal></Term>
+<ListItem>
+<Para>
+Use <Literal>blah</Literal> as the makefile, rather than <Literal>makefile</Literal>
+or <Literal>Makefile</Literal>.  If <Literal>blah</Literal> doesn't exist, <Literal>mkdependHS</Literal> creates it.
+We often use <Literal>-f .depend</Literal> to put the dependencies in <Literal>.depend</Literal> and
+then <Literal>include</Literal> the file <Literal>.depend</Literal> into <Literal>Makefilpe</Literal>.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-o &lt;osuf&gt;</Literal></Term>
+<ListItem>
+<Para>
+Use <Literal>.&lt;osuf&gt;</Literal> as the "target file" suffix ( default: <Literal>o</Literal>).
+Multiple <Literal>-o</Literal> flags are permitted (GHC2.05 onwards).  Thus "<Literal>-o hc -o o</Literal>"
+will generate dependencies for <Literal>.hc</Literal> and <Literal>.o</Literal> files.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-s &lt;suf&gt;</Literal></Term>
+<ListItem>
+<Para>
+Make extra dependencies that declare that files with
+suffix <Literal>.&lt;suf&gt;&lowbar;&lt;osuf&gt;</Literal> depend on interface files with suffix <Literal>.&lt;suf&gt;&lowbar;hi</Literal>, or
+(for <Literal>&lcub;-&num; SOURCE &num;-&rcub;</Literal> imports) on <Literal>.hi-boot</Literal>.
+Multiple <Literal>-s</Literal> flags are permitted.
+For example, "<Literal>-o hc -s a -s b</Literal>" will
+make dependencies for <Literal>.hc</Literal> on <Literal>.hi</Literal>, <Literal>.a&lowbar;hc</Literal> on <Literal>.a&lowbar;hi</Literal>, and <Literal>.b&lowbar;hc</Literal> on <Literal>.b&lowbar;hi</Literal>.
+(Useful in conjunction with NoFib "ways".)  
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>--exclude-module=&lt;file&gt;</Literal></Term>
+<ListItem>
+<Para>
+Regard <Literal>&lt;file&gt;</Literal> as "stable"; i.e., exclude it from having
+dependencies on it.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-x</Literal></Term>
+<ListItem>
+<Para>
+same as <Literal>--exclude-module</Literal>
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>--exclude-directory=&lt;dirs&gt;</Literal></Term>
+<ListItem>
+<Para>
+Regard the colon-separated list of directories <Literal>&lt;dirs&gt;</Literal> as containing stable,
+don't generate any dependencies on modules therein.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>-Xdirs</Literal></Term>
+<ListItem>
+<Para>
+same as <Literal>--exclude-directory</Literal>.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>--include-module=&lt;file&gt;</Literal></Term>
+<ListItem>
+<Para>
+Regard <Literal>&lt;file&gt;</Literal> as not "stable"; i.e., generate dependencies
+on it (if any). This option is normally used in conjunction 
+with the <Literal>--exclude-directory</Literal> option.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term><Literal>--include-prelude</Literal></Term>
+<ListItem>
+<Para>
+Regard prelude libraries as unstable, i.e., generate dependencies
+on the prelude modules used (including <Literal>Prelude</Literal>).
+This option is normally only used by the various system libraries. If
+a <Literal>-syslib</Literal> option is used, dependencies will also be
+generated on the library's interfaces. 
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+</Sect1>
+
+<Sect1 id="hstags">
+<Title>Emacs `TAGS' for Haskell: <Literal>hstags</Literal>
+</Title>
+
+<Para>
+<IndexTerm><Primary>hstags</Primary></IndexTerm>
+<IndexTerm><Primary>TAGS for Haskell</Primary></IndexTerm>
+</Para>
+
+<Para>
+`Tags' is a facility for indexing the definitions of
+programming-language things in a multi-file program, and then using
+that index to jump around among these definitions.
+</Para>
+
+<Para>
+Rather than scratch your head, saying ``Now where did we define
+`foo'?'', you just do (in Emacs) <Literal>M-. foo RET</Literal>, and You're There!
+Some people go wild over this stuff&hellip;
+</Para>
+
+<Para>
+GHC comes with a program <Literal>hstags</Literal>, which build Emacs-able TAGS files.  The invocation syntax is:
+
+<Screen>
+hstags [GHC-options] file [files...]
+</Screen>
+
+</Para>
+
+<Para>
+The best thing is just to feed it your GHC command-line flags.
+A good Makefile entry might be:
+
+<ProgramListing>
+tags:
+        $(RM) TAGS
+        hstags $(GHC_FLAGS) *.lhs
+</ProgramListing>
+
+</Para>
+
+<Para>
+The only flags of its own are: <Literal>-v</Literal> to be verbose; <Literal>-a</Literal> to
+**APPEND** to the TAGS file, rather than write to it.
+</Para>
+
+<Para>
+Shortcomings: (1)&nbsp;Instance declarations don't get into the TAGS file
+(but the definitions inside them do); as instances aren't named, this
+is probably just as well.  (2)&nbsp;Data-constructor definitions don't get
+in.  Go for the corresponding type constructor instead.
+</Para>
+
+<Para>
+(Actually, GHC also comes with <Literal>etags</Literal> &lsqb;for C&rsqb;, and <Literal>perltags</Literal>
+&lsqb;for You Know What&rsqb;.  And&mdash;I cannot tell a lie&mdash;there is Denis
+Howe's <Literal>fptags</Literal> &lsqb;for Haskell, etc.&rsqb; in the <Literal>ghc/CONTRIB</Literal>
+section&hellip;)
+</Para>
+
+</Sect1>
+
+<Sect1 id="happy">
+<Title>``Yacc for Haskell'': <Literal>happy</Literal>
+</Title>
+
+<Para>
+<IndexTerm><Primary>happy</Primary></IndexTerm>
+<IndexTerm><Primary>Yacc for Haskell</Primary></IndexTerm>
+<IndexTerm><Primary>parser generator for Haskell</Primary></IndexTerm>
+Andy Gill and Simon Marlow have written a parser-generator for
+Haskell, called <Literal>happy</Literal>.<IndexTerm><Primary>happy parser generator</Primary></IndexTerm> <Literal>Happy</Literal>
+is to Haskell what <Literal>Yacc</Literal> is to C.
+</Para>
+
+<Para>
+You can get <Literal>happy</Literal> by FTP from <Literal>ftp.dcs.gla.ac.uk</Literal> in
+<Literal>pub/haskell/happy</Literal>, the file <Literal>happy-1.5-src.tar.gz</Literal>.
+</Para>
+
+<Para>
+<Literal>Happy</Literal> is at its shining best when compiled by GHC.
+</Para>
+
+</Sect1>
+
+<Sect1 id="pphs">
+<Title>Pretty-printing Haskell: <Literal>pphs</Literal>
+</Title>
+
+<Para>
+<IndexTerm><Primary>pphs</Primary></IndexTerm>
+<IndexTerm><Primary>pretty-printing Haskell code</Primary></IndexTerm>
+</Para>
+
+<Para>
+Andrew Preece has written
+<Literal>pphs</Literal>,<IndexTerm><Primary>pphs</Primary></IndexTerm><IndexTerm><Primary>pretty-printing Haskell</Primary></IndexTerm>
+a utility to pretty-print Haskell code in LaTeX documents.
+Keywords in bolds, variables in italics&mdash;that sort of thing.  It is
+good at lining up program clauses and equals signs, things that are
+very tiresome to do by hand.
+</Para>
+
+<Para>
+The code is distributed with GHC in <Literal>ghc/CONTRIB/pphs</Literal>.
+</Para>
+
+</Sect1>
+
+</Chapter>
diff --git a/ghc/docs/users_guide/vs_haskell.sgml b/ghc/docs/users_guide/vs_haskell.sgml
new file mode 100644 (file)
index 0000000..d3f2d3b
--- /dev/null
@@ -0,0 +1,191 @@
+<Sect1 id="vs-Haskell-defn">
+<Title>Haskell&nbsp;98 vs.&nbsp;Glasgow Haskell: language non-compliance
+</Title>
+
+<Para>
+<IndexTerm><Primary>GHC vs the Haskell 98 language</Primary></IndexTerm>
+<IndexTerm><Primary>Haskell 98 language vs GHC</Primary></IndexTerm>
+</Para>
+
+<Para>
+This section lists Glasgow Haskell infelicities in its implementation
+of Haskell&nbsp;98.  See also the ``when things go wrong'' section
+(<XRef LinkEnd="wrong">)
+for information about crashes, space leaks, and other undesirable
+phenomena.
+</Para>
+
+<Para>
+The limitations here are listed in Haskell-Report order (roughly).
+</Para>
+
+<Sect2 id="infelicities-exprs-pats">
+<Title>Expressions and patterns
+</Title>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term>Very long <Literal>String</Literal> constants:</Term>
+<ListItem>
+<Para>
+May not go through.  If you add a ``string gap'' every
+few thousand characters, then the strings can be as long
+as you like.
+</Para>
+
+<Para>
+Bear in mind that string gaps and the <Literal>-cpp</Literal><IndexTerm><Primary>-cpp option</Primary></IndexTerm>
+option don't mix very well (see <XRef LinkEnd="c-pre-processor">).
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>Very long literal lists:</Term>
+<ListItem>
+<Para>
+These may tickle a ``yacc stack overflow'' error in the parser.
+(It depends on the Yacc used to build your parser.)
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>Single quotes in module names:</Term>
+<ListItem>
+<Para>
+It might work, but it's just begging for trouble.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+</Sect2>
+
+<Sect2 id="infelicities-decls">
+<Title>Declarations and bindings
+</Title>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term>Derived instances for records:</Term>
+<ListItem>
+<Para>
+Hmmm.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+</Sect2>
+
+<Sect2 id="infelicities-Modules">
+<Title>Module system and interface files
+</Title>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term> Namespace pollution </Term>
+<ListItem>
+<Para>
+Several modules internal to GHC are visible in the standard namespace.
+All of these modules begin with <Literal>Prel</Literal>, so the rule is: don't use any
+modules beginning with <Literal>Prel</Literal> in your program, or you will be
+comprehensively screwed.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+</Sect2>
+
+<Sect2 id="infelicities-numbers">
+<Title>Numbers, basic types, and built-in classes
+</Title>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term>Unchecked arithmetic:</Term>
+<ListItem>
+<Para>
+Arguably <Emphasis>not</Emphasis> an infelicity, but&hellip; Bear in mind that
+operations on <Literal>Int</Literal>, <Literal>Float</Literal>, and <Literal>Double</Literal> numbers are
+<Emphasis>unchecked</Emphasis> for overflow, underflow, and other sad occurrences.
+(note, however that some architectures trap floating-point overflow
+and loss-of-precision and report a floating-point
+exception)<IndexTerm><Primary>floating-point exceptions</Primary></IndexTerm>.
+</Para>
+
+<Para>
+Use <Literal>Integer</Literal>, <Literal>Rational</Literal>, etc., numeric types if this stuff
+keeps you awake at night.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>Multiply-defined array elements&mdash;not checked:</Term>
+<ListItem>
+<Para>
+This code fragment <Emphasis>should</Emphasis> elicit a fatal error, but it does not:
+
+<ProgramListing>
+main = print (array (1,1) [ 1:=2, 1:=3 ])
+</ProgramListing>
+
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+</Sect2>
+
+<Sect2 id="infelicities-Prelude">
+<Title>In Prelude support
+</Title>
+
+<Para>
+<VariableList>
+
+<VarListEntry>
+<Term>Arbitrary-sized tuples:</Term>
+<ListItem>
+<Para>
+Plain old tuples of arbitrary size <Emphasis>do</Emphasis> work.
+</Para>
+
+<Para>
+HOWEVER: standard instances for tuples (<Literal>Eq</Literal>, <Literal>Ord</Literal>, <Literal>Bounded</Literal>, <Literal>Ix</Literal>
+<Literal>Read</Literal>, and <Literal>Show</Literal>) are available <Emphasis>only</Emphasis> up to 5-tuples.
+</Para>
+
+<Para>
+These limitations are easily subvertible, so please ask if you get
+stuck on them.
+</Para>
+</ListItem>
+</VarListEntry>
+<VarListEntry>
+<Term>Unicode character set:</Term>
+<ListItem>
+<Para>
+Haskell 98 embraces the Unicode character set, but GHC doesn't
+handle it. Yet.
+</Para>
+</ListItem>
+</VarListEntry>
+</VariableList>
+</Para>
+
+</Sect2>
+
+</Sect1>