diff --git a/ghc/docs/users_guide/4-00-notes.vsgml b/ghc/docs/users_guide/4-00-notes.vsgml deleted file mode 100644 index 3309016dcd46db985dcbea6652cc9d0d6a791604..0000000000000000000000000000000000000000 --- a/ghc/docs/users_guide/4-00-notes.vsgml +++ /dev/null @@ -1,168 +0,0 @@ -<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 @forall a. ...@ instead of @All a => ...@. - -<item> Multi-paramter type classes. We have relaxed some of the rules - since GHC 3.00. In particular - -<descrip> - <tag>@-fallow-overlapping-instances@</tag> - allows overlapping instances - <tag>@-fallow-undecidable-instances@</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>@Dynamic@</tag> - -Dynamic types. - -<tag>@Exceptions@</tag> - -The library @Exception@ in @-syslib exts@ provide an interface for -exception handling. Calls to @error@, 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 @-H@ options anymore. In fact, the @-H@ option -is now ignored for compatibility with older versions. - -Stacks are now also expandable, and the @-K@ option now specifies a -<em/maximum/ heap size. The default is (a perhaps conservative) @1M@. - -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 @-prof -auto-all@, then -run it with @+RTS -p@ and see what comes out (in the @<prog>.prof@ -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> @forkIO@ now returns a @ThreadId@, and there's a new operation -@killThread@ which will terminate an existing thread. See Section -<ref name="The Concurrent interface" id="concurrent-interface"> for -more details. - -<item> You need @-syslib concurrent@ to get the @Concurrent@ library. - -<item> The rewritten IO library from 3.03 has been ported to 4.00. - -<item> New constructs: @foriegn import@ and @foreign export@ 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 @-A@ 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> @seq@ works better than in 3.xx - you can now @seq@ functions -without crashing the program. - -<item> The @Eval@ class has been removed (i.e. every type is assumed -to be in class @Eval@). 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.vsgml b/ghc/docs/users_guide/4-01-notes.vsgml deleted file mode 100644 index d0aaa7c362f34134a16e45e5a90e61740f783d4e..0000000000000000000000000000000000000000 --- a/ghc/docs/users_guide/4-01-notes.vsgml +++ /dev/null @@ -1,31 +0,0 @@ -<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.vsgml b/ghc/docs/users_guide/4-02-notes.vsgml deleted file mode 100644 index cda5219caf4928011730644e2560dc17a88a231f..0000000000000000000000000000000000000000 --- a/ghc/docs/users_guide/4-02-notes.vsgml +++ /dev/null @@ -1,59 +0,0 @@ -<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<size>/ 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.vsgml b/ghc/docs/users_guide/4-03-notes.vsgml deleted file mode 100644 index a402be8b9b66b65df29849a765dddc922ea4ba54..0000000000000000000000000000000000000000 --- a/ghc/docs/users_guide/4-03-notes.vsgml +++ /dev/null @@ -1,26 +0,0 @@ -<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 @-funbox-strict-fields@ for unboxing/unpacking strict -constructor fields. - -</itemize> diff --git a/ghc/docs/users_guide/4-04-notes.vsgml b/ghc/docs/users_guide/4-04-notes.vsgml deleted file mode 100644 index c7d307f82b9725dfcb104c25cc97a8a4d95203cd..0000000000000000000000000000000000000000 --- a/ghc/docs/users_guide/4-04-notes.vsgml +++ /dev/null @@ -1,94 +0,0 @@ -<sect1>Release notes for version~4.04---7/99 -<label id="release-4-04"> -<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. - <item> A weak pointer whose key is itself a weak pointer will now do - the right thing. - </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 @-funbox-strict-fields@ for unboxing/unpacking strict -constructor fields. - -<item> GHC now has a license! Check out <tt>fptools/ghc/LICENSE/</tt>. - -<item> Added CPR analysis, which reduces allocation by unboxing -function results (thanks to Kevin Glynn <tt><keving@@cs.mu.OZ.AU></tt>). - -<item> UsageSP analysis added, but not yet functional. - -<item> Added a simple common sub-expression analysis pass. - -<item> Implemented update-in-place for certain very restricted cases. - -<item> 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. - -<item> Added <tt>Concurrent.yield :: IO ()</tt>. - -<item> Added RULES pragms - transformation rules for Haskell source. -This is used for list fusion: now intermediate lists between map, -foldr, list comprehensions are removed automatically. - -<item> Unregisterised/unmangled builds now work. - -<item> Much performance tuning: GHC 4.04 produces faster code than all -previous compilers. - -<item> GHC now defines <tt/__HASKELL98__/ when compiling files with -<tt/-cpp/. - -<item> <tt/hppa1.1-hp-hpux/ port reinstated. - -<item> New operations for unsafely thawing byte arrays: -<tt/unsafeThaw{Byte,ST,IO}Array/. - -<item> <tt/mkdependHS/ now lives in GHC's lib directory, not the -binary directory. It isn't intended to be run standalone, only via -<tt/ghc -M/. - -<item> Asynchronous exceptions are now supported (see Section <ref name="The Concurrent Library" id="concurrent-interface">). New operations: - - <itemize> <item> <tt/Exception.killThread/ now raises an exception - (<tt/AsyncException.KilledThread/) in the killed thread. - <item> <tt/Exception.raiseInThread/ allows a thread to raise an - exception in another thread. - <item> <tt/Concurrent.myThreadId/ returns the <tt/ThreadId/ of the - calling thread. - <item> Stack overflow results in <tt/AsyncException.StackOverflow/ - being raised in the offending thread. - </itemize> - -<item> Assertion failures now raise an <tt/AssertionFailed/ exception. - -<item> Added simple high-level interface to the Regex library, see -Section <ref name="The RegexString Library" id="RegexString">. - -<item> <tt/forkIO/ now handles any uncaught exceptions cleanly. - -<item> <tt/integer2Int#/ isn't sign preserving any longer, but modulo -<tt/(maxBound::Int + 1) * 2/. - -<item> <tt/-ddump-rdr/ is now called <tt/-ddump-parsed/. - -<item> Signal handling with the <tt/Posix/ library now works. - -<item> Many, many bugs fixed. - -</itemize> diff --git a/ghc/docs/users_guide/debugging.vsgml b/ghc/docs/users_guide/debugging.vsgml deleted file mode 100644 index f3fed156e436448ffec47e689704ed56538d87c1..0000000000000000000000000000000000000000 --- a/ghc/docs/users_guide/debugging.vsgml +++ /dev/null @@ -1,337 +0,0 @@ -%************************************************************************ -%* * -<sect1>Debugging the compiler -<label id="options-debugging"> -<p> -<nidx>debugging options (for GHC)</nidx> -%* * -%************************************************************************ - -HACKER TERRITORY. HACKER TERRITORY. -(You were warned.) - -%---------------------------------------------------------------------- -<sect2>Replacing the program for one or more phases. -<label id="replacing-phases"> -<p> -<nidx>GHC phases, changing</nidx> -<nidx>phases, changing GHC</nidx> - -You may specify that a different program be used for one of the phases -of the compilation system, in place of whatever the driver @ghc@ has -wired into it. For example, you might want to try a different -assembler. The -@-pgm<phase-code><program-name>@<nidx>-pgm<phase><stuff> -option</nidx> option to @ghc@ will cause it to use @<program-name>@ -for phase @<phase-code>@, where the codes to indicate the phases are: - -<tabular ca="ll"> -<bf>code</bf> | <bf>phase</bf> @@ -@@ -L | literate pre-processor @@ -P | C pre-processor (if -cpp only) @@ -C | Haskell compiler @@ -c | C compiler@@ -a | assembler @@ -l | linker @@ -dep | Makefile dependency generator @@ -</tabular> - -%---------------------------------------------------------------------- -<sect2>Forcing options to a particular phase. -<label id="forcing-options-through"> -<p> -<nidx>forcing GHC-phase options</nidx> - -The preceding sections describe driver options that are mostly -applicable to one particular phase. You may also <em>force</em> a -specific option @<option>@ to be passed to a particular phase -@<phase-code>@ by feeding the driver the option -@-opt<phase-code><option>@.<nidx>-opt<phase><stuff> -option</nidx> The codes to indicate the phases are the same as in the -previous section. - -So, for example, to force an @-Ewurble@ option to the assembler, you -would tell the driver @-opta-Ewurble@ (the dash before the E is -required). - -Besides getting options to the Haskell compiler with @-optC<blah>@, -you can get options through to its runtime system with -@-optCrts<blah>@<nidx>-optCrts<blah> option</nidx>. - -So, for example: when I want to use my normal driver but with my -profiled compiler binary, I use this script: -<tscreen><verb> -#! /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 \ - "$@" -</verb></tscreen> - -%---------------------------------------------------------------------- -<sect2>Dumping out compiler intermediate structures -<label id="dumping-output"> -<p> -<nidx>dumping GHC intermediates</nidx> -<nidx>intermediate passes, output</nidx> - -<descrip> -<tag>@-noC@:</tag> -<nidx>-noC option</nidx> -Don't bother generating C output <em>or</em> an interface file. Usually -used in conjunction with one or more of the @-ddump-*@ options; for -example: @ghc -noC -ddump-simpl Foo.hs@ - -<tag>@-hi@:</tag> -<nidx>-hi option</nidx> -<em>Do</em> generate an interface file. This would normally be used in -conjunction with @-noC@, which turns off interface generation; -thus: @-noC -hi@. - -<tag>@-dshow-passes@:</tag> -<nidx>-dshow-passes option</nidx> -Prints a message to stderr as each pass starts. Gives a warm but -undoubtedly misleading feeling that GHC is telling you what's -happening. - -<tag>@-ddump-<pass>@:</tag> -<nidx>-ddump-<pass> options</nidx> -Make a debugging dump after pass @<pass>@ (may be common enough to -need a short form...). You can get all of these at once (<em/lots/ of -output) by using @-ddump-all@, or most of them with @-ddump-most@. -Some of the most useful ones are: - -<descrip> -<tag>@-ddump-parsed@:</tag> parser output -<tag>@-ddump-rn@:</tag> renamer output -<tag>@-ddump-tc@:</tag> typechecker output -<tag>@-ddump-deriv@:</tag> derived instances -<tag>@-ddump-ds@:</tag> desugarer output -<tag>@-ddump-spec@:</tag> output of specialisation pass -<tag>@-ddump-rules@:</tag> dumps all rewrite rules (including those generated by the specialisation pass) -<tag>@-ddump-simpl@:</tag> simplifer output (Core-to-Core passes) -<tag>@-ddump-usagesp@:</tag> UsageSP inference pre-inf and output -<tag>@-ddump-cpranal@:</tag> CPR analyser output -<tag>@-ddump-stranal@:</tag> strictness analyser output -<tag>@-ddump-workwrap@:</tag> worker/wrapper split output -<tag>@-ddump-occur-anal@:</tag> `occurrence analysis' output -<tag>@-ddump-stg@:</tag> output of STG-to-STG passes -<tag>@-ddump-absC@:</tag> <em>un</em>flattened Abstract~C -<tag>@-ddump-flatC@:</tag> <em>flattened</em> Abstract~C -<tag>@-ddump-realC@:</tag> same as what goes to the C compiler -<tag>@-ddump-asm@:</tag> assembly language from the native-code generator -<tag>@-ddump-most@:</tag> most of the above, plus @-dshow-passes@, @-dsource-stats@, @-ddump-simpl-stats@, -<tag>@-ddump-all@:</tag> all the above, plus @-ddump-inlinings@, -@-ddump-simpl-iterations@, @-ddump-rn-trace@, -@-ddump-verbose-simpl@, @-ddump-verbose-stg@. -</descrip> - -<nidx>-ddump-all option</nidx>% -<nidx>-ddump-most option</nidx>% -<nidx>-ddump-parsed option</nidx>% -<nidx>-ddump-rn option</nidx>% -<nidx>-ddump-tc option</nidx>% -<nidx>-ddump-deriv option</nidx>% -<nidx>-ddump-ds option</nidx>% -<nidx>-ddump-simpl option</nidx>% -<nidx>-ddump-cpranal option</nidx>% -<nidx>-ddump-workwrap option</nidx>% -<nidx>-ddump-rules option</nidx>% -<nidx>-ddump-usagesp option</nidx>% -<nidx>-ddump-stranal option</nidx>% -<nidx>-ddump-occur-anal option</nidx>% -<nidx>-ddump-spec option</nidx>% -<nidx>-ddump-stg option</nidx>% -<nidx>-ddump-absC option</nidx>% -<nidx>-ddump-flatC option</nidx>% -<nidx>-ddump-realC option</nidx>% -<nidx>-ddump-asm option</nidx> - -%For any other @-ddump-*@ options: consult the source, notably -%@ghc/compiler/main/CmdLineOpts.lhs@. - -<tag>@-dverbose-simpl@ and @-dverbose-stg@:</tag> -<nidx>-dverbose-simpl option</nidx> -<nidx>-dverbose-stg option</nidx> -Show the output of the intermediate Core-to-Core and STG-to-STG -passes, respectively. (<em>Lots</em> of output!) So: when we're -really desperate: -<tscreen><verb> -% ghc -noC -O -ddump-simpl -dverbose-simpl -dcore-lint Foo.hs -</verb></tscreen> - -<tag>@-ddump-simpl-iterations@:</tag> -<nidx>-ddump-simpl-iterations option</nidx> -Show the output of each <em/iteration/ of the simplifier (each run of -the simplifier has a maximum number of iterations, normally 4). Used -when even @-dverbose-simpl@ doesn't cut it. - -<tag>@-dppr-{user,debug@}:</tag> -<nidx>-dppr-user option</nidx> -<nidx>-dppr-debug option</nidx> -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). - -<tag>@-ddump-simpl-stats@:</tag> -<nidx>-ddump-simpl-stats option</nidx> -Dump statistics about how many of each kind -of transformation too place. If you add @-dppr-debug@ you get more detailed information. - -<tag>@-ddump-raw-asm@:</tag> -<nidx>-ddump-raw-asm option</nidx> -Dump out the assembly-language stuff, before the ``mangler'' gets it. - -<tag>@-ddump-rn-trace@:</tag> -<nidx>-ddump-rn-trace</nidx> -Make the renamer be *real* chatty about what it is upto. - -<tag>@-dshow-rn-stats@:</tag> -<nidx>-dshow-rn-stats</nidx> -Print out summary of what kind of information the renamer had to bring -in. -<tag>@-dshow-unused-imports@:</tag> -<nidx>-dshow-unused-imports</nidx> -Have the renamer report what imports does not contribute. - -% -%<tag>@-dgc-debug@:</tag> -%<nidx>-dgc-debug option</nidx> -%Enables some debugging code related to the garbage-collector. -</descrip> - -%ToDo: -ddump-asm-insn-counts -%-ddump-asm-globals-info - -%---------------------------------------------------------------------- -<sect2>Checking for consistency -<label id="checking-consistency"> -<p> -<nidx>consistency checks</nidx> -<nidx>lint</nidx> - -<descrip> -<tag>@-dcore-lint@:</tag> -<nidx>-dcore-lint option</nidx> -Turn on heavyweight intra-pass sanity-checking within GHC, at Core -level. (It checks GHC's sanity, not yours.) - -<tag>@-dstg-lint@:</tag> -<nidx>-dstg-lint option</nidx> -Ditto for STG level. - -<tag>@-dusagesp-lint@:</tag> -<nidx>-dstg-lint option</nidx> -Turn on checks around UsageSP inference (@-fusagesp@). 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. -</descrip> - -%---------------------------------------------------------------------- -<sect2>How to read Core syntax (from some @-ddump-*@ flags) -<p> -<nidx>reading Core syntax</nidx> -<nidx>Core syntax, how to read</nidx> - -Let's do this by commenting an example. It's from doing -@-ddump-ds@ on this code: -<tscreen><verb> -skip2 m = m : skip2 (m+2) -</verb></tscreen> - -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., @_@ means ``built-in type variable''; -@t@ means ``from the typechecker''; @s@ means ``from the -simplifier''; and so on. The `number' is printed fairly compactly in -a `base-62' format, which everyone hates except me (WDP). - -Remember, everything has a ``Unique'' and it is usually printed out -when debugging, in some form or another. So here we go... - -<tscreen><verb> -Desugared: -Main.skip2{-r1L6-} :: _forall_ a$_4 =>{{Num a$_4}} -> a$_4 -> [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 -> \ d.Num.t4Gt -> - let { - {- CoRec -} - +.t4Hg :: _4 -> _4 -> _4 - _NI_ - +.t4Hg = (+{-r3JH-} _4) d.Num.t4Gt - - fromInt.t4GS :: Int{-2i-} -> _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 -> [_4] - _NI_ - skip2.t3Ja = - \ m.r1H4 -> - 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 -</verb></tscreen> - -(``It's just a simple functional language'' is an unregisterised -trademark of Peyton Jones Enterprises, plc.) - -%---------------------------------------------------------------------- diff --git a/ghc/docs/users_guide/end.vsgml b/ghc/docs/users_guide/end.vsgml deleted file mode 100644 index ef51cdc4de77fa5f4f704dfaad78b2c7c4daabbf..0000000000000000000000000000000000000000 --- a/ghc/docs/users_guide/end.vsgml +++ /dev/null @@ -1,3 +0,0 @@ -% document trailer for user guide. - -</article> diff --git a/ghc/docs/users_guide/glasgow_exts.vsgml b/ghc/docs/users_guide/glasgow_exts.vsgml deleted file mode 100644 index b29df6211ae7fe7be15baf7e32840e443486cc95..0000000000000000000000000000000000000000 --- a/ghc/docs/users_guide/glasgow_exts.vsgml +++ /dev/null @@ -1,2679 +0,0 @@ -% -% $Id: glasgow_exts.vsgml,v 1.20 1999/11/25 10:28:41 simonpj Exp $ -% -% GHC Language Extensions. -% - -As with all known Haskell systems, GHC implements some extensions to -the language. To use them, you'll need to give a @-fglasgow-exts@% -<nidx>-fglasgow-exts option</nidx> option. - -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---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! - -Executive summary of our extensions: - -<descrip> - -<tag>Unboxed types and primitive operations:</tag> - -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 Section <ref name="Unboxed types" -id="glasgow-unboxed"> and following. - -<tag>Multi-parameter type classes:</tag> - -GHC's type system supports extended type classes with multiple -parameters. Please see Section <ref name="Mult-parameter type -classes" id="multi-param-type-classes">. - -<tag>Local universal quantification:</tag> - -GHC's type system supports explicit universal quantification in -constructor fields and function arguments. This is useful for things -like defining @runST@ from the state-thread world. See Section <ref -name="Local universal quantification" id="universal-quantification">. - -<tag>Extistentially quantification in data types:</tag> - -Some or all of the type variables in a datatype declaration may be -<em>existentially quantified</em>. More details in Section <ref -name="Existential Quantification" id="existential-quantification">. - -<tag>Scoped type variables:</tag> - -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 Section <ref name="Scoped Type Variables" -id="scoped-type-variables">. - -<tag>Calling out to C:</tag> - -Just what it sounds like. We provide <em>lots</em> of rope that you -can dangle around your neck. Please see Section <ref name="Calling~C -directly from Haskell" id="glasgow-ccalls">. - -<tag>Pragmas</tag> - -Pragmas are special instructions to the compiler placed in the source -file. The pragmas GHC supports are described in Section <ref -name="Pragmas" id="pragmas">. - -<tag>Rewrite rules:</tag> - -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 Section <ref name="Rewrite Rules" -id="rewrite-rules">. - -<tag>Pattern guards</tag> - -add a more flexible syntax and semantics for guards in function definitions. -This gives expressiveness somewhat comparable to that of ``views''. -</descrip> - -Before you get too carried away working at the lowest level (e.g., -sloshing @MutableByteArray#@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 Section <ref name="GHC -Prelude and libraries" id="ghc-prelude">. - -%************************************************************************ -%* * -<sect1>Unboxed types -<label id="glasgow-unboxed"> -<p> -<nidx>Unboxed types (Glasgow extension)</nidx> -%* * -%************************************************************************ - -These types correspond to the ``raw machine'' types you would use in -C: @Int#@ (long int), @Double#@ (double), @Addr#@ (void *), etc. The -<em>primitive operations</em> (PrimOps) on these types are what you -might expect; e.g., @(+#)@ is addition on @Int#@s, and is the -machine-addition that we all know and love---usually one instruction. - -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 -@[Int#]@ (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 @seq@ 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 -(@Double#@ for instance). - -Nevertheless, A numerically-intensive program using unboxed types can -go a <em>lot</em> faster than its ``standard'' counterpart---we saw a -threefold speedup on one example. - -Please see Section <ref name="The module PrelGHC: really primitive -stuff" id="ghc-libs-ghc"> for the details of unboxed types and the -operations on them. - -%************************************************************************ -%* * -<sect1>Primitive state-transformer monad -<label id="glasgow-ST-monad"> -<p> -<nidx>state transformers (Glasgow extensions)</nidx> -<nidx>ST monad (Glasgow extension)</nidx> -%* * -%************************************************************************ - -This monad underlies our implementation of arrays, mutable and -immutable, and our implementation of I/O, including ``C calls''. - -The @ST@ library, which provides access to the @ST@ monad, is a -GHC/Hugs extension library and is described in the separate <htmlurl -name="GHC/Hugs Extension Libraries" url="libs.html"> document. - -%************************************************************************ -%* * -<sect1>Primitive arrays, mutable and otherwise -<label id="glasgow-prim-arrays"> -<p> -<nidx>primitive arrays (Glasgow extension)</nidx> -<nidx>arrays, primitive (Glasgow extension)</nidx> -%* * -%************************************************************************ - -GHC knows about quite a few flavours of Large Swathes of Bytes. - -First, GHC distinguishes between primitive arrays of (boxed) Haskell -objects (type @Array# obj@) and primitive arrays of bytes (type -@ByteArray#@). - -Second, it distinguishes between... -<descrip> -<tag>Immutable:</tag> -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. - -<tag>Mutable:</tag> -Arrays that may be changed or ``mutated.'' All the operations on them -live within the state-transformer monad and the updates happen -<em>in-place</em>. - -<tag>``Static'' (in C land):</tag> -A C routine may pass an @Addr#@ 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. - -<tag>``Stable'' pointers:</tag> -If, for some reason, you wish to hand a Haskell pointer (i.e., -<em>not</em> 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. - -Please see Section <ref name="Subverting automatic unboxing with -``stable pointers''" id="glasgow-stablePtrs"> for more details. - -<tag>``Foreign objects'':</tag> -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.'' - -Please see Section <ref name="Pointing outside the Haskell heap" -id="glasgow-foreignObjs"> for more details. - -</descrip> - -The libraries section gives more details on all these ``primitive -array'' types and the operations on them, Section <ref name="The GHC -Prelude and Libraries" id="ghc-prelude">. Some of these extensions -are also supported by Hugs, and the supporting libraries are described -in the <htmlurl name="GHC/Hugs Extension Libraries" url="libs.html"> -document. - -%************************************************************************ -%* * -<sect1>Calling~C directly from Haskell -<label id="glasgow-ccalls"> -<p> -<nidx>C calls (Glasgow extension)</nidx> -<nidx>_ccall_ (Glasgow extension)</nidx> -<nidx>_casm_ (Glasgow extension)</nidx> -%* * -%************************************************************************ - -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. - -%************************************************************************ -%* * -<sect2>@_ccall_@ and @_casm_@: an introduction -<label id="ccall-intro"> -<p> -%* * -%************************************************************************ - -The simplest way to use a simple C function - -<tscreen><verb> -double fooC( FILE *in, char c, int i, double d, unsigned int u ) -</verb></tscreen> - -is to provide a Haskell wrapper: - -<tscreen><verb> -fooH :: Char -> Int -> Double -> Word -> IO Double -fooH c i d w = _ccall_ fooC (``stdin''::Addr) c i d w -</verb></tscreen> - -The function @fooH@ will unbox all of its arguments, call the C -function @fooC@ and box the corresponding arguments. - -One of the annoyances about @_ccall_@s is when the C types don't quite -match the Haskell compiler's ideas. For this, the @_casm_@ variant -may be just the ticket (NB: <em>no chance</em> of such code going -through a native-code generator): - -<tscreen><verb> -import Addr -import CString - -oldGetEnv name - = _casm_ ``%r = getenv((char *) %0);'' name >>= \ litstring -> - return ( - if (litstring == nullAddr) then - Left ("Fail:oldGetEnv:"++name) - else - Right (unpackCString litstring) - ) -</verb></tscreen> - -The first literal-literal argument to a @_casm_@ is like a @printf@ -format: @%r@ is replaced with the ``result,'' @%0@--@%n-1@ are -replaced with the 1st--nth arguments. As you can see above, it is an -easy way to do simple C~casting. Everything said about @_ccall_@ goes -for @_casm_@ as well. - -The use of @_casm_@ 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 @_casm_@, its unfolding will <em/not/ 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 @_casm_@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 @_casm_@, 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 @_casm_@ 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. - -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 -@-funfold-casms-in-hi-file@ will turn off the default behaviour. -<nidx>-funfold-casms-in-hi-file option</nidx> - -%************************************************************************ -%* * -<sect2>Literal-literals -<label id="glasgow-literal-literals"> -<p> -<nidx>Literal-literals</nidx> -%* * -%************************************************************************ - -The literal-literal argument to @_casm_@ can be made use of separately -from the @_casm_@ construct itself. Indeed, we've already used it: - -<tscreen><verb> -fooH :: Char -> Int -> Double -> Word -> IO Double -fooH c i d w = _ccall_ fooC (``stdin''::Addr) c i d w -</verb></tscreen> - -The first argument that's passed to @fooC@ is given as a literal-literal, -that is, a literal chunk of C code that will be inserted into the generated -@.hc@ code at the right place. - -A literal-literal is restricted to having a type that's an instance of -the @CCallable@ class, see <ref name="CCallable" id="ccall-gotchas"> -for more information. - -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. - -%************************************************************************ -%* * -<sect2>Using function headers -<label id="glasgow-foreign-headers"> -<p> -<nidx>C calls, function headers</nidx> -%* * -%************************************************************************ - -When generating C (using the @-fvia-C@ directive), one can assist the -C compiler in detecting type errors by using the @-#include@ directive -to provide @.h@ files containing function headers. - -For example, - -<tscreen><verb> -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); -</verb></tscreen> - -You can find appropriate definitions for @StgInt@, @StgForeignObj@, -etc using @gcc@ on your architecture by consulting -@ghc/includes/StgTypes.h@. The following table summarises the -relationship between Haskell types and C types. - -<tabular ca="ll"> -<bf>C type name</bf> | <bf>Haskell Type</bf> @@ -@@ -@StgChar@ | @Char#@ @@ -@StgInt@ | @Int#@ @@ -@StgWord@ | @Word#@ @@ -@StgAddr@ | @Addr#@ @@ -@StgFloat@ | @Float#@ @@ -@StgDouble@ | @Double#@ @@ - -@StgArray@ | @Array#@ @@ -@StgByteArray@ | @ByteArray#@ @@ -@StgArray@ | @MutableArray#@ @@ -@StgByteArray@ | @MutableByteArray#@ @@ - -@StgStablePtr@ | @StablePtr#@ @@ -@StgForeignObj@ | @ForeignObj#@ -</tabular> - -Note that this approach is only <em>essential</em> for returning -@float@s (or if @sizeof(int) != sizeof(int *)@ on your -architecture) but is a Good Thing for anyone who cares about writing -solid code. You're crazy not to do it. - -%************************************************************************ -%* * -<sect2>Subverting automatic unboxing with ``stable pointers'' -<label id="glasgow-stablePtrs"> -<p> -<nidx>stable pointers (Glasgow extension)</nidx> -%* * -%************************************************************************ - -The arguments of a @_ccall_@ are automatically unboxed before the -call. There are two reasons why this is usually the Right Thing to -do: - -<itemize> -<item> -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. - -<item> Boxed values are stored on the Haskell heap and may be moved -within the heap if a garbage collection occurs---that is, pointers -to boxed objects are not <em>stable</em>. -</itemize> - -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 @storeC@ and -@fetchC@, one might write: - -<tscreen><verb> -storeH :: Int -> IO () -storeH x = makeStablePtr x >>= \ stable_x -> - _ccall_ storeC stable_x - -fetchH :: IO Int -fetchH x = _ccall_ fetchC >>= \ stable_x -> - deRefStablePtr stable_x >>= \ x -> - freeStablePtr stable_x >> - return x -</verb></tscreen> - -The garbage collector will refrain from throwing a stable pointer away -until you explicitly call one of the following from C or Haskell. - -<tscreen><verb> -void freeStablePointer( StgStablePtr stablePtrToToss ) -freeStablePtr :: StablePtr a -> IO () -</verb></tscreen> - -As with the use of @free@ 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. - -And to force evaluation of the argument within @fooC@, one would -call one of the following C functions (according to type of argument). - -<tscreen><verb> -void performIO ( StgStablePtr stableIndex /* StablePtr s (IO ()) */ ); -StgInt enterInt ( StgStablePtr stableIndex /* StablePtr s Int */ ); -StgFloat enterFloat ( StgStablePtr stableIndex /* StablePtr s Float */ ); -</verb></tscreen> - -<nidx>performIO</nidx> -<nidx>enterInt</nidx> -<nidx>enterFloat</nidx> - -Note Bene: @_ccall_GC_@<nidx>_ccall_GC_</nidx> must be used if any of -these functions are used. - -%************************************************************************ -%* * -<sect2>Foreign objects: pointing outside the Haskell heap -<label id="glasgow-foreignObjs"> -<p> -<nidx>foreign objects (Glasgow extension)</nidx> -%* * -%************************************************************************ - -There are two types that @ghc@ programs can use to reference -(heap-allocated) objects outside the Haskell world: @Addr@ and -@ForeignObj@. - -If you use @Addr@, it is up to you to the programmer to arrange -allocation and deallocation of the objects. - -If you use @ForeignObj@, @ghc@'s garbage collector will call upon the -user-supplied <em>finaliser</em> 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 @ForeignObj@ is created). The finaliser function is -expressed in C, and is passed as argument the object: - -<tscreen><verb> -void foreignFinaliser ( StgForeignObj fo ) -</verb></tscreen> - -when the Haskell world can no longer access the object. Since -@ForeignObj@s only get released when a garbage collection occurs, we -provide ways of triggering a garbage collection from within C and from -within Haskell. - -<tscreen><verb> -void GarbageCollect() -performGC :: IO () -</verb></tscreen> - -More information on the programmers' interface to @ForeignObj@ can be -found in the library documentation. - -%************************************************************************ -%* * -<sect2>Avoiding monads -<label id="glasgow-avoiding-monads"> -<p> -<nidx>C calls to `pure C'</nidx> -<nidx>unsafePerformIO</nidx> -%* * -%************************************************************************ - -The @_ccall_@ construct is part of the @IO@ monad because 9 out of 10 -uses will be to call imperative functions with side effects such as -@printf@. Use of the monad ensures that these operations happen in a -predictable order in spite of laziness and compiler optimisations. - -To avoid having to be in the monad to call a C function, it is -possible to use @unsafePerformIO@, which is available from the -@IOExts@ module. There are three situations where one might like to -call a C function from outside the IO world: - -<itemize> -<item> -Calling a function with no side-effects: -<tscreen><verb> -atan2d :: Double -> Double -> Double -atan2d y x = unsafePerformIO (_ccall_ atan2d y x) - -sincosd :: Double -> (Double, Double) -sincosd x = unsafePerformIO $ do - da <- newDoubleArray (0, 1) - _casm_ ``sincosd( %0, &((double *)%1[0]), &((double *)%1[1]) );'' x da - s <- readDoubleArray da 0 - c <- readDoubleArray da 1 - return (s, c) -</verb></tscreen> - -<item> 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. - -<tscreen><verb> -empty :: EFS x -update :: EFS x -> Int -> x -> EFS x -lookup :: EFS a -> Int -> a - -empty = unsafePerformIO (_ccall_ emptyEFS) - -update a i x = unsafePerformIO $ - makeStablePtr x >>= \ stable_x -> - _ccall_ updateEFS a i stable_x - -lookup a i = unsafePerformIO $ - _ccall_ lookupEFS a i >>= \ stable_x -> - deRefStablePtr stable_x -</verb></tscreen> - -You will almost always want to use @ForeignObj@s with this. - -<item> Calling a side-effecting function even though the results will -be unpredictable. For example the @trace@ function is defined by: - -<tscreen><verb> -trace :: String -> a -> a -trace string expr - = unsafePerformIO ( - ((_ccall_ PreTraceHook sTDERR{-msg-}):: IO ()) >> - fputs sTDERR string >> - ((_ccall_ PostTraceHook sTDERR{-msg-}):: IO ()) >> - return expr ) - where - sTDERR = (``stderr'' :: Addr) -</verb></tscreen> - -(This kind of use is not highly recommended --- it is only really -useful in debugging code.) -</itemize> - -%************************************************************************ -%* * -<sect2>C-calling ``gotchas'' checklist -<label id="ccall-gotchas"> -<p> -<nidx>C call dangers</nidx> -<nidx>CCallable</nidx> -<nidx>CReturnable</nidx> -%* * -%************************************************************************ - -And some advice, too. - -<itemize> -<item> For modules that use @_ccall_@s, etc., compile with -@-fvia-C@.<nidx>-fvia-C option</nidx> You don't have to, but you should. - -Also, use the @-#include "prototypes.h"@ flag (hack) to inform the C -compiler of the fully-prototyped types of all the C functions you -call. (Section <ref name="Using function headers" -id="glasgow-foreign-headers"> says more about this...) - -This scheme is the <em>only</em> way that you will get <em>any</em> -typechecking of your @_ccall_@s. (It shouldn't be that way, but...). -GHC will pass the flag @-Wimplicit@ to gcc so that you'll get warnings -if any @_ccall_@ed functions have no prototypes. - -<item> -Try to avoid @_ccall_@s to C~functions that take @float@ -arguments or return @float@ results. Reason: if you do, you will -become entangled in (ANSI?) C's rules for when arguments/results are -promoted to @doubles@. It's a nightmare and just not worth it. -Use @doubles@ if possible. - -If you do use @floats@, check and re-check that the right thing is -happening. Perhaps compile with @-keep-hc-file-too@ and look at -the intermediate C (@.hc@ file). - -<item> The compiler uses two non-standard type-classes when -type-checking the arguments and results of @_ccall_@: the arguments -(respectively result) of @_ccall_@ must be instances of the class -@CCallable@ (respectively @CReturnable@). Both classes may be -imported from the module @CCall@, but this should only be -necessary if you want to define a new instance. (Neither class -defines any methods --- 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, - -<tscreen><verb> -f x = _ccall_ foo x -</verb></tscreen> - -is not good enough, because the compiler can't work out what type @x@ -is, nor what type the @_ccall_@ returns. You have to write, say: - -<tscreen><verb> -f :: Int -> IO Double -f x = _ccall_ foo x -</verb></tscreen> - -This table summarises the standard instances of these classes. - -% ToDo: check this table against implementation! - -<tabular ca="llll"> -<bf>Type</bf> |<bf>CCallable</bf>|<bf>CReturnable</bf> | <bf>Which is probably...</bf> @@ - -@Char@ | Yes | Yes | @unsigned char@ @@ -@Int@ | Yes | Yes | @long int@ @@ -@Word@ | Yes | Yes | @unsigned long int@ @@ -@Addr@ | Yes | Yes | @void *@ @@ -@Float@ | Yes | Yes | @float@ @@ -@Double@ | Yes | Yes | @double@ @@ -@()@ | No | Yes | @void@ @@ -@[Char]@ | Yes | No | @char *@ (null-terminated) @@ - -@Array@ | Yes | No | @unsigned long *@ @@ -@ByteArray@ | Yes | No | @unsigned long *@ @@ -@MutableArray@ | Yes | No | @unsigned long *@ @@ -@MutableByteArray@ | Yes | No | @unsigned long *@ @@ - -@State@ | Yes | Yes | nothing!@@ - -@StablePtr@ | Yes | Yes | @unsigned long *@ @@ -@ForeignObjs@ | Yes | Yes | see later @@ -</tabular> - -Actually, the @Word@ type is defined as being the same size as a -pointer on the target architecture, which is <em>probably</em> -@unsigned long int@. - -The brave and careful programmer can add their own instances of these -classes for the following types: - -<itemize> -<item> -A <em>boxed-primitive</em> type may be made an instance of both -@CCallable@ and @CReturnable@. - -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: - -<tscreen><verb> -Int -Double -data XDisplay = XDisplay Addr# -data EFS a = EFS# ForeignObj# -</verb></tscreen> - -<tscreen><verb> -instance CCallable (EFS a) -instance CReturnable (EFS a) -</verb></tscreen> - -<item> Any datatype with a single nullary constructor may be made an -instance of @CReturnable@. For example: - -<tscreen><verb> -data MyVoid = MyVoid -instance CReturnable MyVoid -</verb></tscreen> - -<item> As at version 2.09, @String@ (i.e., @[Char]@) is still -not a @CReturnable@ type. - -Also, the now-builtin type @PackedString@ is neither -@CCallable@ nor @CReturnable@. (But there are functions in -the PackedString interface to let you get at the necessary bits...) -</itemize> - -<item> The code-generator will complain if you attempt to use @%r@ in -a @_casm_@ whose result type is @IO ()@; or if you don't use @%r@ -<em>precisely</em> once for any other result type. These messages are -supposed to be helpful and catch bugs---please tell us if they wreck -your life. - -<item> If you call out to C code which may trigger the Haskell garbage -collector or create new threads (examples of this later...), then you -must use the @_ccall_GC_@<nidx>_ccall_GC_ primitive</nidx> or -@_casm_GC_@<nidx>_casm_GC_ primitive</nidx> variant of C-calls. (This -does not work with the native code generator - use @\fvia-C@.) This -stuff is hairy with a capital H! </itemize> - -<sect1> Multi-parameter type classes -<label id="multi-param-type-classes"> -<p> - -This section documents GHC's implementation of multi-paramter type -classes. There's lots of background in the paper <url name="Type -classes: exploring the design space" -url="http://www.dcs.gla.ac.uk/~simonpj/multi.ps.gz"> (Simon Peyton -Jones, Mark Jones, Erik Meijer). - -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.) - -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. - -<sect2>Types -<p> - -There are the following restrictions on the form of a qualified -type: - -<tscreen><verb> - forall tv1..tvn (c1, ...,cn) => type -</verb></tscreen> - -(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 Section <ref -name="Explicit universal quantification" -id="universal-quantification">). - -<enum> - -<item> <bf>Each universally quantified type variable -@tvi@ must be mentioned (i.e. appear free) in @type@</bf>. - -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: - -<tscreen><verb> - forall a. Eq a => Int -</verb></tscreen> - -When a value with this type was used, the constraint <tt>Eq tv</tt> -would be introduced where <tt>tv</tt> is a fresh type variable, and -(in the dictionary-translation implementation) the value would be -applied to a dictionary for <tt>Eq tv</tt>. The difficulty is that we -can never know which instance of <tt>Eq</tt> to use because we never -get any more information about <tt>tv</tt>. - -<item> <bf>Every constraint @ci@ must mention at least one of the -universally quantified type variables @tvi@</bf>. - -For example, this type is OK because <tt>C a b</tt> mentions the -universally quantified type variable <tt>b</tt>: - -<tscreen><verb> - forall a. C a b => burble -</verb></tscreen> - -The next type is illegal because the constraint <tt>Eq b</tt> does not -mention <tt>a</tt>: - -<tscreen><verb> - forall a. Eq b => burble -</verb></tscreen> - -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. - -</enum> - -These restrictions apply to all types, whether declared in a type signature -or inferred. - -Unlike Haskell 1.4, constraints in types do <bf>not</bf> have to be of -the form <em>(class type-variables)</em>. Thus, these type signatures -are perfectly OK - -<tscreen><verb> - f :: Eq (m a) => [m a] -> [m a] - g :: Eq [a] => ... -</verb></tscreen> - -This choice recovers principal types, a property that Haskell 1.4 does not have. - -<sect2>Class declarations -<p> - -<enum> - -<item> <bf>Multi-parameter type classes are permitted</bf>. For example: - -<tscreen><verb> - class Collection c a where - union :: c a -> c a -> c a - ...etc.. -</verb></tscreen> - - -<item> <bf>The class hierarchy must be acyclic</bf>. However, the definition -of "acyclic" involves only the superclass relationships. For example, -this is OK: - -<tscreen><verb> - class C a where { - op :: D b => a -> b -> b - } - - class C a => D a where { ... } -</verb></tscreen> - -Here, <tt>C</tt> is a superclass of <tt>D</tt>, but it's OK for a -class operation <tt>op</tt> of <tt>C</tt> to mention <tt>D</tt>. (It -would not be OK for <tt>D</tt> to be a superclass of <tt>C</tt>.) - -<item> <bf>There are no restrictions on the context in a class declaration -(which introduces superclasses), except that the class hierarchy must -be acyclic</bf>. So these class declarations are OK: - -<tscreen><verb> - class Functor (m k) => FiniteMap m k where - ... - - class (Monad m, Monad (t m)) => Transform t m where - lift :: m a -> (t m) a -</verb></tscreen> - -<item> <bf>In the signature of a class operation, every constraint -must mention at least one type variable that is not a class type -variable</bf>. - -Thus: - -<tscreen><verb> - class Collection c a where - mapC :: Collection c b => (a->b) -> c a -> c b -</verb></tscreen> - -is OK because the constraint <tt>(Collection a b)</tt> mentions -<tt>b</tt>, even though it also mentions the class variable -<tt>a</tt>. On the other hand: - -<tscreen><verb> - class C a where - op :: Eq a => (a,b) -> (a,b) -</verb></tscreen> - -is not OK because the constraint <tt>(Eq a)</tt> mentions on the class -type variable <tt>a</tt>, but not <tt>b</tt>. However, any such -example is easily fixed by moving the offending context up to the -superclass context: - -<tscreen><verb> - class Eq a => C a where - op ::(a,b) -> (a,b) -</verb></tscreen> - -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. - -<item> <bf>The type of each class operation must mention <em/all/ of -the class type variables</bf>. For example: - -<tscreen><verb> - class Coll s a where - empty :: s - insert :: s -> a -> s -</verb></tscreen> - -is not OK, because the type of <tt>empty</tt> doesn't mention -<tt>a</tt>. 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, <tt>Coll</tt> might be rewritten - -<tscreen><verb> - class Coll s a where - empty :: s a - insert :: s a -> a -> s a -</verb></tscreen> - -which makes the connection between the type of a collection of -<tt>a</tt>'s (namely <tt>(s a)</tt>) and the element type <tt>a</tt>. -Occasionally this really doesn't work, in which case you can split the -class like this: - -<tscreen><verb> - class CollE s where - empty :: s - - class CollE s => Coll s a where - insert :: s -> a -> s -</verb></tscreen> - -</enum> - -<sect2>Instance declarations -<p> - -<enum> - -<item> <bf>Instance declarations may not overlap</bf>. The two instance -declarations - -<tscreen><verb> - instance context1 => C type1 where ... - instance context2 => C type2 where ... -</verb></tscreen> - -"overlap" if @type1@ and @type2@ unify - -However, if you give the command line option -@-fallow-overlapping-instances@<nidx>-fallow-overlapping-instances -option</nidx> then two overlapping instance declarations are permitted -iff - -<itemize> -<item> EITHER @type1@ and @type2@ do not unify -<item> OR @type2@ is a substitution instance of @type1@ - (but not identical to @type1@) -<item> OR vice versa -</itemize> - -Notice that these rules - -<itemize> -<item> make it clear which instance decl to use - (pick the most specific one that matches) - -<item> do not mention the contexts @context1@, @context2@ - Reason: you can pick which instance decl - "matches" based on the type. -</itemize> - -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 <tt>Main</tt>. 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 <tt>Main</tt>.) - -<item> <bf>There are no restrictions on the type in an instance -<em/head/, except that at least one must not be a type variable</bf>. -The instance "head" is the bit after the "=>" in an instance decl. For -example, these are OK: - -<tscreen><verb> - instance C Int a where ... - - instance D (Int, Int) where ... - - instance E [[a]] where ... -</verb></tscreen> - -Note that instance heads <bf>may</bf> contain repeated type variables. -For example, this is OK: - -<tscreen><verb> - instance Stateful (ST s) (MutVar s) where ... -</verb></tscreen> - -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: - -<tscreen><verb> - instance C a => C a where ... -</verb></tscreen> - -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: - -<tscreen><verb> - instance C a where - op = ... -- Default -</verb></tscreen> - -Second, sometimes you might want to use the following to get the -effect of a "class synonym": - -<tscreen><verb> - class (C1 a, C2 a, C3 a) => C a where { } - - instance (C1 a, C2 a, C3 a) => C a where { } -</verb></tscreen> - -This allows you to write shorter signatures: - -<tscreen><verb> - f :: C a => ... -</verb></tscreen> - -instead of - -<tscreen><verb> - f :: (C1 a, C2 a, C3 a) => ... -</verb></tscreen> - -I'm on the lookout for a simple rule that preserves decidability while -allowing these idioms. The experimental flag -@-fallow-undecidable-instances@<nidx>-fallow-undecidable-instances -option</nidx> lifts this restriction, allowing all the types in an -instance head to be type variables. - -<item> <bf>Unlike Haskell 1.4, instance heads may use type -synonyms</bf>. As always, using a type synonym is just shorthand for -writing the RHS of the type synonym definition. For example: - -<tscreen><verb> - type Point = (Int,Int) - instance C Point where ... - instance C [Point] where ... -</verb></tscreen> - -is legal. However, if you added - -<tscreen><verb> - instance C (Int,Int) where ... -</verb></tscreen> - -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: - -<tscreen><verb> - type P a = [[a]] - instance Monad P where ... -</verb></tscreen> - -This design decision is independent of all the others, and easily -reversed, but it makes sense to me. - -<item><bf>The types in an instance-declaration <em/context/ must all -be type variables</bf>. Thus - -<tscreen><verb> - instance C a b => Eq (a,b) where ... -</verb></tscreen> - -is OK, but - -<tscreen><verb> - instance C Int b => Foo b where ... -</verb></tscreen> - -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 <tt>-fallow-undecidable-instances</tt> 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 <tt>-fcontext-stack</tt><em/N/. - -</enum> - -% ----------------------------------------------------------------------------- -<sect1>Explicit universal quantification -<label id="universal-quantification"> -<p> - -GHC now allows you to write explicitly quantified types. GHC's -syntax for this now agrees with Hugs's, namely: - -<tscreen><verb> - forall a b. (Ord a, Eq b) => a -> b -> a -</verb></tscreen> - -The context is, of course, optional. You can't use <tt>forall</tt> as -a type variable any more! - -Haskell type signatures are implicitly quantified. The <tt>forall</tt> -allows us to say exactly what this means. For example: - -<tscreen><verb> - g :: b -> b -</verb></tscreen> - -means this: - -<tscreen><verb> - g :: forall b. (b -> b) -</verb></tscreen> - -The two are treated identically. - -<sect2>Universally-quantified data type fields -<label id="univ"> -<p> - -In a <tt>data</tt> or <tt>newtype</tt> declaration one can quantify -the types of the constructor arguments. Here are several examples: - -<tscreen><verb> -data T a = T1 (forall b. b -> b -> b) a - -data MonadT m = MkMonad { return :: forall a. a -> m a, - bind :: forall a b. m a -> (a -> m b) -> m b - } - -newtype Swizzle = MkSwizzle (Ord a => [a] -> [a]) -</verb></tscreen> - -The constructors now have so-called <em/rank 2/ polymorphic -types, in which there is a for-all in the argument types.: - -<tscreen><verb> -T1 :: forall a. (forall b. b -> b -> b) -> a -> T1 a -MkMonad :: forall m. (forall a. a -> m a) - -> (forall a b. m a -> (a -> m b) -> m b) - -> MonadT m -MkSwizzle :: (Ord a => [a] -> [a]) -> Swizzle -</verb></tscreen> - -Notice that you don't need to use a <tt>forall</tt> if there's an -explicit context. For example in the first argument of the -constructor <tt>MkSwizzle</tt>, an implicit "<tt>forall a.</tt>" is -prefixed to the argument type. The implicit <tt>forall</tt> -quantifies all type variables that are not already in scope, and are -mentioned in the type quantified over. - -As for type signatures, implicit quantification happens for non-overloaded -types too. So if you write this: -<tscreen><verb> - data T a = MkT (Either a b) (b -> b) -</verb></tscreen> -it's just as if you had written this: -<tscreen><verb> - data T a = MkT (forall b. Either a b) (forall b. b -> b) -</verb></tscreen> -That is, since the type variable <tt>b</tt> isn't in scope, it's -implicitly universally quantified. (Arguably, it would be better -to <em>require</em> explicit quantification on constructor arguments -where that is what is wanted. Feedback welcomed.) - -<sect2> Construction -<p> - -You construct values of types <tt>T1, MonadT, Swizzle</tt> by applying -the constructor to suitable values, just as usual. For example, - -<tscreen><verb> -(T1 (\xy->x) 3) :: T Int - -(MkSwizzle sort) :: Swizzle -(MkSwizzle reverse) :: Swizzle - -(let r x = Just x - b m k = case m of - Just y -> k y - Nothing -> Nothing - in - MkMonad r b) :: MonadT Maybe -</verb></tscreen> - -The type of the argument can, as usual, be more general than the type -required, as <tt>(MkSwizzle reverse)</tt> shows. (<tt>reverse</tt> -does not need the <tt>Ord</tt> constraint.) - -<sect2>Pattern matching -<p> - -When you use pattern matching, the bound variables may now have -polymorphic types. For example: - -<tscreen><verb> - f :: T a -> a -> (a, Char) - f (T1 f k) x = (f k x, f 'c' 'd') - - g :: (Ord a, Ord b) => Swizzle -> [a] -> (a -> b) -> [b] - g (MkSwizzle s) xs f = s (map f (s xs)) - - h :: MonadT m -> [m a] -> m [a] - h m [] = return m [] - h m (x:xs) = bind m x $ \y -> - bind m (h m xs) $ \ys -> - return m (y:ys) -</verb></tscreen> - -In the function <tt>h</tt> we use the record selectors <tt>return</tt> -and <tt>bind</tt> to extract the polymorphic bind and return functions -from the <tt>MonadT</tt> data structure, rather than using pattern -matching. - -You cannot pattern-match against an argument that is polymorphic. -For example: -<tscreen><verb> - newtype TIM s a = TIM (ST s (Maybe a)) - - runTIM :: (forall s. TIM s a) -> Maybe a - runTIM (TIM m) = runST m -</verb></tscreen> - -Here the pattern-match fails, because you can't pattern-match against -an argument of type <tt>(forall s. TIM s a)</tt>. Instead you -must bind the variable and pattern match in the right hand side: -<tscreen><verb> - runTIM :: (forall s. TIM s a) -> Maybe a - runTIM tm = case tm of { TIM m -> runST m } -</verb></tscreen> -The <tt>tm</tt> on the right hand side is (invisibly) instantiated, like -any polymorphic value at its occurrence site, and now you can pattern-match -against it. - -<sect2>The partial-application restriction -<p> - -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: - -<tscreen><verb> - map MkSwizzle [sort, reverse] -</verb></tscreen> - -The restriction is this: <em>every subexpression of the program must -have a type that has no for-alls, except that in a function -application (f e1 ... en) the partial applications are not subject to -this rule</em>. The restriction makes type inference feasible. - -In the illegal example, the sub-expression <tt>MkSwizzle</tt> has the -polymorphic type <tt>(Ord b => [b] -> [b]) -> Swizzle</tt> and is not -a sub-expression of an enclosing application. On the other hand, this -expression is OK: - -<tscreen><verb> - map (T1 (\a b -> a)) [1,2,3] -</verb></tscreen> - -even though it involves a partial application of <tt>T1</tt>, because -the sub-expression <tt>T1 (\a b -> a)</tt> has type <tt>Int -> T -Int</tt>. - -<sect2>Type signatures -<label id="sigs"> -<p> - -Once you have data constructors with universally-quantified fields, or -constants such as <tt>runST</tt> that have rank-2 types, it isn't long -before you discover that you need more! Consider: - -<tscreen><verb> - mkTs f x y = [T1 f x, T1 f y] -</verb></tscreen> - -<tt>mkTs</tt> is a fuction that constructs some values of type -<tt>T</tt>, using some pieces passed to it. The trouble is that since -<tt>f</tt> is a function argument, Haskell assumes that it is -monomorphic, so we'll get a type error when applying <tt>T1</tt> 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 <tt>runST</tt> for exactly the same reason. -In short, it is impossible to build abstractions around functions with -rank-2 types. - -The solution is fairly clear. We provide the ability to give a rank-2 -type signature for <em>ordinary</em> functions (not only data -constructors), thus: - -<tscreen><verb> - mkTs :: (forall b. b -> b -> b) -> a -> [T a] - mkTs f x y = [T1 f x, T1 f y] -</verb></tscreen> - -This type signature tells the compiler to attribute <tt>f</tt> with -the polymorphic type <tt>(forall b. b -> b -> b)</tt> when type -checking the body of <tt>mkTs</tt>, so now the application of -<tt>T1</tt> is fine. - -There are two restrictions: - -<itemize> -<item> You can only define a rank 2 type, specified by the following -grammar: - -<tscreen><verb> - rank2type ::= [forall tyvars .] [context =>] funty - funty ::= ([forall tyvars .] [context =>] ty) -> funty - | ty - ty ::= ...current Haskell monotype syntax... -</verb></tscreen> - -Informally, the universal quantification must all be right at the beginning, -or at the top level of a function argument. - -<item> 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 "<tt>=</tt>" sign. You can't -define <tt>mkTs</tt> like this: - -<tscreen><verb> - mkTs :: (forall b. b -> b -> b) -> a -> [T a] - mkTs = \ f x y -> [T1 f x, T1 f y] -</verb></tscreen> - - -The same partial-application rule applies to ordinary functions with -rank-2 types as applied to data constructors. - -</itemize> - -% ----------------------------------------------------------------------------- -<sect1>Existentially quantified data constructors -<label id="existential-quantification"> -<p> - -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 <tt>hbc</tt> Haskell compiler for several years, and -proved very useful. Here's the idea. Consider the declaration: - -<tscreen><verb> - data Foo = forall a. MkFoo a (a -> Bool) - | Nil -</verb></tscreen> - -The data type <tt>Foo</tt> has two constructors with types: - -<tscreen><verb> - MkFoo :: forall a. a -> (a -> Bool) -> Foo - Nil :: Foo -</verb></tscreen> - -Notice that the type variable <tt>a</tt> in the type of <tt>MkFoo</tt> -does not appear in the data type itself, which is plain <tt>Foo</tt>. -For example, the following expression is fine: - -<tscreen><verb> - [MkFoo 3 even, MkFoo 'c' isUpper] :: [Foo] -</verb></tscreen> - -Here, <tt>(MkFoo 3 even)</tt> packages an integer with a function -<tt>even</tt> that maps an integer to <tt>Bool</tt>; and <tt>MkFoo 'c' -isUpper</tt> packages a character with a compatible function. These -two things are each of type <tt>Foo</tt> and can be put in a list. - -What can we do with a value of type <tt>Foo</tt>?. In particular, -what happens when we pattern-match on <tt>MkFoo</tt>? - -<tscreen><verb> - f (MkFoo val fn) = ??? -</verb></tscreen> - -Since all we know about <tt>val</tt> and <tt>fn</tt> is that they -are compatible, the only (useful) thing we can do with them is to -apply <tt>fn</tt> to <tt>val</tt> to get a boolean. For example: - -<tscreen><verb> - f :: Foo -> Bool - f (MkFoo val fn) = fn val -</verb></tscreen> - -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. - -<sect2>Why existential? -<label id="existential"> -<p> - -What has this to do with <em>existential</em> quantification? -Simply that <tt>MkFoo</tt> has the (nearly) isomorphic type - -<tscreen><verb> - MkFoo :: (exists a . (a, a -> Bool)) -> Foo -</verb></tscreen> - -But Haskell programmers can safely think of the ordinary -<em>universally</em> quantified type given above, thereby avoiding -adding a new existential quantification construct. - -<sect2>Type classes -<p> - -An easy extension (implemented in <tt>hbc</tt>) is to allow -arbitrary contexts before the constructor. For example: - -<tscreen><verb> - data Baz = forall a. Eq a => Baz1 a a - | forall b. Show b => Baz2 b (b -> b) -</verb></tscreen> - -The two constructors have the types you'd expect: - -<tscreen><verb> - Baz1 :: forall a. Eq a => a -> a -> Baz - Baz2 :: forall b. Show b => b -> (b -> b) -> Baz -</verb></tscreen> - -But when pattern matching on <tt>Baz1</tt> the matched values can be compared -for equality, and when pattern matching on <tt>Baz2</tt> the first matched -value can be converted to a string (as well as applying the function to it). -So this program is legal: - -<tscreen><verb> - f :: Baz -> String - f (Baz1 p q) | p == q = "Yes" - | otherwise = "No" - f (Baz1 v fn) = show (fn v) -</verb></tscreen> - -Operationally, in a dictionary-passing implementation, the -constructors <tt>Baz1</tt> and <tt>Baz2</tt> must store the -dictionaries for <tt>Eq</tt> and <tt>Show</tt> respectively, and -extract it on pattern matching. - -Notice the way that the syntax fits smoothly with that used for -universal quantification earlier. - -<sect2>Restrictions -<p> - -There are several restrictions on the ways in which existentially-quantified -constructors can be use. - -<itemize> - -<item> 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: - -<tscreen><verb> - f1 (MkFoo a f) = a -</verb></tscreen> - -Here, the type bound by <tt>MkFoo</tt> "escapes", because <tt>a</tt> -is the result of <tt>f1</tt>. One way to see why this is wrong is to -ask what type <tt>f1</tt> has: - -<tscreen><verb> - f1 :: Foo -> a -- Weird! -</verb></tscreen> - -What is this "<tt>a</tt>" in the result type? Clearly we don't mean -this: - -<tscreen><verb> - f1 :: forall a. Foo -> a -- Wrong! -</verb></tscreen> - -The original program is just plain wrong. Here's another sort of error - -<tscreen><verb> - f2 (Baz1 a b) (Baz1 p q) = a==q -</verb></tscreen> - -It's ok to say <tt>a==b</tt> or <tt>p==q</tt>, but -<tt>a==q</tt> is wrong because it equates the two distinct types arising -from the two <tt>Baz1</tt> constructors. - - -<item>You can't pattern-match on an existentially quantified -constructor in a <tt>let</tt> or <tt>where</tt> group of -bindings. So this is illegal: - -<tscreen><verb> - f3 x = a==b where { Baz1 a b = x } -</verb></tscreen> - -You can only pattern-match -on an existentially-quantified constructor in a <tt>case</tt> 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. - -<item>You can't use existential quantification for <tt>newtype</tt> -declarations. So this is illegal: - -<tscreen><verb> - newtype T = forall a. Ord a => MkT a -</verb></tscreen> - -Reason: a value of type <tt>T</tt> must be represented as a pair -of a dictionary for <tt>Ord t</tt> and a value of type <tt>t</tt>. -That contradicts the idea that <tt>newtype</tt> should have no -concrete representation. You can get just the same efficiency and effect -by using <tt>data</tt> instead of <tt>newtype</tt>. If there is no -overloading involved, then there is more of a case for allowing -an existentially-quantified <tt>newtype</tt>, because the <tt>data</tt> -because the <tt>data</tt> version does carry an implementation cost, -but single-field existentially quantified constructors aren't much -use. So the simple restriction (no existential stuff on <tt>newtype</tt>) -stands, unless there are convincing reasons to change it. - - -<item> You can't use <tt>deriving</tt> to define instances of a -data type with existentially quantified data constructors. - -Reason: in most cases it would not make sense. For example:# -<tscreen><verb> - data T = forall a. MkT [a] deriving( Eq ) -</verb></tscreen> -To derive <tt>Eq</tt> in the standard way we would need to have equality -between the single component of two <tt>MkT</tt> constructors: -<tscreen><verb> - instance Eq T where - (MkT a) == (MkT b) = ??? -</verb></tscreen> -But <tt>a</tt> and <tt>b</tt> 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! -</itemize> - - -<sect1> <idx/Assertions/ -<label id="sec:assertions"> -<p> - -If you want to make use of assertions in your standard Haskell code, you -could define a function like the following: - -<tscreen><verb> -assert :: Bool -> a -> a -assert False x = error "assertion failed!" -assert _ x = x -</verb></tscreen> - -which works, but gives you back a less than useful error message -- -an assertion failed, but which and where? - -One way out is to define an extended <tt/assert/ 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 <tt/assert/ was used. - -Ghc offers a helping hand here, doing all of this for you. For every -use of <tt/assert/ in the user's source: - -<tscreen><verb> -kelvinToC :: Double -> Double -kelvinToC k = assert (k >= 0.0) (k+273.15) -</verb></tscreen> - -Ghc will rewrite this to also include the source location where the -assertion was made, - -<tscreen><verb> -assert pred val ==> assertError "Main.hs|15" pred val -</verb></tscreen> - -The rewrite is only performed by the compiler when it spots -applications of <tt>Exception.assert</tt>, so you can still define and -use your own versions of <tt/assert/, should you so wish. If not, -import <tt/Exception/ to make use <tt/assert/ in your code. - -To have the compiler ignore uses of assert, use the compiler option -@-fignore-asserts@. <nidx>-fignore-asserts option</nidx> That is, -expressions of the form @assert pred e@ will be rewritten to @e@. - -Assertion failures can be caught, see the documentation for the -Hugs/GHC Exception library for information of how. - -% ----------------------------------------------------------------------------- -<sect1>Scoped Type Variables -<label id="scoped-type-variables"> -<p> - -A <em/pattern type signature/ can introduce a <em/scoped type -variable/. For example - -<tscreen><verb> -f (xs::[a]) = ys ++ ys - where - ys :: [a] - ys = reverse xs -</verb></tscreen> - -The pattern @(xs::[a])@ includes a type signature for @xs@. -This brings the type variable @a@ into scope; it scopes over -all the patterns and right hand sides for this equation for @f@. -In particular, it is in scope at the type signature for @y@. - -At ordinary type signatures, such as that for @ys@, any type variables -mentioned in the type signature <em/that are not in scope/ 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 @a@ -is in scope, it is not universally quantified, so the type of @ys@ is -the same as that of @xs@. In Haskell 98 it is not possible to declare -a type for @ys@; a major benefit of scoped type variables is that -it becomes possible to do so. - -Scoped type variables are implemented in both GHC and Hugs. Where the -implementations differ from the specification below, those differences -are noted. - -So much for the basic idea. Here are the details. - -<sect2>Scope and implicit quantification -<p> - -<itemize> -<item> 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 <em/type variables bound by the equation/. - -<item> The type variables thus brought into scope may be mentioned -in ordinary type signatures or pattern type signatures anywhere within -their scope. - -<item> In ordinary type signatures, any type variable mentioned in the -signature that is in scope is <em/not/ universally quantified. - -<item> Ordinary type signatures do not bring any new type variables -into scope (except in the type signature itself!). So this is illegal: - -<tscreen><verb> - f :: a -> a - f x = x::a -</verb></tscreen> - -It's illegal because @a@ is not in scope in the body of @f@, -so the ordinary signature @x::a@ is equivalent to @x::forall a.a@; -and that is an incorrect typing. - -<item> There is no implicit universal quantification on pattern type -signatures, nor may one write an explicit @forall@ type in a pattern -type signature. The pattern type signature is a monotype. - -<item> -The type variables in the head of a @class@ or @instance@ declaration -scope over the methods defined in the @where@ part. For example: - -<tscreen><verb> - class C a where - op :: [a] -> a - - op xs = let ys::[a] - ys = reverse xs - in - head ys -</verb></tscreen> - -(Not implemented in Hugs yet, Dec 98). -</itemize> - -<sect2>Polymorphism -<p> - -<itemize> -<item> 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. - -<tscreen><verb> - f :: [a] -> [a] - f (xs::[b]) = reverse xs -</verb></tscreen> - -<item> The function must be polymorphic in the type variables -bound by all its equations. Operationally, the type variables bound -by one equation must not: - -<itemize> -<item> Be unified with a type (such as @Int@, or @[a]@). -<item> Be unified with a type variable free in the environment. -<item> Be unified with each other. (They may unify with the type variables -bound by another equation for the same function, of course.) -</itemize> - -For example, the following all fail to type check: - -<tscreen><verb> - 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] -> [b] - w (x::a) = x -- a unifies with [b] -</verb></tscreen> - -<item> The pattern-bound type variable may, however, be constrained -by the context of the principal type, thus: - -<tscreen><verb> - f (x::a) (y::a) = x+y*2 -</verb></tscreen> - -gets the inferred type: @forall a. Num a => a -> a -> a@. -</itemize> - -<sect2>Result type signatures -<p> - -<itemize> -<item> The result type of a function can be given a signature, -thus: - -<tscreen><verb> - f (x::a) :: [a] = [x,x,x] -</verb></tscreen> - -The final @":: [a]"@ after all the patterns gives a signature to the -result type. Sometimes this is the only way of naming the type variable -you want: - -<tscreen><verb> - f :: Int -> [a] -> [a] - f n :: ([a] -> [a]) = let g (x::a, y::a) = (y,x) - in \xs -> map g (reverse xs `zip` xs) -</verb></tscreen> - -</itemize> - -Result type signatures are not yet implemented in Hugs. - -<sect2>Pattern signatures on other constructs -<p> - -<itemize> -<item> A pattern type signature can be on an arbitrary sub-pattern, not -just on a variable: - -<tscreen><verb> - f ((x,y)::(a,b)) = (y,x) :: (b,a) -</verb></tscreen> - -<item> Pattern type signatures, including the result part, can be used -in lambda abstractions: - -<tscreen><verb> - (\ (x::a, y) :: a -> x) -</verb></tscreen> - -Type variables bound by these patterns must be polymorphic in -the sense defined above. -For example: - -<tscreen><verb> - f1 (x::c) = f1 x -- ok - f2 = \(x::c) -> f2 x -- not ok -</verb></tscreen> - -Here, @f1@ is OK, but @f2@ is not, because @c@ gets unified -with a type variable free in the environment, in this -case, the type of @f2@, which is in the environment when -the lambda abstraction is checked. - -<item> Pattern type signatures, including the result part, can be used -in @case@ expressions: - -<tscreen><verb> - case e of { (x::a, y) :: a -> x } -</verb></tscreen> - -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: - -<tscreen><verb> - case (True,False) of { (x::a, y) -> x } -</verb></tscreen> - -Even though the context is that of a pair of booleans, -the alternative itself is polymorphic. Of course, it is -also OK to say: - -<tscreen><verb> - case (True,False) of { (x::Bool, y) -> x } -</verb></tscreen> - -<item> -To avoid ambiguity, the type after the ``@::@'' in a result -pattern signature on a lambda or @case@ must be atomic (i.e. a single -token or a parenthesised type of some sort). To see why, -consider how one would parse this: - -<tscreen><verb> - \ x :: a -> b -> x -</verb></tscreen> - -<item> Pattern type signatures that bind new type variables -may not be used in pattern bindings at all. -So this is illegal: - -<tscreen><verb> - f x = let (y, z::a) = x in ... -</verb></tscreen> - -But these are OK, because they do not bind fresh type variables: - -<tscreen><verb> - f1 x = let (y, z::Int) = x in ... - f2 (x::(Int,a)) = let (y, z::a) = x in ... -</verb></tscreen> - -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: - -<tscreen><verb> - f :: (b->b) = \(x::b) -> x -</verb></tscreen> - -</itemize> -Such degnerate function bindings do not fall under the monomorphism -restriction. Thus: - -<tscreen><verb> - g :: a -> a -> Bool = \x y. x==y -</verb></tscreen> - -Here @g@ has type @forall a. Eq a => a -> a -> Bool@, just as if -@g@ had a separate type signature. Lacking a type signature, @g@ -would get a monomorphic type. - -<sect2>Existentials -<p> - -<itemize> -<item> Pattern type signatures can bind existential type variables. -For example: - -<tscreen><verb> - data T = forall a. MkT [a] - - f :: T -> T - f (MkT [t::a]) = MkT t3 - where - t3::[a] = [t,t,t] -</verb></tscreen> - -</itemize> - -%----------------------------------------------------------------------------- -<sect1>Pragmas -<label id="pragmas"> -<p> - -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. - -<sect2>INLINE pragma -<label id="inline-pragma"> -<nidx>INLINE pragma</nidx> -<nidx>pragma, INLINE</nidx> -<p> - -GHC (with @-O@, 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. - -You will probably see these unfoldings (in Core syntax) in your -interface files. - -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. - -The sledgehammer you can bring to bear is the -@INLINE@<nidx>INLINE pragma</nidx> pragma, used thusly: -<tscreen><verb> -key_function :: Int -> String -> (Bool, Double) - -#ifdef __GLASGOW_HASKELL__ -{-# INLINE key_function #-} -#endif -</verb></tscreen> -(You don't need to do the C pre-processor carry-on unless you're going -to stick the code through HBC---it doesn't like @INLINE@ pragmas.) - -The major effect of an @INLINE@ pragma is to declare a function's -``cost'' to be very low. The normal unfolding machinery will then be -very keen to inline it. - -An @INLINE@ pragma for a function can be put anywhere its type -signature could be put. - -@INLINE@ pragmas are a particularly good idea for the -@then@/@return@ (or @bind@/@unit@) functions in a monad. -For example, in GHC's own @UniqueSupply@ monad code, we have: -<tscreen><verb> -#ifdef __GLASGOW_HASKELL__ -{-# INLINE thenUs #-} -{-# INLINE returnUs #-} -#endif -</verb></tscreen> - -<sect2>NOINLINE pragma -<label id="noinline-pragma"> -<p> -<nidx>NOINLINE pragma</nidx> -<nidx>pragma, NOINLINE</nidx> - -The @NOINLINE@ 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. - -<sect2>SPECIALIZE pragma -<label id="specialize-pragma"> -<p> -<nidx>SPECIALIZE pragma</nidx> -<nidx>pragma, SPECIALIZE</nidx> -<nidx>overloading, death to</nidx> - -(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: - -<tscreen><verb> -hammeredLookup :: Ord key => [(key, value)] -> key -> value -</verb></tscreen> - -If it is heavily used on lists with @Widget@ keys, you could -specialise it as follows: -<tscreen><verb> -{-# SPECIALIZE hammeredLookup :: [(Widget, value)] -> Widget -> value #-} -</verb></tscreen> - -To get very fancy, you can also specify a named function to use for -the specialised value, by adding @= blah@, as in: -<tscreen><verb> -{-# SPECIALIZE hammeredLookup :: ...as before... = blah #-} -</verb></tscreen> -It's <em>Your Responsibility</em> to make sure that @blah@ really -behaves as a specialised version of @hammeredLookup@!!! - -NOTE: the @=blah@ feature isn't implemented in GHC 4.xx. - -An example in which the @= blah@ form will Win Big: -<tscreen><verb> -toDouble :: Real a => a -> Double -toDouble = fromRational . toRational - -{-# SPECIALIZE toDouble :: Int -> Double = i2d #-} -i2d (I# i) = D# (int2Double# i) -- uses Glasgow prim-op directly -</verb></tscreen> -The @i2d@ function is virtually one machine instruction; the -default conversion---via an intermediate @Rational@---is obscenely -expensive by comparison. - -By using the US spelling, your @SPECIALIZE@ pragma will work with -HBC, too. Note that HBC doesn't support the @= blah@ form. - -A @SPECIALIZE@ pragma for a function can be put anywhere its type -signature could be put. - -<sect2>SPECIALIZE instance pragma -<label id="specialize-instance-pragma"> -<p> -<nidx>SPECIALIZE pragma</nidx> -<nidx>overloading, death to</nidx> -Same idea, except for instance declarations. For example: -<tscreen><verb> -instance (Eq a) => Eq (Foo a) where { ... usual stuff ... } - -{-# SPECIALIZE instance Eq (Foo [(Int, Bar)] #-} -</verb></tscreen> -Compatible with HBC, by the way. - -<sect2>LINE pragma -<label id="line-pragma"> -<p> -<nidx>LINE pragma</nidx> -<nidx>pragma, LINE</nidx> - -This pragma is similar to C's @#line@ 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 - -<tscreen><verb> -{-# LINE 42 "Foo.vhs" #-} -</verb></tscreen> - -if you'd generated the current file from something called @Foo.vhs@ -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 @LINE@ -pragma. - -<sect2>RULES pragma -<p> -The RULES pragma lets you specify rewrite rules. It is described in -Section <ref name="Rewrite Rules" -id="rewrite-rules">. - -%----------------------------------------------------------------------------- -<sect1>Rewrite rules -<label id="rewrite-rules"> -<nidx>RULES pagma</nidx> -<nidx>pragma, RULES</nidx> -<nidx>rewrite rules</nidx> -<p> - -The programmer can specify rewrite rules as part of the source program -(in a pragma). GHC applies these rewrite rules wherever it can. - -Here is an example: -<tscreen><verb> - {-# RULES - "map/map" forall f g xs. map f (map g xs) = map (f.g) xs - #-} -</verb></tscreen> - -<sect2>Syntax -<p> - -From a syntactic point of view: -<itemize> -<item> 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. -<item> There may be zero or more rules in a @RULES@ pragma. -<item> Layout applies in a @RULES@ pragma. Currently no new indentation level -is set, so you must lay out your rules starting in the same column as the -enclosing definitions. -<item> Each variable mentioned in a rule must either be in scope (e.g. @map@), -or bound by the @forall@ (e.g. @f@, @g@, @xs@). The variables bound by -the @forall@ are called the <em>pattern</em> variables. They are separated -by spaces, just like in a type @forall@. -<item> A pattern variable may optionally have a type signature. -If the type of the pattern variable is polymorphic, it <em>must</em> have a type signature. -For example, here is the @foldr/build@ rule: -<tscreen><verb> - "fold/build" forall k z (g::forall b. (a->b->b) -> b -> b) . - foldr k z (build g) = g k z -</verb></tscreen> -Since @g@ has a polymorphic type, it must have a type signature. - -<item> The left hand side of a rule must consist of a top-level variable applied -to arbitrary expressions. For example, this is <em>not</em> OK: -<tscreen><verb> - "wrong1" forall e1 e2. case True of { True -> e1; False -> e2 } = e1 - "wrong2" forall f. f True = True -</verb></tscreen> -In @"wrong1"@, the LHS is not an application; in @"wrong1"@, the LHS has a pattern variable -in the head. -<item> 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. -<item> Rules are automatically exported from a module, just as instance declarations are. -</itemize> - -<sect2>Semantics -<p> - -From a semantic point of view: -<itemize> -<item> Rules are only applied if you use the @-O@ flag. - -<item> 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. - -<item> The LHS and RHS of a rule are typechecked, and must have the -same type. - -<item> 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! - -<item> GHC makes no attempt to make sure that the rules are confluent or -terminating. For example: -<tscreen><verb> - "loop" forall x,y. f x y = f y x -</verb></tscreen> -This rule will cause the compiler to go into an infinite loop. - -<item> If more than one rule matches a call, GHC will choose one arbitrarily to apply. - -<item> 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). -<p> -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 Section <ref name="Specialisation" id="rule-spec"> below. - -<item> GHC keeps trying to apply the rules as it optimises the program. -For example, consider: -<tscreen><verb> - let s = map f - t = map g - in - s (t xs) -</verb></tscreen> -The expression @s (t xs)@ does not match the rule @"map/map"@, but GHC -will substitute for @s@ and @t@, giving an expression which does match. -If @s@ or @t@ was (a) used more than once, and (b) large or a redex, then it would -not be substituted, and the rule would not fire. - -<item> In the earlier phases of compilation, GHC inlines <em>nothing -that appears on the LHS of a rule</em>, because once you have substituted -for something you can't match against it (given the simple minded -matching). So if you write the rule -<tscreen><verb> - "map/map" forall f,g. map f . map g = map (f.g) -</verb></tscreen> -this <em>won't</em> match the expression @map f (map g xs)@. -It will only match something written with explicit use of ".". -Well, not quite. It <em>will</em> match the expression -<tscreen><verb> - wibble f g xs -</verb></tscreen> -where @wibble@ is defined: -<tscreen><verb> - wibble f g = map f . map g -</verb></tscreen> -because @wibble@ 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 @-finline-phase@n. - -<item> 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. -</itemize> - -<sect2>List fusion -<p> - -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. -<p> -The following are good producers: -<itemize> -<item> List comprehensions -<item> Enumerations of @Int@ and @Char@ (e.g. @['a'..'z']@). -<item> Explicit lists (e.g. @[True, False]@) -<item> The cons constructor (e.g @3:4:[]@) -<item> @++@ -<item> @map@ -<item> @filter@ -<item> @iterate@, @repeat@ -<item> @zip@, @zipWith@ -</itemize> - -The following are good consumers: -<itemize> -<item> List comprehensions -<item> @array@ (on its second argument) -<item> @length@ -<item> @++@ (on its first argument) -<item> @map@ -<item> @filter@ -<item> @concat@ -<item> @unzip@, @unzip2@, @unzip3@, @unzip4@ -<item> @zip@, @zipWith@ (but on one argument only; if both are good producers, @zip@ -will fuse with one but not the other) -<item> @partition@ -<item> @head@ -<item> @and@, @or@, @any@, @all@ -<item> @sequence_@ -<item> @msum@ -<item> @sortBy@ -</itemize> - -So, for example, the following should generate no intermediate lists: -<tscreen><verb> - array (1,10) [(i,i*i) | i <- map (+ 1) [0..9]] -</verb></tscreen> - -This list could readily be extended; if there are Prelude functions that you use -a lot which are not included, please tell us. -<p> -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. - -<sect2>Specialisation -<label id="rule-spec"> -<p> - -Rewrite rules can be used to get the same effect as a feature -present in earlier version of GHC: -<tscreen><verb> - {-# SPECIALIZE fromIntegral :: Int8 -> Int16 = int8ToInt16 #-} -</verb></tscreen> -This told GHC to use @int8ToInt16@ instead of @fromIntegral@ whenever -the latter was called with type @Int8 -> Int16@. That is, rather than -specialising the original definition of @fromIntegral@ the programmer is -promising that it is safe to use @int8ToInt16@ instead. - -This feature is no longer in GHC. But rewrite rules let you do the -same thing: -<tscreen><verb> - {-# RULES - "fromIntegral/Int8/Int16" fromIntegral = int8ToInt16 - #-} -</verb></tscreen> -This slightly odd-looking rule instructs GHC to replace @fromIntegral@ -by @int8ToInt16@ <em>whenever the types match</em>. Speaking more operationally, -GHC adds the type and dictionary applications to get the typed rule -<tscreen><verb> - forall (d1::Integral Int8) (d2::Num Int16) . - fromIntegral Int8 Int16 d1 d2 = int8ToInt16 -</verb></tscreen> -What is more, -this rule does not need to be in the same file as fromIntegral, -unlike the @SPECIALISE@ pragmas which currently do (so that they -have an original definition available to specialise). - -<sect2>Controlling what's going on -<p> - -<itemize> -<item> Use @-ddump-rules@ to see what transformation rules GHC is using. -<item> Use @-ddump-simpl-stats@ to see what rules are being fired. -If you add @-dppr-debug@ you get a more detailed listing. -<item> The defintion of (say) @build@ in @PrelBase.lhs@ looks llike this: -<tscreen><verb> - build :: forall a. (forall b. (a -> b -> b) -> b -> b) -> [a] - {-# INLINE build #-} - build g = g (:) [] -</verb></tscreen> -Notice the @INLINE@! That prevents @(:)@ from being inlined when compiling -@PrelBase@, so that an importing module will ``see'' the @(:)@, and can -match it on the LHS of a rule. @INLINE@ prevents any inlining happening -in the RHS of the @INLINE@ thing. I regret the delicacy of this. - -<item> In @ghc/lib/std/PrelBase.lhs@ look at the rules for @map@ 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 @PrelList.lhs@. -</itemize> - - -%----------------------------------------------------------------------------- -<sect1>Pattern guards -<label id="pattern-guards"> -<p> -GHC supports the ``pattern-guards'' extension to -the guards that form part of Haskell function -definitions. The general aim is similar to that of views [1,2], -but the expressive power of this proposal is a little different, in places -more expressive than views, and in places less so. - -<sect2>What's the problem? -<p> -Consider the following Haskell function definition -<tscreen><verb> - filter p [] = [] - filter p (y:ys) | p y = y : filter p ys - | otherwise = filter p ys -</verb></tscreen> - -<p>The decision of which right-hand side to choose is made in -two stages: first, pattern matching selects a guarded group, -and second, the boolean-valued guards select among the right-hand -sides of the group. In these two stages, only the pattern-matching -stage can bind variables. A guard is simply a boolean valued expression. - -<p>So pattern-matching combines selection with binding, whereas guards simply -perform selection. Sometimes this is a tremendous nuisance. For example, -suppose we have an abstract data type of finite maps, with a lookup -operation: -<tscreen><verb> - lookup :: FinteMap -> Int -> Maybe Int -</verb></tscreen> - -<p>The lookup returns Nothing if the supplied key is not in the -domain of the mapping, and (Just v) otherwise, where v is -the value that the key maps to. Now consider the following -definition: -<tscreen><verb> - clunky env var1 var2 | ok1 && ok2 = val1 + val2 - | otherwise = var1 + var2 - where - m1 = lookup env var1 - m2 = lookup env var2 - ok1 = maybeToBool m1 - ok2 = maybeToBool m2 - val1 = expectJust m1 - val2 = expectJust m2 -</verb></tscreen> -The auxiliary functions are -<tscreen><verb> - maybeToBool :: Maybe a -> Bool - maybeToBool (Just x) = True - maybeToBool Nothing = False - - expectJust :: Maybe a -> a - expectJust (Just x) = x - expectJust Nothing = error "Unexpected Nothing" -</verb></tscreen> -<p>What is <tt>clunky</tt> doing? The guard <tt>ok1 && ok2</tt> checks that both -lookups succeed, using <tt>maybeToBool</tt> to convert the maybe types to -booleans. The (lazily evaluated) <tt>expectJust</tt> calls extract the values -from the results of the lookups, and binds the returned values to -<tt>val1</tt> and <tt>val2</tt> respectively. If either lookup fails, then <tt>clunky</tt> -takes the <tt>otherwise</tt> case and returns the sum of its arguments. - -<p>This is certainly legal Haskell, but it is a tremendously verbose -and un-obvious way to achieve the desired effect. Arguably, a more -direct way to write <tt>clunky</tt> would be to use case expressions: -<tscreen><verb> - clunky env var1 var1 = case lookup env var1 of - Nothing -> fail - Just val1 -> case lookup env var2 of - Nothing -> fail - Just val2 -> val1 + val2 - where - fail = val1 + val2 -</verb></tscreen> -<p>This is a bit shorter, but hardly better. Of course, we can rewrite -any set of pattern-matching, guarded equations as case expressions; -that is precisely what the compiler does when compiling equations! -The reason that Haskell provides guarded equations is because they -allow us to write down the cases we want to consider, one at a time, -independently of each other. This structure is hidden in the case -version. Two of the right-hand sides are really the same (<tt>fail</tt>), -and the whole expression tends to become more and more indented. - -<p>Worse, if this was just one equation of <tt>clunky</tt>, with others that -follow, then the thing wouldn't work at all. That is, suppose we have -<tscreen><verb> - clunky' env (var1:var2:vars) | ok1 && ok2 = val1 + val2 - where - m1 = lookup env var1 - ...as before... - - clunky' env [var1] = ...some stuff... - clunky' env [] = ...more stuff... -</verb></tscreen> -Now, if either the lookups fail we want to fall through to the second -and third equations for <tt>clunky'</tt>. If we write the definition in the -form of a case expression we are forced to make the latter two -equations for <tt>clunky'</tt> into a separate definition and call it in -the right hand side of <tt>fail</tt>. Ugh. Ugh. Ugh. This is precisely -why Haskell provides guards at all, rather than relying on if-then-else -expressions: if the guard fails we fall through to the next equation, -whereas we can't do that with a conditional. - - -<p>What is frustrating about this is that the solution is so tantalisingly -near at hand! What we want to do is to pattern-match on the result of -the lookup. We can do it like this: -<tscreen><verb> - clunky' env vars@(var1:var2:vars) - = clunky_help (lookup env var1) (lookup env var2) vars - where - clunky_help (Just val1) (Just val2) vars = val1 + val2 - clunky_help _ _ [var1] = ...some stuff... - clunky_help _ _ [] = ...more stuff... -</verb></tscreen> -<p>Now we do get three equations, one for each right-hand side, but -it is still clunky. In a big set of equations it becomes hard to -remember what each <tt>Just</tt> pattern corresponds to. Worse, we can't -use one lookup in the next. For example, suppose our function was -like this: -<tscreen><verb> - clunky'' env var1 var2 - | ok1 && ok2 = val2 - | otherwise = var1 + var2 - where - m1 = lookup env var1 - m2 = lookup env (var2 + val1) - ok1 = maybeToBool m1 - ok2 = maybeToBool m2 - val1 = expectJust m1 - val2 = expectJust m2 -</verb></tscreen> -<p>Notice that the second lookup uses val1, the result of the first lookup. -To express this with a <tt>clunky_help</tt> function requires a second helper -function nested inside the first. Dire stuff. - -<p>So the original definition, using <tt>maybeToBool</tt> and <tt>expectJust</tt> has the -merit that it scales nicely, to accommodate both multiple equations -and successive lookups. Yet it stinks. - - -<sect2>The pattern guards extension -<p> -The extension that GHC implements is simple: -<em>instead of being a boolean expression, -a guard is a list of qualifiers, -exactly as in a list comprehension</em>. - -<p>That is, the only syntax change is to replace -<em>exp</em> by <em>quals</em> in the syntax of guarded equations. - -<p>Here is how you can now write <tt>clunky</tt>: -<tscreen><verb> - clunky env var1 var1 - | Just val1 <- lookup env var1 - , Just val2 <- lookup env var2 - = val1 + val2 - ...other equations for clunky... -</verb></tscreen> -<p>The semantics should be clear enough. The qualifers are matched in -order. For a <tt><-</tt> qualifier, which I call a <em>pattern guard</em>, the -right hand side is evaluated and matched against the pattern on the -left. If the match fails then the whole guard fails and the next -equation is tried. If it succeeds, then the appropriate binding takes -place, and the next qualifier is matched, in the augmented -environment. Unlike list comprehensions, however, the type of the -expression to the right of the <tt><-</tt> is the same as the type of the -pattern to its left. The bindings introduced by pattern guards scope -over all the remaining guard qualifiers, and over the right hand side -of the equation. - -<p>Just as with list comprehensions, boolean expressions can be freely mixed -with among the pattern guards. For example: -<tscreen><verb> - f x | [y] <- x - , y > 3 - , Just z <- h y - = ... -</verb></tscreen> -<p>Haskell's current guards therefore emerge as a special case, in which the -qualifier list has just one element, a boolean expression. - -<p>Just as with list comprehensions, a <tt>let</tt> qualifier can introduce a binding. -It is also possible to do this with pattern guard with a simple -variable pattern <tt>a <- e</tt> -However a <tt>let</tt> qualifier is a little more powerful, because it can -introduce a recursive or mutually-recursive binding. It is not clear -whether this power is particularly useful, but it seems more uniform to -have exactly the same syntax as list comprehensions. - -<p>One could argue that the notation <tt><-</tt> is misleading, suggesting -the idea of <em>drawn from</em> as in a list comprehension. But it's very -nice to reuse precisely the list-comprehension syntax. Furthermore, -the only viable alternative is <tt>=</tt>, and that would lead to parsing -difficulties, because we rely on the <tt>=</tt> to herald the arrival of -the right-hand side of the equation. Consider <tt>f x | y = h x = 3</tt>. - -<sect2>Views - -<p>One very useful application of pattern guards is to abstract data types. -Given an abstract data type it's quite common to have conditional -selectors. For example: -<tscreen><verb> - addressMaybe :: Person -> Maybe String -</verb></tscreen> -<p>The function <tt>addressMaybe</tt> extracts a string from the abstract data type -<tt>Person</tt>, but returns <tt>Nothing</tt> if the person has no address. Inside -GHC we have lots of functions like: -<tscreen><verb> - getFunTyMaybe :: Type -> Maybe (Type,Type) -</verb></tscreen> -<p>This returns <tt>Nothing</tt> if the argument is not a function type, and -<tt>(Just arg_ty res_ty)</tt> if the argument is a function type. The data -type <tt>Type</tt> is abstract. - -<p>Since <tt>Type</tt> and <tt>Person</tt> are abstract we can't pattern-match on them, -but it's really nice to be able to say: -<tscreen><verb> - f person | Just address <- addressMaybe person - = ... - | otherwise - = ... -</verb></tscreen> -<p>Thus, pattern guards can be seen as addressing a similar goal to -that of views, namely reconciling pattern matching with data abstraction. -Views were proposed by Wadler ages ago [1], and are the subject of a -recent concrete proposal for a Haskell language extension [2]. - -<p>It is natural to ask whether views subsume pattern guards or vice versa. -The answer is "neither". - -<sect3>Do views subsume pattern guards? - -<p>The views proposal [2] points out that you can use views to simulate -(some) guards and, as we saw above, views have similar purpose and -functionality to at least some applications of pattern guards. - -<p>However, views give a view on a <em>single</em> value, whereas guards allow -arbitrary function calls to combine in-scope values. For example, -<tt>clunky</tt> matches <tt>(Just val1)</tt> against <tt>(lookup env var1)</tt>. We do not want a -view of <tt>env</tt> nor of <tt>var1</tt> but rather of their combination by -<tt>lookup</tt>. Views simply do not help with <tt>clunky</tt>. - -<p>Views are capable of dealing with the data abstraction issue of -course. However, each conditional selector (such as <tt>getFunTyMaybe</tt>) -would require its own view, complete with its own viewtype: -<tscreen><verb> - view FunType of Type = FunType Type Type - | NotFunType - where - funType (Fun arg res) = FunType arg res - funType other_type = NotFunType -</verb></tscreen> -This seems a bit heavyweight (three new names instead of one) -compared with -<tscreen><verb> - getFunTypeMaybe (Fun arg res) = Just (arg,res) - getFunTypeMaybe other_type = Nothing -</verb></tscreen> -<p>Here we can re-use the existing <tt>Maybe</tt> type. Not only does this -save defining new types, but it allows the existing library of -functions on <tt>Maybe</tt> types to be applied directly to the result -of <tt>getFunTypeMaybe</tt>. - -<p>Just to put this point another way, suppose we had a function -<tscreen><verb> - tyvarsOf :: Type -> [TyVar] -</verb></tscreen> -that returns the free type variables of a type. -Would anyone suggest that we make this into a view of <tt>Type</tt>? -<tscreen><verb> - view TyVarsOf of Type = TyVarsOf [TyVar] - where - tyVarsOf ty = ... -</verb></tscreen> -Now we could write -<tscreen><verb> - f :: Type -> Int - f (TyVarsOf tyvars) = length tyvars -</verb></tscreen> -instead of -<tscreen><verb> - f :: Type -> Int - f ty = length (tyvarsOf ty) -</verb></tscreen> -Surely not! So why do so just because the value returned is a <tt>Maybe</tt> type? - -<sect3>Do pattern guards subsume views? - -<p>There are two ways in which views might be desired even if you -had pattern guards:<p> -<itemize> -<item> -We might prefer to write (using views) -<tscreen><verb> - addCpx (Rect r1 i1) (Rect r1 i2) = rect (r1+r2) (c1+c2) -</verb></tscreen> -rather than (using pattern guards) -<tscreen><verb> - addCpx c1 c2 - | Rect r1 i1 <- getRect c1 - , Rect r1 i2 <- getRect c2 - = mkRect (r1+r2) (c1+c2) -</verb></tscreen>(One might argue, though, that the latter accurately indicates that there may be some work involved in matching against a view, compared to ordinary pattern matching.) -</item> -<item> -The pattern-guard notation gets a bit more clunky if we want a view that has more than one information-carrying constructor. For example, consider the following view: -<tscreen><verb> - view AbsInt of Int = Pos Int | Neg Int - where - absInt n = if n>=0 then Pos n else Neg (-n) -</verb></tscreen> -Here the view returns a Pos or Neg constructor, each of which contains the absolute value of the original Int. Now we can say -<tscreen><verb> - f (Pos n) = n+1 - f (Neg n) = n-1 -</verb></tscreen> -Then <tt>f 4 = 5</tt>, <tt>f (-3) = -4</tt>. - -Without views, but with pattern guards, we could write this: -<tscreen><verb> - data AbsInt = Pos Int | Neg Int - absInt n = if n>=0 then Pos n else Neg n - - f n | Pos n' <- abs_n = n'+1 - | Neg n' <- abs_n = n'-1 - where - abs_n = absInt n -</verb></tscreen> -<p>Here we've used a where clause to ensure that <tt>absInt</tt> is only called once (though we could instead duplicate the call to <tt>absInt</tt> and hope the compile spots the common subexpression). - -<p>The view version is undoubtedly more compact. (Again, one might wonder, though, whether it perhaps conceals too much.) -</item> -<item> -When nested pattern guards are used, though, the use of a where clause fails. For example, consider the following silly function using the <tt>AbsInt</tt> view -<tscreen><verb> - g (Pos (Pos n)) = n+1 - g (Pos (Neg n)) = n-1 -- A bit silly -</verb></tscreen> -Without views we have to write -<tscreen><verb> - g n | n1 <- abs_n - , Pos n2 <- absInt n1 - = n2+1 - | Pos n1 <- abs_n - , Neg n2 <- absInt n1 - = n2-1 - where - abs_n = absInt n -</verb></tscreen> -<p>We can share the first call to <tt>absInt</tt> but not the second. This is a compilation issue. Just as we might hope that the compiler would spot the common sub-expression if we replaced <tt>abs_n by (absInt n)</tt>, so we might hope that it would optimise the second. -The views optimisation seems more simple to spot, somehow. -</item> -</itemize> - -<sect3>Views --- summary -<p> -My gut feel at the moment is that the pattern-guard proposal -<itemize> -<item>is much simpler to specify and implement than views -<item> gets some expressiveness that is simply inaccessible to views. -<item>successfully reconciles pattern matching with data abstraction, -albeit with a slightly less compact notation than views -- -but the extra notation carries useful clues -<item>is less heavyweight to use when defining many information -extraction functions over an ADT -</itemize> -So I think the case for pattern guards is stronger than that for views, -and (if implemented) reduces, without eliminating, the need for views. - -<sect2>Argument evaluation order - -<p>Haskell specifies that patterns are evaluated left to right. Thus -<tscreen><verb> - f (x:xs) (y:ys) = ... - f xs ys = ... -</verb></tscreen> -Here, the first argument is evaluated and matched against <tt>(x:xs)</tt> and -then the second argument is evaluated and matched against <tt>(y:ys)</tt>. -If you want to match the second argument first --- a significant change -since it changes the semantics of the function --- you are out of luck. -You must either change the order of the arguments, or use case expressions -instead. - -<p>With pattern guards you can say what you want, without changing the -argument order: -<tscreen><verb> - f xs ys | (y:ys) <- ys - (x:xs) <- xs - = ... - f xs ys = ... -</verb></tscreen> -(Since a pattern guard is a non recursive binding I have shadowed -xs and ys, just to remind us that it's OK to do so.) - -<p>I can't say that this is a very important feature in practice, but -it's worth noting. - -<sect2>References - -<p>[1] P Wadler, "Views: a way for pattern matching to cohabit with -data abstraction", POPL 14 (1987), 307-313 - -<p>[2] W Burton, E Meijer, P Sansom, S Thompson, P Wadler, "A (sic) extension -to Haskell 1.3 for views", sent to the Haskell mailing list -23 Oct 1996 diff --git a/ghc/docs/users_guide/gone_wrong.vsgml b/ghc/docs/users_guide/gone_wrong.vsgml deleted file mode 100644 index df056931fb7f7a3d37727ad6cade4ec874924483..0000000000000000000000000000000000000000 --- a/ghc/docs/users_guide/gone_wrong.vsgml +++ /dev/null @@ -1,291 +0,0 @@ -%************************************************************************ -%* * -<sect>What to do when something goes wrong -<label id="wrong"> -<p> -<nidx>problems</nidx> -%* * -%************************************************************************ - -If you still have a problem after consulting this section, then you -may have found a <em>bug</em>---please report it! See Section <ref -name="How to report a bug in the GHC system" id="bug-reports"> for a -list of things we'd like to know about your bug. If in doubt, send a -report---we love mail from irate users :-! - -(Section <ref name="Haskell 98 vs. Glasgow Haskell: language -non-compliance" id="vs-Haskell-defn">, which describes Glasgow -Haskell's shortcomings vs.~the Haskell language definition, may also -be of interest.) - -%************************************************************************ -%* * -<sect1>When the compiler ``does the wrong thing'' -<label id="wrong-compiler"> -<p> -<nidx>compiler problems</nidx> -<nidx>problems with the compiler</nidx> -%* * -%************************************************************************ - -<descrip> -%------------------------------------------------------------------- -<tag>``Help! The compiler crashed (or `panic'd)!''</tag> -These events are <em>always</em> bugs in the GHC system---please report -them. - -%------------------------------------------------------------------- -<tag>``The compiler ran out of heap (or stack) when compiling itself!''</tag> -It happens. We try to supply reasonable @-H<n>@ flags for -@ghc/compiler/@ and @ghc/lib/@, but GHC's memory consumption -can vary by platform (e.g., on a 64-bit machine). - -Just say @make all EXTRA_HC_OPTS=-H<a reasonable number>@ and see -how you get along. - -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. - -%------------------------------------------------------------------- -<tag>``The compiler died with a pattern-matching error.''</tag> -This is a bug just as surely as a ``panic.'' Please report it. - -%------------------------------------------------------------------- -<tag>``This is a terrible error message.''</tag> -If you think that GHC could have produced a better error message, -please report it as a bug. - -%------------------------------------------------------------------- -<tag>``What about these `trace' messages from GHC?''</tag> -Almost surely not a problem. About some specific cases... -<descrip> -<tag>Simplifier still going after N iterations:</tag> -Sad, but harmless. You can change the number with a -@-fmax-simplifier-iterations<N>@<nidx>-fmax-simplifier-iterations<N> option</nidx> option (no space); -and you can see what actions took place in each iteration by -turning on the @-fshow-simplifier-progress@ -<nidx>-fshow-simplifier-progress option</nidx> option. - -If the simplifier definitely seems to be ``looping,'' please report -it. -</descrip> - -%------------------------------------------------------------------- -<tag>``What about this warning from the C compiler?''</tag> - -For example: ``...warning: `Foo' declared `static' but never defined.'' -Unsightly, but shouldn't be a problem. - -%------------------------------------------------------------------- -<tag>Sensitivity to @.hi@ interface files:</tag> - -GHC is very sensitive about interface files. For example, if it picks -up a non-standard @Prelude.hi@ file, pretty terrible things will -happen. If you turn on -@-fno-implicit-prelude@<nidx>-fno-implicit-prelude option</nidx>, the -compiler will almost surely die, unless you know what you are doing. - -Furthermore, as sketched below, you may have big problems -running programs compiled using unstable interfaces. - -%------------------------------------------------------------------- -<tag>``I think GHC is producing incorrect code'':</tag> - -Unlikely :-) A useful be-more-paranoid option to give to GHC is -@-dcore-lint@<nidx>-dcore-lint option</nidx>; this causes a ``lint'' -pass to check for errors (notably type errors) after each Core-to-Core -transformation pass. We run with @-dcore-lint@ on all the time; it -costs about 5\% in compile time. - -%------------------------------------------------------------------- -<tag>``Why did I get a link error?''</tag> - -If the linker complains about not finding @_<something>_fast@, then -something is inconsistent: you probably didn't compile modules in the -proper dependency order. - -%------------------------------------------------------------------- -<tag>``What's a `consistency error'?''</tag> -(These are reported just after linking your program.) - -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. - -If you run @nm -o *.o | egrep 't (cc|hsc)\.'@ (or, on -unregisterised files: @what *.o@), you'll see all the consistency -tags/strings in your object files. They must all be the same! -(ToDo: tell you what they mean...) - -%------------------------------------------------------------------- -<tag>``Is this line number right?''</tag> -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. - -Please report line-number errors that you find particularly unhelpful. -</descrip> - -%************************************************************************ -%* * -<sect1>When your program ``does the wrong thing'' -<label id="wrong-compilee"> -<p> -<nidx>problems running your program</nidx> -%* * -%************************************************************************ - -(For advice about overly slow or memory-hungry Haskell programs, -please see Section <ref name="Advice on: sooner, faster, smaller, -stingier" id="sooner-faster-quicker">). - -<descrip> -%----------------------------------------------------------------------- -<tag>``Help! My program crashed!''</tag> -(e.g., a `segmentation fault' or `core dumped') -<nidx>segmentation fault</nidx> - -If your program has no @_ccall_@s/@_casm_@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 @.hi-boot@ files, in which -case these <em/must/ be correct with respect to the module source). - -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. -<em>This applies to pragmas inside interfaces too!</em> 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. - -In short, if you compile a module and its interface changes, then all -the modules that import that interface <em>must</em> be re-compiled. - -A useful option to alert you when interfaces change is -@-hi-diffs@<nidx>-hi-diffs option</nidx>. It will run @diff@ on the -changed interface file, before and after, when applicable. - -If you are using @make@, a useful tool to make sure that every module -<em>is</em> up-to-date with respect to its imported interfaces is -@mkdependHS@ (which comes with GHC). Please see Section <ref -name="Makefile dependencies in Haskell: using mkdependHS" -id="mkdependHS">. - -If you are down to your last-compile-before-a-bug-report, we would -recommend that you add a @-dcore-lint@ option (for extra checking) to -your compilation options. - -So, before you report a bug because of a core dump, you should probably: -<tscreen><verb> -% 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... -</verb></tscreen> - -Of course, if you have @_ccall_@s/@_casm_@s in your program then all -bets are off, because you can trash the heap, the stack, or whatever. - -If you are interested in hard-core debugging of a crashing -GHC-compiled program, please see Section <ref name="Hard-core -debugging of GHC-compiled programs" id="hard-core-debug">. - -%------------------------------------------------------------------- -<tag>``My program entered an `absent' argument.''</tag> -This is definitely caused by a bug in GHC. Please report it. - -%----------------------------------------------------------------------- -<tag>``What's with this `arithmetic (or `floating') exception' ''?</tag> - -@Int@, @Float@, and @Double@ arithmetic is <em>unchecked</em>. -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 <em>may</em> cause an untrapped -exception (please report it if it does). - -</descrip> - -%************************************************************************ -%* * -<sect1>How to report a bug in the GHC system -<label id="bug-reports"> -<p> -<nidx>bug reports</nidx> -%* * -%************************************************************************ - -Glasgow Haskell is a changing system so there are sure to be bugs in -it. Please report them to <htmlurl -name="glasgow-haskell-bugs@@haskell.org" -url="mailto:glasgow-haskell-bugs@@haskell.org">! (However, please -check the earlier part of this section to be sure it's not a known -not-really-a problem.) - -The name of the bug-reporting game is: facts, facts, facts. -Don't omit them because ``Oh, they won't be interested...'' - -<enum> - -<item> What kind of machine are you running on, and exactly what -version of the operating system are you using? (@uname -a@ or @cat -/etc/motd@ will show the desired information.) - -<item> What version of GCC are you using? @gcc -v@ will tell you. - -<item> 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. - -<item> Be sure any Haskell compilations are run with a @-v@ (verbose) -flag, so we can see exactly what was run, what versions of things you -have, etc. - -<item> What is the program behaviour that is wrong, in your opinion? - -<item> If practical, please send enough source files/interface files -for us to duplicate the problem. - -<item> 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. - -</enum> - -%************************************************************************ -%* * -<sect1>Hard-core debugging of GHC-compiled programs -<label id="hard-core-debug"> -<p> -<nidx>debugging, hard-core</nidx> -%* * -%************************************************************************ - -If your program is crashing, you should almost surely file a bug -report, as outlined in previous sections. - -This section suggests ways to Make Further Progress Anyway. - -The first thing to establish is: Is it a garbage-collection (GC) bug? -Try your program with a very large heap and a @-Sstderr@ RTS -flag. -<itemize> -<item> -If it crashes <em>without</em> garbage-collecting, then it is -definitely <em>not</em> a GC bug. -<item> -If you can make it crash with one heap size but not with another, then -it <em>probably is</em> a GC bug. -<item> -If it crashes with the normal -collector, but not when you force two-space collection (@-F2s@ -runtime flag), then it <em>probably is</em> a GC bug. -</itemize> - -If it <em>is</em> a GC bug, you may be able to avoid it by using a -particular heap size or by using a @-F2s@ runtime flag. (But don't -forget to report the bug!!!) - -ToDo: more here? diff --git a/ghc/docs/users_guide/intro.vsgml b/ghc/docs/users_guide/intro.vsgml deleted file mode 100644 index ce1ad3be34238826ad1989b17071e319b83b4673..0000000000000000000000000000000000000000 --- a/ghc/docs/users_guide/intro.vsgml +++ /dev/null @@ -1,239 +0,0 @@ -<sect>Introduction to GHC -<label id="introduction-GHC"> -<p> - -This is a guide to using the Glasgow Haskell compilation (GHC) system. -It is a batch compiler for the Haskell~98 language, with support for -various Glasgow-only extensions. -In this document, we assume that GHC has been installed at your site -as @ghc@. A separate document, ``Building and Installing the -Glasgow Functional Programming Tools Suite'', -describes how to install @ghc@. - -Many people will use GHC very simply: compile some -modules---@ghc -c -O Foo.hs Bar.hs@; and link them--- -@ghc -o wiggle -O Foo.o Bar.o@. - -But if you need to do something more complicated, GHC can do that, -too: -<tscreen><verb> -ghc -c -O -fno-foldr-build -dcore-lint -fvia-C -ddump-simpl Foo.lhs -</verb></tscreen> -Stay tuned---all will be revealed! - -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. - -%************************************************************************ -%* * -<sect1>The (batch) compilation system components -<label id="batch-system-parts"> -<p> -%* * -%************************************************************************ - -The Glorious Haskell Compilation System, as with most UNIX (batch) -compilation systems, has several interacting parts: -<enum> -<item> -A <em>driver</em><nidx>driver program</nidx> @ghc@<nidx>ghc</nidx>---which you -usually think of as ``the compiler''---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. - -<item> -A <em>literate pre-processor</em> -<nidx>literate pre-processor</nidx> -<nidx>pre-processor, literate</nidx> -@unlit@<nidx>unlit</nidx> that extracts Haskell -code from a literate script; used if you believe in that sort of -thing. - -<item> -The <em>Haskellised C pre-processor</em> -<nidx>Haskellised C pre-processor</nidx> -<nidx>C pre-processor, Haskellised</nidx> -<nidx>pre-processor, Haskellised C</nidx> -@hscpp@,<nidx>hscpp</nidx> only needed by people requiring conditional -compilation, probably for large systems. The ``Haskellised'' part -just means that @#line@ directives in the output have been -converted into proper Haskell @{-# LINE ... -@} pragmas. - -You must give an explicit @-cpp@ option -<nidx>-cpp option</nidx> for the C pre-processor to be invoked. - -<item> -The <em>Haskell compiler</em> -<nidx>Haskell compiler</nidx> -<nidx>compiler, Haskell</nidx> -@hsc@,<nidx>hsc</nidx> -which---in normal use---takes its input from the C pre-processor -and produces assembly-language output (sometimes: ANSI C output). - -<item> -The <em>ANSI~C Haskell high-level assembler :-)</em> -<nidx>ANSI C compiler</nidx> -<nidx>high-level assembler</nidx> -<nidx>assembler, high-level</nidx> - -compiles @hsc@'s C output into assembly language for a particular -target architecture. In fact, the only C compiler we currently -support is <tt/gcc/, 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). - -<item> -The <em>assembler</em><nidx>assembler</nidx>---a standard UNIX one, probably -@as@<nidx>as</nidx>. - -<item> -The <em>linker</em><nidx>linker</nidx>---a standard UNIX one, probably -@ld@.<nidx>ld</nidx> - -<item> -A <em>runtime system</em>,<nidx>runtime system</nidx> including (most notably) -a storage manager; the linker links in the code for this. - -<item> -The <em>Haskell standard prelude</em><nidx>standard prelude</nidx>, a -large library of standard functions, is linked in as well. - -<item> -Parts of other <em>installed libraries</em> that you have at your site -may be linked in also. -</enum> - -%************************************************************************ -%* * -<sect1>What really happens when I ``compile'' a Haskell program? -<label id="compile-what-really-happens"> -<p> -%* * -%************************************************************************ - -You invoke the Glasgow Haskell compilation system through the -driver program @ghc@.<nidx>ghc</nidx> For example, if you had typed a -literate ``Hello, world!'' program into @hello.lhs@, and you then -invoked: -<tscreen><verb> -ghc hello.lhs -</verb></tscreen> - -the following would happen: -<enum> -<item> -The file @hello.lhs@ is run through the literate-program -code extractor @unlit@<nidx>unlit</nidx>, feeding its output to - -<item> -The Haskell compiler proper @hsc@<nidx>hsc</nidx>, which produces -input for - -<item> -The assembler (or that ubiquitous ``high-level assembler,'' a C -compiler), which produces an object file and passes it to - -<item> -The linker, which links your code with the appropriate libraries -(including the standard prelude), producing an executable program in -the default output file named @a.out@. -</enum> - -You have considerable control over the compilation process. You feed -command-line arguments (call them ``options,'' for short) to the -driver, @ghc@; the ``types'' of the input files (as encoded in -their names' suffixes) also matter. - -Here's hoping this is enough background so that you can read the rest -of this guide! - -% The ``style'' of the driver program @ghc@ follows that of the GNU C -% compiler driver @gcc@. The use of environment variables to provide -% defaults is more extensive in this compilation system. - -%-------------------------------------------------------------------- -<sect1>Meta-information: Web sites, mailing lists, etc. -<label id="mailing-lists-GHC"> -<p> -<nidx>mailing lists, Glasgow Haskell</nidx> -<nidx>Glasgow Haskell mailing lists</nidx> - -On the World-Wide Web, there are several URLs of likely interest: - -<itemize> -<item> <url name="Haskell home page" url="http://www.haskell.org/"> -<item> <url name="GHC home page" url="http://www.haskell.org/ghc/"> -<item> <url name="Glasgow FP group page" url="http://www.dcs.gla.ac.uk/fp/"> -<item> <url name="comp.lang.functional FAQ" url="http://www.cs.nott.ac.uk/Department/Staff/mpj/faq.html"> -</itemize> - -We run two mailing lists about Glasgow Haskell. We encourage you to -join, as you feel is appropriate. - -<descrip> - -<tag>glasgow-haskell-users:</tag> - -This list is for GHC users to chat among themselves. Subscribe by -sending mail to <htmlurl name="majordomo@@haskell.org" -url="mailto:majordomo@@haskell.org">, with a message body (not -header) like this: - -<tscreen><verb> -subscribe glasgow-haskell-users MyName <m.y.self@@bigbucks.com> -</verb></tscreen> - -(The last bit is your all-important e-mail address, of course.) - -To communicate with your fellow users, send mail to <url -name="glasgow-haskell-users@@haskell.org" -url="mailto:glasgow-haskell-users@@haskell.org">. - -To contact the list administrator, send mail to <htmlurl -name="glasgow-haskell-users-request@@haskell.org" -url="mailto:glasgow-haskell-users-request@@haskell.org">. An archive -of the list is available on the Web: <url name="glasgow-haskell-users -mailing list archive" -url="http://www.dcs.gla.ac.uk/mail-www/glasgow-haskell-users">. - -<tag>glasgow-haskell-bugs:</tag> -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. - -Subscribe via <htmlurl name="majordomo@@haskell.org" -url="mailto:majordomo@@haskell.org"> with: - -<tscreen><verb> -subscribe glasgow-haskell-bugs My Name <m.y.self@@hackers.r.us> -</verb></tscreen> - -Again, you may contact the list administrator at <htmlurl -name="glasgow-haskell-bugs-request@@haskell.org" -url="mailto:glasgow-haskell-bugs-request@@haskell.org">. -And, yes, an archive of the list is available on the Web at: : <url -name="glasgow-haskell-bugs mailing list archive" -url="http://www.dcs.gla.ac.uk/mail-www/glasgow-haskell-bugs"> - -</descrip> - -There is also the general Haskell mailing list. Subscribe by sending -email to <htmlurl name="majordomo@@dcs.gla.ac.uk" -url="mailto:majordomo@@dcs.gla.ac.uk">, with the usual message body: - -<tscreen><verb> -subscribe haskell My Name <m.y.self@@fp.rules.ok.org> -</verb></tscreen> - -Some Haskell-related discussion takes place in the Usenet newsgroup -@comp.lang.functional@. (But note: news is basically dead at Glasgow. -That's one reason Glaswegians aren't too active in c.f.l.) - -The main anonymous-FTP site for Glasgow Haskell is <htmlurl -name="ftp://ftp.dcs.gla.ac.uk/pub/haskell/glasgow" -url="ftp://ftp.dcs.gla.ac.uk/pub/haskell/glasgow">. ``Important'' -bits are mirrored at other Haskell archive sites (and we have their -stuff, too). diff --git a/ghc/docs/users_guide/lang.vsgml b/ghc/docs/users_guide/lang.vsgml deleted file mode 100644 index 2e03a0e02353827e6e06131a539e298cf8f600aa..0000000000000000000000000000000000000000 --- a/ghc/docs/users_guide/lang.vsgml +++ /dev/null @@ -1,9 +0,0 @@ -%************************************************************************ -%* * -<sect>GHC Language Features -<label id="ghc-language-features"> -<p> -<nidx>language, GHC</nidx> -<nidx>extensions, GHC</nidx> -%* * -%************************************************************************ diff --git a/ghc/docs/users_guide/libmisc.vsgml b/ghc/docs/users_guide/libmisc.vsgml deleted file mode 100644 index d6b926af179f9745c774c90deeffa5cfe9485c74..0000000000000000000000000000000000000000 --- a/ghc/docs/users_guide/libmisc.vsgml +++ /dev/null @@ -1,870 +0,0 @@ -%************************************************************************ -%* * -<sect1>Miscellaneous libraries -<label id="GHC-library"> -<p> -<nidx>libraries, miscellaneous</nidx> -<nidx>misc, syslib</nidx> -%* * -%************************************************************************ - -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 @-syslib misc@<nidx>-syslib misc option</nidx>. - -%************************************************************************ -%* * -<sect2>The @Bag@ type -<label id="Bag"> -<p> -<nidx>Bag module (misc syslib)</nidx> -%* * -%************************************************************************ - -A <em>bag</em> is an unordered collection of elements which may contain -duplicates. To use, @import Bag@. - -<tscreen><verb> -data Bag elt -- abstract - -emptyBag :: Bag elt -unitBag :: elt -> Bag elt - -consBag :: elt -> Bag elt -> Bag elt -snocBag :: Bag elt -> elt -> Bag elt - -unionBags :: Bag elt -> Bag elt -> Bag elt -unionManyBags :: [Bag elt] -> Bag elt - -isEmptyBag :: Bag elt -> Bool -elemBag :: Eq elt => elt -> Bag elt -> Bool - -filterBag :: (elt -> Bool) -> Bag elt -> Bag elt -partitionBag :: (elt -> Bool) -> Bag elt-> (Bag elt, Bag elt) - -- returns the elements that do/don't satisfy the predicate - -concatBag :: Bag (Bag a) -> Bag a -foldBag :: (r -> r -> r) -> (a -> r) -> r -> Bag a -> r -mapBag :: (a -> b) -> Bag a -> Bag b - -listToBag :: [elt] -> Bag elt -bagToList :: Bag elt -> [elt] -</verb></tscreen> - -%************************************************************************ -%* * -<sect2>The @FiniteMap@ type -<label id="FiniteMap"> -<p> -<nidx>FiniteMap module (misc syslib)</nidx> -%* * -%************************************************************************ - -What functional programmers call a <em>finite map</em>, everyone else -calls a <em>lookup table</em>. - -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. - -<tscreen><verb> -data FiniteMap key elt -- abstract - --- BUILDING -emptyFM :: FiniteMap key elt -unitFM :: key -> elt -> FiniteMap key elt -listToFM :: Ord key => [(key,elt)] -> 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 => FiniteMap key elt -> key -> elt -> FiniteMap key elt -addListToFM :: Ord key => FiniteMap key elt -> [(key,elt)] -> 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 => (elt -> elt -> elt) - -> FiniteMap key elt -> key -> elt - -> FiniteMap key elt -addListToFM_C :: Ord key => (elt -> elt -> elt) - -> FiniteMap key elt -> [(key,elt)] - -> FiniteMap key elt - - -- Deletion doesn't complain if you try to delete something - -- which isn't there -delFromFM :: Ord key => FiniteMap key elt -> key -> FiniteMap key elt -delListFromFM :: Ord key => FiniteMap key elt -> [key] -> FiniteMap key elt - --- COMBINING - -- Bindings in right argument shadow those in the left -plusFM :: Ord key => FiniteMap key elt -> FiniteMap key elt - -> FiniteMap key elt - - -- Combines bindings for the same thing with the given function -plusFM_C :: Ord key => (elt -> elt -> elt) - -> FiniteMap key elt -> FiniteMap key elt -> FiniteMap key elt - -minusFM :: Ord key => FiniteMap key elt -> FiniteMap key elt -> FiniteMap key elt - -- (minusFM a1 a2) deletes from a1 any bindings which are bound in a2 - -intersectFM :: Ord key => FiniteMap key elt -> FiniteMap key elt -> FiniteMap key elt -intersectFM_C :: Ord key => (elt -> elt -> elt) - -> FiniteMap key elt -> FiniteMap key elt -> FiniteMap key elt - --- MAPPING, FOLDING, FILTERING -foldFM :: (key -> elt -> a -> a) -> a -> FiniteMap key elt -> a -mapFM :: (key -> elt1 -> elt2) -> FiniteMap key elt1 -> FiniteMap key elt2 -filterFM :: Ord key => (key -> elt -> Bool) - -> FiniteMap key elt -> FiniteMap key elt - --- INTERROGATING -sizeFM :: FiniteMap key elt -> Int -isEmptyFM :: FiniteMap key elt -> Bool - -elemFM :: Ord key => key -> FiniteMap key elt -> Bool -lookupFM :: Ord key => FiniteMap key elt -> key -> Maybe elt -lookupWithDefaultFM - :: Ord key => FiniteMap key elt -> elt -> key -> elt - -- lookupWithDefaultFM supplies a "default" elt - -- to return for an unmapped key - --- LISTIFYING -fmToList :: FiniteMap key elt -> [(key,elt)] -keysFM :: FiniteMap key elt -> [key] -eltsFM :: FiniteMap key elt -> [elt] -</verb></tscreen> - -%************************************************************************ -%* * -<sect2>The @ListSetOps@ type -<label id="ListSetOps"> -<p> -<nidx>ListSetOps module (misc syslib)</nidx> -%* * -%************************************************************************ - -Just a few set-sounding operations on lists. If you want sets, use -the @Set@ module. - -<tscreen><verb> -unionLists :: Eq a => [a] -> [a] -> [a] -intersectLists :: Eq a => [a] -> [a] -> [a] -minusList :: Eq a => [a] -> [a] -> [a] -disjointLists :: Eq a => [a] -> [a] -> Bool -intersectingLists :: Eq a => [a] -> [a] -> Bool -</verb></tscreen> - -%************************************************************************ -%* * -<sect2>The @Maybes@ type -<label id="Maybes"> -<p> -<nidx>Maybes module (misc syslib)</nidx> -%* * -%************************************************************************ - -The @Maybe@ type is in the Haskell 1.4 prelude. Moreover, the -required @Maybe@ library provides many useful functions on -@Maybe@s. This (pre-1.3) module provides some more: - -An @Either@-like type called @MaybeErr@: -<tscreen><verb> -data MaybeErr val err = Succeeded val | Failed err -</verb></tscreen> - -Some operations to do with @Maybe@ (some commentary follows): -<tscreen><verb> -maybeToBool :: Maybe a -> Bool -- Nothing => False; Just => True -allMaybes :: [Maybe a] -> Maybe [a] -firstJust :: [Maybe a] -> Maybe a -findJust :: (a -> Maybe b) -> [a] -> Maybe b - -assocMaybe :: Eq a => [(a,b)] -> a -> Maybe b -mkLookupFun :: (key -> key -> Bool) -- Equality predicate - -> [(key,val)] -- The assoc list - -> (key -> Maybe val) -- A lookup fun to use -mkLookupFunDef :: (key -> key -> Bool) -- Equality predicate - -> [(key,val)] -- The assoc list - -> val -- Value to return on failure - -> key -- The key - -> val -- The corresponding value - - -- a monad thing -thenMaybe :: Maybe a -> (a -> Maybe b) -> Maybe b -returnMaybe :: a -> Maybe a -failMaybe :: Maybe a -mapMaybe :: (a -> Maybe b) -> [a] -> Maybe [b] -</verb></tscreen> - -NB: @catMaybes@ which used to be here, is now available via the -standard @Maybe@ interface (@Maybe@ is an instance of @MonadPlus@). - -@allMaybes@ collects a list of @Justs@ into a single @Just@, returning -@Nothing@ if there are any @Nothings@. - -@firstJust@ takes a list of @Maybes@ and returns the -first @Just@ if there is one, or @Nothing@ otherwise. - -@assocMaybe@ looks up in an association list, returning -@Nothing@ if it fails. - -Now, some operations to do with @MaybeErr@ (comments follow): -<tscreen><verb> - -- a monad thing (surprise, surprise) -thenMaB :: MaybeErr a err -> (a -> MaybeErr b err) -> MaybeErr b err -returnMaB :: val -> MaybeErr val err -failMaB :: err -> MaybeErr val err - -listMaybeErrs :: [MaybeErr val err] -> MaybeErr [val] [err] -foldlMaybeErrs :: (acc -> input -> MaybeErr acc err) - -> acc - -> [input] - -> MaybeErr acc [err] -</verb></tscreen> - -@listMaybeErrs@ takes a list of @MaybeErrs@ and, if they all succeed, -returns a @Succeeded@ of a list of their values. If any fail, it -returns a @Failed@ of the list of all the errors in the list. - -@foldlMaybeErrs@ 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. - -%************************************************************************ -%* * -<sect2>The @Memo@ library -<label id="memo-library"> -<p> -<nidx>Memo (misc syslib)</nidx> -%* * -%************************************************************************ - -The @Memo@ library provides fast polymorphic memo functions using hash -tables. The interface is: - -<tscreen><verb> -memo :: (a -> b) -> a -> b -</verb></tscreen> - -So, for example, @memo f@ is a version of @f@ that caches the results -of previous calls. - -The searching is very fast, being based on pointer equality. One -consequence of this is that the caching will only be effective if -<em/exactly the same argument is passed again to the memoised -function/. 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. - -This memoisation library works well when the keys are large (or even -infinite). - -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. - -There's another version of @memo@ if you want to explicitly give a -size for the hash table (the default size is 1001 buckets): - -<tscreen><verb> -memo_sized :: Int -> (a -> b) -> a -> b -</verb></tscreen> - -%************************************************************************ -%* * -<sect2>The @PackedString@ type -<label id="PackedString"> -<p> -<nidx>PackedString module (misc syslib)</nidx> -%* * -%************************************************************************ - -You need to @import PackedString@ and heave in your -@-syslib ghc@ to use @PackedString@s. - -The basic type and functions available are: -<tscreen><verb> -data PackedString -- abstract - -packString :: [Char] -> PackedString -packStringST :: [Char] -> ST s PackedString -packCBytesST :: Int -> Addr -> ST s PackedString -packBytesForCST :: [Char] -> ST s (ByteArray Int) -byteArrayToPS :: ByteArray Int -> PackedString -unsafeByteArrayToPS :: ByteArray a -> Int -> PackedString -psToByteArray :: PackedString -> ByteArray Int -psToByteArrayST :: PackedString -> ST s (ByteArray Int) - -unpackPS :: PackedString -> [Char] -</verb></tscreen> - -We also provide a wad of list-manipulation-like functions: -<tscreen><verb> -nilPS :: PackedString -consPS :: Char -> PackedString -> PackedString - -headPS :: PackedString -> Char -tailPS :: PackedString -> PackedString -nullPS :: PackedString -> Bool -appendPS :: PackedString -> PackedString -> PackedString -lengthPS :: PackedString -> Int -indexPS :: PackedString -> Int -> Char - -- 0-origin indexing into the string -mapPS :: (Char -> Char) -> PackedString -> PackedString -filterPS :: (Char -> Bool) -> PackedString -> PackedString -foldlPS :: (a -> Char -> a) -> a -> PackedString -> a -foldrPS :: (Char -> a -> a) -> a -> PackedString -> a -takePS :: Int -> PackedString -> PackedString -dropPS :: Int -> PackedString -> PackedString -splitAtPS :: Int -> PackedString -> (PackedString, PackedString) -takeWhilePS :: (Char -> Bool) -> PackedString -> PackedString -dropWhilePS :: (Char -> Bool) -> PackedString -> PackedString -spanPS :: (Char -> Bool) -> PackedString -> (PackedString, PackedString) -breakPS :: (Char -> Bool) -> PackedString -> (PackedString, PackedString) -linesPS :: PackedString -> [PackedString] -wordsPS :: PackedString -> [PackedString] -reversePS :: PackedString -> PackedString -concatPS :: [PackedString] -> PackedString -elemPS :: Char -> PackedString -> Bool - -- Perl-style split&join -splitPS :: Char -> PackedString -> [PackedString] -splitWithPS :: (Char -> Bool) -> PackedString -> [PackedString] -joinPS :: PackedString -> [PackedString] -> PackedString - -substrPS :: PackedString -> Int -> Int -> PackedString - -- pluck out a piece of a PackedString - -- start and end chars you want; both 0-origin-specified -</verb></tscreen> - -%************************************************************************ -%* * -<sect2>The @Set@ type -<label id="Set"> -<p> -<nidx>Set module (misc syslib)</nidx> -%* * -%************************************************************************ - -Our implementation of <em>sets</em> (key property: no duplicates) is just -a variant of the @FiniteMap@ module. - -<tscreen><verb> -data Set -- abstract - -- instance of: Eq - -emptySet :: Set a -mkSet :: Ord a => [a] -> Set a -setToList :: Set a -> [a] -unitSet :: a -> Set a -singletonSet :: a -> Set a -- deprecated, use unitSet. - -union :: Ord a => Set a -> Set a -> Set a -unionManySets :: Ord a => [Set a] -> Set a -minusSet :: Ord a => Set a -> Set a -> Set a -mapSet :: Ord a => (b -> a) -> Set b -> Set a -intersect :: Ord a => Set a -> Set a -> Set a - -elementOf :: Ord a => a -> Set a -> Bool -isEmptySet :: Set a -> Bool - -cardinality :: Set a -> Int - -</verb></tscreen> - -%************************************************************************ -%* * -<sect2>The @BitSet@ interface -<label id="BitSet"> -<p> -<nidx>Bitset interface (misc syslib)</nidx> -%* * -%************************************************************************ - -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. - -<tscreen><verb> -data BitSet -- abstract - -- instance of: - -emptyBS :: BitSet -mkBS :: [Int] -> BitSet -unitBS :: Int -> BitSet -unionBS :: BitSet -> BitSet -> BitSet -minusBS :: BitSet -> BitSet -> BitSet -isEmptyBS :: BitSet -> Bool -intersectBS :: BitSet -> BitSet -> BitSet -elementBS :: Int -> BitSet -> Bool -listBS :: BitSet -> [Int] -</verb></tscreen> - -%************************************************************************ -%* * -<sect2>The @Util@ type -<label id="Util"> -<p> -<nidx>Util module (misc syslib)</nidx> -%* * -%************************************************************************ - -Stuff that has been generally useful to use in writing the compiler. -Don't be too surprised if this stuff moves/gets-renamed/etc. - -<tscreen><verb> --- general list processing -forall :: (a -> Bool) -> [a] -> Bool -exists :: (a -> Bool) -> [a] -> Bool - -nOfThem :: Int -> a -> [a] -lengthExceeds :: [a] -> Int -> Bool -isSingleton :: [a] -> Bool - ---paranoid zip'ing (equal length lists) -zipEqual :: [a] -> [b] -> [(a,b)] -zipWithEqual :: String -> (a->b->c) -> [a]->[b]->[c] -zipWith3Equal :: String -> (a->b->c->d) -> [a]->[b]->[c]->[d] -zipWith4Equal :: String -> (a->b->c->d->e) -> [a]->[b]->[c]->[d]->[e] --- lazy in second argument -zipLazy :: [a] -> [b] -> [(a,b)] - -mapAndUnzip :: (a -> (b, c)) -> [a] -> ([b], [c]) -mapAndUnzip3 :: (a -> (b, c, d)) -> [a] -> ([b], [c], [d]) - --- prefix and suffix matching on lists of characters. -startsWith :: {-prefix-}String -> String -> Maybe String -endsWith :: {-suffix-}String -> String -> Maybe String - --- association lists -assoc :: Eq a => String -> [(a, b)] -> a -> b - --- duplicate handling -hasNoDups :: Eq a => [a] -> Bool -equivClasses :: (a -> a -> Ordering) -> [a] -> [[a]] -runs :: (a -> a -> Bool) -> [a] -> [[a]] -removeDups :: (a -> a -> Ordering) -> [a] -> ([a], [[a]]) - --- sorting (don't complain of no choice...) -quicksort :: (a -> a -> Bool) -> [a] -> [a] -sortLt :: (a -> a -> Bool) -> [a] -> [a] -stableSortLt :: (a -> a -> Bool) -> [a] -> [a] -mergesort :: (a -> a -> _CMP_TAG) -> [a] -> [a] -mergeSort :: Ord a => [a] -> [a] -naturalMergeSort :: Ord a => [a] -> [a] -mergeSortLe :: Ord a => [a] -> [a] -naturalMergeSortLe :: Ord a => [a] -> [a] - --- transitive closures -transitiveClosure :: (a -> [a]) -- Successor function - -> (a -> a -> Bool) -- Equality predicate - -> [a] - -> [a] -- The transitive closure - --- accumulating (Left, Right, Bi-directional) -mapAccumL :: (acc -> x -> (acc, y)) - -- Function of elt of input list and - -- accumulator, returning new accumulator and - -- elt of result list - -> acc -- Initial accumulator - -> [x] -- Input list - -> (acc, [y]) -- Final accumulator and result list - -mapAccumR :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y]) - -mapAccumB :: (accl -> accr -> x -> (accl, accr,y)) - -> accl -> accr -> [x] - -> (accl, accr, [y]) - ---list comparison with explicit element comparer. -cmpList :: (a -> a -> Ordering) -> [a] -> [a] -> Ordering - --- pairs -applyToPair :: ((a -> c), (b -> d)) -> (a, b) -> (c, d) -applyToFst :: (a -> c) -> (a, b) -> (c, b) -applyToSnd :: (b -> d) -> (a, b) -> (a, d) -foldPair :: (a->a->a, b->b->b) -> (a, b) -> [(a, b)] -> (a, b) -unzipWith :: (a -> b -> c) -> [(a, b)] -> [c] -</verb></tscreen> - -%************************************************************************ -%* * -<sect1>Interfaces to C libraries -<label id="C-interfaces"> -<p> -<nidx>C library interfaces</nidx> -<nidx>interfaces, C library</nidx> -%* * -%************************************************************************ - -The GHC system library (@-syslib misc@) also provides interfaces to -several useful C libraries, mostly from the GNU project. - -%************************************************************************ -%* * -<sect2>The @Readline@ interface -<label id="Readline"> -<p> -<nidx>Readline library (misc syslib)</nidx> -<nidx>command-line editing library</nidx> -%* * -%************************************************************************ - -(Darren Moffat supplied the @Readline@ interface.) - -The @Readline@ module is a straightforward interface to the GNU -Readline library. As such, you will need to look at the GNU -documentation (and have a @libreadline.a@ file around somewhere...) - -You'll need to link any Readlining program with @-lreadline -ltermcap@, -besides the usual @-syslib ghc@ (and @-fhaskell-1.3@). - -The main function you'll use is: -<tscreen><verb> -readline :: String{-the prompt-} -> IO String -</verb></tscreen> - -If you want to mess around with Full Readline G(l)ory, we also -provide: -<tscreen><verb> -rlInitialize, addHistory, - -rlBindKey, rlAddDefun, RlCallbackFunction(..), - -rlGetLineBuffer, rlSetLineBuffer, rlGetPoint, rlSetPoint, rlGetEnd, -rlSetEnd, rlGetMark, rlSetMark, rlSetDone, rlPendingInput, - -rlPrompt, rlTerminalName, rlSetReadlineName, rlGetReadlineName -</verb></tscreen> -(All those names are just Haskellised versions of what you -will see in the GNU readline documentation.) - -%************************************************************************ -%* * -<sect2>The @Regex@ and @MatchPS@ interfaces -<label id="Regex"> -<p> -<nidx>Regex library (misc syslib)</nidx> -<nidx>MatchPS library (misc syslib)</nidx> -<nidx>regular-expressions library</nidx> -%* * -%************************************************************************ - -(Sigbjorn Finne supplied the regular-expressions interface.) - -The @Regex@ library provides quite direct interface to the GNU -regular-expression library, for doing manipulation on @PackedString@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 -@RegexString@ interface. - -The datatypes and functions that @Regex@ provides are: -<tscreen><verb> -data PatBuffer # just a bunch of bytes (mutable) - -data REmatch - = REmatch (Array Int GroupBounds) -- for $1, ... $n - GroupBounds -- for $` (everything before match) - GroupBounds -- for $& (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 - -> Bool -- True <=> assume single-line mode - -> Bool -- True <=> case-insensitive - -> PrimIO PatBuffer - -re_match :: PatBuffer -- compiled regexp - -> PackedString -- string to match - -> Int -- start position - -> Bool -- True <=> record results in registers - -> 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 - -> PackedString - -> PackedString - -> Int - -> Int - -> Bool - -> PrimIO (Maybe REmatch) - -re_search :: PatBuffer -- compiled regexp - -> PackedString -- string to search - -> Int -- start index - -> Int -- stop index - -> Bool -- True <=> record results in registers - -> PrimIO (Maybe REmatch) - -re_search2 :: PatBuffer -- Double buffer search - -> PackedString - -> PackedString - -> Int -- start index - -> Int -- range (?) - -> Int -- stop index - -> Bool -- True <=> results in registers - -> PrimIO (Maybe REmatch) -</verb></tscreen> - -The @MatchPS@ module provides Perl-like ``higher-level'' facilities -to operate on @PackedStrings@. The regular expressions in -question are in Perl syntax. The ``flags'' on various functions can -include: @i@ for case-insensitive, @s@ for single-line mode, and -@g@ for global. (It's probably worth your time to peruse the -source code...) - -<tscreen><verb> -matchPS :: PackedString -- regexp - -> PackedString -- string to match - -> [Char] -- flags - -> Maybe REmatch -- info about what matched and where - -searchPS :: PackedString -- regexp - -> PackedString -- string to match - -> [Char] -- flags - -> Maybe REmatch - --- Perl-like match-and-substitute: -substPS :: PackedString -- regexp - -> PackedString -- replacement - -> [Char] -- flags - -> PackedString -- string - -> PackedString - --- same as substPS, but no prefix and suffix: -replacePS :: PackedString -- regexp - -> PackedString -- replacement - -> [Char] -- flags - -> PackedString -- string - -> PackedString - -match2PS :: PackedString -- regexp - -> PackedString -- string1 to match - -> PackedString -- string2 to match - -> [Char] -- flags - -> Maybe REmatch - -search2PS :: PackedString -- regexp - -> PackedString -- string to match - -> PackedString -- string to match - -> [Char] -- flags - -> Maybe REmatch - --- functions to pull the matched pieces out of an REmatch: - -getMatchesNo :: REmatch -> Int -getMatchedGroup :: REmatch -> Int -> PackedString -> PackedString -getWholeMatch :: REmatch -> PackedString -> PackedString -getLastMatch :: REmatch -> PackedString -> PackedString -getAfterMatch :: REmatch -> PackedString -> PackedString - --- (reverse) brute-force string matching; --- Perl equivalent is index/rindex: -findPS, rfindPS :: PackedString -> PackedString -> Maybe Int - --- Equivalent to Perl "chop" (off the last character, if any): -chopPS :: PackedString -> 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 -> PackedString -> Int -</verb></tscreen> - -%************************************************************************ -%* * -<sect2>The @RegexString@ interface -<label id="RegexString"> -<p> -<nidx>RegexString library (misc syslib)</nidx> -<nidx>regular-expressions library</nidx> -%* * -%************************************************************************ - -(Simon Marlow supplied the String Regex wrapper.) - -For simple regular expression operations, the @Regex@ library is a -little heavyweight. @RegexString@ permits regex matching on ordinary -Haskell @String@s. - -The datatypes and functions that @RegexString@ provides are: -<tscreen><verb> -data Regex -- a compiled regular expression - -mkRegex - :: String -- regexp to compile - -> Regex -- compiled regexp - -matchRegex - :: Regex -- compiled regexp - -> String -- string to match - -> Maybe [String] -- text of $1, $2, ... (if matched) -</verb></tscreen> - -%************************************************************************ -%* * -<sect2>Network-interface toolkit---@Socket@ and @SocketPrim@ -<label id="Socket"> -<p> -<nidx>SocketPrim interface (misc syslib)</nidx> -<nidx>Socket interface (misc syslib)</nidx> -<nidx>network-interface library</nidx> -<nidx>sockets library</nidx> -<nidx>BSD sockets library</nidx> -%* * -%************************************************************************ - -(Darren Moffat supplied the initial version of this library.) - -Your best bet for documentation is to look at the code---really!--- -normally in @fptools/ghc/lib/misc/{BSD,Socket,SocketPrim@.lhs}. - -The @BSD@ module provides functions to get at system-database info; -pretty straightforward if you're into this sort of thing: -<tscreen><verb> -getHostName :: IO String - -getServiceByName :: ServiceName -> IO ServiceEntry -getServicePortNumber:: ServiceName -> IO PortNumber -getServiceEntry :: IO ServiceEntry -setServiceEntry :: Bool -> IO () -endServiceEntry :: IO () - -getProtocolByName :: ProtocolName -> IO ProtocolEntry -getProtocolByNumber :: ProtocolNumber -> IO ProtcolEntry -getProtocolNumber :: ProtocolName -> ProtocolNumber -getProtocolEntry :: IO ProtocolEntry -setProtocolEntry :: Bool -> IO () -endProtocolEntry :: IO () - -getHostByName :: HostName -> IO HostEntry -getHostByAddr :: Family -> HostAddress -> IO HostEntry -getHostEntry :: IO HostEntry -setHostEntry :: Bool -> IO () -endHostEntry :: IO () -</verb></tscreen> - -The @SocketPrim@ 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... - -The @Socket@ 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! - -The interface is relatively modest: -<tscreen><verb> -connectTo :: Hostname -> PortID -> IO Handle -listenOn :: PortID -> IO Socket - -accept :: Socket -> IO (Handle, HostName) -sendTo :: Hostname -> PortID -> String -> IO () - -recvFrom :: Hostname -> PortID -> IO String -socketPort :: Socket -> 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 -> PortNumber -</verb></tscreen> - -Various examples of networking Haskell code are provided in -%@ghc/misc/examples/@, notably the @net???/Main.hs@ programs. - -%************************************************************************ -%* * -<sect2>The @Select@ interface -<label id="Select"> -<p> -<nidx>Select interface (misc syslib)</nidx> -%* * -%************************************************************************ - -The <tt/Select/ interface provides a Haskell wrapper for the <tt/select()/ -OS call supplied by many modern UNIX variants. <tt/Select/ exports the -following: - -<tscreen><verb> -type TimeOut = Maybe Int - -- Nothing => wait indefinitely. - -- Just x | x >= 0 => block waiting for 'x' micro seconds. - -- | otherwise => block waiting for '-x' micro seconds. - -hSelect :: [Handle] - -> [Handle] - -> [Handle] - -> TimeOut - -> IO SelectResult - -type SelectResult - = ( [Handle] -- input handles ready - , [Handle] -- output handles ready - , [Handle] -- exc. handles ready - ) - -</verb></tscreen> - -Here's an example of how it could be used: - -<tscreen><verb> -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 <- getChar - print x - -</verb></tscreen> - -where the call to <tt/hSelect/ makes the process go to sleep -until there's input available on <tt/stdin/. - -Notice that this particular use of <tt/hSelect/ 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 <tt/select()/ for you, if needs be. However, <tt/hSelect/ exposes -functionality that is useful in other contexts (e.g., you want to -wait for input on two <tt/Handles/ for 3 seconds, but no longer.) - diff --git a/ghc/docs/users_guide/libraries.vsgml b/ghc/docs/users_guide/libraries.vsgml deleted file mode 100644 index 4c48c37f18fe8e0afdd26f73a6af3fd37ecdd712..0000000000000000000000000000000000000000 --- a/ghc/docs/users_guide/libraries.vsgml +++ /dev/null @@ -1,891 +0,0 @@ -% -% $Id: libraries.vsgml,v 1.6 1999/08/17 15:39:38 simonpj Exp $ -% -% GHC Prelude and Libraries. -% - -<sect>The GHC prelude and libraries -<label id="ghc-prelude"> -<p> - -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: - -<itemize> - -<item> GHC's additional non-standard libraries and types, such as - state transformers, packed strings, foreign objects, stable - pointers, and so on. - -<item> 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. - -<item> The organisation of these libraries into directories. - -<item> Short description of programmer interface to the non-standard - libraries provided in addition to the standard prelude. -</itemize> - -A number of the libraries that provide access to GHC's language -extensions are shared by Hugs, and are described in the <htmlurl -name="GHC/Hugs Extension Libraries" url="libs.html"> document. - -<sect1>Prelude extensions -<label id="ghc-prelude-exts"> -<p> - -GHC's prelude contains the following non-standard extensions: - -<descrip> - -<tag>@fromInt@ method in class @Num@:</tag> It's there. Converts from -an @Int@ to the type. - -<tag>@toInt@ method in class @Integral@:</tag> Converts from Integral -type to an @Int@. - -</descrip> - -GHC also internally uses a number of modules that begin with the -string @Prel@<nidx>Prel module prefix</nidx>: for this reason, we -don't recommend that you use any module names beginning with @Prel@ in -your own programs. The @Prel@ modules are always available: in fact, -you can get access to several extensions this way (for some you might -need to give the @-fglasgow-exts@<nidx>-fglasgow-exts option</nidx> -flag). - - -<sect1>GHC/Hugs Extension Libraries -<p> - -The extension libraries provided by both GHC and Hugs are described in -the -<htmlurl name="GHC/Hugs Extension Library Document" url="http://www.dcs.gla.ac.uk/fp/software/ghc/hg-libs/hg-libs.html"> - -<sect1>GHC-only Extension Libraries -<p> -<nidx>libraries, ghc-only</nidx> -<nidx>extension libraries, ghc-only</nidx> - -If you rely on the implicit @import Prelude@ that GHC normally does -for you, and if you don't use any weird flags (notably -@-fglasgow-exts@), and if you don't import the Glasgow extensions -interface, @GlaExts@, then GHC should work <em>exactly</em> as the -Haskell report says (modulo a few minor issues, see Section <ref -id="vs-Haskell-defn" name="Language Non-compliance">). - -If you turn on @-fglasgow-exts@, 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.) - -&mutablearray; -&bytearray; - -<sect2>The @CCall@ module -<p> - -The @CCall@ module defines the classes @CCallable@ and @CReturnable@, -along with instances for the primitive types (@Int@, @Int#@, @Float@, -@Float#@ etc.) GHC knows to import this module if you use @_ccall_@, -but if you need to define your own instances of these classes, you -will need to import @CCall@ explicitly. - -More information on how to use @_ccall_@ can be found in Section -<ref name="Calling~C directly from Haskell" id="glasgow-ccalls">. - -<sect2>The @GlaExts@ interface -<p> -<nidx>GlaExts interface (GHC extensions)</nidx> - -The @GlaExts@ 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 (@+#@, @==#@, etc.). - -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 -@GlaExts@ for compatibility, but this facility will likely be removed -in the future). - -<tscreen><verb> --- 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. -</verb></tscreen> - -<sect1>The module @PrelGHC@: really primitive stuff -<label id="ghc-libs-ghc"> -<p> -<nidx>PrelGHC module</nidx> - -This module defines all the types which are primitive in Glasgow -Haskell, and the operations provided for them. - -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 @#@ suffix. - -Primitive values are often represented by a simple bit-pattern, such -as @Int#@, @Float#@, @Double#@. But this is not necessarily the case: -a primitive value might be represented by a pointer to a -heap-allocated object. Examples include @Array#@, 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...nothing can be at the other end of the pointer than the -primitive value. - -<sect2>Unboxed Tuples -<label id="unboxed-tuples"> -<p> - -Unboxed tuples aren't really exported by @PrelGHC@, they're available -by default with @-fglasgow-exts@. An unboxed tuple looks like this: - -<tscreen><verb> -(# e_1, ..., e_n #) -</verb></tscreen> - -where @e_1..e_n@ are expressions of any type (primitive or -non-primitive). The type of an unboxed tuple looks the same. - -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. - -There are some pretty stringent restrictions on the use of unboxed tuples: - -<itemize> - -<item> 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. - -<item> Unboxed tuples may only be constructed as the direct result of -a function, and may only be deconstructed with a @case@ expression. -eg. the following are valid: - -<tscreen><verb> -f x y = (# x+1, y-1 #) -g x = case f x x of { (# a, b #) -> a + b } -</verb></tscreen> - -but the following are invalid: - -<tscreen><verb> -f x y = g (# x, y #) -g (# x, y #) = x + y -</verb></tscreen> - -<item> No variable can have an unboxed tuple type. This is illegal: - -<tscreen><verb> -f :: (# Int, Int #) -> (# Int, Int #) -f x = x -</verb></tscreen> - -because @x@ has an unboxed tuple type. - -</itemize> - -Note: we may relax some of these restrictions in the future. - -The @IO@ and @ST@ monads use unboxed tuples to avoid unnecessary -allocation during sequences of operations. - -<sect2>Character and numeric types -<p> -<nidx>character types, primitive</nidx> -<nidx>numeric types, primitive</nidx> -<nidx>integer types, primitive</nidx> -<nidx>floating point types, primitive</nidx> - -There are the following obvious primitive types: - -<tscreen><verb> -type Char# -type Int# -- see also Word# and Addr#, later -type Float# -type Double# -</verb></tscreen> -<ncdx>Char#</ncdx> -<ncdx>Int#</ncdx> -<ncdx>Float#</ncdx> -<ncdx>Double#</ncdx> - -If you really want to know their exact equivalents in C, see -@ghc/includes/StgTypes.h@ in the GHC source tree. - -Literals for these types may be written as follows: - -<tscreen><verb> -1# an Int# -1.2# a Float# -1.34## a Double# -'a'# a Char#; for weird characters, use '\o<octal>'# -"a"# an Addr# (a `char *') -</verb></tscreen> -<nidx>literals, primitive</nidx> -<nidx>constants, primitive</nidx> -<nidx>numbers, primitive</nidx> - -<sect2> Comparison operations -<p> -<nidx>comparisons, primitive</nidx> -<nidx>operators, comparison</nidx> - -<tscreen><verb> -{>,>=,==,/=,<,<=}# :: Int# -> Int# -> Bool - -{gt,ge,eq,ne,lt,le}Char# :: Char# -> Char# -> Bool - -- ditto for Word# and Addr# -</verb></tscreen> -<ncdx>>#</ncdx> -<ncdx>>=#</ncdx> -<ncdx>==#</ncdx> -<ncdx>/=#</ncdx> -<ncdx><#</ncdx> -<ncdx><=#</ncdx> -<ncdx>gt{Char,Word,Addr}#</ncdx> -<ncdx>ge{Char,Word,Addr}#</ncdx> -<ncdx>eq{Char,Word,Addr}#</ncdx> -<ncdx>ne{Char,Word,Addr}#</ncdx> -<ncdx>lt{Char,Word,Addr}#</ncdx> -<ncdx>le{Char,Word,Addr}#</ncdx> - -<sect2> Primitive-character operations -<p> -<nidx>characters, primitive operations</nidx> -<nidx>operators, primitive character</nidx> - -<tscreen><verb> -ord# :: Char# -> Int# -chr# :: Int# -> Char# -</verb></tscreen> -<ncdx>ord#</ncdx> -<ncdx>chr#</ncdx> - - -<sect2> Primitive-@Int@ operations -<p> -<nidx>integers, primitive operations</nidx> -<nidx>operators, primitive integer</nidx> - -<tscreen><verb> -{+,-,*,quotInt,remInt}# :: Int# -> Int# -> Int# -negateInt# :: Int# -> Int# - -iShiftL#, iShiftRA#, iShiftRL# :: Int# -> Int# -> Int# - -- shift left, right arithmetic, right logical -</verb></tscreen> -<ncdx>+#</ncdx> -<ncdx>-#</ncdx> -<ncdx>*#</ncdx> -<ncdx>quotInt#</ncdx> -<ncdx>remInt#</ncdx> -<ncdx>iShiftL#</ncdx> -<ncdx>iShiftRA#</ncdx> -<ncdx>iShiftRL#</ncdx> -<nidx>shift operations, integer</nidx> - -<bf>Note:</bf> No error/overflow checking! - -<sect2> Primitive-@Double@ and @Float@ operations -<p> -<nidx>floating point numbers, primitive</nidx> -<nidx>operators, primitive floating point</nidx> - -<tscreen><verb> -{+,-,*,/}## :: Double# -> Double# -> Double# -{<,<=,==,/=,>=,>}## :: Double# -> Double# -> Bool -negateDouble# :: Double# -> Double# -double2Int# :: Double# -> Int# -int2Double# :: Int# -> Double# - -{plus,minux,times,divide}Float# :: Float# -> Float# -> Float# -{gt,ge,eq,ne,lt,le}Float# :: Float# -> Float# -> Bool -negateFloat# :: Float# -> Float# -float2Int# :: Float# -> Int# -int2Float# :: Int# -> Float# -</verb></tscreen> - -<ncdx>+##</ncdx> -<ncdx>-##</ncdx> -<ncdx>*##</ncdx> -<ncdx>/##</ncdx> -<ncdx><##</ncdx> -<ncdx><=##</ncdx> -<ncdx>==##</ncdx> -<ncdx>=/##</ncdx> -<ncdx>>=##</ncdx> -<ncdx>>##</ncdx> -<ncdx>negateDouble#</ncdx> -<ncdx>double2Int#</ncdx> -<ncdx>int2Double#</ncdx> - -<ncdx>plusFloat#</ncdx> -<ncdx>minusFloat#</ncdx> -<ncdx>timesFloat#</ncdx> -<ncdx>divideFloat#</ncdx> -<ncdx>gtFloat#</ncdx> -<ncdx>geFloat#</ncdx> -<ncdx>eqFloat#</ncdx> -<ncdx>neFloat#</ncdx> -<ncdx>ltFloat#</ncdx> -<ncdx>leFloat#</ncdx> -<ncdx>negateFloat#</ncdx> -<ncdx>float2Int#</ncdx> -<ncdx>int2Float#</ncdx> - -And a full complement of trigonometric functions: - -<tscreen> <verb> -expDouble# :: Double# -> Double# -logDouble# :: Double# -> Double# -sqrtDouble# :: Double# -> Double# -sinDouble# :: Double# -> Double# -cosDouble# :: Double# -> Double# -tanDouble# :: Double# -> Double# -asinDouble# :: Double# -> Double# -acosDouble# :: Double# -> Double# -atanDouble# :: Double# -> Double# -sinhDouble# :: Double# -> Double# -coshDouble# :: Double# -> Double# -tanhDouble# :: Double# -> Double# -powerDouble# :: Double# -> Double# -> Double# -</verb></tscreen> -<nidx>trigonometric functions, primitive</nidx> - -similarly for @Float#@. - -There are two coercion functions for @Float#@/@Double#@: - -<tscreen><verb> -float2Double# :: Float# -> Double# -double2Float# :: Double# -> Float# -</verb></tscreen> -<ncdx>float2Double#</ncdx> -<ncdx>double2Float#</ncdx> - -The primitive versions of @encodeDouble@/@decodeDouble@: - -<tscreen><verb> -encodeDouble# :: Int# -> Int# -> ByteArray# -- Integer mantissa - -> Int# -- Int exponent - -> Double# - -decodeDouble# :: Double# -> PrelNum.ReturnIntAndGMP -</verb></tscreen> -<ncdx>encodeDouble#</ncdx> -<ncdx>decodeDouble#</ncdx> - -(And the same for @Float#@s.) - -<sect2>Operations on/for @Integers@ (interface to GMP) -<label id="integer-operations"> -<p> -<nidx>arbitrary precision integers</nidx> -<nidx>Integer, operations on</nidx> - -We implement @Integers@ (arbitrary-precision integers) using the GNU -multiple-precision (GMP) package (version 2.0.2). - -The data type for @Integer@ is either a small integer, -represented by an @Int@, or a large integer represented -using the pieces requird by GMP's @MP_INT@ in @gmp.h@ -(see @gmp.info@ in @ghc/includes/runtime/gmp@). It comes out as: - -<tscreen><verb> -data Integer = S# Int# -- small integers - | J# Int# ByteArray# -- large integers -</verb></tscreen> -<nidx>Integer type</nidx> -The primitive ops to support large @Integers@ use the ``pieces'' of the -representation, and are as follows: - -<tscreen><verb> -negateInteger# :: Int# -> ByteArray# -> Integer - -{plus,minus,times}Integer# :: Int# -> ByteArray# - -> Int# -> ByteArray# - -> Integer - -cmpInteger# :: Int# -> ByteArray# - -> Int# -> ByteArray# - -> Int# -- -1 for <; 0 for ==; +1 for > - -divModInteger#, quotRemInteger# - :: Int# -> ByteArray# - -> Int# -> ByteArray# - -> PrelNum.Return2GMPs - -integer2Int# :: Int# -> ByteArray# -> Int# - -int2Integer# :: Int# -> Integer -- NB: no error-checking on these two! -word2Integer# :: Word# -> Integer - -addr2Integer# :: Addr# -> Integer - -- the Addr# is taken to be a `char *' string - -- to be converted into an Integer. -</verb></tscreen> -<ncdx>negateInteger#</ncdx> -<ncdx>plusInteger#</ncdx> -<ncdx>minusInteger#</ncdx> -<ncdx>timesInteger#</ncdx> -<ncdx>cmpInteger#</ncdx> -<ncdx>divModInteger#</ncdx> -<ncdx>quotRemInteger#</ncdx> -<ncdx>integer2Int#</ncdx> -<ncdx>int2Integer#</ncdx> -<ncdx>word2Integer#</ncdx> -<ncdx>addr2Integer#</ncdx> - -<sect2>Words and addresses -<p> -<nidx>word, primitive type</nidx> -<nidx>address, primitive type</nidx> -<nidx>unsigned integer, primitive type</nidx> -<nidx>pointer, primitive type</nidx> - -A @Word#@ is used for bit-twiddling operations. It is the same size as -an @Int#@, but has no sign nor any arithmetic operations. -<tscreen><verb> -type Word# -- Same size/etc as Int# but *unsigned* -type Addr# -- A pointer from outside the "Haskell world" (from C, probably); - -- described under "arrays" - -</verb></tscreen> -<ncdx>Word#</ncdx> -<ncdx>Addr#</ncdx> - -@Word#@s and @Addr#@s have the usual comparison operations. -Other unboxed-@Word@ ops (bit-twiddling and coercions): - -<tscreen><verb> -and#, or#, xor# :: Word# -> Word# -> Word# - -- standard bit ops. - -quotWord#, remWord# :: Word# -> Word# -> Word# - -- word (i.e. unsigned) versions are different from int - -- versions, so we have to provide these explicitly. - -not# :: Word# -> Word# - -shiftL#, shiftRA#, shiftRL# :: Word# -> Int# -> Word# - -- shift left, right arithmetic, right logical - -int2Word# :: Int# -> Word# -- just a cast, really -word2Int# :: Word# -> Int# -</verb></tscreen> -<nidx>bit operations, Word and Addr</nidx> -<ncdx>and#</ncdx> -<ncdx>or#</ncdx> -<ncdx>xor#</ncdx> -<ncdx>not#</ncdx> -<ncdx>quotWord#</ncdx> -<ncdx>remWord#</ncdx> -<ncdx>shiftL#</ncdx> -<ncdx>shiftRA#</ncdx> -<ncdx>shiftRL#</ncdx> -<ncdx>int2Word#</ncdx> -<ncdx>word2Int#</ncdx> - -Unboxed-@Addr@ ops (C casts, really): -<tscreen><verb> -int2Addr# :: Int# -> Addr# -addr2Int# :: Addr# -> Int# -</verb></tscreen> -<ncdx>int2Addr#</ncdx> -<ncdx>addr2Int#</ncdx> - -The casts between @Int#@, @Word#@ and @Addr#@ correspond to null -operations at the machine level, but are required to keep the Haskell -type checker happy. - -Operations for indexing off of C pointers (@Addr#@s) to snatch values -are listed under ``arrays''. - -<sect2>Arrays -<p> -<nidx>arrays, primitive</nidx> - -The type @Array# elt@ is the type of primitive, unpointed arrays of -values of type @elt@. - -<tscreen><verb> -type Array# elt -</verb></tscreen> -<ncdx>Array#</ncdx> - -@Array#@ is more primitive than a Haskell array --- indeed, the -Haskell @Array@ interface is implemented using @Array#@ --- in that an -@Array#@ is indexed only by @Int#@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 @Array#@ are themselves boxed. - -The type @ByteArray#@ is similar to @Array#@, except that it contains -just a string of (non-pointer) bytes. - -<tscreen><verb> -type ByteArray# -</verb></tscreen> -<ncdx>ByteArray#</ncdx> - -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, @ByteArray#@ is deliberately -a bit vague about the type of its components. Operations are provided -to extract values of type @Char#@, @Int#@, @Float#@, @Double#@, and -@Addr#@ from arbitrary offsets within a @ByteArray#@. (For type -@Foo#@, the $i$th offset gets you the $i$th @Foo#@, not the @Foo#@ at -byte-position $i$. Mumble.) (If you want a @Word#@, grab an @Int#@, -then coerce it.) - -Lastly, we have static byte-arrays, of type @Addr#@ [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 @ByteArray#@. They -are only needed in order to pass values from C to Haskell. - -<sect2>Reading and writing -<p> - -Primitive arrays are linear, and indexed starting at zero. - -The size and indices of a @ByteArray#@, @Addr#@, and -@MutableByteArray#@ 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 @ByteArray#@ to contain a mixture of values of different -type, which is often needed when preparing data for and unpicking -results from C. (Umm... not true of indices... WDP 95/09) - -<em>Should we provide some @sizeOfDouble#@ constants?</em> - -Out-of-range errors on indexing should be caught by the code which -uses the primitive operation; the primitive operations themselves do -<em>not</em> check for out-of-range indexes. The intention is that the -primitive ops compile to one machine instruction or thereabouts. - -We use the terms ``reading'' and ``writing'' to refer to accessing -<em>mutable</em> arrays (see Section~<ref name="Mutable arrays" id="sect:mutable">), and -``indexing'' to refer to reading a value from an <em>immutable</em> -array. - -Immutable byte arrays are straightforward to index (all indices in bytes): -<tscreen><verb> -indexCharArray# :: ByteArray# -> Int# -> Char# -indexIntArray# :: ByteArray# -> Int# -> Int# -indexAddrArray# :: ByteArray# -> Int# -> Addr# -indexFloatArray# :: ByteArray# -> Int# -> Float# -indexDoubleArray# :: ByteArray# -> Int# -> Double# - -indexCharOffAddr# :: Addr# -> Int# -> Char# -indexIntOffAddr# :: Addr# -> Int# -> Int# -indexFloatOffAddr# :: Addr# -> Int# -> Float# -indexDoubleOffAddr# :: Addr# -> Int# -> Double# -indexAddrOffAddr# :: Addr# -> Int# -> Addr# - -- Get an Addr# from an Addr# offset -</verb></tscreen> -<ncdx>indexCharArray#</ncdx> -<ncdx>indexIntArray#</ncdx> -<ncdx>indexAddrArray#</ncdx> -<ncdx>indexFloatArray#</ncdx> -<ncdx>indexDoubleArray#</ncdx> -<ncdx>indexCharOffAddr#</ncdx> -<ncdx>indexIntOffAddr#</ncdx> -<ncdx>indexFloatOffAddr#</ncdx> -<ncdx>indexDoubleOffAddr#</ncdx> -<ncdx>indexAddrOffAddr#</ncdx> - -The last of these, @indexAddrOffAddr#@, extracts an @Addr#@ using an offset -from another @Addr#@, thereby providing the ability to follow a chain of -C pointers. - -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 --- 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 Section <ref name="Unboxed -Tuples" id="unboxed-tuples">). - -<tscreen><verb> -indexArray# :: Array# elt -> Int# -> (# elt #) -</verb></tscreen> -<ncdx>indexArray#</ncdx> - - -<sect2>The state type -<p> -<ncdx>state, primitive type</ncdx> -<ncdx>State#</ncdx> - -The primitive type @State#@ 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 <em>only</em> effect of this parameterisation is in the type -system: all values of type @State#@ 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. - -<tscreen><verb> -type State# s -</verb></tscreen> - -The type @GHC.RealWorld@ 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 <em>not unlifted!</em> Its only role in life is to be -the type which distinguishes the @IO@ state transformer. - -<tscreen><verb> -data RealWorld -</verb></tscreen> - -<sect2>State of the world -<p> - -A single, primitive, value of type @State# RealWorld@ is provided. - -<tscreen><verb> -realWorld# :: State# RealWorld -</verb></tscreen> -<nidx>realWorld# state object</nidx> - -(Note: in the compiler, not a @PrimOp@; just a mucho magic -@Id@. Exported from @GHC@, though). - -<sect2>Mutable arrays -<p> -<label id="sect:mutable"> -<nidx>mutable arrays</nidx> -<nidx>arrays, mutable</nidx> - -Corresponding to @Array#@ and @ByteArray#@, 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. - -<tscreen><verb> -type MutableArray# s elt -type MutableByteArray# s -</verb></tscreen> -<ncdx>MutableArray#</ncdx> -<ncdx>MutableByteArray#</ncdx> - -<sect3>Allocation -<p> -<nidx>mutable arrays, allocation</nidx> -<nidx>arrays, allocation</nidx> -<nidx>allocation, of mutable arrays</nidx> - -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. - -<tscreen><verb> -newArray# :: Int# -> elt -> State# s -> (# State# s, MutableArray# s elt #) - -newCharArray# :: Int# -> State# s -> (# State# s, MutableByteArray# s elt #) -newIntArray# :: Int# -> State# s -> (# State# s, MutableByteArray# s elt #) -newAddrArray# :: Int# -> State# s -> (# State# s, MutableByteArray# s elt #) -newFloatArray# :: Int# -> State# s -> (# State# s, MutableByteArray# s elt #) -newDoubleArray# :: Int# -> State# s -> (# State# s, MutableByteArray# s elt #) -</verb></tscreen> -<ncdx>newArray#</ncdx> -<ncdx>newCharArray#</ncdx> -<ncdx>newIntArray#</ncdx> -<ncdx>newAddrArray#</ncdx> -<ncdx>newFloatArray#</ncdx> -<ncdx>newDoubleArray#</ncdx> - -The size of a @ByteArray#@ is given in bytes. - -<sect3>Reading and writing -<p> -<nidx>arrays, reading and writing</nidx> - -<tscreen><verb> -readArray# :: MutableArray# s elt -> Int# -> State# s -> (# State# s, elt #) -readCharArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Char# #) -readIntArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #) -readAddrArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Addr# #) -readFloatArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Float# #) -readDoubleArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Double# #) - -writeArray# :: MutableArray# s elt -> Int# -> elt -> State# s -> State# s -writeCharArray# :: MutableByteArray# s -> Int# -> Char# -> State# s -> State# s -writeIntArray# :: MutableByteArray# s -> Int# -> Int# -> State# s -> State# s -writeAddrArray# :: MutableByteArray# s -> Int# -> Addr# -> State# s -> State# s -writeFloatArray# :: MutableByteArray# s -> Int# -> Float# -> State# s -> State# s -writeDoubleArray# :: MutableByteArray# s -> Int# -> Double# -> State# s -> State# s -</verb></tscreen> -<ncdx>readArray#</ncdx> -<ncdx>readCharArray#</ncdx> -<ncdx>readIntArray#</ncdx> -<ncdx>readAddrArray#</ncdx> -<ncdx>readFloatArray#</ncdx> -<ncdx>readDoubleArray#</ncdx> -<ncdx>writeArray#</ncdx> -<ncdx>writeCharArray#</ncdx> -<ncdx>writeIntArray#</ncdx> -<ncdx>writeAddrArray#</ncdx> -<ncdx>writeFloatArray#</ncdx> -<ncdx>writeDoubleArray#</ncdx> - - -<sect3>Equality -<p> -<nidx>arrays, testing for equality</nidx> - -One can take ``equality'' of mutable arrays. What is compared is the -<em>name</em> or reference to the mutable array, not its contents. - -<tscreen><verb> -sameMutableArray# :: MutableArray# s elt -> MutableArray# s elt -> Bool -sameMutableByteArray# :: MutableByteArray# s -> MutableByteArray# s -> Bool -</verb></tscreen> -<ncdx>sameMutableArray#</ncdx> -<ncdx>sameMutableByteArray#</ncdx> - -<sect3>Freezing mutable arrays -<p> -<nidx>arrays, freezing mutable</nidx> -<nidx>freezing mutable arrays</nidx> -<nidx>mutable arrays, freezing</nidx> - -Only unsafe-freeze has a primitive. (Safe freeze is done directly in Haskell -by copying the array and then using @unsafeFreeze@.) - -<tscreen><verb> -unsafeFreezeArray# :: MutableArray# s elt -> State# s -> (# State# s, Array# s elt #) -unsafeFreezeByteArray# :: MutableByteArray# s -> State# s -> (# State# s, ByteArray# #) -</verb></tscreen> -<ncdx>unsafeFreezeArray#</ncdx> -<ncdx>unsafeFreezeByteArray#</ncdx> - -<sect2>Stable pointers -<p> -<nidx>stable pointers</nidx> -<nidx>pointers, stable</nidx> - -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 --- in contrast to -the address of the object which may well change. - -The stable pointer type is parameterised by the type of the thing -which is named. - -<tscreen><verb> -type StablePtr# a -</verb></tscreen> -<ncdx>StablePtr#</ncdx> - -A stable pointer is represented by an index into the (static) -@StablePointerTable@. The Haskell garbage collector treats the -@StablePointerTable@ as a source of roots for GC. - -The @makeStablePointer@ function converts a value into a stable -pointer. It is part of the @IO@ monad, because we want to be sure -we don't allocate one twice by accident, and then only free one of the -copies. - -<tscreen><verb> -makeStablePointer# :: a -> State# RealWorld -> (# State# RealWord, StablePtr# a #) -freeStablePointer# :: StablePtr# a -> State# RealWorld -> State# RealWorld -deRefStablePointer# :: StablePtr# a -> State# RealWorld -> (# State# RealWorld, a #) -</verb></tscreen> -<ncdx>makeStablePointer#</ncdx> -<ncdx>freeStablePointer#</ncdx> -<ncdx>deRefStablePointer#</ncdx> - -There is also a C procedure @FreeStablePtr@ which frees a stable pointer. - -%<em>Andy's comment.</em> {\bf Errors:} The following is not strictly true: the current -%implementation is not as polymorphic as claimed. The reason for this -%is that the C programmer will have to use a different entry-routine -%for each type of stable pointer. At present, we only supply a very -%limited number (3) of these routines. It might be possible to -%increase the range of these routines by providing general purpose -%entry points to apply stable pointers to (stable pointers to) -%arguments and to enter (stable pointers to) boxed primitive values. -%<em>End of Andy's comment.</em> - -<sect2>Foreign objects -<p> -<nidx>Foreign objects</nidx> - -A @ForeignObj#@ 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 ...''. - -<tscreen><verb> -type ForeignObj# -</verb></tscreen> -<ncdx>ForeignObj#</ncdx> - -GHC provides two primitives on @ForeignObj#@: - -<tscreen><verb> -makeForeignObj# - :: Addr# -- foreign reference - -> Addr# -- pointer to finalisation routine - -> (# State# RealWorld, ForeignObj# ) -writeForeignObj - :: ForeignObj# -- foreign object - -> Addr# -- datum - -> State# RealWorld - -> State# RealWorld -</verb></tscreen> -<ncdx>makeForeignObj#</ncdx> -<ncdx>writeForeignObj#</ncdx> - -The module @Foreign@ (see library documentation) provides a more -programmer-friendly interface to foreign objects. - -<sect2>Synchronizing variables (M-vars) -<p> -<nidx>synchronising variables (M-vars)</nidx> -<nidx>M-Vars</nidx> - -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). - -<tscreen><verb> -type MVar# s elt -- primitive - -newMVar# :: State# s -> (# State# s, MVar# s elt #) -takeMVar# :: SynchVar# s elt -> State# s -> (# State# s, elt #) -putMVar# :: SynchVar# s elt -> State# s -> State# s -</verb></tscreen> -<ncdx>SynchVar#</ncdx> -<ncdx>newSynchVar#</ncdx> -<ncdx>takeMVar</ncdx> -<ncdx>putMVar</ncdx> diff --git a/ghc/docs/users_guide/parallel.vsgml b/ghc/docs/users_guide/parallel.vsgml deleted file mode 100644 index 7b077b291c481b0b6692996e1a621d141775eb77..0000000000000000000000000000000000000000 --- a/ghc/docs/users_guide/parallel.vsgml +++ /dev/null @@ -1,152 +0,0 @@ -% both concurrent and parallel -%************************************************************************ -%* * -<sect1>Concurrent and Parallel Haskell -<label id="concurrent-and-parallel"> -<p> -<nidx>Concurrent Haskell</nidx> -<nidx>Parallel Haskell</nidx> -%* * -%************************************************************************ - -Concurrent and Parallel Haskell are Glasgow extensions to Haskell -which let you structure your program as a group of independent -`threads'. - -Concurrent and Parallel Haskell have very different purposes. - -Concurrent Haskell is for applications which have an inherent -structure of interacting, concurrent tasks (i.e. `threads'). Threads -in such programs may be <em>required</em>. For example, if a concurrent -thread has been spawned to handle a mouse click, it isn't -optional---the user wants something done! - -A Concurrent Haskell program implies multiple `threads' running within -a single Unix process on a single processor. - -You will find at least one paper about Concurrent Haskell hanging off -of <url name="Simon Peyton Jones's Web page" -url="http://www.dcs.gla.ac.uk/~simonpj/">. - -Parallel Haskell is about <em>speed</em>---spawning threads onto multiple -processors so that your program will run faster. The `threads' -are always <em>advisory</em>---if the runtime system thinks it can -get the job done more quickly by sequential execution, then fine. - -A Parallel Haskell program implies multiple processes running on -multiple processors, under a PVM (Parallel Virtual Machine) framework. - -Parallel Haskell is still relatively new; it is more about ``research -fun'' than about ``speed.'' That will change. - -Again, check Simon's Web page for publications about Parallel Haskell -(including ``GUM'', the key bits of the runtime system). - -Some details about Parallel Haskell follow. For more information -about concurrent Haskell, see the Concurrent section in the <htmlurl -name="GHC/Hugs Extension Libraries" url="libs.html"> documentation. - -%************************************************************************ -%* * -<sect2>Features specific to Parallel Haskell -<nidx>Parallel Haskell---features</nidx> -<p> -%* * -%************************************************************************ - -%************************************************************************ -%* * -<sect3>The @Parallel@ interface (recommended) -<nidx>Parallel interface</nidx> -<p> -%* * -%************************************************************************ - -GHC provides two functions for controlling parallel execution, through -the @Parallel@ interface: - -<tscreen><verb> -interface Parallel where -infixr 0 `par` -infixr 1 `seq` - -par :: a -> b -> b -seq :: a -> b -> b -</verb></tscreen> - -The expression @(x `par` y)@ <em>sparks</em> the evaluation of @x@ -(to weak head normal form) and returns @y@. 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. - -The expression @(x `seq` y)@ evaluates @x@ to weak head normal -form and then returns @y@. The @seq@ 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. - -For example, consider the following parallel version of our old -nemesis, @nfib@: - -<tscreen><verb> -import Parallel - -nfib :: Int -> Int -nfib n | n <= 1 = 1 - | otherwise = par n1 (seq n2 (n1 + n2 + 1)) - where n1 = nfib (n-1) - n2 = nfib (n-2) -</verb></tscreen> - -For values of @n@ greater than 1, we use @par@ to spark a thread -to evaluate @nfib (n-1)@, and then we use @seq@ to force the -parent thread to evaluate @nfib (n-2)@ 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 -@seq@ to ensure that the parent will evaluate @n2@ <em>before</em> -@n1@ in the expression @(n1 + n2 + 1)@. It is not sufficient to -reorder the expression as @(n2 + n1 + 1)@, because the compiler may -not generate code to evaluate the addends from left to right. - -%************************************************************************ -%* * -<sect3>Underlying functions and primitives -<nidx>parallelism primitives</nidx> -<nidx>primitives for parallelism</nidx> -<p> -%* * -%************************************************************************ - -The functions @par@ and @seq@ are wired into GHC, and unfold -into uses of the @par#@ and @seq#@ primitives, respectively. If -you'd like to see this with your very own eyes, just run GHC with the -@-ddump-simpl@ option. (Anything for a good time...) - -%************************************************************************ -%* * -<sect3>Scheduling policy for concurrent/parallel threads -<nidx>Scheduling---concurrent/parallel</nidx> -<nidx>Concurrent/parallel scheduling</nidx> -<p> -%* * -%************************************************************************ - -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 -@-C[<num>]@<nidx>-C<num> RTS option (concurrent, -parallel)</nidx> 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. - -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 @-t<num>@<nidx>-t <num> RTS option (concurrent, parallel)</nidx> -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. diff --git a/ghc/docs/users_guide/posix.vsgml b/ghc/docs/users_guide/posix.vsgml deleted file mode 100644 index 44eb171d27e5b442d3bec47abc602173ff9ff5d0..0000000000000000000000000000000000000000 --- a/ghc/docs/users_guide/posix.vsgml +++ /dev/null @@ -1,1441 +0,0 @@ -%************************************************************************ -%* * -<sect1>The Posix library -<label id="Posix-library"> -<p> -<nidx>Posix library</nidx> -<nidx>libraries, Posix</nidx> -%* * -%************************************************************************ - -The @Posix@ interface gives you access to the set of OS services -standardised by POSIX 1003.1b (or the <em>IEEE Portable Operating System -Interface for Computing Environments</em> - IEEE Std. 1003.1). The -interface is accessed by @import Posix@ and adding -@-syslib posix@ on your command-line. - -<sect2>Posix data types -<label id="Posix data types"> -<p> -<nidx>Posix, data types</nidx> - - -<tscreen><verb> -data ByteCount -- instances of : Eq Ord Num Real Integral Ix Enum Show -</verb></tscreen> - -A @ByteCount@ is a primitive of type @unsigned@. At a minimum, -an conforming implementation must support values in the range -@[0, UINT_MAX]@. - -<tscreen><verb> -data ClockTick -- instances of : Eq Ord Num Real Integral Ix Enum Show -</verb></tscreen> - -A @ClockTick@ is a primitive of type @clock_t@, which -is used to measure intervals of time in fractions of a second. The -resolution is determined by @getSysVar ClockTick@. - -<tscreen><verb> -data DeviceID -- instances of : Eq Ord Num Real Integral Ix Enum Show -</verb></tscreen> - -A @DeviceID@ is a primitive of type @dev_t@. It must -be an arithmetic type. - -<tscreen><verb> -data EpochTime -- instances of : Eq Ord Num Real Integral Ix Enum Show -</verb></tscreen> - -A @EpochTime@ is a primitive of type @time_t@, which is -used to measure seconds since the Epoch. At a minimum, the implementation -must support values in the range @[0, INT_MAX]@. - -<tscreen><verb> -data FileID -- instances of : Eq Ord Num Real Integral Ix Enum Show -</verb></tscreen> - -A @FileID@ is a primitive of type @ino_t@. It must -be an arithmetic type. - -<tscreen><verb> -data FileMode -- instances of : Eq Ord Num Real Integral Ix Enum Show -</verb></tscreen> - -A @FileMode@ is a primitive of type @mode_t@. -It must be an arithmetic type. - -<tscreen><verb> -data FileOffset -- instances of : Eq Ord Num Real Integral Ix Enum Show -</verb></tscreen> - -A @FileOffset@ is a primitive of type @off_t@. It must -be an arithmetic type. - -<tscreen><verb> -data GroupID -- instances of : Eq Ord Num Real Integral Ix Enum Show -</verb></tscreen> - -A @GroupID@ is a primitive of type @gid_t@. It must -be an arithmetic type. -<tscreen><verb> -data Limit -- instances of : Eq Ord Num Real Integral Ix Enum Show -</verb></tscreen> - -A @Limit@ is a primitive of type @long@. -At a minimum, the implementation must support values in the range -@[LONG_MIN, LONG_MAX]@. - -<tscreen><verb> -data LinkCount -- instances of : Eq Ord Num Real Integral Ix Enum Show -</verb></tscreen> - -A @LinkCount@ is a primitive of type @nlink_t@. It must -be an arithmetic type. - -<tscreen><verb> -data ProcessID -- instances of : Eq Ord Num Real Integral Ix Enum Show -type ProcessGroupID = ProcessID -</verb></tscreen> - -A @ProcessID@ is a primitive of type @pid_t@. It -must be a signed arithmetic type. -<tscreen><verb> -data UserID -- instances of : Eq Ord Num Real Integral Ix Enum Show -</verb></tscreen> - -A @UserID@ is a primitive of type @uid_t@. It -must be an arithmetic type. - -<tscreen><verb> -data DirStream -</verb></tscreen> -A @DirStream@ is a primitive of type @DIR *@. - -<tscreen><verb> -data FileStatus -</verb></tscreen> -A @FileStatus@ is a primitive of type @struct stat@. - -<tscreen><verb> -data GroupEntry -</verb></tscreen> - -A @GroupEntry@ is a primitive of type @struct group@. -<tscreen><verb> -data ProcessTimes -</verb></tscreen> - -@ProcessTimes@ is a primitive structure containing a -@clock_t@ and a @struct tms@. - -<tscreen><verb> -data SignalSet -</verb></tscreen> - -An @SignalSet@ is a primitive of type @sigset_t@. - -<tscreen><verb> -data SystemID -</verb></tscreen> - -A @SystemID@ is a primitive of type @struct utsname@. - -<tscreen><verb> -data TerminalAttributes -</verb></tscreen> -@TerminalAttributes@ is a primitive of type @struct termios@. - -<tscreen><verb> -data UserEntry -</verb></tscreen> - -A @UserEntry@ is a primitive of type @struct passwd@. - -<tscreen><verb> -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 -> 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) -</verb></tscreen> - -<sect2>Posix Process Primitives -<label id="Process Primitives"> -<p> - -<tscreen><verb> -forkProcess :: IO (Maybe ProcessID) -</verb></tscreen> - -@forkProcess@ calls @fork@, returning -@Just pid@ to the parent, where @pid@ is the -ProcessID of the child, and returning @Nothing@ to the -child. - -<tscreen><verb> -executeFile :: FilePath -- Command - -> Bool -- Search PATH? - -> [String] -- Arguments - -> Maybe [(String, String)] -- Environment - -> IO () -</verb></tscreen> - -@executeFile cmd args env@ calls one of the -@execv*@ 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 @execv*@ as @arg[0]@; -the argument list passed to @executeFile@ therefore begins -with @arg[1]@. - -<tscreen><verb> -Search PATH? Supersede environ? Call -~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~ ~~~~~~~ -False False execv -False True execve -True False execvp -True True execvpe* -</verb></tscreen> - -Note that @execvpe@ 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. - -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' @fork()@ semantics. Using -Haskell, there's the extra complication that arguments to -@executeFile@ might come from files that are read lazily (using -@hGetContents@, or some such.) If this is the case, then for your own -sanity, please ensure that the arguments to @executeFile@ have been -fully evaluated before calling @forkProcess@ (followed by -@executeFile@.) Consider yourself warned :-) - -A successful @executeFile@ overlays the current process image with -a new one, so it only returns on failure. - -<tscreen><verb> -runProcess :: FilePath -- Command - -> [String] -- Arguments - -> Maybe [(String, String)] -- Environment (Nothing -> Inherited) - -> Maybe FilePath -- Working directory (Nothing -> inherited) - -> Maybe Handle -- stdin (Nothing -> inherited) - -> Maybe Handle -- stdout (Nothing -> inherited) - -> Maybe Handle -- stderr (Nothing -> inherited) - -> IO () -</verb></tscreen> - -@runProcess@ is our candidate for the high-level OS-independent -primitive. - -@runProcess cmd args env wd inhdl outhdl errhdl@ runs @cmd@ -(searching the current @PATH@) with arguments @args@. If -@env@ is @Just pairs@, the command is executed with the -environment specified by @pairs@ of variables and values; -otherwise, the command is executed with the current environment. If -@wd@ is @Just dir@, the command is executed with working -directory @dir@; otherwise, the command is executed in the current -working directory. If @{in,out,err@hdl} is @Just handle@, the -command is executed with the @Fd@ for @std{in,out,err@} -attached to the specified @handle@; otherwise, the @Fd@ for -@std{in,out,err@} is left unchanged. - -<tscreen><verb> -getProcessStatus :: Bool -- Block? - -> Bool -- Stopped processes? - -> ProcessID - -> IO (Maybe ProcessStatus) -</verb></tscreen> - -@getProcessStatus blk stopped pid@ calls @waitpid@, returning -@Just tc@, the @ProcessStatus@ for process @pid@ if it is -available, @Nothing@ otherwise. If @blk@ is @False@, then -@WNOHANG@ is set in the options for @waitpid@, otherwise not. -If @stopped@ is @True@, then @WUNTRACED@ is set in the -options for @waitpid@, otherwise not. - -<tscreen><verb> -getGroupProcessStatus :: Bool -- Block? - -> Bool -- Stopped processes? - -> ProcessGroupID - -> IO (Maybe (ProcessID, ProcessStatus)) -</verb></tscreen> - -@getGroupProcessStatus blk stopped pgid@ calls @waitpid@, -returning @Just (pid, tc)@, the @ProcessID@ and -@ProcessStatus@ for any process in group @pgid@ if one is -available, @Nothing@ otherwise. If @blk@ is @False@, then -@WNOHANG@ is set in the options for @waitpid@, otherwise not. -If @stopped@ is @True@, then @WUNTRACED@ is set in the -options for @waitpid@, otherwise not. - -<tscreen><verb> -getAnyProcessStatus :: Bool -- Block? - -> Bool -- Stopped processes? - -> IO (Maybe (ProcessID, ProcessStatus)) -</verb></tscreen> - -@getAnyProcessStatus blk stopped@ calls @waitpid@, returning -@Just (pid, tc)@, the @ProcessID@ and @ProcessStatus@ for any -child process if one is available, @Nothing@ otherwise. If -@blk@ is @False@, then @WNOHANG@ is set in the options for -@waitpid@, otherwise not. If @stopped@ is @True@, then -@WUNTRACED@ is set in the options for @waitpid@, otherwise not. - -<tscreen><verb> -exitImmediately :: ExitCode -> IO () -</verb></tscreen> - -@exitImmediately status@ calls @_exit@ to terminate the process -with the indicated exit @status@. -The operation never returns. - -<tscreen><verb> -getEnvironment :: IO [(String, String)] -</verb></tscreen> - -@getEnvironment@ parses the environment variable mapping provided by -@environ@, returning @(variable, value)@ pairs. -The operation never fails. - -<tscreen><verb> -setEnvironment :: [(String, String)] -> IO () -</verb></tscreen> - -@setEnvironment@ replaces the process environment with the provided -mapping of @(variable, value)@ pairs. - -<tscreen><verb> -getEnvVar :: String -> IO String -</verb></tscreen> - -@getEnvVar var@ returns the value associated with variable @var@ -in the current environment (identical functionality provided through -standard Haskell library function @System.getEnv@). - -The operation may fail with: - -<descrip> -<tag>@NoSuchThing@</tag> -The variable has no mapping in the current environment. -</descrip> - -<tscreen><verb> -setEnvVar :: String -> String -> IO () -</verb></tscreen> - -@setEnvVar var val@ sets the value associated with variable @var@ -in the current environment to be @val@. Any previous mapping is -superseded. - -<tscreen><verb> -removeEnvVar :: String -> IO () -</verb></tscreen> - -@removeEnvVar var@ removes any value associated with variable @var@ -in the current environment. Deleting a variable for which there is no mapping -does not generate an error. - -<tscreen><verb> -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 -> ProcessID -> IO () -</verb></tscreen> - -@signalProcess int pid@ calls @kill@ to signal -process @pid@ with interrupt signal @int@. - -<tscreen><verb> -raiseSignal :: Signal -> IO () -</verb></tscreen> - -@raiseSignal int@ calls @kill@ to signal the current process -with interrupt signal @int@. - -<tscreen><verb> -signalProcessGroup :: Signal -> ProcessGroupID -> IO () -</verb></tscreen> - -@signalProcessGroup int pgid@ calls @kill@ to signal -all processes in group @pgid@ with interrupt signal @int@. - -<tscreen><verb> -setStoppedChildFlag :: Bool -> IO Bool -</verb></tscreen> - -@setStoppedChildFlag bool@ sets a flag which controls whether or -not the @NOCLDSTOP@ option will be used the next time a signal -handler is installed for @SIGCHLD@. If @bool@ is @True@ (the -default), @NOCLDSTOP@ will not be used; otherwise it will be. The -operation never fails. - -<tscreen><verb> -queryStoppedChildFlag :: IO Bool -</verb></tscreen> - -@queryStoppedChildFlag@ queries the flag which -controls whether or not the @NOCLDSTOP@ option will be used -the next time a signal handler is installed for @SIGCHLD@. -If @NOCLDSTOP@ will be used, it returns @False@; -otherwise (the default) it returns @True@. -The operation never fails. - -<tscreen><verb> -emptySignalSet :: SignalSet -fullSignalSet :: SignalSet -addSignal :: Signal -> SignalSet -> SignalSet -deleteSignal :: Signal -> SignalSet -> SignalSet -inSignalSet :: Signal -> SignalSet -> Bool - -installHandler :: Signal - -> Handler - -> Maybe SignalSet -- other signals to block - -> IO Handler -- old handler -</verb></tscreen> - -@installHandler int handler iset@ calls @sigaction@ to install an -interrupt handler for signal @int@. If @handler@ is @Default@, -@SIG_DFL@ is installed; if @handler@ is @Ignore@, @SIG_IGN@ is -installed; if @handler@ is @Catch action@, a handler is installed -which will invoke @action@ in a new thread when (or shortly after) the -signal is received. See Section <ref name="Concurrent Haskell" -id="concurrent-haskell"> for details on how to communicate between -threads. - -If @iset@ is @Just s@, then the @sa_mask@ of the @sigaction@ structure -is set to @s@; otherwise it is cleared. The previously installed -signal handler for @int@ is returned. - -<tscreen><verb> -getSignalMask :: IO SignalSet -</verb></tscreen> - -@getSignalMask@ calls @sigprocmask@ to determine the -set of interrupts which are currently being blocked. - -<tscreen><verb> -setSignalMask :: SignalSet -> IO SignalSet -</verb></tscreen> - -@setSignalMask mask@ calls @sigprocmask@ with -@SIG_SETMASK@ to block all interrupts in @mask@. The -previous set of blocked interrupts is returned. - -<tscreen><verb> -blockSignals :: SignalSet -> IO SignalSet -</verb></tscreen> - -@setSignalMask mask@ calls @sigprocmask@ with -@SIG_BLOCK@ to add all interrupts in @mask@ to the -set of blocked interrupts. The previous set of blocked interrupts is returned. - -<tscreen><verb> -unBlockSignals :: SignalSet -> IO SignalSet -</verb></tscreen> - -@setSignalMask mask@ calls @sigprocmask@ with -@SIG_UNBLOCK@ to remove all interrupts in @mask@ from the -set of blocked interrupts. The previous set of blocked interrupts is returned. - -<tscreen><verb> -getPendingSignals :: IO SignalSet -</verb></tscreen> - -@getPendingSignals@ calls @sigpending@ to obtain -the set of interrupts which have been received but are currently blocked. - -<tscreen><verb> -awaitSignal :: Maybe SignalSet -> IO () -</verb></tscreen> - -@awaitSignal iset@ suspends execution until an interrupt is received. -If @iset@ is @Just s@, @awaitSignal@ calls @sigsuspend@, installing -@s@ as the new signal mask before suspending execution; otherwise, it -calls @pause@. @awaitSignal@ returns on receipt of a signal. If you -have installed any signal handlers with @installHandler@, it may be -wise to call @yield@ directly after @awaitSignal@ to ensure that the -signal handler runs as promptly. - -<tscreen><verb> -scheduleAlarm :: Int -> IO Int -</verb></tscreen> - -@scheduleAlarm i@ calls @alarm@ to schedule a real time -alarm at least @i@ seconds in the future. - -<tscreen><verb> -sleep :: Int -> IO () -</verb></tscreen> - -@sleep i@ calls @sleep@ to suspend execution of the -program until at least @i@ seconds have elapsed or a signal is -received. - -<sect2>Posix Process Environment -<label id="Process Environment"> -<p> -<nidx>Posix, process environment</nidx> - -<tscreen><verb> -getProcessID :: IO ProcessID -</verb></tscreen> - -@getProcessID@ calls @getpid@ to obtain the @ProcessID@ for -the current process. - -<tscreen><verb> -getParentProcessID :: IO ProcessID -</verb></tscreen> - -@getProcessID@ calls @getppid@ to obtain the @ProcessID@ for -the parent of the current process. - -<tscreen><verb> -getRealUserID :: IO UserID -</verb></tscreen> - -@getRealUserID@ calls @getuid@ to obtain the real @UserID@ -associated with the current process. - -<tscreen><verb> -getEffectiveUserID :: IO UserID -</verb></tscreen> - -@getRealUserID@ calls @geteuid@ to obtain the effective -@UserID@ associated with the current process. - -<tscreen><verb> -setUserID :: UserID -> IO () -</verb></tscreen> - -@setUserID uid@ calls @setuid@ to set the real, effective, and -saved set-user-id associated with the current process to @uid@. - -<tscreen><verb> -getLoginName :: IO String -</verb></tscreen> - -@getLoginName@ calls @getlogin@ to obtain the login name -associated with the current process. - -<tscreen><verb> -getRealGroupID :: IO GroupID -</verb></tscreen> - -@getRealGroupID@ calls @getgid@ to obtain the real @GroupID@ -associated with the current process. - -<tscreen><verb> -getEffectiveGroupID :: IO GroupID -</verb></tscreen> - -@getEffectiveGroupID@ calls @getegid@ to obtain the effective -@GroupID@ associated with the current process. - -<tscreen><verb> -setGroupID :: GroupID -> IO () -</verb></tscreen> - -@setGroupID gid@ calls @setgid@ to set the real, effective, and -saved set-group-id associated with the current process to @gid@. - -<tscreen><verb> -getGroups :: IO [GroupID] -</verb></tscreen> - -@getGroups@ calls @getgroups@ to obtain the list of -supplementary @GroupID@s associated with the current process. - -<tscreen><verb> -getEffectiveUserName :: IO String -</verb></tscreen> - -@getEffectiveUserName@ calls @cuserid@ to obtain a name -associated with the effective @UserID@ of the process. - -<tscreen><verb> -getProcessGroupID :: IO ProcessGroupID -</verb></tscreen> - -@getProcessGroupID@ calls @getpgrp@ to obtain the -@ProcessGroupID@ for the current process. - -<tscreen><verb> -createProcessGroup :: ProcessID -> IO ProcessGroupID -</verb></tscreen> - -@createProcessGroup pid@ calls @setpgid@ to make -process @pid@ a new process group leader. - -<tscreen><verb> -joinProcessGroup :: ProcessGroupID -> IO ProcessGroupID -</verb></tscreen> - -@joinProcessGroup pgid@ calls @setpgid@ to set the -@ProcessGroupID@ of the current process to @pgid@. - -<tscreen><verb> -setProcessGroupID :: ProcessID -> ProcessGroupID -> IO () -</verb></tscreen> - -@setProcessGroupID pid pgid@ calls @setpgid@ to set the -@ProcessGroupID@ for process @pid@ to @pgid@. - -<tscreen><verb> -createSession :: IO ProcessGroupID -</verb></tscreen> - -@createSession@ calls @setsid@ to create a new session -with the current process as session leader. - -<tscreen><verb> -systemName :: SystemID -> String -nodeName :: SystemID -> String -release :: SystemID -> String -version :: SystemID -> String -machine :: SystemID -> String - -getSystemID :: IO SystemID -</verb></tscreen> - -@getSystemID@ calls @uname@ to obtain information -about the current operating system. - -<tscreen><verb> -> epochTime :: IO EpochTime -</verb></tscreen> - -@epochTime@ calls @time@ to obtain the number of -seconds that have elapsed since the epoch (Jan 01 00:00:00 GMT 1970). - -<tscreen><verb> -elapsedTime :: ProcessTimes -> ClockTick -userTime :: ProcessTimes -> ClockTick -systemTime :: ProcessTimes -> ClockTick -childUserTime :: ProcessTimes -> ClockTick -childSystemTime :: ProcessTimes -> ClockTick - -getProcessTimes :: IO ProcessTimes -</verb></tscreen> - -@getProcessTimes@ calls @times@ to obtain time-accounting -information for the current process and its children. - -<tscreen><verb> -getControllingTerminalName :: IO FilePath -</verb></tscreen> - -@getControllingTerminalName@ calls @ctermid@ to obtain -a name associated with the controlling terminal for the process. If a -controlling terminal exists, -@getControllingTerminalName@ returns the name of the -controlling terminal. - -The operation may fail with: - -<descrip> -<tag>@NoSuchThing@</tag> -There is no controlling terminal, or its name cannot be determined. -<tag>@SystemError@</tag> -Various other causes. -</descrip> - -<tscreen><verb> -getTerminalName :: Fd -> IO FilePath -</verb></tscreen> - -@getTerminalName fd@ calls @ttyname@ to obtain a name associated -with the terminal for @Fd@ @fd@. If @fd@ is associated -with a terminal, @getTerminalName@ returns the name of the -terminal. - -The operation may fail with: - -<descrip> -<tag>@InappropriateType@</tag> -The channel is not associated with a terminal. -<tag>@NoSuchThing@</tag> -The channel is associated with a terminal, but it has no name. -<tag>@SystemError@</tag> -Various other causes. -</descrip> - -<tscreen><verb> -queryTerminal :: Fd -> IO Bool -</verb></tscreen> - -@queryTerminal fd@ calls @isatty@ to determine whether or -not @Fd@ @fd@ is associated with a terminal. - -<tscreen><verb> -getSysVar :: SysVar -> IO Limit -</verb></tscreen> - -@getSysVar var@ calls @sysconf@ to obtain the -dynamic value of the requested configurable system limit or option. -For defined system limits, @getSysVar@ returns the associated -value. For defined system options, the result of @getSysVar@ -is undefined, but not failure. - -The operation may fail with: - -<descrip> -<tag>@NoSuchThing@</tag> -The requested system limit or option is undefined. -</descrip> - -<sect2>Posix operations on files and directories -<label id="Files and Directories"> -<p> -<nidx>Posix, files and directories</nidx> - -<tscreen><verb> -openDirStream :: FilePath -> IO DirStream -</verb></tscreen> - -@openDirStream dir@ calls @opendir@ to obtain a -directory stream for @dir@. - -<tscreen><verb> -readDirStream :: DirStream -> IO String -</verb></tscreen> - -@readDirStream dp@ calls @readdir@ to obtain the -next directory entry (@struct dirent@) for the open directory -stream @dp@, and returns the @d_name@ member of that -structure. - -The operation may fail with: - -<descrip> -<tag>@EOF@</tag> -End of file has been reached. -<tag>@SystemError@</tag> -Various other causes. -</descrip> - -<tscreen><verb> -rewindDirStream :: DirStream -> IO () -</verb></tscreen> - -@rewindDirStream dp@ calls @rewinddir@ to reposition -the directory stream @dp@ at the beginning of the directory. - -<tscreen><verb> -closeDirStream :: DirStream -> IO () -</verb></tscreen> - -@closeDirStream dp@ calls @closedir@ to close -the directory stream @dp@. - -<tscreen><verb> -getWorkingDirectory :: IO FilePath -</verb></tscreen> - -@getWorkingDirectory@ calls @getcwd@ to obtain the name -of the current working directory. - -<tscreen><verb> -changeWorkingDirectory :: FilePath -> IO () -</verb></tscreen> - -@changeWorkingDirectory dir@ calls @chdir@ to change -the current working directory to @dir@. - -<tscreen><verb> -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 -> FileMode -> FileMode -intersectFileModes :: FileMode -> FileMode -> 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 - -> OpenMode - -> Maybe FileMode -- Just x => O_CREAT, Nothing => must exist - -> OpenFileFlags - -> IO Fd -</verb></tscreen> - -@openFd path acc mode (OpenFileFlags app excl noctty nonblock trunc)@ calls -@open@ to obtain a @Fd@ for the file @path@ with access -mode @acc@. If @mode@ is @Just m@, the @O_CREAT@ flag is -set and the file's permissions will be based on @m@ if it does not -already exist; otherwise, the @O_CREAT@ flag is not set. The -arguments @app@, @excl@, @noctty@, @nonblock@, and -@trunc@ control whether or not the flags @O_APPEND@, -@O_EXCL@, @O_NOCTTY@, @O_NONBLOCK@, and @O_TRUNC@ are set, -respectively. - -<tscreen><verb> -createFile :: FilePath -> FileMode -> IO Fd -</verb></tscreen> - -@createFile path mode@ calls @creat@ to obtain a @Fd@ -for file @path@, which will be created with permissions based on -@mode@ if it does not already exist. - -<tscreen><verb> -setFileCreationMask :: FileMode -> IO FileMode -</verb></tscreen> - -@setFileCreationMask mode@ calls @umask@ to set -the process's file creation mask to @mode@. The previous file -creation mask is returned. - -<tscreen><verb> -createLink :: FilePath -> FilePath -> IO () -</verb></tscreen> - -@createLink old new@ calls @link@ to create a -new path, @new@, linked to an existing file, @old@. -<tscreen><verb> -createDirectory :: FilePath -> FileMode -> IO () -</verb></tscreen> - -@createDirectory dir mode@ calls @mkdir@ to -create a new directory, @dir@, with permissions based on -@mode@. - -<tscreen><verb> -createNamedPipe :: FilePath -> FileMode -> IO () -</verb></tscreen> - -@createNamedPipe fifo mode@ calls @mkfifo@ to -create a new named pipe, @fifo@, with permissions based on -@mode@. - -<tscreen><verb> -removeLink :: FilePath -> IO () -</verb></tscreen> - -@removeLink path@ calls @unlink@ to remove the link -named @path@. - -<tscreen><verb> -removeDirectory :: FilePath -> IO () -</verb></tscreen> - -@removeDirectory dir@ calls @rmdir@ to remove the -directory named @dir@. - -<tscreen><verb> -rename :: FilePath -> FilePath -> IO () -</verb></tscreen> - -@rename old new@ calls @rename@ to rename a -file or directory from @old@ to @new@. - -<tscreen><verb> -fileMode :: FileStatus -> FileMode - -fileID :: FileStatus -> FileID -deviceID :: FileStatus -> DeviceID - -linkCount :: FileStatus -> LinkCount - -fileOwner :: FileStatus -> UserID -fileGroup :: FileStatus -> GroupID -fileSize :: FileStatus -> FileOffset - -accessTime :: FileStatus -> EpochTime -modificationTime :: FileStatus -> EpochTime -statusChangeTime :: FileStatus -> EpochTime - -isDirectory :: FileStatus -> Bool -isCharacterDevice :: FileStatus -> Bool -isBlockDevice :: FileStatus -> Bool -isRegularFile :: FileStatus -> Bool -isNamedPipe :: FileStatus -> Bool - -getFileStatus :: FilePath -> IO FileStatus -</verb></tscreen> - -@getFileStatus path@ calls @stat@ to get the -@FileStatus@ information for the file @path@. - -<tscreen><verb> -getFdStatus :: Fd -> IO FileStatus -</verb></tscreen> - -@getFdStatus fd@ calls @fstat@ to get the -@FileStatus@ information for the file associated with -@Fd@ @fd@. - -<tscreen><verb> -queryAccess :: FilePath -> Bool -> Bool -> Bool -> IO Bool -</verb></tscreen> - -@queryAccess path r w x@ calls @access@ to test the access -permissions for file @path@. The three arguments, @r@, @w@, -and @x@ control whether or not @access@ is called with -@R_OK@, @W_OK@, and @X_OK@ respectively. - -<tscreen><verb> -queryFile :: FilePath -> IO Bool -</verb></tscreen> - -@queryFile path@ calls @access@ with @F_OK@ to test for the -existence for file @path@. - -<tscreen><verb> -setFileMode :: FilePath -> FileMode -> IO () -</verb></tscreen> - -@setFileMode path mode@ calls @chmod@ to set the -permission bits associated with file @path@ to @mode@. - -<tscreen><verb> -setOwnerAndGroup :: FilePath -> UserID -> GroupID -> IO () -</verb></tscreen> - -@setOwnerAndGroup path uid gid@ calls @chown@ to -set the @UserID@ and @GroupID@ associated with file -@path@ to @uid@ and @gid@, respectively. - -<tscreen><verb> -setFileTimes :: FilePath -> EpochTime -> EpochTime -> IO () -</verb></tscreen> - -@setFileTimes path atime mtime@ calls @utime@ to -set the access and modification times associated with file -@path@ to @atime@ and @mtime@, respectively. - -<tscreen><verb> -touchFile :: FilePath -> IO () -</verb></tscreen> - -@touchFile path@ calls @utime@ to -set the access and modification times associated with file -@path@ to the current time. - -<tscreen><verb> -getPathVar :: PathVar -> FilePath -> IO Limit -</verb></tscreen> - -@getPathVar var path@ calls @pathconf@ to obtain the -dynamic value of the requested configurable file limit or option associated -with file or directory @path@. For -defined file limits, @getPathVar@ returns the associated -value. For defined file options, the result of @getPathVar@ -is undefined, but not failure. -The operation may fail with: -<descrip> -<tag>@NoSuchThing@</tag> -The requested file limit or option is undefined. -<tag>@SystemError@</tag> -Various other causes. -</descrip> - - -<tscreen><verb> -getFdVar :: PathVar -> Fd -> IO Limit -</verb></tscreen> - -@getFdVar var fd@ calls @fpathconf@ to obtain the -dynamic value of the requested configurable file limit or option associated -with the file or directory attached to the open channel @fd@. -For defined file limits, @getFdVar@ returns the associated -value. For defined file options, the result of @getFdVar@ -is undefined, but not failure. - -The operation may fail with: - -<descrip> -<tag>@NoSuchThing@</tag> -The requested file limit or option is undefined. -<tag>@SystemError@</tag> -Various other causes. -</descrip> - -<sect2>Posix Input and Output Primitives -<label id="Input/Output"> -<p> -<nidx>Posix, input/output</nidx> - -<tscreen><verb> -createPipe :: IO (Fd, Fd) -</verb></tscreen> - -@createPipe@ calls @pipe@ to create a pipe and returns a pair of -@Fd@s, the first for reading and the second for writing. - -<tscreen><verb> -dup :: Fd -> IO Fd -</verb></tscreen> - -@dup fd@ calls @dup@ to duplicate @Fd@ @fd@ to -another @Fd@. - -<tscreen><verb> -dupTo :: Fd -> Fd -> IO () -</verb></tscreen> - -@dupTo src dst@ calls @dup2@ to duplicate @Fd@ -@src@ to @Fd@ @dst@. - -<tscreen><verb> -fdClose :: Fd -> IO () -</verb></tscreen> - -@fdClose fd@ calls @close@ to close @Fd@ @fd@. - -<tscreen><verb> -fdRead :: Fd -> ByteCount -> IO (String, ByteCount) -</verb></tscreen> - -@fdRead fd nbytes@ calls @read@ to read at most @nbytes@ -bytes from @Fd@ @fd@, and returns the result as a string -paired with the number of bytes actually read. - -The operation may fail with: - -<descrip> -<tag>@EOF@</tag> -End of file has been reached. -<tag>@SystemError@</tag> -Various other causes. -</descrip> - -<tscreen><verb> -fdWrite :: Fd -> String -> IO ByteCount -</verb></tscreen> - -@fdWrite fd s@ calls @write@ to write -the string @s@ to @Fd@ @fd@ as a -contiguous sequence of bytes. It returns the number of bytes successfully -written. - -<tscreen><verb> -queryFdOption :: FdOption -> Fd -> IO Bool -</verb></tscreen> - -@getFdOption opt fd@ calls @fcntl@ to determine whether or -not the flag associated with @FdOption@ @opt@ is set for -@Fd@ @fd@. - -<tscreen><verb> -setFdOption :: Fd -> FdOption -> Bool -> IO () -</verb></tscreen> - -@setFdOption fd opt val@ calls @fcntl@ to set the flag -associated with @FdOption@ @opt@ on @Fd@ @fd@ to -@val@. - -<tscreen><verb> -getLock :: Fd -> FileLock -> IO (Maybe (ProcessID, FileLock)) -</verb></tscreen> - -@getLock fd lock@ calls @fcntl@ to get the first @FileLock@ -for @Fd@ @fd@ which blocks the @FileLock@ @lock@. If -no such @FileLock@ exists, @getLock@ returns @Nothing@. -Otherwise, it returns @Just (pid, block)@, where @block@ is the -blocking @FileLock@ and @pid@ is the @ProcessID@ of the -process holding the blocking @FileLock@. - - -<tscreen><verb> -setLock :: Fd -> FileLock -> IO () -</verb></tscreen> - -@setLock fd lock@ calls @fcntl@ with @F_SETLK@ to set or -clear a lock segment for @Fd@ @fd@ as indicated by the -@FileLock@ @lock@. @setLock@ does not block, but fails with -@SystemError@ if the request cannot be satisfied immediately. - -<tscreen><verb> -waitToSetLock :: Fd -> FileLock -> IO () -</verb></tscreen> - -@waitToSetLock fd lock@ calls @fcntl@ with @F_SETLKW@ to set -or clear a lock segment for @Fd@ @fd@ as indicated by the -@FileLock@ @lock@. If the request cannot be satisfied -immediately, @waitToSetLock@ blocks until the request can be -satisfied. - - -<tscreen><verb> -fdSeek :: Fd -> SeekMode -> FileOffset -> IO FileOffset -</verb></tscreen> - -@fdSeek fd whence offset@ calls @lseek@ to position the -@Fd@ @fd@ at the given @offset@ from the starting location -indicated by @whence@. It returns the resulting offset from the -start of the file in bytes. - -<sect2>Posix, Device- and Class-Specific Functions -<label id="Device Specific Functions"> -<p> -<nidx>Posix, device and class-specific functions</nidx> - -<tscreen><verb> -terminalMode :: TerminalMode -> TerminalAttributes -> Bool -withMode :: TerminalAttributes -> TerminalMode -> TerminalAttributes -withoutMode :: TerminalAttributes -> TerminalMode -> TerminalAttributes - -bitsPerByte :: TerminalAttributes -> Int -withBits :: TerminalAttributes -> Int -> TerminalAttributes - -controlChar :: TerminalAttributes -> ControlCharacter -> Maybe Char -withCC :: TerminalAttributes - -> (ControlCharacter, Char) - -> TerminalAttributes -withoutCC :: TerminalAttributes - -> ControlCharacter - -> TerminalAttributes - -inputTime :: TerminalAttributes -> Int -withTime :: TerminalAttributes -> Int -> TerminalAttributes - -minInput :: TerminalAttributes -> Int -withMinInput :: TerminalAttributes -> Int -> TerminalAttributes - -inputSpeed :: TerminalAttributes -> BaudRate -withInputSpeed :: TerminalAttributes -> BaudRate -> TerminalAttributes - -outputSpeed :: TerminalAttributes -> BaudRate -withOutputSpeed :: TerminalAttributes -> BaudRate -> TerminalAttributes - -getTerminalAttributes :: Fd -> IO TerminalAttributes -</verb></tscreen> - -@getTerminalAttributes fd@ calls @tcgetattr@ to obtain -the @TerminalAttributes@ associated with @Fd@ @fd@. - -<tscreen><verb> -setTerminalAttributes :: Fd - -> TerminalAttributes - -> TerminalState - -> IO () -</verb></tscreen> - -@setTerminalAttributes fd attr ts@ calls @tcsetattr@ to change -the @TerminalAttributes@ associated with @Fd@ @fd@ to -@attr@, when the terminal is in the state indicated by @ts@. - -<tscreen><verb> -sendBreak :: Fd -> Int -> IO () -</verb></tscreen> - -@sendBreak fd duration@ calls @tcsendbreak@ to transmit a -continuous stream of zero-valued bits on @Fd@ @fd@ for the -specified implementation-dependent @duration@. - -<tscreen><verb> -drainOutput :: Fd -> IO () -</verb></tscreen> - -@drainOutput fd@ calls @tcdrain@ to block until all output -written to @Fd@ @fd@ has been transmitted. - -<tscreen><verb> -discardData :: Fd -> QueueSelector -> IO () -</verb></tscreen> - -@discardData fd queues@ calls @tcflush@ to discard -pending input and/or output for @Fd@ @fd@, -as indicated by the @QueueSelector@ @queues@. - -<tscreen><verb> -controlFlow :: Fd -> FlowAction -> IO () -</verb></tscreen> - -@controlFlow fd action@ calls @tcflow@ to control the -flow of data on @Fd@ @fd@, as indicated by -@action@. - -<tscreen><verb> -getTerminalProcessGroupID :: Fd -> IO ProcessGroupID -</verb></tscreen> - -@getTerminalProcessGroupID fd@ calls @tcgetpgrp@ to -obtain the @ProcessGroupID@ of the foreground process group -associated with the terminal attached to @Fd@ @fd@. - -<tscreen><verb> -setTerminalProcessGroupID :: Fd -> ProcessGroupID -> IO () -</verb></tscreen> - -@setTerminalProcessGroupID fd pgid@ calls @tcsetpgrp@ to -set the @ProcessGroupID@ of the foreground process group -associated with the terminal attached to @Fd@ -@fd@ to @pgid@. - -<sect2>Posix System Databases -<label id="System Database"> -<p> -<nidx>Posix, system databases</nidx> - -<tscreen><verb> -groupName :: GroupEntry -> String -groupID :: GroupEntry -> GroupID -groupMembers :: GroupEntry -> [String] - -getGroupEntryForID :: GroupID -> IO GroupEntry -</verb></tscreen> - -@getGroupEntryForID gid@ calls @getgrgid@ to obtain -the @GroupEntry@ information associated with @GroupID@ -@gid@. - -The operation may fail with: - -<descrip> -<tag>@NoSuchThing@</tag> -There is no group entry for the GroupID. -</descrip> - -<tscreen><verb> -getGroupEntryForName :: String -> IO GroupEntry -</verb></tscreen> - -@getGroupEntryForName name@ calls @getgrnam@ to obtain -the @GroupEntry@ information associated with the group called -@name@. - -The operation may fail with: - -<descrip> -<tag>@NoSuchThing@</tag> -There is no group entry for the name. -</descrip> - -<tscreen><verb> -userName :: UserEntry -> String -userID :: UserEntry -> UserID -userGroupID :: UserEntry -> GroupID -homeDirectory :: UserEntry -> String -userShell :: UserEntry -> String - -getUserEntryForID :: UserID -> IO UserEntry -</verb></tscreen> - -@getUserEntryForID gid@ calls @getpwuid@ to obtain -the @UserEntry@ information associated with @UserID@ -@uid@. -The operation may fail with: - -<descrip> -<tag>@NoSuchThing@</tag> -There is no user entry for the UserID. -</descrip> - -<tscreen><verb> -getUserEntryForName :: String -> IO UserEntry -</verb></tscreen> - -@getUserEntryForName name@ calls @getpwnam@ to obtain -the @UserEntry@ information associated with the user login -@name@. - -The operation may fail with: - -<descrip> -<tag>@NoSuchThing@</tag> -There is no user entry for the name. -</descrip> - -<sect2>POSIX Errors -<label id="Error reporting and handling"> -<p> -<nidx>Posix, errors</nidx> - -<tscreen><verb> -getErrorCode :: IO ErrorCode -</verb></tscreen> - -@getErrorCode@ returns the current value of the external -variable @errno@. It never fails. - -<tscreen><verb> -setErrorCode :: ErrorCode -> IO () -</verb></tscreen> - -@setErrorCode err@ sets the external -variable @errno@ to @err@. It never fails. - -<tscreen><verb> -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 - -</verb></tscreen> diff --git a/ghc/docs/users_guide/profiling.vsgml b/ghc/docs/users_guide/profiling.vsgml deleted file mode 100644 index 5b82b5515b1b8550a4da1b4549b7b606f19cd082..0000000000000000000000000000000000000000 --- a/ghc/docs/users_guide/profiling.vsgml +++ /dev/null @@ -1,612 +0,0 @@ -<sect>Profiling -<label id="profiling"> -<p> -<nidx>profiling, with cost-centres</nidx> -<nidx>cost-centre profiling</nidx> - -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. - -Any comments, suggestions and/or improvements you have are welcome. -Recommended ``profiling tricks'' would be especially cool! - -<sect1>How to profile a Haskell program -<label id="profiling-intro"> -<p> - -The GHC approach to profiling is very simple: annotate the expressions -you consider ``interesting'' with <em>cost centre</em> labels (strings); -so, for example, you might have: - -<tscreen><verb> -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 -</verb></tscreen> - -The costs of the evaluating the expressions bound to @output1@, -@output2@ and @output3@ will be attributed to the ``cost -centres'' @Pass1@, @Pass2@ and @Pass3@, respectively. - -The costs of evaluating other expressions, e.g., @concat output4@, -will be inherited by the scope which referenced the function @f@. - -You can put in cost-centres via @_scc_@ constructs by hand, as in the -example above. Perfectly cool. That's probably what you -<em>would</em> do if your program divided into obvious ``passes'' or -``phases'', or whatever. - -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 @_scc_@ -constructs, automagically. Add an @-auto@ compilation flag to the -usual @-prof@ option. - -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. - -To use profiling, you must <em>compile</em> and <em>run</em> with special -options. (We usually forget the ``run'' magic!---Do as we say, not as -we do...) Details follow. - -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 <url name="Glasgow FP group web page" -url="http://www.dcs.gla.ac.uk/fp/">... - -<sect1>Compiling programs for profiling -<label id="prof-compiler-options"> -<p> -<nidx>profiling options</nidx> -<nidx>options, for profiling</nidx> - -To make use of the cost centre profiling system <em>all</em> modules must -be compiled and linked with the @-prof@ option.<nidx>-prof option</nidx> -Any @_scc_@ constructs you've put in your source will spring to life. - -Without a @-prof@ option, your @_scc_@s are ignored; so you can -compiled @_scc_@-laden code without changing it. - -There are a few other profiling-related compilation options. Use them -<em>in addition to</em> @-prof@. These do not have to be used -consistently for all modules in a program. - -<descrip> -<tag>@-auto@:</tag> -<nidx>-auto option</nidx> -<nidx>cost centres, automatically inserting</nidx> -GHC will automatically add @_scc_@ constructs for -all top-level, exported functions. - -<tag>@-auto-all@:</tag> -<nidx>-auto-all option</nidx> -<em>All</em> top-level functions, exported or not, will be automatically -@_scc_@'d. - -<tag>@-caf-all@:</tag> -<nidx>-caf-all option</nidx> -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... - -%<tag>@-dict-all@:</tag> -%<nidx>-dict-all option</nidx> -%Similarly, this option means that all ``dictionaries'' (internal -%constructs to support Haskell overloading) should get their own -%cost-centre. (Again, the costs are usually attributed to one ``big'' -%DICT cost-centre.) -% -%Incidentally, something is probably Bad Wrong (i.e., a GHC bug) if you -%see big costs attributed to dictionaries. - -<tag>@-ignore-scc@:</tag> -<nidx>-ignore-scc option</nidx> -Ignore any @_scc_@ constructs, -so a module which already has @_scc_@s can be -compiled for profiling with the annotations ignored. - -<tag>@-G<group>@:</tag> -<nidx>-G<group> option</nidx> -Specifies the @<group>@ to be attached to all the cost-centres -declared in the module. If no group is specified it defaults to the -module name. -</descrip> - -In addition to the @-prof@ option your system might be setup to enable -you to compile and link with the @-prof-details@ <nidx>-prof-details -option</nidx> option instead. This enables additional detailed counts -to be reported with the @-P@ RTS option. - -%-prof-details should also enable age profiling if we get it going again ... - -<sect1>How to control your profiled program at runtime -<label id="prof-rts-options"> -<p> -<nidx>profiling RTS options</nidx> -<nidx>RTS options, for profiling</nidx> - -It isn't enough to compile your program for profiling with @-prof@! - -When you <em>run</em> 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. - -Executive summary: @./a.out +RTS -pT@ produces a time profile in -@a.out.prof@; @./a.out +RTS -hC@ produces space-profiling -info which can be mangled by @hp2ps@ and viewed with @ghostview@ -(or equivalent). - -Profiling runtime flags are passed to your program between the usual -@+RTS@ and @-RTS@ options. - -<descrip> -<tag>@-p<sort>@ or @-P<sort>@:</tag> -<nidx>-p<sort> RTS option (profiling)</nidx> -<nidx>-P<sort> RTS option (profiling)</nidx> -<nidx>time profile</nidx> -<nidx>serial time profile</nidx> -The @-p?@ option produces a standard <em>time profile</em> report. -It is written into the file @<program>@@.prof@. - -The @-P?@ option produces a more detailed report containing the -actual time and allocation data as well. (Not used much.) - -%The @-P?@ option also produces <em>serial time-profiling</em> -%information, in the file @<program>@@.time@. This can be -%converted into a (somewhat unsatisfactory) PostScript graph using -%@hp2ps@ (see Section <ref name="hp2ps - heap profile to PostScript" id="hp2ps">). - -%???? -F2s needed for serial time profile??? ToDo - -The @<sort>@ indicates how the cost centres are to be sorted in the -report. Valid @<sort>@ options are: -<descrip> -<tag>@T@:</tag> by time, largest first (the default); -<tag>@A@:</tag> by bytes allocated, largest first; -<tag>@C@:</tag> alphabetically by group, module and cost centre. -</descrip> - -<tag>@-i<secs>@:</tag> <nidx>-i<secs> RTS option -(profiling)</nidx> Set the profiling (sampling) interval to @<secs>@ -seconds (the default is 1~second). Fractions are allowed: for example -@-i0.2@ will get 5 samples per second. - -<tag>@-h<break-down>@:</tag> -<nidx>-h<break-down> RTS option (profiling)</nidx> -<nidx>heap profile</nidx> - -Produce a detailed <em>space profile</em> of the heap occupied by live -closures. The profile is written to the file @<program>@@.hp@ from -which a PostScript graph can be produced using @hp2ps@ (see Section -<ref name="hp2ps - heap profile to PostScript" id="hp2ps">). - -The heap space profile may be broken down by different criteria: -<descrip> -<tag>@-hC@:</tag> cost centre which produced the closure (the default). -<tag>@-hM@:</tag> cost centre module which produced the closure. -<tag>@-hG@:</tag> cost centre group which produced the closure. -<tag>@-hD@:</tag> closure description --- a string describing the closure. -<tag>@-hY@:</tag> closure type --- a string describing the closure's type. -%<tag>@-hT<ints>,<start>@:</tag> the time interval the closure was -%created. @<ints>@ specifies the no. of interval bands plotted -%(default 18) and @<start>@ the number of seconds after which the -%reported intervals start (default 0.0). -</descrip> -By default all live closures in the heap are profiled, but particular -closures of interest can be selected (see below). -</descrip> - - -Heap (space) profiling uses hash tables. If these tables -should fill the run will abort. The -@-z<tbl><size>@<nidx>-z<tbl><size> RTS option (profiling)</nidx> option is used to -increase the size of the relevant hash table (@C@, @M@, -@G@, @D@ or @Y@, defined as for @<break-down>@ above). The -actual size used is the next largest power of 2. - -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: - -<descrip> -<tag>@-c{<mod>:<lab>,<mod>:<lab>...@}:</tag> -<nidx>-c{<lab></nidx> RTS option (profiling)} -Selects individual cost centre(s). -<tag>@-m{<mod>,<mod>...@}:</tag> -<nidx>-m{<mod></nidx> RTS option (profiling)} -Selects all cost centres from the module(s) specified. -<tag>@-g{<grp>,<grp>...@}:</tag> -<nidx>-g{<grp></nidx> RTS option (profiling)} -Selects all cost centres from the groups(s) specified. -<tag>@-d{<des>,<des>...@}:</tag> -<nidx>-d{<des></nidx> RTS option (profiling)} -Selects closures which have one of the specified descriptions. -<tag>@-y{<typ>,<typ>...@}:</tag> -<nidx>-y{<typ></nidx> RTS option (profiling)} -Selects closures which have one of the specified type descriptions. -<tag>@-k{<knd>,<knd>...@}:</tag> -<nidx>-k{<knd></nidx> RTS option (profiling)} -Selects closures which are of one of the specified closure kinds. -Valid closure kinds are @CON@ (constructor), @FN@ (manifest -function), @PAP@ (partial application), @BH@ (black hole) and -@THK@ (thunk). -</descrip> - -The space occupied by a closure will be reported in the heap profile -if the closure satisfies the following logical expression: - -<quote> -([-c] or [-m] or [-g]) and ([-d] or [-y] or [-k]) -</quote> - -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). - -<sect1>What's in a profiling report? -<label id="prof-output"> -<p> -<nidx>profiling report, meaning thereof</nidx> - -When you run your profiled program with the @-p@ RTS option <nidx>-p -RTS option</nidx>, you get the following information about your ``cost -centres'': - -<descrip> -%------------------------------------------------------------- -<tag>@COST CENTRE@:</tag> The cost-centre's name. -%------------------------------------------------------------- -<tag>@MODULE@:</tag> -The module associated with the cost-centre; -important mostly if you have identically-named cost-centres in -different modules. -%------------------------------------------------------------- -<tag>@scc@:</tag> -How many times this cost-centre was entered; think -of it as ``I got to the @_scc_@ construct this many times...'' -%------------------------------------------------------------- -<tag>@%time@:</tag> -What part of the time was spent in this cost-centre (see also ``ticks,'' -below). -%------------------------------------------------------------- -<tag>@%alloc@:</tag> -What part of the memory allocation was done in this cost-centre -(see also ``bytes,'' below). -%------------------------------------------------------------- -<tag>@inner@:</tag> -How many times this cost-centre ``passed control'' to an inner -cost-centre; for example, @scc=4@ plus @subscc=8@ means -``This @_scc_@ was entered four times, but went out to -other @_scc_s@ eight times.'' -%------------------------------------------------------------- -<tag>@cafs@:</tag> -<nidx>CAF, profiling</nidx> -How many CAFs this cost centre evaluated. -%------------------------------------------------------------- -<tag>@dicts@:</tag> -<nidx>Dictionaries, profiling</nidx> -How many dictionaries this cost centre evaluated. -</descrip> - -In addition you can use the @-P@ RTS option <nidx></nidx> to get the following additional information: -<descrip> -%------------------------------------------------------------- -<tag>@ticks@:</tag> The raw number of time ``ticks'' which were -attributed to this cost-centre; from this, we get the @%time@ -figure mentioned above. -%------------------------------------------------------------- -<tag>@bytes@:</tag> Number of bytes allocated in the heap while in -this cost-centre; again, this is the raw number from which we -get the @%alloc@ figure mentioned above. -</descrip> - -Finally if you built your program with @-prof-details@ -<nidx></nidx> the @-P@ RTS option will also -produce the following information: -<descrip> -%------------------------------------------------------------- -<tag>@closures@:</tag> -<nidx>closures, profiling</nidx> -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...) -%------------------------------------------------------------- -<tag>@thunks@:</tag> -<nidx>thunks, profiling</nidx> -How many times we entered (evaluated) a thunk---an unevaluated -object in the heap---while we were in this cost-centre. -%------------------------------------------------------------- -<tag>@funcs@:</tag> -<nidx>functions, profiling</nidx> -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) -%------------------------------------------------------------- -<tag>@PAPs@:</tag> -<nidx>partial applications, profiling</nidx> -How many times we entered (evaluated) a partial application (PAP), i.e., -a function applied to fewer arguments than it needs. For example, @Int@ -addition applied to one argument would be a PAP. A PAP is really -just a particular form for a function. -</descrip> - -<sect1>Producing graphical heap profiles -<label id="prof-graphs"> -<p> -<nidx>heap profiles, producing</nidx> - -Utility programs which produce graphical profiles. - -<sect2>@hp2ps@--heap profile to PostScript -<label id="hp2ps"> -<p> -<nidx>hp2ps (utility)</nidx> -<nidx>heap profiles</nidx> -<nidx>PostScript, from heap profiles</nidx> - -Usage: - -<tscreen> <verb> -hp2ps [flags] [<file>[.stat]] -</verb> </tscreen> - -The program @hp2ps@<nidx>hp2ps program</nidx> converts a heap profile -as produced by the @-h<break-down>@<nidx>-h<break-down> RTS -option</nidx> runtime option into a PostScript graph of the heap -profile. By convention, the file to be processed by @hp2ps@ has a -@.hp@ extension. The PostScript output is written to @<file>@@.ps@. If -@<file>@ is omitted entirely, then the program behaves as a filter. - -@hp2ps@ is distributed in @ghc/utils/hp2ps@ in a GHC source -distribution. It was originally developed by Dave Wakeling as part of -the HBC/LML heap profiler. - -The flags are: -<descrip> -<tag>@-d@</tag> -In order to make graphs more readable, @hp2ps@ 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 -@-d@ option causes rougher bands (those representing series of -values with the largest standard deviations) to be stacked on top of -smoother ones. - -<tag>@-b@</tag> -Normally, @hp2ps@ 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 -@hp2ps@ will choose to use a big box instead. The @-b@ -option forces @hp2ps@ to use a big box. - -<tag>@-e<float>[in|mm|pt]@</tag> -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 @hp2ps@ 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 @-e@ 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 @dvips@. - -<tag>@-g@</tag> -Create output suitable for the @gs@ PostScript previewer (or -similar). In this case the graph is printed in portrait mode without -scaling. The output is unsuitable for a laser printer. - -<tag>@-l@</tag> -Normally a profile is limited to 20 bands with additional identifiers -being grouped into an @OTHER@ band. The @-l@ 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. - -<tag>@-m<int>@</tag> -Normally a profile is limited to 20 bands with additional identifiers -being grouped into an @OTHER@ band. The @-m@ flag specifies an -alternative band limit (the maximum is 20). - -@-m0@ 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. - -<tag>@-p@</tag> -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 @-p@ flag causes -the graph to be drawn using the parameters determined by a previous -run of @hp2ps@ on @file@. These are extracted from -@file@@.aux@. - -<tag>@-s@</tag> Use a small box for the title. - -<tag>@-t<float>@</tag> -Normally trace elements which sum to a total of less than 1\% of the -profile are removed from the profile. The @-t@ option allows this -percentage to be modified (maximum 5\%). - -@-t0@ requests no trace elements to be removed from the profile, -ensuring that all the data will be displayed. - -<tag>@-?@</tag> Print out usage information. -</descrip> - -<sect2>@stat2resid@---residency info from GC stats -<label id="stat2resid"> -<p> -<nidx>stat2resid (utility)</nidx> -<nidx>GC stats---residency info</nidx> -<nidx>residency, from GC stats</nidx> - -Usage: - -<tscreen> <verb> -stat2resid [<file>[.stat] [<outfile>]] -</verb> </tscreen> - -The program @stat2resid@<nidx>stat2resid</nidx> converts a detailed -garbage collection statistics file produced by the -@-S@<nidx>-S RTS option</nidx> runtime option into a PostScript heap -residency graph. The garbage collection statistics file can be -produced without compiling your program for profiling. - -By convention, the file to be processed by @stat2resid@ has a -@.stat@ extension. If the @<outfile>@ is not specified the -PostScript will be written to @<file>@@.resid.ps@. If -@<file>@ is omitted entirely, then the program behaves as a filter. - -The plot can not be produced from the statistics file for a -generational collector, though a suitable stats file can be produced -using the @-F2s@<nidx>-F2s RTS option</nidx> runtime option when the -program has been compiled for generational garbage collection (the -default). - -@stat2resid@ is distributed in @ghc/utils/stat2resid@ in a GHC source -distribution. - -%************************************************************************ -%* * -<sect1>Using ``ticky-ticky'' profiling (for implementors) -<label id="ticky-ticky"> -<p> -<nidx>ticky-ticky profiling (implementors)</nidx> -%* * -%************************************************************************ - -(ToDo: document properly.) - -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,<nidx>ticky-ticky profiling</nidx>% -<nidx>profiling, ticky-ticky</nidx> because that's the sound a Sun4 makes -when it is running up all those counters (<em>slowly</em>). - -Ticky-ticky profiling is mainly intended for implementors; it is quite -separate from the main ``cost-centre'' profiling system, intended for -all users everywhere. - -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. - -To get your compiled program to spit out the ticky-ticky numbers, use -a @-r@ RTS option<nidx>-r RTS option</nidx>. See Section <ref -name="Running a compiled program" id="runtime-control">. - -Compiling your program with the @-ticky@ switch yields an executable -that performs these counts. Here is a sample ticky-ticky statistics -file, generated by the invocation @foo +RTS -rfoo.ticky@. - -<tscreen> <verb> -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 -</verb> </tscreen> - -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 <em>all counters</em> 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. - -In fact, not <em>all</em> 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 @ENT_PERM_IND_ctr@ appears with an inserted @!@ -above). Software analysing this output should always check that it -has the counters it expects. Also, beware: some of the counters can -have <em>large</em> values! -<p> - - - diff --git a/ghc/docs/users_guide/release-notes.vsgml b/ghc/docs/users_guide/release-notes.vsgml deleted file mode 100644 index 9e21910c243f86235141c668e846f1b7a6d9db2b..0000000000000000000000000000000000000000 --- a/ghc/docs/users_guide/release-notes.vsgml +++ /dev/null @@ -1,9 +0,0 @@ -<sect1>Compiler release notes -<p> - -<itemize> -<item> To reflect the fact that the <tt/Pretty/ library is part of -the common Hugs / GHC extension libraries, <tt/Pretty/ has been moved -from the <tt/misc/ library to <tt/exts/, i.e., only <tt/syslib exts/ -should be required to get at these extension libraries. -</itemize> diff --git a/ghc/docs/users_guide/release.vsgml b/ghc/docs/users_guide/release.vsgml deleted file mode 100644 index a0f77b552e9b5d181a07dea85decb6db7f285e34..0000000000000000000000000000000000000000 --- a/ghc/docs/users_guide/release.vsgml +++ /dev/null @@ -1,13 +0,0 @@ -% NOTE TO MAINTAINERS: the way these notes are organized: -% (1) What's new in the current release -% (2) What's next ("real soon now") -% (3) What was new in previous releases (reverse chronological order) -% (4) anything else -% -% Remember: this isn't the compiler documentation! -- it's just -% pointers to it. Mentioning something in the release notes is not -% the same as documenting it. - -<sect>Release notes -<label id="release-notes"> -<p> diff --git a/ghc/docs/users_guide/runtime_control.vsgml b/ghc/docs/users_guide/runtime_control.vsgml deleted file mode 100644 index 04caf42424792a60be9b7942e77405e2cf8e5307..0000000000000000000000000000000000000000 --- a/ghc/docs/users_guide/runtime_control.vsgml +++ /dev/null @@ -1,414 +0,0 @@ -%************************************************************************ -%* * -<sect1>Running a compiled program -<label id="runtime-control"> -<p> -<nidx>runtime control of Haskell programs</nidx> -<nidx>running, compiled program</nidx> -<nidx>RTS options</nidx> -%* * -%************************************************************************ - -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. - -You have some control over the behaviour of the RTS, by giving special -command-line arguments to your program. - -When your Haskell program starts up, its RTS extracts command-line -arguments bracketed between @+RTS@<nidx>+RTS option</nidx> and -@-RTS@<nidx>-RTS option</nidx> as its own. For example: - -<tscreen><verb> -% ./a.out -f +RTS -p -S -RTS -h foo bar -</verb></tscreen> - -The RTS will snaffle @-p -S@ for itself, and the remaining arguments -@-f -h foo bar@ will be handed to your program if/when it calls -@System.getArgs@. - -No @-RTS@ option is required if the runtime-system options extend to -the end of the command line, as in this example: - -<tscreen><verb> -% hls -ltr /usr/etc +RTS -A5m -</verb></tscreen> - -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 -@--RTS@<nidx>--RTS option</nidx>. - -As always, for RTS options that take @<size>@s: If the last -character of @size@ 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 <em>your</em> fault!) - -Giving a @+RTS -f@<nidx>-f RTS option</nidx> option will print out the -RTS options actually available in your program (which vary, depending -on how you compiled). - -NOTE: to send RTS options to the compiler itself, you need to prefix -the option with @-optCrts@, eg. to increase the maximum heap size for -a compilation to 128M, you would add @-optCrts-M128m@ to the command -line. The compiler understands some options directly without needing -@-optCrts@: these are @-H@ and @-K@. - -%************************************************************************ -%* * -<sect2>RTS options to control the garbage-collector -<label id="rts-options-gc"> -<p> -<nidx>RTS options, garbage-collection</nidx> -%* * -%************************************************************************ - -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. - -<descrip> -<tag>@-A<size>@:</tag> -<nidx>-A<size> RTS option</nidx> -<nidx>allocation area, size</nidx> - -[Default: 256k] 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 <tt/-H/, below). - -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). - -With only 1 generation (<tt/-G1/) the <tt/-A/ 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 -<tt/-F/, below). - -<tag>@-F<factor>@:</tag> -<nidx>-F<factor> RTS option</nidx> -<nidx>heap size, factor</nidx> - -[Default: 2] 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. - -The default seems to work well here. If you have plenty of memory, it -is usually better to use <tt/-H<size>/ than to increase -<tt/-F<factor>/. - -The <tt/-F/ setting will be automatically reduced by the garbage -collector when the maximum heap size (the <tt/-M<size>/ setting) -is approaching. - -<tag>@-G<generations>@:</tag> -<nidx>-G<generations> RTS option</nidx> -<nidx>generations, number of</nidx> - -[Default: 2] 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 -<em/long/ time, because the oldest generation will never get -collected. - -Specifying 1 generation with @+RTS -G1@ gives you a simple 2-space -collector, as you would expect. In a 2-space collector, the @-A@ -option (see above) specifies the <em/minimum/ 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 <tt/-H/ option, see below). - -<tag>@-H<size>@:</tag> -<nidx>-H<size> RTS option</nidx> -<nidx>heap size, suggested</nidx> - -[Default: 0] 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. - -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 <tt/-H<size>/. For -improving GC performance, using <tt/-H<size>/ is usually a better -bet than <tt/-A<size>/. - -<tag>@-k<size>@:</tag> -<nidx>-k<size> RTS option</nidx> -<nidx>stack, minimum size</nidx> - -[Default: 1k] 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. - -The main thread is normally started with a slightly larger heap to cut -down on unnecessary stack growth while the program is starting up. - -<tag>@-K<size>@:</tag> -<nidx>-K<size> RTS option</nidx> -<nidx>stack, maximum size</nidx> - -[Default: 1M] Set the maximum stack size for an individual thread to -@<size>@ 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. - -<tag>@-m<n>@:</tag> -<nidx>-m<n> RTS option</nidx> -Minimum \% @<n>@ of heap which must be available for allocation. -The default is 3\%. -<nidx>heap, minimum free</nidx> - -<tag>@-M<size>@:</tag> -<nidx>-M<size> RTS option</nidx> -<nidx>heap size, maximum</nidx> - -[Default: 64M] Set the maximum heap size to @<size>@ 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. - -<tag>@-s<file>@ or @-S<file>@:</tag> -<nidx>-S<file> RTS option</nidx> -<nidx>-s<file> RTS option</nidx> -Write modest (@-s@) or verbose (@-S@) garbage-collector -statistics into file @<file>@. The default @<file>@ is -@<program>@@.stat@. The @<file>@ @stderr@ is treated -specially, with the output really being sent to @stderr@. - -This option is useful for watching how the storage manager adjusts the -heap size based on the current amount of live data. - -% ToDo: --SDM -%For some garbage collectors (not including the default one, sadly), -%you can convert the @-S@ output into a residency graph (in -%PostScript), using the @stat2resid@<nidx>stat2resid</nidx> utility in -%the GHC distribution (@ghc/utils/stat2resid@). - -% <tag>@-j<size>@:</tag> -% <nidx>-j<size> RTS option</nidx> -% Force a major garbage collection every @<size>@ bytes. (Normally -% used because you're keen on getting major-GC stats, notably heap residency -% info.) - -</descrip> - -%************************************************************************ -%* * -<sect2>RTS options for profiling and Concurrent/Parallel Haskell -<p> -%* * -%************************************************************************ - -The RTS options related to profiling are described in Section <ref -name="How to control your profiled program at runtime" -id="prof-rts-options">; and those for concurrent/parallel stuff, in -Section <ref name="RTS options for Concurrent/Parallel Haskell" -id="parallel-rts-opts">. - -%************************************************************************ -%* * -<sect2>RTS options for hackers, debuggers, and over-interested souls -<p> -<nidx>RTS options, hacking/debugging</nidx> -%* * -%************************************************************************ - -These RTS options might be used (a)~to avoid a GHC bug, (b)~to see -``what's really happening'', or (c)~because you feel like it. Not -recommended for everyday use! - -<descrip> -<tag>@-B@:</tag> -<nidx>-B RTS option</nidx> -Sound the bell at the start of each (major) garbage collection. - -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---honestly!---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 [the -program] is in by the beep pattern. But the major use is for annoying -others in the same office...'' - -<tag>@-r<file>@:</tag> -<nidx>-r <file> RTS option</nidx> -<nidx>ticky ticky profiling</nidx> -Produce ``ticky-ticky'' statistics at the end of the program run. -The @<file>@ business works just like on the @-S@ RTS option (above). - -``Ticky-ticky'' statistics are counts of various program actions -(updates, enters, etc.) The program must have been compiled using -@-ticky@<nidx>-ticky option</nidx> (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 Section <ref name="Using ``ticky-ticky'' profiling -(for implementors)" id="ticky-ticky">. - -<tag>@-xc@:</tag> -<nidx>-xc RTS option</nidx> -<nidx>cost centre display on exception</nidx> -Display the current cost centre stack whenever an exception is -raised. The program must have been compiled with profiling turned on: -see Section <ref name="Profiling" id="profiling">. This feature is -experimental; one day it will display the information only on -<em>uncaught</em> exceptions. - -<tag>@-D<num>@:</tag> -<nidx>-D RTS option</nidx> -An RTS debugging flag; varying quantities of output depending on which -bits are set in @<num>@. Only works if the RTS was compiled with the -@DEBUG@ option. - -% Blackholing can't be turned off in new RTS --SDM -% -% <tag>@-N@:</tag> -% <nidx>-N RTS option</nidx> -% -% Normally, the garbage collector black-holes closures which are being -% evaluated, as a space-saving measure. This option turns off -% blackholing. You shouldn't ever need to use it. -% -% Historical note: this option used to be used to work around a problem -% with signal handling, where a signal handler might need to evaluate -% blackholed closures. Signal handlers are now run in a separate -% thread, and don't suffer from this problem. - -<tag>@-Z@:</tag> -<nidx>-Z RTS option</nidx> -Turn <em>off</em> ``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.) -</descrip> - -%************************************************************************ -%* * -<sect2>``Hooks'' to change RTS behaviour -<label id="rts-hooks"> -<p> -<nidx>hooks, RTS</nidx> -<nidx>RTS hooks</nidx> -<nidx>RTS behaviour, changing</nidx> -%* * -%************************************************************************ - -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. - -The function @defaultsHook@<nidx>defaultHook</nidx> 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 @-H8m -K1m@: - -<tscreen><verb> -#include "Rts.h" -#include "RtsFlags.h" -void defaultsHook (void) { - RTSflags.GcFlags.stksSize = 1000002 / sizeof(W_); - RTSflags.GcFlags.heapSize = 8000002 / sizeof(W_); -} -</verb></tscreen> - -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 @ghc/rts/RtsFlags.h@ the the GHC source tree. - -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: - -<descrip> -<tag>@void ErrorHdrHook (FILE *)@:</tag> -<nidx>ErrorHdrHook</nidx> -What's printed out before the message from @error@. - -<tag>@void OutOfHeapHook (unsigned long, unsigned long)@:</tag> -<nidx>OutOfHeapHook</nidx> -The heap-overflow message. - -<tag>@void StackOverflowHook (long int)@:</tag> -<nidx>StackOverflowHook</nidx> -The stack-overflow message. - -<tag>@void MallocFailHook (long int)@:</tag> -<nidx>MallocFailHook</nidx> -The message printed if @malloc@ fails. - -<tag>@void PatErrorHdrHook (FILE *)@:</tag> -<nidx>PatErrorHdrHook</nidx> -The message printed if a pattern-match fails (the failures -that were not handled by the Haskell programmer). - -<tag>@void PreTraceHook (FILE *)@:</tag> -<nidx>PreTraceHook</nidx> -What's printed out before a @trace@ message. - -<tag>@void PostTraceHook (FILE *)@:</tag> -<nidx>PostTraceHook</nidx> -What's printed out after a @trace@ message. -</descrip> - -For example, here is the ``hooks'' code used by GHC itself: -<tscreen><verb> -#include <stdio.h> -#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<size>' - 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<size>' 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" */ -} -</verb></tscreen> diff --git a/ghc/docs/users_guide/sooner.vsgml b/ghc/docs/users_guide/sooner.vsgml deleted file mode 100644 index 0957f45abe77d6c65c4c598e24f2138e65601902..0000000000000000000000000000000000000000 --- a/ghc/docs/users_guide/sooner.vsgml +++ /dev/null @@ -1,411 +0,0 @@ -%************************************************************************ -%* * -<sect>Advice on: sooner, faster, smaller, stingier -<label id="sooner-faster-quicker"> -<p> -%* * -%************************************************************************ - -Please advise us of other ``helpful hints'' that should go here! - -%************************************************************************ -%* * -<sect1>Sooner: producing a program more quickly -<label id="sooner"> -<p> -<nidx>compiling faster</nidx> -<nidx>faster compiling</nidx> -%* * -%************************************************************************ - -<descrip> -%---------------------------------------------------------------- -<tag>Don't use @-O@ or (especially) @-O2@:</tag> -By using them, you are telling GHC that you are willing to suffer -longer compilation times for better-quality code. - -GHC is surprisingly zippy for normal compilations without @-O@! - -%---------------------------------------------------------------- -<tag>Use more memory:</tag> -Within reason, more memory for heap space means less garbage -collection for GHC, which means less compilation time. If you use -the @-Rgc-stats@ option, you'll get a garbage-collector report. -(Again, you can use the cheap-and-nasty @-optCrts-Sstderr@ option to -send the GC stats straight to standard error.) - -If it says you're using more than 20\% of total time in garbage -collecting, then more memory would help. - -If the heap size is approaching the maximum (64M by default), and you -have lots of memory, try increasing the maximum with the -@-M<size>@<nidx>-M<size> option</nidx> option, e.g.: @ghc -c -O --M16m Foo.hs@. - -Increasing the default allocation area size used by the compiler's RTS -might also help: use the @-A<size>@<nidx>-A<size> option</nidx> -option. - -If GHC persists in being a bad memory citizen, please report it as a -bug. - -%---------------------------------------------------------------- -<tag>Don't use too much memory!</tag> -As soon as GHC plus its ``fellow citizens'' (other processes on your -machine) start using more than the <em>real memory</em> on your -machine, and the machine starts ``thrashing,'' <em>the party is -over</em>. Compile times will be worse than terrible! Use something -like the csh-builtin @time@ command to get a report on how many page -faults you're getting. - -If you don't know what virtual memory, thrashing, and page faults are, -or you don't know the memory configuration of your machine, -<em>don't</em> try to be clever about memory use: you'll just make -your life a misery (and for other people, too, probably). - -%---------------------------------------------------------------- -<tag>Try to use local disks when linking:</tag> -Because Haskell objects and libraries tend to be large, it can take -many real seconds to slurp the bits to/from a remote filesystem. - -It would be quite sensible to <em>compile</em> on a fast machine using -remotely-mounted disks; then <em>link</em> on a slow machine that had -your disks directly mounted. - -%---------------------------------------------------------------- -<tag>Don't derive/use @Read@ unnecessarily:</tag> -It's ugly and slow. - -%---------------------------------------------------------------- -<tag>GHC compiles some program constructs slowly:</tag> -Deeply-nested list comprehensions seem to be one such; in the past, -very large constant tables were bad, too. - -We'd rather you reported such behaviour as a bug, so that we can try -to correct it. - -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 -@-fno-strictness@<nidx>-fno-strictness anti-option</nidx> and -@-fno-update-analysis@.<nidx>-fno-update-analysis anti-option</nidx> - -To figure out which part of the compiler is badly behaved, the -@-dshow-passes@<nidx>-dshow-passes option</nidx> option is your -friend. - -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 @-fvia-C@<nidx>-fvia-C option</nidx> -(not that GCC will be that quick about it, either). - -%---------------------------------------------------------------- -<tag>Avoid the consistency-check on linking:</tag> - -Use @-no-link-chk@<nidx>-no-link-chk</nidx>; saves effort. This is -probably safe in a I-only-compile-things-one-way setup. - -%---------------------------------------------------------------- -<tag>Explicit @import@ declarations:</tag> - -Instead of saying @import Foo@, say @import Foo (...stuff I want...)@. - -Truthfully, the reduction on compilation time will be very small. -However, judicious use of @import@ declarations can make a -program easier to understand, so it may be a good idea anyway. -</descrip> - -%************************************************************************ -%* * -<sect1>Faster: producing a program that runs quicker -<label id="faster"> -<p> -<nidx>faster programs, how to produce</nidx> -%* * -%************************************************************************ - -The key tool to use in making your Haskell program run faster are -GHC's profiling facilities, described separately in Section <ref -name="Profiling" id="profiling">. There is <em>no substitute</em> for -finding where your program's time/space is <em>really</em> going, as -opposed to where you imagine it is going. - -Another point to bear in mind: By far the best way to improve a -program's performance <em>dramatically</em> 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. - -Another extremely efficient way to make your program snappy is to use -library code that has been Seriously Tuned By Someone Else. You -<em>might</em> be able to write a better quicksort than the one in the -HBC library, but it will take you much longer than typing @import -QSort@. (Incidentally, it doesn't hurt if the Someone Else is Lennart -Augustsson.) - -Please report any overly-slow GHC-compiled programs. The current -definition of ``overly-slow'' is ``the HBC-compiled version ran -faster''... - -<descrip> -%---------------------------------------------------------------- -<tag>Optimise, using @-O@ or @-O2@:</tag> This is the most basic way -to make your program go faster. Compilation time will be slower, -especially with @-O2@. - -At present, @-O2@ is nearly indistinguishable from @-O@. - -%---------------------------------------------------------------- -<tag>Compile via C and crank up GCC:</tag> Even with @-O@, 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. - -So, when we want very fast code, we use: @-O -fvia-C -O2-for-C@. - -%---------------------------------------------------------------- -<tag>Overloaded functions are not your friend:</tag> -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? - -<descrip> -<tag>Give explicit type signatures:</tag> -Signatures are the basic trick; putting them on exported, top-level -functions is good software-engineering practice, anyway. (Tip: using -@-fwarn-missing-signatures@<nidx>-fwarn-missing-signatures -option</nidx> can help enforce good signature-practice). - -The automatic specialisation of overloaded functions (with @-O@) -should take care of overloaded local and/or unexported functions. - -<tag>Use @SPECIALIZE@ pragmas:</tag> -<nidx>SPECIALIZE pragma</nidx> -<nidx>overloading, death to</nidx> - -Specialize the overloading on key functions in your program. See -Sections <ref name="SPECIALIZE pragmas" id="specialize-pragma"> and -<ref name="SPECIALIZE instance pragmas" id="specialize-instance-pragma"> - -% See also: overlapping instances, in Section <ref name="``HBC-ish'' -% extensions implemented by GHC" id="glasgow-hbc-exts">. They are to -% @SPECIALIZE instance@ pragmas what @= blah@ hacks are to @SPECIALIZE@ -% (value) pragmas... - -%ToDo: there's nothing like this at the moment: --SDM - -% <tag>``How do I know what's happening with specialisations?'':</tag> - -% The @-fshow-specialisations@<nidx>-fshow-specialisations option</nidx> -% will show the specialisations that actually take place. - -% The @-fshow-import-specs@<nidx>-fshow-import-specs option</nidx> will -% show the specialisations that GHC <em>wished</em> were available, but -% were not. You can add the relevant pragmas to your code if you wish. - -% You're a bit stuck if the desired specialisation is of a Prelude -% function. If it's Really Important, you can just snap a copy of the -% Prelude code, rename it, and then SPECIALIZE that to your heart's -% content. - -<tag>``But how do I know where overloading is creeping in?'':</tag> - -A low-tech way: grep (search) your interface files for overloaded -type signatures; e.g.,: -<tscreen><verb> -% egrep '^[a-z].*::.*=>' *.hi -</verb></tscreen> -</descrip> - -%---------------------------------------------------------------- -<tag>Strict functions are your dear friends:</tag> -and, among other things, lazy pattern-matching is your enemy. - -(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.) - -Consider these two code fragments: -<tscreen><verb> -f (Wibble x y) = ... # strict - -f arg = let { (Wibble x y) = arg } in ... # lazy -</verb></tscreen> -The former will result in far better code. - -A less contrived example shows the use of @cases@ instead -of @lets@ to get stricter code (a good thing): -<tscreen><verb> -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) -> - case (unpackFoo y) of { (a2, b2, c2) -> - ... - }} -</verb></tscreen> - -%---------------------------------------------------------------- -<tag>GHC loves single-constructor data-types:</tag> - -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). - -%---------------------------------------------------------------- -<tag>Newtypes are better than datatypes:</tag> - -If your datatype has a single constructor with a single field, use a -@newtype@ declaration instead of a @data@ declaration. The @newtype@ -will be optimised away in most cases. - -%---------------------------------------------------------------- -<tag>``How do I find out a function's strictness?''</tag> - -Don't guess---look it up. - -Look for your function in the interface file, then for the third field -in the pragma; it should say @_S_ <string>@. The @<string>@ -gives the strictness of the function's arguments. @L@ is lazy -(bad), @S@ and @E@ are strict (good), @P@ is ``primitive'' (good), -@U(...)@ is strict and -``unpackable'' (very good), and @A@ is absent (very good). - -For an ``unpackable'' @U(...)@ argument, the info inside -tells the strictness of its components. So, if the argument is a -pair, and it says @U(AU(LSS))@, 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 \& third).'' - -If the function isn't exported, just compile with the extra flag @-ddump-simpl@; -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!) - -%---------------------------------------------------------------- -<tag>Force key functions to be @INLINE@d (esp. monads):</tag> - -Placing @INLINE@ pragmas on certain functions that are used a lot can -have a dramatic effect. See Section <ref name="INLINE pragmas" -id="inline-pragma">. - -%---------------------------------------------------------------- -<tag>Explicit @export@ list:</tag> -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 -<em>unused</em> (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. - -GHC can be quite a bit more aggressive with pieces of code if it knows -they are not exported. - -%---------------------------------------------------------------- -<tag>Look at the Core syntax!</tag> -(The form in which GHC manipulates your code.) Just run your -compilation with @-ddump-simpl@ (don't forget the @-O@). - -If profiling has pointed the finger at particular functions, look at -their Core code. @lets@ are bad, @cases@ are good, dictionaries -(@d.<Class>.<Unique>@) [or anything overloading-ish] are bad, -nested lambdas are bad, explicit data constructors are good, primitive -operations (e.g., @eqInt#@) are good, ... - -%---------------------------------------------------------------- -<tag>Use unboxed types (a GHC extension):</tag> -When you are <em>really</em> desperate for speed, and you want to get -right down to the ``raw bits.'' Please see Section <ref name="Unboxed -types" id="glasgow-unboxed"> for some information about using unboxed -types. - -%---------------------------------------------------------------- -<tag>Use @_ccall_s@ (a GHC extension) to plug into fast libraries:</tag> -This may take real work, but... There exist piles of -massively-tuned library code, and the best thing is not -to compete with it, but link with it. - -Section <ref name="Calling~C directly from Haskell" id="glasgow-ccalls"> says a little about how to use C calls. - -%---------------------------------------------------------------- -<tag>Don't use @Float@s:</tag> -We don't provide specialisations of Prelude functions for @Float@ -(but we do for @Double@). If you end up executing overloaded -code, you will lose on performance, perhaps badly. - -@Floats@ (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---modern machines will use the same -floating-point unit for both. With @Doubles@, you are much less -likely to hang yourself with numerical errors. - -One time when @Float@ might be a good idea is if you have a -<em>lot</em> of them, say a giant array of @Float@s. They take up -half the space in the heap compared to @Doubles@. However, this isn't -true on a 64-bit machine. - -%---------------------------------------------------------------- -<tag>Use a bigger heap!</tag> - -If your program's GC stats (@-S@<nidx>-S RTS option</nidx> RTS option) -indicate that it's doing lots of garbage-collection (say, more than -20\% of execution time), more memory might help---with the -@-M<size>@<nidx>-M<size> RTS option</nidx> or -@-A<size>@<nidx>-A<size> RTS option</nidx> RTS options (see -Section <ref name="RTS options to control the garbage-collector" -id="rts-options-gc">). -</descrip> - -%************************************************************************ -%* * -<sect1>Smaller: producing a program that is smaller -<label id="smaller"> -<p> -<nidx>smaller programs, how to produce</nidx> -%* * -%************************************************************************ - -Decrease the ``go-for-it'' threshold for unfolding smallish -expressions. Give a -@-funfolding-use-threshold0@<nidx>-funfolding-use-threshold0 -option</nidx> 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 -<em>increase</em> the size of your program, because unfolding -generally enables extra simplifying optimisations to be performed. - -Avoid @Read@. - -Use @strip@ on your executables. - -%************************************************************************ -%* * -<sect1>Stingier: producing a program that gobbles less heap space -<label id="stingier"> -<p> -<nidx>memory, using less heap</nidx> -<nidx>space-leaks, avoiding</nidx> -<nidx>heap space, using less</nidx> -%* * -%************************************************************************ - -``I think I have a space leak...'' Re-run your program with -@+RTS -Sstderr@,<nidx>-Sstderr RTS option</nidx> and remove all doubt! -(You'll see the heap usage get bigger and bigger...) [Hmmm... this -might be even easier with the @-F2s@<nidx>-F2s RTS option</nidx> RTS -option; so... @./a.out +RTS -Sstderr -F2s@...] - -Once again, the profiling facilities (Section <ref name="Profiling" -id="profiling">) are the basic tool for demystifying the space -behaviour of your program. - -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). diff --git a/ghc/docs/users_guide/users_guide.vsgml b/ghc/docs/users_guide/users_guide.vsgml deleted file mode 100644 index 96d89094f6ab3e4c33625fcfdab423dcbb916062..0000000000000000000000000000000000000000 --- a/ghc/docs/users_guide/users_guide.vsgml +++ /dev/null @@ -1,47 +0,0 @@ -<!doctype linuxdoc system [ - <!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"> -]> -<article> - -<title>The Glasgow Haskell Compiler User's Guide, Version~4.04 -<author>The GHC Team, -Email: @glasgow-haskell-{bugs,users}-request@@haskell.org@ -<toc> - -&intro -&relnotes -&using - &runtime - &debug -&prof -&sooner -&lang - &glaexts - ¶llel - &vs-hs -&libs - &posix - &libmisc -&wrong -&utils -&win32-dll - -</article> diff --git a/ghc/docs/users_guide/using.vsgml b/ghc/docs/users_guide/using.vsgml deleted file mode 100644 index 88d404ad2822d4c5a05e7f337d5beda25fd483b9..0000000000000000000000000000000000000000 --- a/ghc/docs/users_guide/using.vsgml +++ /dev/null @@ -1,1664 +0,0 @@ -<sect> Using GHC -<label id="using-GHC"> -<p> -<nidx>GHC, using</nidx> -<nidx>using GHC</nidx> - -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 @make@ 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. - -%************************************************************************ -%* * -<sect1> Overall command-line structure -<label id="command-line-structure"> -<p> -<nidx>structure, command-line</nidx> -<nidx>command-line structure</nidx> -%* * -%************************************************************************ - -An invocation of GHC takes the following form: - -<tscreen> <verb> -ghc [argument...] -</verb> </tscreen> - -Command-line arguments are either options or file names. - -Command-line options begin with @-@. They may <em>not</em> be -grouped: @-vO@ is different from @-v -O@. Options need not -precede filenames: e.g., @ghc *.o -o foo@. All options are -processed and then applied to all files; you cannot, for example, invoke -@ghc -c -O1 Foo.hs -O2 Bar.hs@ to apply different optimisation -levels to the files @Foo.hs@ and @Bar.hs@. For conflicting -options, e.g., @-c -S@, we reserve the right to do anything we -want. (Usually, the last one applies.) - -%************************************************************************ -%* * -<sect1>Meaningful file suffixes -<label id="file-suffixes"> -<p> -<nidx>suffixes, file</nidx> -<nidx>file suffixes for GHC</nidx> -%* * -%************************************************************************ - -File names with ``meaningful'' suffixes (e.g., @.lhs@ or @.o@) -cause the ``right thing'' to happen to those files. - -<descrip> -<tag>@.lhs@:</tag> -<nidx>lhs suffix</nidx> -A ``literate Haskell'' module. - -<tag>@.hs@:</tag> -A not-so-literate Haskell module. - -<tag>@.hi@:</tag> -A Haskell interface file, probably compiler-generated. - -<tag>@.hc@:</tag> -Intermediate C file produced by the Haskell compiler. - -<tag>@.c@:</tag> -A C~file not produced by the Haskell compiler. - -% <tag>@.i@:</tag> -% C code after it has be preprocessed by the C compiler (using the -% @-E@ flag). - -<tag>@.s@:</tag> -An assembly-language source file, usually -produced by the compiler. - -<tag>@.o@:</tag> -An object file, produced by an assembler. -</descrip> - -Files with other suffixes (or without suffixes) are passed straight -to the linker. - -%************************************************************************ -%* * -<sect1>Help and verbosity options -<label id="options-help"> -<p> -<nidx>help options (GHC)</nidx> -<nidx>verbose option (GHC)</nidx> -%* * -%************************************************************************ - -A good option to start with is the @-help@ (or @-?@) option. -<nidx>-help option</nidx> -<nidx>-? option</nidx> -GHC spews a long message to standard output and then exits. - -The @-v@<nidx>-v option</nidx> option makes GHC <em>verbose</em>: it -reports its version number and shows (on stderr) exactly how it invokes each -phase of the compilation system. Moreover, it passes -the @-v@ flag to most phases; each reports -its version number (and possibly some other information). - -Please, oh please, use the @-v@ option when reporting bugs! -Knowing that you ran the right bits in the right order is always the -first thing we want to verify. - -If you're just interested in the compiler version number, the -@--version@<nidx>--version option</nidx> option prints out a -one-line string containing the requested info. - -%************************************************************************ -%* * -<sect1>Running the right phases in the right order -<label id="options-order"> -<p> -<nidx>order of passes in GHC</nidx> -<nidx>pass ordering in GHC</nidx> -%* * -%************************************************************************ - -The basic task of the @ghc@ driver is to run each input file -through the right phases (compiling, linking, etc.). - -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: - -<tabular ca="llll"> -Phase of the | Suffix saying | Flag saying | (suffix of) @@ -compilation system | ``start here''| ``stop after''| output file @@ -@@ -literate pre-processor | .lhs | - | - @@ -C pre-processor (opt.) | - | - | - @@ -Haskell compiler | .hs | -C, -S | .hc, .s @@ -C compiler (opt.) | .hc or .c | -S | .s @@ -assembler | .s | -c | .o @@ -linker | other | - | a.out @@ -</tabular> -<nidx>-C option</nidx> -<nidx>-S option</nidx> -<nidx>-c option</nidx> - -Thus, a common invocation would be: @ghc -c Foo.hs@ - -Note: What the Haskell compiler proper produces depends on whether a -native-code generator is used (producing assembly language) or not -(producing C). - -The option @-cpp@<nidx>-cpp option</nidx> 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. - -The option @-E@<nidx>-E option</nidx> 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 @-cpp@, the -output is the de-litted version of the original source. - -The option @-optcpp-E@<nidx>-optcpp-E option</nidx> runs just the -pre-processing stage of the C-compiling phase, sending the result to -stdout. (For debugging or obfuscation contests, usually.) - -%************************************************************************ -%* * -<sect1>Re-directing the compilation output(s) -<label id="options-output"> -<p> -<nidx>output-directing options</nidx> -%* * -%************************************************************************ - -GHC's compiled output normally goes into a @.hc@, @.o@, etc., file, -depending on the last-run compilation phase. The option @-o -foo@<nidx>-o option</nidx> re-directs the output of that last-run -phase to file @foo@. - -Note: this ``feature'' can be counterintuitive: -@ghc -C -o foo.o foo.hs@ will put the intermediate C code in the -file @foo.o@, name notwithstanding! - -EXOTICA: But the @-o@ option isn't of much use if you have -<em>several</em> input files... 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 @-odir <dir>@<nidx>-odir <dir> option</nidx> (the -``Oh, dear'' option). For example: - -<tscreen><verb> -% ghc -c parse/Foo.hs parse/Bar.hs gurgle/Bumble.hs -odir `arch` -</verb></tscreen> - -The output files, @Foo.o@, @Bar.o@, and @Bumble.o@ would be -put into a subdirectory named after the architecture of the executing -machine (@sun4@, @mips@, etc). The directory must already -exist; it won't be created. - -Note that the @-odir@ option does <em>not</em> affect where the -interface files are put. In the above example, they would still be -put in @parse/Foo.hi@, @parse/Bar.hi@, and @gurgle/Bumble.hi@. - -MORE EXOTICA: The @-osuf <suffix>@<nidx>-osuf <suffix> -option</nidx> will change the @.o@ file suffix for object files to -whatever you specify. (We use this in compiling the prelude.). -Similarly, the @-hisuf <suffix>@<nidx>-hisuf <suffix> -option</nidx> will change the @.hi@ file suffix for non-system -interface files (see Section <ref name="Other options related to -interface files" id="hi-options">). - -The @-hisuf@/@-osuf@ 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 @.hi@/@.o@ suffixes; add @-hisuf g_hi -osuf g_o@ to your -@make@ rule for GHC compiling... - -FURTHER EXOTICA: If you are doing a normal @.hs@-to-@.o@ compilation -but would like to hang onto the intermediate @.hc@ C file, just -throw in a @-keep-hc-file-too@ option<nidx>-keep-hc-file-too option</nidx>. -If you would like to look at the assembler output, toss in a -@-keep-s-file-too@,<nidx>-keep-s-file-too option</nidx> too. - -<sect2> Saving GHC's standard error output -<label id="saving-ghc-stderr"> -<p> -<nidx>standard error, saving</nidx> - -Sometimes, you may cause GHC to be rather chatty on standard error; -with @-v@, for example. You can instruct GHC to <em>append</em> this -output to a particular log file with a @-odump <blah>@<nidx>-odump -<blah> option</nidx> option. - -<sect2> Redirecting temporary files -<label id="temp-files"> -<p> -<nidx>temporary files, redirecting</nidx> - -If you have trouble because of running out of space in @/tmp@ (or -wherever your installation thinks temporary files should go), you may -use the @-tmpdir <dir>@<nidx>-tmpdir <dir> option</nidx> option -to specify an alternate directory. For example, @-tmpdir .@ says to -put temporary files in the current working directory. - -Alternatively, use your @TMPDIR@ environment variable.<nidx>TMPDIR -environment variable</nidx> Set it to the name of the directory where -temporary files should be put. GCC and other programs will honour the -@TMPDIR@ variable as well. - -Even better idea: Set the @TMPDIR@ variable when building GHC, and -never worry about @TMPDIR@ again. (see the build documentation). - -%************************************************************************ -%* * -<sect1>Warnings and sanity-checking -<label id="options-sanity"> -<p> -<nidx>sanity-checking options</nidx> -<nidx>warnings</nidx> -%* * -%************************************************************************ - -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: -@-fwarn-overlpapping-patterns@, @-fwarn-duplicate-exports@, and -@-fwarn-missing-methods@. The following flags are simple ways to -select standard ``packages'' of warnings: - -<descrip> - -<tag>@-Wnot@:</tag> -<nidx>-Wnot option</nidx> - -Turns off all warnings, including the standard ones. - -<tag>@-w@:</tag> -<nidx>-w option</nidx> - -Synonym for @-Wnot@. - -<tag>@-W@:</tag> -<nidx>-W option</nidx> - -Provides the standard warnings plus @-fwarn-incomplete-patterns@, -@-fwarn-unused-imports@ and @-fwarn-unused-binds@. - -<tag>@-Wall@:</tag> -<nidx>-Wall option</nidx> - -Turns on all warning options. - -</descrip> - -The full set of warning options is described below. To turn off any -warning, simply give the corresponding @-fno-warn-...@ option on -the command line. - -<descrip> - -<tag>@-fwarn-name-shadowing@:</tag> -<nidx>-fwarn-name-shadowing option</nidx> -<nidx>shadowing, warning</nidx> - -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 -@let x = ... x ... in@. - -Consequently, this option does <em>not</em> allow cyclic recursive -definitions. - -<tag>@-fwarn-overlapping-patterns@:</tag> -<nidx>-fwarn-overlapping-patterns option</nidx> -<nidx>overlapping patterns, warning</nidx> -<nidx>patterns, overlapping</nidx> - -By default, the compiler will warn you if a set of patterns are -overlapping, i.e., - -<tscreen><verb> -f :: String -> Int -f [] = 0 -f (_:xs) = 1 -f "2" = 2 -</verb></tscreen> - -where the last pattern match in @f@ 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. - -<tag>@-fwarn-incomplete-patterns@:</tag> -<nidx>-fwarn-incomplete-patterns option</nidx> -<nidx>incomplete patterns, warning</nidx> -<nidx>patterns, incomplete</nidx> - -Similarly for incomplete patterns, the function @g@ below will fail -when applied to non-empty lists, so the compiler will emit a warning -about this when @-fwarn-incomplete-patterns@ is enabled. - -<tscreen><verb> -g [] = 2 -</verb></tscreen> - -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. - -<tag>@-fwarn-missing-methods@:</tag> -<nidx>-fwarn-missing-methods option</nidx> -<nidx>missing methods, warning</nidx> -<nidx>methods, missing</nidx> - -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. - -<tag>@-fwarn-missing-fields@:</tag> -<nidx>-fwarn-missing-fields option</nidx> -<nidx>missing fields, warning</nidx> -<nidx>fields, missing</nidx> - -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. - -<tag>@-fwarn-unused-imports@:</tag> -<nidx>-fwarn-unused-imports option</nidx> -<nidx>unused imports, warning</nidx> -<nidx>imports, unused</nidx> - -Report any objects that are explicitly imported but never used. - -<tag>@-fwarn-unused-binds@:</tag> -<nidx>-fwarn-unused-binds option</nidx> -<nidx>unused binds, warning</nidx> -<nidx>binds, unused</nidx> - -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. - -<tag>@-fwarn-unused-matches@:</tag> -<nidx>-fwarn-unused-matches option</nidx> -<nidx>unused matches, warning</nidx> -<nidx>matches, unused</nidx> - -Report all unused variables which arise from pattern matches, -including patterns consisting of a single variable. For instance @f x -y = []@ would report @x@ and @y@ as unused. To eliminate the warning, -all unused variables can be replaced with wildcards. - -<tag>@-fwarn-duplicate-exports@:</tag> -<nidx>-fwarn-duplicate-exports option</nidx> -<nidx>duplicate exports, warning</nidx> -<nidx>export lists, duplicates</nidx> - -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. - -This option is on by default. - -<tag><tt>-fwarn-type-defaults</tt>:</tag> -<nidx>-fwarn-type-defaults option</nidx> -<nidx>defaulting mechanism, warning</nidx> - -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 <tt>1</tt> to be given -the type <tt>Int</tt>, whereas Haskell 98 defaults it to -<tt>Integer</tt>. This may lead to differences in performance and -behaviour, hence the usefulness of being non-silent about this. - -This warning is off by default. - -<tag>@-fwarn-missing-signatures@:</tag> -<nidx>-fwarn-missing-signatures option</nidx> -<nidx>type signatures, missing</nidx> - -If you would like GHC to check that every top-level function/value has -a type signature, use the @-fwarn-missing-signatures@ option. This -option is off by default. - -</descrip> - -If you're feeling really paranoid, the @-dcore-lint@ -option<nidx>-dcore-lint option</nidx> is a good choice. It turns on -heavyweight intra-pass sanity-checking within GHC. (It checks GHC's -sanity, not yours.) - -%************************************************************************ -%* * -<sect1>Separate compilation -<label id="separate-compilation"> -<p> -<nidx>separate compilation</nidx> -<nidx>recompilation checker</nidx> -<nidx>make and recompilation</nidx> -%* * -%************************************************************************ - -This section describes how GHC supports separate compilation. - -<sect2>Interface files -<label id="hi-files"> -<p> -<nidx>interface files</nidx> -<nidx>.hi files</nidx> - -When GHC compiles a source file @F@ which contains a module @A@, say, -it generates an object @F.o@, <em>and</em> a companion <em>interface -file</em> @A.hi@. 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. - -NOTE: <em>The name of the interface file is derived from the name -of the module, not from the name of the file containing the module</em>. -This means that GHC knows what to look for when it sees <tt>import A</tt> -in another module. However, having the name of the interface file follow the module name and -not the file name, means that working with tools such as @make(1)@ -become harder. @make@ 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. - -The interface file for @A@ contains information needed by the compiler -when it compiles any module @B@ that imports @A@, whether directly or -indirectly. When compiling @B@, GHC will read @A.hi@ to find the -details that it needs to know about things defined in @A@. - -Furthermore, when compiling module @C@ which imports @B@, GHC may -decide that it needs to know something about @A@ --- for example, @B@ -might export a function that involves a type defined in @A@. In this -case, GHC will go and read @A.hi@ even though @C@ does not explicitly -import @A@ at all. - -The interface file may contain all sorts of things that aren't -explicitly exported from @A@ by the programmer. For example, even -though a data type is exported abstractly, @A.hi@ will contain the -full data type definition. For small function definitions, @A.hi@ -will contain the complete definition of the function. For bigger -functions, @A.hi@ will contain strictness information about the -function. And so on. GHC puts much more information into @.hi@ files -when optimisation is turned on with the @-O@ flag. Without @-O@ it -puts in just the minimum; with @-O@ it lobs in a whole pile of stuff. -<nidx>optimsation, effect on .hi files</nidx> - -@A.hi@ should really be thought of as a compiler-readable version of -@A.o@. If you use a @.hi@ file that wasn't generated by the same -compilation run that generates the @.o@ file the compiler may assume -all sorts of incorrect things about @A@, resulting in core dumps and -other unpleasant happenings. - -%************************************************************************ -%* * -<sect2>File names and module names -<label id="files-and-modules"> -<p> -%* * -%************************************************************************ - -Typically, a module @Foo@ will be contained in a file called @Foo.hs@ -or @Foo.lhs@. But GHC does not require that to be the case. You can put a module -named @Foo@ in a file named @SomethingElse@. In this case, <em>GHC will still -write an interface file @Foo.hi@</em>, but it will write an object fild -@SomethingElse.o@. Any module that imports @Foo@ will -of course look for @Foo.hi@, and it will find it. - -A useful consequence is that you can have many files, @A.hs@, @B.hs@, etc, containing -the module @Main@. This is useful if you want to build distinct programs -in the same directory. - - -%************************************************************************ -%* * -<sect2>Finding interface files -<label id="options-finding-imports"> -<p> -<nidx>interface files, finding them</nidx> -<nidx>finding interface files</nidx> -%* * -%************************************************************************ - -In your program, you import a module @Foo@ by saying -@import Foo@. GHC goes looking for an interface file, @Foo.hi@. -It has a builtin list of directories (notably including @.@) where -it looks. - -<descrip> - -<tag>@-i<dirs>@</tag><nidx>-i<dirs> option</nidx> This flag -prepends a colon-separated list of @dirs@ to the ``import -directories'' list. -See also Section <ref id="recomp"> for the significance of using -relative and absolute pathnames in the @-i@ list. - -<tag>@-i@</tag> resets the ``import directories'' list back to nothing. - -<tag>@-fno-implicit-prelude@</tag> -<nidx>-fno-implicit-prelude option</nidx> -GHC normally imports @Prelude.hi@ files for you. If you'd rather it -didn't, then give it a @-fno-implicit-prelude@ option. You are -unlikely to get very far without a Prelude, but, hey, it's a free -country. - -<tag>@-syslib <lib>@</tag> -<nidx>-syslib <lib> option</nidx> - -If you are using a system-supplied non-Prelude library (e.g., the -POSIX library), just use a @-syslib posix@ option (for example). The -right interface files should then be available. Section <ref -name="The GHC Prelude and Libraries" id="ghc-prelude"> lists the -libraries available by this mechanism. - -<tag>@-I<dir>@</tag> -<nidx>-I<dir> option</nidx> - -Once a Haskell module has been compiled to C (@.hc@ file), you may -wish to specify where GHC tells the C compiler to look for @.h@ files. -(Or, if you are using the @-cpp@ option<nidx>-cpp option</nidx>, where -it tells the C pre-processor to look...) For this purpose, use a @-I@ -option in the usual C-ish way. - -</descrip> - -%************************************************************************ -%* * -<sect2>Other options related to interface files -<label id="hi-options"> -<p> -<nidx>interface files, options</nidx> -%* * -%************************************************************************ - -GHC supports some other more exotic command-line options related to interface files. -Most programmers should never need to use any of them. - -<descrip> - -<tag>@-ohi@ <filename></tag> -<nidx>-ohi <file> option</nidx> - -The interface output may be directed to another file -@bar2/Wurble.iface@ with the option @-ohi bar2/Wurble.iface@ -(not recommended). - -<tag>@-nohi@</tag> -<nidx>-nohi option</nidx> - -Don't generate an interface file at all. - -<tag>@-hi-diffs@, @-hi-diffs-with-usages@, @-keep-hi-diffs@</tag> -<nidx>-hi-diffs option</nidx> -<nidx>-hi-diffs-with-usages option</nidx> -<nidx>-keep-hi-diffs option</nidx> -The compiler does not overwrite an existing @.hi@ interface file if -the new one is byte-for-byte the same as the old one; this is friendly -to @make@. When an interface does change, it is often enlightening to -be informed. The @-hi-diffs@ option will -make @ghc@ run @diff@ on the old and new @.hi@ files. You can also -record the difference in the interface file itself, the -@-keep-hi-diffs@<nidx>-keep-hi-diffs</nidx> option takes care of that. - -The @.hi@ 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 -@-hi-diffs-with-usages@<nidx>-hi-diffs-with-usages option</nidx> -option. - -<tag>@-fignore-interface-pragmas@</tag> -<nidx>-fignore-interface-pragmas option</nidx> - -Interface files are normally jammed full of compiler-produced -<em>pragmas</em>, 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 -@-fignore-interface-pragmas@ option. - -<tag>@-fno-prune-tydecls@</tag> -<nidx>-fno-prune-tydecls option</nidx> -When compiling without optimisations on, the compiler is extra-careful -about not slurping in data constructors that it will not need. -The @-fno-prune-tydecls@ flag lets you turn this cleverness off; the reason -is to allow us to measure the effect of the cleverness. (In earlier versions -of GHC there was a bug that meant you <em>had</em> to turn it off sometimes, -but that is no longer true.) -</descrip> - -See also Section <ref name="Linking and consistency-checking" -id="options-linker">, which describes how the linker finds standard -Haskell libraries. - -%************************************************************************ -%* * -<sect2>The recompilation checker -<label id="recomp"> -<p> -<nidx>recompilation checker</nidx> -%* * -%************************************************************************ - -In the olden days, GHC compared the newly-generated @.hi@ 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 @.hi@ file were not -recompiled. - -This doesn't work any more. In our earlier example, module @C@ does -not import module @A@ directly, yet changes to @A.hi@ should force a -recompilation of @C@. And some changes to @A@ (changing the -definition of a function that appears in an inlining of a function -exported by @B@, say) may conceivably not change @B.hi@ one jot. So -now... - -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 @.o@ 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! - -GHC <em>only</em> keeps detailed dependency information for ``user'' modules, -not for ``library'' modules. It distinguishes the two by a hack: a module -whose @.hi@ 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 <em>relative</em> path names in your -@-i@ path, to force GHC to record detailed dependency information. -Use absolute path names only for directories containing slowly-changing -library modules. - -A path is considered ``absolute'' if it starts with ``@/@'', or -``@A:/@'', or ``@A:\@'' (or ``@B:/@'', ``@B:\@'' etc). - -Patrick Sansom had a workshop paper about how all this is done (though -the details have changed quite a bit). Ask -him (email: <htmlurl name="sansom@@dcs.gla.ac.uk" -url="mailto:sansom@@dcs.gla.ac.uk">) if you want a copy. - -%************************************************************************ -%* * -<sect2>Using @make@ -<label id="using-make"> -<p> -<ncdx>make</ncdx> -%* * -%************************************************************************ - -It is reasonably straightforward to set up a @Makefile@ to use with -GHC, assuming you name your source files the same as your modules. -Thus: - -<tscreen><verb> -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 $< $(HC_OPTS) - -.hs.o: - $(HC) -c $< $(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 -</verb></tscreen> - -(Sophisticated @make@ variants may achieve some of the above more -elegantly. Notably, @gmake@'s pattern rules let you write the more -comprehensible: - -<tscreen><verb> -%.o : %.lhs - $(HC) -c $< $(HC_OPTS) -</verb></tscreen> - -What we've shown should work with any @make@.) - -Note the cheesy @.o.hi@ rule: It records the dependency of the -interface (@.hi@) file on the source. The rule says a @.hi@ file can -be made from a @.o@ file by doing... nothing. Which is true. - -Note the inter-module dependencies at the end of the Makefile, which -take the form - -<tscreen><verb> -Foo.o Foo.hc Foo.s : Baz.hi # Foo imports Baz -</verb></tscreen> - -They tell @make@ that if any of @Foo.o@, @Foo.hc@ or @Foo.s@ have an -earlier modification date than @Baz.hi@, then the out-of-date file -must be brought up to date. To bring it up to date, @make@ looks for -a rule to do so; one of the preceding suffix rules does the job -nicely. - -Putting inter-dependencies of the form @Foo.o : Bar.hi@ into your -@Makefile@ by hand is rather error-prone. Don't worry---never fear, -@mkdependHS@ is here! (and is distributed as part of GHC) Add the -following to your @Makefile@: - -<tscreen><verb> -depend : - mkdependHS -- $(HC_OPTS) -- $(SRCS) -</verb></tscreen> - -Now, before you start compiling, and any time you change the @imports@ -in your program, do @make depend@ before you do @make cool_pgm@. -@mkdependHS@ will append the needed dependencies to your @Makefile@. -@mkdependHS@ is fully describe in Section <ref name="Makefile -dependencies in Haskell: using mkdependHS" id="mkdependHS">. - -A few caveats about this simple scheme: - -<itemize> - -<item> You may need to compile some modules explicitly to create their -interfaces in the first place (e.g., @make Bar.o@ to create @Bar.hi@). - -<item> You may have to type @make@ more than once for the dependencies -to have full effect. However, a @make@ run that does nothing -<em>does</em> mean ``everything's up-to-date.'' - -<item> This scheme will work with mutually-recursive modules but, -again, it may take multiple iterations to ``settle.'' - -</itemize> - -%************************************************************************ -%* * -<sect2>How to compile mutually recursive modules -<label id="mutual-recursion"> -<p> -<nidx>module system, recursion</nidx> -<nidx>recursion, between modules</nidx> -%* * -%************************************************************************ - -Currently, the compiler does not have proper support for dealing with -mutually recursive modules: - -<tscreen><verb> -module A where - -import B - -newtype TA = MkTA Int - -f :: TB -> TA -f (MkTB x) = MkTA x --------- -module B where - -import A - -data TB = MkTB !Int - -g :: TA -> TB -g (MkTA x) = MkTB x -</verb></tscreen> - -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 @hi-boot@ files, and are placed in a file -called @<module>.hi-boot@. To import from an @hi-boot@ file instead -of the standard @.hi@ file, use the following syntax in the importing module: -<nidx>hi-boot files</nidx> -<nidx>importing, hi-boot files</nidx> - -<tscreen> <verb> -import {-# SOURCE #-} A -</verb> </tscreen> - -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 <em/everything/ -that module @A@ exports, only the things required by the module that -imports @A@ recursively. - -For the example at hand, the boot interface file for A would look like -the following: - -<tscreen><verb> -__interface A 1 404 where -__export A TA{MkTA} ; -1 newtype TA = MkTA PrelBase.Int ; -</verb></tscreen> - -The syntax is essentially the same as a normal @.hi@ file -(unfortunately), but you can usually tailor an existing @.hi@ file to -make a @.hi-boot@ file. - -Notice that we only put the declaration for the newtype @TA@ in the -@hi-boot@ file, not the signature for @f@, since @f@ isn't used by -@B@. - -The number ``1'' after ``__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 <em>syntax</em>; 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. - -The number ``1'' at the beginning of a declaration is the <em>version -number</em> of that declaration: for the purposes of @.hi-boot@ files -these can all be set to 1. All names must be fully qualified with the -<em/original/ module that an object comes from: for example, the -reference to @Int@ in the interface for @A@ comes from @PrelBase@, -which is a module internal to GHC's prelude. It's a pain, but that's -the way it is. - -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: - -<tscreen><verb> -__interface A 1 404 where -__export A TA; -1 data TA -</verb></tscreen> - -(You must write all the type parameters, but leave out the '=' and everything that follows it.) - -<bf>Note:</bf> This is all a temporary solution, a version of the -compiler that handles mutually recursive properly without the manual -construction of interface files, is (allegedly) in the works. - -%************************************************************************ -%* * -<sect1>Command line options in source files -<label id="source-file-options"> -<p> -<nidx>source-file options</nidx> -%* * -%************************************************************************ - -GHC expects its flags on the command line, but it is also possible -to embed them in the Haskell module itself, using the @OPTIONS@ -pragma <nidx>OPTIONS pragma</nidx>: -<tscreen><verb> - {-# OPTIONS -fglasgow-exts -fno-cpr-analyse #-} - module X where - - ... -</verb></tscreen> -@OPTIONS@ pragmas are only looked for at the top of your source -files, upto the first (non-literate,non-empty) line not containing -@OPTIONS@. Multiple @OPTIONS@ 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 @OPTIONS@. - -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. - -It is not recommended to move all the contents of your Makefiles into -your source files, but in some circumstances, the @OPTIONS@ pragma -is the Right Thing. (If you use @-keep-hc-file-too@ and have @OPTIONS@ -flags in your module, the @OPTIONS@ will get put into the generated .hc -file). - - -%************************************************************************ -%* * -<sect1>Optimisation (code improvement) -<label id="options-optimise"> -<p> -<nidx>optimisation (GHC)</nidx> -<nidx>improvement, code (GHC)</nidx> -%* * -%************************************************************************ - -The @-O*@ options specify convenient ``packages'' of optimisation -flags; the @-f*@ options described later on specify -<em>individual</em> optimisations to be turned on/off; the @-m*@ -options specify <em>machine-specific</em> optimisations to be turned -on/off. - -%---------------------------------------------------------------------- -<sect2>@-O*@: convenient ``packages'' of optimisation flags. -<label id="optimise-pkgs"> -<p> -<nidx>-O options</nidx> - -There are <em>many</em> 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. - -Once you choose a @-O*@ ``package,'' stick with it---don't chop and -change. Modules' interfaces <em>will</em> change with a shift to a new -@-O*@ option, and you may have to recompile a large chunk of all -importing modules before your program can again be run -safely (see Section <ref name="The recompilation checker" id="recomp">). - -<descrip> -<tag>No @-O*@-type option specified:</tag> -<nidx>-O* not specified</nidx> -This is taken to mean: ``Please compile quickly; I'm not over-bothered -about compiled-code quality.'' So, for example: @ghc -c Foo.hs@ - -<tag>@-O@ or @-O1@:</tag> -<nidx>-O option</nidx> -<nidx>-O1 option</nidx> -<nidx>optimise normally</nidx> -Means: ``Generate good-quality code without taking too long about it.'' -Thus, for example: @ghc -c -O Main.lhs@ - -<tag>@-O2@:</tag> -<nidx>-O2 option</nidx> -<nidx>optimise aggressively</nidx> -Means: ``Apply every non-dangerous optimisation, even if it means -significantly longer compile times.'' - -The avoided ``dangerous'' optimisations are those that can make -runtime or space <em>worse</em> if you're unlucky. They are -normally turned on or off individually. - -At the moment, @-O2@ is <em>unlikely</em> to produce -better code than @-O@. - -<tag>@-O2-for-C@:</tag> -<nidx>-O2-for-C option</nidx> -<nidx>gcc, invoking with -O2</nidx> - -Says to run GCC with @-O2@, which may be worth a few percent in -execution speed. Don't forget @-fvia-C@, lest you use the native-code -generator and bypass GCC altogether! - -<tag>@-Onot@:</tag> -<nidx>-Onot option</nidx> -<nidx>optimising, reset</nidx> - -This option will make GHC ``forget'' any @-O@ish options it has seen so -far. Sometimes useful; for example: @make all EXTRA_HC_OPTS=-Onot@. - -<tag>@-Ofile <file>@:</tag> -<nidx>-Ofile <file> option</nidx> -<nidx>optimising, customised</nidx> - -For those who need <em>absolute</em> control over <em>exactly</em> -what options are used (e.g., compiler writers, sometimes :-), a list -of options can be put in a file and then slurped in with @-Ofile@. - -In that file, comments are of the @#@-to-end-of-line variety; blank -lines and most whitespace is ignored. - -Please ask if you are baffled and would like an example of @-Ofile@! -</descrip> - -At Glasgow, we don't use a @-O*@ flag for day-to-day work. We use -@-O@ to get respectable speed; e.g., when we want to measure -something. When we want to go for broke, we tend to use @-O -fvia-C --O2-for-C@ (and we go for lots of coffee breaks). - -The easiest way to see what @-O@ (etc.) ``really mean'' is to run with -@-v@, then stand back in amazement. Alternatively, just look at the -@HsC_minus<blah>@ lists in the @ghc@ driver script. - -%---------------------------------------------------------------------- -<sect2>@-f*@: platform-independent flags -<p> -<nidx>-f* options (GHC)</nidx> -<nidx>-fno-* options (GHC)</nidx> - -Flags can be turned <em>off</em> individually. (NB: I hope you have a -good reason for doing this....) To turn off the @-ffoo@ flag, just use -the @-fno-foo@ flag.<nidx>-fno-<opt> anti-option</nidx> So, for -example, you can say @-O2 -fno-strictness@, which will then drop out -any running of the strictness analyser. - -The options you are most likely to want to turn off are: -<itemize> -<item> -@-fno-strictness@<nidx>-fno-strictness option</nidx> (strictness -analyser, because it is sometimes slow), -<item> -@-fno-specialise@<nidx>-fno-specialise option</nidx> (automatic -specialisation of overloaded functions, because it can make your code -bigger) (US spelling also accepted), and -<item> -@-fno-cpr-analyse@<nidx>-fno-cpr-analyse option</nidx> switches off the CPR (constructed product -result) analyser. -</itemize> - -Should you wish to turn individual flags <em>on</em>, you are advised -to use the @-Ofile@ 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. - -Here are some ``dangerous'' optimisations you <em>might</em> want to try: -<descrip> -%------------------------------------------------------------------ -<tag>@-fvia-C@:</tag> -<nidx>-fvia-C option</nidx> -<nidx>native code generator, turning off</nidx> - -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 @_ccall_gc_@s or -@_casm_@s, you probably <em>have to</em> use @-fvia-C@. - -The lower-case incantation, @-fvia-c@, is synonymous. - -Compiling via C will probably be slower (in compilation time) than -using GHC's native code generator. - -<tag>@-funfolding-interface-threshold<n>@:</tag> -<nidx>-funfolding-interface-threshold option</nidx> -<nidx>inlining, controlling</nidx> -<nidx>unfolding, controlling</nidx> -(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.) - -<tag>@-funfolding-creation-threshold<n>@:</tag> -<nidx>-funfolding-creation-threshold option</nidx> -<nidx>inlining, controlling</nidx> -<nidx>unfolding, controlling</nidx> -(Default: 30) This option is similar to -@-funfolding-interface-threshold@, 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: - -<tag>@-funfolding-use-threshold<n>@:</tag> -<nidx>-funfolding-use-threshold option</nidx> -<nidx>inlining, controlling</nidx> -<nidx>unfolding, controlling</nidx> -(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 @-funfolding-con-discount@). - -<tag>@-funfolding-con-discount<n>@:</tag> -<nidx>-funfolding-con-discount option</nidx> -<nidx>inlining, controlling</nidx> -<nidx>unfolding, controlling</nidx> -(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. - -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. - -<tag>@-funbox-strict-fields@:</tag> -<nidx>-funbox-strict-fields option</nidx> -<nidx>strict constructor fields</nidx> -<nidx>constructor fields, strict</nidx> - -This option causes all constructor fields which are marked strict -(i.e. ``!'') to be unboxed or unpacked if possible. For example: - -<tscreen><verb> -data T = T !Float !Float -</verb></tscreen> - -will create a constructor @T@ containing two unboxed floats if the -@-funbox-strict-fields@ flag is given. This may not always be an -optimisation: if the @T@ 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). - -This option should only be used in conjunction with @-O@, in order to -expose unfoldings to the compiler so the reboxing can be removed as -often as possible. For example: - -<tscreen><verb> -f :: T -> Float -f (T f1 f2) = f1 + f2 -</verb></tscreen> - -The compiler will avoid reboxing @f1@ and @f2@ by inlining @+@ on -floats, but only when @-O@ is on. - -Any single-constructor data is eligible for unpacking; for example - -<tscreen><verb> -data T = T !(Int,Int) -</verb></tscreen> - -will store the two @Int@s directly in the @T@ constructor, by flattening -the pair. Multi-level unpacking is also supported: - -<tscreen><verb> -data T = T !S -data S = S !Int !Int -</verb></tscreen> - -will store two unboxed @Int#@s directly in the @T@ constructor. - -<tag>@-fsemi-tagging@:</tag> -This option (which <em>does not work</em> 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.) - -We have not played with @-fsemi-tagging@ enough to recommend it. -(For all we know, it doesn't even work anymore... Sigh.) -</descrip> - -%---------------------------------------------------------------------- -<sect2>@-m*@: platform-specific flags -<p> -<nidx>-m* options (GHC)</nidx> -<nidx>platform-specific options</nidx> -<nidx>machine-specific options</nidx> - -Some flags only make sense for particular target platforms. - -<descrip> -<tag>@-mv8@:</tag> -(SPARC machines)<nidx>-mv8 option (SPARC only)</nidx> -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 @-m*@ GCC options for SPARC also work, actually. - -<tag>@-mlong-calls@:</tag> -(HPPA machines)<nidx>-mlong-calls option (HPPA only)</nidx> -Means to pass the like-named option to GCC. Required for Very Big -modules, maybe. (Probably means you're in trouble...) - -<tag>@-monly-[32]-regs@:</tag> -(iX86 machines)<nidx>-monly-N-regs option (iX86 only)</nidx> -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: -<tscreen><verb> -Foo.hc:533: fixed or forbidden register was spilled. -This may be due to a compiler bug or to impossible asm -statements or clauses. -</verb></tscreen> -Just give some registers back with @-monly-N-regs@. Try `3' first, -then `2'. If `2' doesn't work, please report the bug to us. -</descrip> - -%---------------------------------------------------------------------- -<sect2>Code improvement by the C compiler. -<label id="optimise-C-compiler"> -<p> -<nidx>optimisation by GCC</nidx> -<nidx>GCC optimisation</nidx> - -The C~compiler (GCC) is run with @-O@ turned on. (It has -to be, actually). - -If you want to run GCC with @-O2@---which may be worth a few -percent in execution speed---you can give a -@-O2-for-C@<nidx>-O2-for-C option</nidx> option. - -%************************************************************************ -%* * -<sect1>Options related to a particular phase -<label id="options-phases"> -<p> -%* * -%************************************************************************ - -<sect2> The C pre-processor -<label id="c-pre-processor"> -<p> -<nidx>pre-processing: cpp</nidx> -<nidx>C pre-processor options</nidx> -<nidx>cpp, pre-processing with</nidx> - -The C pre-processor @cpp@ is run over your Haskell code only if the -@-cpp@ option <nidx>-cpp option</nidx> is given. Unless you are -building a large system with significant doses of conditional -compilation, you really shouldn't need it. -<descrip> -<tag>@-D<foo>@:</tag> -<nidx>-D<name> option</nidx> -Define macro @<foo>@ in the usual way. NB: does <em>not</em> affect -@-D@ macros passed to the C~compiler when compiling via C! For those, -use the @-optc-Dfoo@ hack... (see Section <ref name="Forcing options -to a particular phase." id="forcing-options-through">). - -<tag>@-U<foo>@:</tag> -<nidx>-U<name> option</nidx> -Undefine macro @<foo>@ in the usual way. - -<tag>@-I<dir>@:</tag> -<nidx>-I<dir> option</nidx> -Specify a directory in which to look for @#include@ files, in -the usual C way. -</descrip> - -The @ghc@ driver pre-defines several macros when processing Haskell -source code (@.hs@ or @.lhs@ files): - -<descrip> -<tag>@__HASKELL98__@:</tag> -<nidx>__HASKELL98__</nidx> -If defined, this means that GHC supports the language defined by the -Haskell 98 report. - -<tag>@__HASKELL__=98@:</tag> -<nidx>__HASKELL__</nidx> -In GHC 4.04 and later, the @__HASKELL__@ macro is defined as having -the value @98@. - -<tag>@__HASKELL1__@:</tag> -<nidx>__HASKELL1__ macro</nidx> -If defined to <em/n/, that means GHC supports the Haskell language -defined in the Haskell report version <em/1.n/. Currently 5. This -macro is deprecated, and will probably disappear in future versions. - -<tag>@__GLASGOW_HASKELL__@:</tag> -<nidx>__GLASGOW_HASKELL__ macro</nidx> -For version <em/n/ of the GHC system, this will be @#define@d to -<em/100n/. So, for version 4.00, it is 400. - -With any luck, @__GLASGOW_HASKELL__@ will be undefined in all other -implementations that support C-style pre-processing. - -(For reference: the comparable symbols for other systems are: -@__HUGS__@ for Hugs and @__HBC__@ for Chalmers.) - -NB. This macro is set when pre-processing both Haskell source and C -source, including the C source generated from a Haskell module -(ie. @.hs@, @.lhs@, @.c@ and @.hc@ files). - -<tag>@__CONCURRENT_HASKELL__@:</tag> -<nidx>__CONCURRENT_HASKELL__ macro</nidx> -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. - -<tag>@__PARALLEL_HASKELL__@:</tag> -<nidx>__PARALLEL_HASKELL__ macro</nidx> -Only defined when @-parallel@ is in use! This symbol is defined when -pre-processing Haskell (input) and pre-processing C (GHC output). -</descrip> - -Options other than the above can be forced through to the C -pre-processor with the @-opt@ flags (see -Section <ref name="Forcing options to a particular phase." id="forcing-options-through">). - -A small word of warning: @-cpp@ is not friendly to ``string -gaps''.<nidx>-cpp vs string gaps</nidx><nidx>string gaps vs --cpp</nidx>. In other words, strings such as the following: - -<tscreen><verb> - strmod = "\ - \ p \ - \ " -</verb></tscreen> - -don't work with @-cpp@; @/usr/bin/cpp@ elides the -backslash-newline pairs. - -However, it appears that if you add a space at the end of the line, -then @cpp@ (at least GNU @cpp@ and possibly other @cpp@s) -leaves the backslash-space pairs alone and the string gap works as -expected. - -%************************************************************************ -%* * -<sect2>Options affecting the C compiler (if applicable) -<label id="options-C-compiler"> -<p> -<nidx>include-file options</nidx> -<nidx>C compiler options</nidx> -<nidx>GCC options</nidx> -%* * -%************************************************************************ - -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: - -<tabular ca="ll"> -@-ansi@ | do ANSI C (not K&R) @@ -@-pedantic@ | be so@@ -@-dgcc-lint@ | (hack) short for ``make GCC very paranoid''@@ -</tabular> -<nidx>-ansi option (for GCC)</nidx> -<nidx>-pedantic option (for GCC)</nidx> -<nidx>-dgcc-lint option (GCC paranoia)</nidx> - -If you are compiling with lots of @ccalls@, etc., you may need to -tell the C~compiler about some @#include@ files. There is no real -pretty way to do this, but you can use this hack from the -command-line: - -<tscreen><verb> -% ghc -c '-#include <X/Xlib.h>' Xstuff.lhs -</verb></tscreen> - - -%************************************************************************ -%* * -<sect2>Linking and consistency-checking -<label id="options-linker"> -<p> -<nidx>linker options</nidx> -<nidx>ld options</nidx> -%* * -%************************************************************************ - -GHC has to link your code with various libraries, possibly including: -user-supplied, GHC-supplied, and system-supplied (@-lm@ math -library, for example). - -<descrip> -<tag>@-l<FOO>@:</tag> -<nidx>-l<lib> option</nidx> -Link in a library named @lib<FOO>.a@ which resides somewhere on the -library directories path. - -Because of the sad state of most UNIX linkers, the order of such -options does matter. Thus: @ghc -lbar *.o@ is almost certainly -wrong, because it will search @libbar.a@ <em>before</em> it has -collected unresolved symbols from the @*.o@ files. -@ghc *.o -lbar@ is probably better. - -The linker will of course be informed about some GHC-supplied -libraries automatically; these are: - -<tabular ca="ll"> -<bf>-l equivalent</bf> | <bf>description</bf> @@ -@@ -@-lHSrts,-lHSclib@ | basic runtime libraries @@ -@-lHS@ | standard Prelude library @@ -@-lHS_cbits@ | C support code for standard Prelude library @@ -@-lgmp@ | GNU multi-precision library (for Integers)@@ -</tabular> - -<nidx>-lHS library</nidx> -<nidx>-lHS_cbits library</nidx> -<nidx>-lHSrts library</nidx> -<nidx>-lgmp library</nidx> - -<tag>@-syslib <name>@:</tag> -<nidx>-syslib <name> option</nidx> - -If you are using a Haskell ``system library'' (e.g., the POSIX -library), just use the @-syslib posix@ option, and the correct code -should be linked in. - -<tag>@-L<dir>@:</tag> -<nidx>-L<dir> option</nidx> -Where to find user-supplied libraries... Prepend the directory -@<dir>@ to the library directories path. - -<tag>@-static@:</tag> -<nidx>-static option</nidx> -Tell the linker to avoid shared libraries. - -<tag>@-no-link-chk@ and @-link-chk@:</tag> -<nidx>-no-link-chk option</nidx> -<nidx>-link-chk option</nidx> -<nidx>consistency checking of executables</nidx> -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 @.o@ file was compiled -for a parallel machine and the others weren't.) You may turn off this -check with @-no-link-chk@. You can turn it (back) on with -@-link-chk@ (the default). - -<tag><tt>-no-hs-main</tt>:</tag> -<nidx>-no-hs-main option</nidx> -<nidx>linking Haskell libraries with foreign code</nidx> - -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 -<tt/main()/ at link-time, you will have to. To signal that to the -driver script when linking, use <tt/-no-hs-main/. - -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 <tt/-v/ on to see what -options the driver passes through to the linker. - -</descrip> - -%************************************************************************ -%* * -<sect1>Using Concurrent Haskell -<p> -<nidx>Concurrent Haskell---use</nidx> -%* * -%************************************************************************ - -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. @Concurrent@ and friends), use the @-syslib concurrent@ option. - -Three RTS options are provided for modifying the behaviour of the -threaded runtime system. See the descriptions of @-C[<us>]@, @-q@, -and @-t<num>@ in Section <ref name="RTS options for -Concurrent/Parallel Haskell" id="parallel-rts-opts">. - -Concurrent Haskell is described in more detail in Section <ref -name="Concurrent and Parallel Haskell" id="concurrent-and-parallel">. - -%************************************************************************ -%* * -<sect1>Using Parallel Haskell -<p> -<nidx>Parallel Haskell---use</nidx> -%* * -%************************************************************************ - -[You won't be able to execute parallel Haskell programs unless PVM3 -(Parallel Virtual Machine, version 3) is installed at your site.] - -To compile a Haskell program for parallel execution under PVM, use the -@-parallel@ option,<nidx>-parallel option</nidx> both when compiling -<em>and linking</em>. You will probably want to @import Parallel@ -into your Haskell modules. - -To run your parallel program, once PVM is going, just invoke it ``as -normal''. The main extra RTS option is @-N<n>@, to say how many -PVM ``processors'' your program to run on. (For more details of -all relevant RTS options, please see Section <ref name="RTS options for Concurrent/Parallel Haskell" id="parallel-rts-opts">.) - -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. - -%************************************************************************ -%* * -<sect2>Dummy's guide to using PVM -<p> -<nidx>PVM, how to use</nidx> -<nidx>Parallel Haskell---PVM use</nidx> -%* * -%************************************************************************ - -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 @.cshrc@ or equivalent: -<tscreen><verb> -setenv PVM_ROOT /wherever/you/put/it -setenv PVM_ARCH `$PVM_ROOT/lib/pvmgetarch` -setenv PVM_DPATH $PVM_ROOT/lib/pvmd -</verb></tscreen> - -Creating and/or controlling your ``parallel machine'' is a purely-PVM -business; nothing specific to Parallel Haskell. - -You use the @pvm@<nidx>pvm command</nidx> command to start PVM on your -machine. You can then do various things to control/monitor your -``parallel machine;'' the most useful being: - -\begin{tabular}{ll} -@Control-D@ & exit @pvm@, leaving it running \\ -@halt@ & kill off this ``parallel machine'' \& exit \\ -@add <host>@ & add @<host>@ as a processor \\ -@delete <host>@ & delete @<host>@ \\ -@reset@ & kill what's going, but leave PVM up \\ -@conf@ & list the current configuration \\ -@ps@ & report processes' status \\ -@pstat <pid>@ & status of a particular process \\ -\end{tabular} - -The PVM documentation can tell you much, much more about @pvm@! - -%************************************************************************ -%* * -<sect2>Parallelism profiles -<p> -<nidx>parallelism profiles</nidx> -<nidx>profiles, parallelism</nidx> -<nidx>visualisation tools</nidx> -%* * -%************************************************************************ - -With Parallel Haskell programs, we usually don't care about the -results---only with ``how parallel'' it was! We want pretty pictures. - -Parallelism profiles (\`a la @hbcpp@) can be generated with the -@-q@<nidx>-q RTS option (concurrent, parallel)</nidx> RTS option. The -per-processor profiling info is dumped into files named -@<full-path><program>.gr@. These are then munged into a PostScript picture, -which you can then display. For example, to run your program -@a.out@ on 8 processors, then view the parallelism profile, do: - -<tscreen><verb> -% ./a.out +RTS -N8 -q -% grs2gr *.???.gr > 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! -</verb></tscreen> - -The scripts for processing the parallelism profiles are distributed -in @ghc/utils/parallel/@. - -%************************************************************************ -%* * -<sect2>Other useful info about running parallel programs -<p> -%* * -%************************************************************************ - -The ``garbage-collection statistics'' RTS options can be useful for -seeing what parallel programs are doing. If you do either -@+RTS -Sstderr@<nidx>-Sstderr RTS option</nidx> or @+RTS -sstderr@, 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 @/tmp/pvml.nnn@, courtesy of PVM. - -Whether doing @+RTS -Sstderr@ or not, a handy way to watch -what's happening overall is: @tail -f /tmp/pvml.nnn@. - -%************************************************************************ -%* * -<sect2>RTS options for Concurrent/Parallel Haskell -<label id="parallel-rts-opts"> -<p> -<nidx>RTS options, concurrent</nidx> -<nidx>RTS options, parallel</nidx> -<nidx>Concurrent Haskell---RTS options</nidx> -<nidx>Parallel Haskell---RTS options</nidx> -%* * -%************************************************************************ - -Besides the usual runtime system (RTS) options -(Section <ref name="Running a compiled program" id="runtime-control">), there are a few options particularly -for concurrent/parallel execution. - -<descrip> -<tag>@-N<N>@:</tag> -<nidx>-N<N> RTS option (parallel)</nidx> -(PARALLEL ONLY) Use @<N>@ PVM processors to run this program; -the default is 2. - -<tag>@-C[<us>]@:</tag> -<nidx>-C<us> RTS option</nidx> -Sets the context switch interval to @<us>@ microseconds. A context -switch will occur at the next heap allocation after the timer expires. -With @-C0@ or @-C@, 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. - -[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]. - -<tag>@-q[v]@:</tag> -<nidx>-q RTS option</nidx> -(PARALLEL ONLY) Produce a quasi-parallel profile of thread activity, -in the file @<program>.qp@. In the style of @hbcpp@, this profile -records the movement of threads between the green (runnable) and red -(blocked) queues. If you specify the verbose suboption (@-qv@), 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 -@hbcpp@ profiling tools or if you are context switching at every heap -check (with @-C@). - -<tag>@-t<num>@:</tag> -<nidx>-t<num> RTS option</nidx> -(PARALLEL ONLY) Limit the number of concurrent threads per processor -to @<num>@. The default is 32. Each thread requires slightly over 1K -<em>words</em> 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.) - -<tag>@-d@:</tag> -<nidx>-d RTS option (parallel)</nidx> -(PARALLEL ONLY) Turn on debugging. It pops up one xterm (or GDB, or -something...) per PVM processor. We use the standard @debugger@ -script that comes with PVM3, but we sometimes meddle with the -@debugger2@ script. We include ours in the GHC distribution, -in @ghc/utils/pvm/@. - -<tag>@-e<num>@:</tag> -<nidx>-e<num> RTS option (parallel)</nidx> -(PARALLEL ONLY) Limit the number of pending sparks per processor to -@<num>@. The default is 100. A larger number may be appropriate if -your program generates large amounts of parallelism initially. - -<tag>@-Q<num>@:</tag> -<nidx>-Q<num> RTS option (parallel)</nidx> -(PARALLEL ONLY) Set the size of packets transmitted between processors -to @<num>@. The default is 1024 words. A larger number may be -appropriate if your machine has a high communication cost relative to -computation speed. -</descrip> diff --git a/ghc/docs/users_guide/utils.vsgml b/ghc/docs/users_guide/utils.vsgml deleted file mode 100644 index 9f0685fed7f991687c19ef5e879449c4ef7a4b22..0000000000000000000000000000000000000000 --- a/ghc/docs/users_guide/utils.vsgml +++ /dev/null @@ -1,216 +0,0 @@ -%************************************************************************ -%* * -<sect>Other Haskell utility programs -<label id="utils"> -<p> -<nidx>utilities, Haskell</nidx> -%* * -%************************************************************************ - -This section describes other program(s) which we distribute, that help -with the Great Haskell Programming Task. - -%************************************************************************ -%* * -<sect1>Makefile dependencies in Haskell: using @mkdependHS@ -<label id="mkdependHS"> -<p> -<nidx>mkdependHS</nidx> -<nidx>Makefile dependencies</nidx> -<nidx>dependencies in Makefiles</nidx> -%* * -%************************************************************************ - -You run @mkdependHS@ like this: -<tscreen><verb> - mkdependHS [mkdependHS options] [-- GHC options --] srcfile1 [srcfile2 ...] -</verb></tscreen> -or -<tscreen><verb> - ghc -M [mkdependHS options(prefix with -optdep)] [ GHC options ] srcfile1 [srcfile2 ...] -</verb></tscreen> -To see @mkdependHS@'s command-line flags, give it a duff flag, -e.g., @mkdependHS -help@. - -In general, if module @A@ contains the line -<tscreen><verb> - import B ...blah... -</verb></tscreen> -then @mkdependHS@ will generate a dependency line of the form: -<tscreen><verb> - A.o : B.hi -</verb></tscreen> -If module @A@ contains the line -<tscreen><verb> - import {-# SOURCE #-} B ...blah... -</verb></tscreen> -then @mkdependHS@ will generate a dependency line of the form: -<tscreen><verb> - A.o : B.hi-boot -</verb></tscreen> -(See Section <ref name="Interface files" id="hi-files"> for details of interface files.) -If @A@ imports multiple modules, then there will be multiple lines with @A.o@ as the -target. - -By default, @mkdependHS@ generates all the dependencies, and then -concatenates them onto the end of -@makefile@ (or @Makefile@ if @makefile@ doesn't exist) bracketed by -the lines "@# DO NOT DELETE: Beginning of Haskell dependencies@" and -"@# DO NOT DELETE: End of Haskell dependencies@". If these lines -already exist in the @makefile@, @mkdependHS@ deletes the old -dependencies first. - -@mkdependHS@ takes GHC options between @--@ brackets. -It understands the following ones. Any options between @--@ brackets -that it doesn't understand are simply ignored; this way you can feed your -Makefile's standard GHC options to @mkdependHS@ un-filtered. -<descrip> - -<tag>@-cpp@</tag> Run the C pre-processor over the input files. The - default is not to. -<tag>@-D<blah>@</tag> A cpp @#define@; usual meaning. - -<tag>@-i<dirs>@</tag> Add @<dirs>@ (colon-separated) to list of directories - to search for "import"ed modules. - -<tag>@-I<dir>@</tag> Add @<dir>@ to list of directories to search for - .h files (i.e., usual meaning). - -<tag>@-syslib <blah>@</tag> This program uses this GHC system library; take - appropriate action (e.g., recognise when they are - "import"ing a module from that library). -</descrip> - -Here are the @mkdependHS@-specific options (not between @--@'s): -<descrip> -<tag>@-v@</tag> Be verbose. -<tag>@-v -v@</tag> Be very verbose. -<tag>@-w@</tag> Turn off warnings about interface file shadowing. -<tag>@-f blah@</tag> - Use @blah@ as the makefile, rather than @makefile@ - or @Makefile@. If @blah@ doesn't exist, @mkdependHS@ creates it. - We often use @-f .depend@ to put the dependencies in @.depend@ and - then @include@ the file @.depend@ into @Makefilpe@. - -<tag>@-o <osuf>@</tag> - Use @.<osuf>@ as the "target file" suffix ( default: @o@). - Multiple @-o@ flags are permitted (GHC2.05 onwards). Thus "@-o hc -o o@" - will generate dependencies for @.hc@ and @.o@ files. - -<tag>@-s <suf>@</tag> - Make extra dependencies that declare that files with - suffix @.<suf>_<osuf>@ depend on interface files with suffix @.<suf>_hi@, or - (for @{-# SOURCE #-}@ imports) on @.hi-boot@. - Multiple @-s@ flags are permitted. - For example, "@-o hc -s a -s b@" will - make dependencies for @.hc@ on @.hi@, @.a_hc@ on @.a_hi@, and @.b_hc@ on @.b_hi@. - (Useful in conjunction with NoFib "ways".) - -<tag>@--exclude-module=<file>@</tag> - Regard @<file>@ as "stable"; i.e., exclude it from having - dependencies on it. - -<tag>@-x@</tag> same as @--exclude-module@ - -<tag>@--exclude-directory=<dirs>@</tag> - Regard the colon-separated list of directories @<dirs>@ as containing stable, - don't generate any dependencies on modules therein. - -<tag>@-Xdirs@</tag> same as @--exclude-directory@. - -<tag>@--include-module=<file>@</tag> - Regard @<file>@ as not "stable"; i.e., generate dependencies - on it (if any). This option is normally used in conjunction - with the @--exclude-directory@ option. -<tag>@--include-prelude@</tag> - Regard prelude libraries as unstable, i.e., generate dependencies - on the prelude modules used (including @Prelude@). - This option is normally only used by the various system libraries. If - a @-syslib@ option is used, dependencies will also be - generated on the library's interfaces. -</descrip> - - -%************************************************************************ -%* * -<sect1>Emacs `TAGS' for Haskell: @hstags@ -<label id="hstags"> -<p> -<nidx>hstags</nidx> -<nidx>TAGS for Haskell</nidx> -%* * -%************************************************************************ - -`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. - -Rather than scratch your head, saying ``Now where did we define -`foo'?'', you just do (in Emacs) @M-. foo RET@, and You're There! -Some people go wild over this stuff... - -GHC comes with a program @hstags@, which build Emacs-able TAGS -files. The invocation syntax is: -<tscreen><verb> -hstags [GHC-options] file [files...] -</verb></tscreen> - -The best thing is just to feed it your GHC command-line flags. -A good Makefile entry might be: -<tscreen><verb> -tags: - $(RM) TAGS - hstags $(GHC_FLAGS) *.lhs -</verb></tscreen> - -The only flags of its own are: @-v@ to be verbose; @-a@ to -**APPEND** to the TAGS file, rather than write to it. - -Shortcomings: (1)~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)~Data-constructor definitions don't get -in. Go for the corresponding type constructor instead. - -(Actually, GHC also comes with @etags@ [for C], and @perltags@ -[for You Know What]. And---I cannot tell a lie---there is Denis -Howe's @fptags@ [for Haskell, etc.] in the @ghc/CONTRIB@ -section...) - -%************************************************************************ -%* * -<sect1>``Yacc for Haskell'': @happy@ -<label id="happy"> -<p> -<nidx>happy</nidx> -<nidx>Yacc for Haskell</nidx> -<nidx>parser generator for Haskell</nidx> -%* * -%************************************************************************ - -Andy Gill and Simon Marlow have written a parser-generator for -Haskell, called @happy@.<nidx>happy parser generator</nidx> @Happy@ -is to Haskell what @Yacc@ is to C. - -You can get @happy@ by FTP from @ftp.dcs.gla.ac.uk@ in -@pub/haskell/happy@, the file @happy-1.5-src.tar.gz@. - -@Happy@ is at its shining best when compiled by GHC. - -%************************************************************************ -%* * -<sect1>Pretty-printing Haskell: @pphs@ -<label id="pphs"> -<p> -<nidx>pphs</nidx> -<nidx>pretty-printing Haskell code</nidx> -%* * -%************************************************************************ - -Andrew Preece has written -@pphs@,<nidx>pphs</nidx><nidx>pretty-printing Haskell</nidx> -a utility to pretty-print Haskell code in LaTeX documents. -Keywords in bolds, variables in italics---that sort of thing. It is -good at lining up program clauses and equals signs, things that are -very tiresome to do by hand. - -The code is distributed with GHC in @ghc/CONTRIB/pphs@. diff --git a/ghc/docs/users_guide/vs_haskell.vsgml b/ghc/docs/users_guide/vs_haskell.vsgml deleted file mode 100644 index 3d08ae8847698bd0e999e3fdc1c88d8309844d2c..0000000000000000000000000000000000000000 --- a/ghc/docs/users_guide/vs_haskell.vsgml +++ /dev/null @@ -1,135 +0,0 @@ -%************************************************************************ -%* * -<sect1>Haskell~98 vs.~Glasgow Haskell: language non-compliance -<label id="vs-Haskell-defn"> -<p> -<nidx>GHC vs the Haskell 98 language</nidx> -<nidx>Haskell 98 language vs GHC</nidx> -%* * -%************************************************************************ - -This section lists Glasgow Haskell infelicities in its implementation -of Haskell~98. See also the ``when things go wrong'' section -(Section <ref name="What to do when something goes wrong" id="wrong">) -for information about crashes, space leaks, and other undesirable -phenomena. - -The limitations here are listed in Haskell-Report order (roughly). - -%************************************************************************ -%* * -<sect2>Expressions and patterns -<label id="infelicities-exprs-pats"> -<p> -%* * -%************************************************************************ - -<descrip> - -%------------------------------------------------------------------- -<tag>Very long @String@ constants:</tag> -May not go through. If you add a ``string gap'' every -few thousand characters, then the strings can be as long -as you like. - -Bear in mind that string gaps and the @-cpp@<nidx>-cpp option</nidx> -option don't mix very well (see Section <ref id="c-pre-processor" -name="The C pre-processor">). - -%------------------------------------------------------------------- -<tag>Very long literal lists:</tag> -These may tickle a ``yacc stack overflow'' error in the parser. -(It depends on the Yacc used to build your parser.) - -%------------------------------------------------------------------- -<tag>Single quotes in module names:</tag> -It might work, but it's just begging for trouble. -</descrip> - -%************************************************************************ -%* * -<sect2>Declarations and bindings -<label id="infelicities-decls"> -<p> -%* * -%************************************************************************ - -<descrip> -%------------------------------------------------------------------- -<tag>Derived instances for records:</tag> Hmmm. -</descrip> - -%************************************************************************ -%* * -<sect2>Module system and interface files -<label id="infelicities-Modules"> -<p> -%* * -%************************************************************************ - -<descrip> -%------------------------------------------------------------------- -<tag> Namespace pollution </tag> - -Several modules internal to GHC are visible in the standard namespace. -All of these modules begin with @Prel@, so the rule is: don't use any -modules beginning with @Prel@ in your program, or you will be -comprehensively screwed. - -</descrip> - -%************************************************************************ -%* * -<sect2>Numbers, basic types, and built-in classes -<label id="infelicities-numbers"> -<p> -%* * -%************************************************************************ - -<descrip> -%------------------------------------------------------------------- -<tag>Unchecked arithmetic:</tag> - -Arguably <em>not</em> an infelicity, but... Bear in mind that -operations on @Int@, @Float@, and @Double@ numbers are -<em>unchecked</em> 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)<nidx>floating-point exceptions</nidx>. - -Use @Integer@, @Rational@, etc., numeric types if this stuff -keeps you awake at night. - -%------------------------------------------------------------------- -<tag>Multiply-defined array elements---not checked:</tag> -This code fragment <em>should</em> elicit a fatal error, but it does not: -<tscreen><verb> -main = print (array (1,1) [ 1:=2, 1:=3 ]) -</verb></tscreen> -</descrip> - -%************************************************************************ -%* * -<sect2>In Prelude support -<label id="infelicities-Prelude"> -<p> -%* * -%************************************************************************ - -<descrip> -%------------------------------------------------------------------- -<tag>Arbitrary-sized tuples:</tag> -Plain old tuples of arbitrary size <em>do</em> work. - -HOWEVER: standard instances for tuples (@Eq@, @Ord@, @Bounded@, @Ix@ -@Read@, and @Show@) are available <em>only</em> up to 5-tuples. - -These limitations are easily subvertible, so please ask if you get -stuck on them. - -%------------------------------------------------------------------- -<tag>Unicode character set:</tag> -Haskell 98 embraces the Unicode character set, but GHC doesn't -handle it. Yet. - -</descrip>