[project @ 2002-08-28 11:29:42 by simonpj]
authorsimonpj <unknown>
Wed, 28 Aug 2002 11:29:42 +0000 (11:29 +0000)
committersimonpj <unknown>
Wed, 28 Aug 2002 11:29:42 +0000 (11:29 +0000)
Add notes about data types

ghc/docs/comm/index.html
ghc/docs/comm/the-beast/data-types.html [new file with mode: 0644]

index a3362b0..b88c15e 100644 (file)
@@ -61,6 +61,7 @@
       <li><a href="the-beast/names.html">The truth about names: Names and OccNamesd</a> 
       <li><a href="the-beast/vars.html">The Real Story about Variables, Ids,
          TyVars, and the like</a> 
+      <li><a href="the-beast/data-types.html">Data types and constructors</a> 
       <li><a href="the-beast/renamer.html">The Glorious Renamer</a>
       <li><a href="the-beast/typecheck.html">Checking Types</a>
       <li><a href="the-beast/desugar.html">Sugar Free: From Haskell To Core</a>
diff --git a/ghc/docs/comm/the-beast/data-types.html b/ghc/docs/comm/the-beast/data-types.html
new file mode 100644 (file)
index 0000000..1d73f6e
--- /dev/null
@@ -0,0 +1,105 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+  <head>
+    <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1">
+    <title>The GHC Commentary - Data types and data constructors</title>
+  </head>
+
+  <body BGCOLOR="FFFFFF">
+    <h1>The GHC Commentary - Data types and data constructors</h1>
+    <p>
+
+
+<h2>Data types</h2>
+
+Consider the following data type declaration:
+
+<pre>
+  data T a = MkT !(a,a) !(T a) | Nil
+</pre>
+The user's source program mentions only the constructors <tt>MkT</tt>
+and <tt>Nil</tt>.  However, these constructors actually <em>do</em> something
+in addition to building a data value.  For a start, <tt>MkT</tt> evaluates
+its arguments.  Secondly, with the flag <tt>-funbox-strict-fields</tt> GHC
+will flatten (or unbox) the strict fields.  So GHC generates a top-level function
+for each data constructor, as follows:
+
+<pre>
+  MkT :: (a,a) -> T a -> T a
+  MkT p t = case p of 
+              (a,b) -> seq t ($wMkT a b t)
+
+  Nil :: T a
+  Nil = $wNil
+</pre>
+
+Here, the <em>wrapper</em> <tt>MkT</tt> evaluates and takes the argument <tt>p</tt>,
+evaluates the argument <tt>t</tt>, and builds a three-field data value
+with the <em>worker</em> constructor <tt>$wMKT</tt>.  (There are more notes below
+about the unboxing of strict fields.)
+<p>
+So the original constructors, <tt>MkT</tt> and <tt>Nil</tt> are really just
+<em>wrappers</em> which perhaps do some work before calling the <em>workers</em>
+<tt>$wMkT</tt> and <tt>$wNil</tt>.  The workers are 
+the "representation constructors" of
+the "representation data type", which we can think of as being defined thus:
+
+<pre>
+  data T a = $wMkT a a Int | $wNil
+</pre>
+
+This representation data type, gives the number and types of
+fields of the constructors used to represent values of type <tt>T</tt>.
+This representation type is also what is emitted when you print External Core 
+from GHC.  
+
+<h3> The constructor wrapper functions </h3>
+
+The wrapper functions are automatically generated by GHC, and are
+really emitted into the result code (albeit only after CorePre; see
+<tt>CorePrep.mkImplicitBinds</tt>).  
+The wrapper functions are inlined very
+vigorously, so you will not see many occurrences of the wrapper
+functions in an optimised program, but you may see some.  For example,
+if your Haskell source has
+<pre>
+    map MkT xs
+</pre>
+then <tt>MkT</tt> will not be inlined (because it is not applied to anything).
+That is why we generate real top-level bindings for the wrapper functions,
+and generate code for them.
+
+
+<h3> Unboxing strict fields </h3>
+
+If GHC unboxes strict fields (as in the first argument of <tt>MkT</tt> above), 
+it also transforms
+source-language case expressions.  Suppose you write this in your Haskell source:
+<pre>
+   case e of 
+     MkT p t -> ..p..t..
+</pre>
+GHC will desugar this to the following Core code:
+<pre>
+   case e of
+     $wMkT a b t -> let p = (a,b) in ..p..t..
+</pre>
+(<em>Important note</em>: perhaps misleadingly, when printing Core we
+actually print the constructor in the case expression as
+"<tt>MkT</tt>" not as "<tt>$wMkT</tt>", but it really means the
+latter.)
+<p>
+The local let-binding reboxes the pair because it may be mentioned in
+the case alternative.  This may well be a bad idea, which is why
+<tt>-funbox-strict-fields</tt> is an experimental feature.
+<p>
+It's essential that when importing a type <tt>T</tt> defined in some
+external module <tt>M</tt>, GHC knows what representation was used for
+that type, and that in turn depends on whether module <tt>M</tt> was
+compiled with <tt>-funbox-strict-fields</tt>.  So when writing an
+interface file, GHC therefore records with each data type whether its
+strict fields (if any) should be unboxed.
+<p>
+  </body>
+</html>
+