[project @ 2002-11-09 09:31:36 by chak]
[ghc-hetmet.git] / ghc / docs / comm / exts / th.html
1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
2 <html>
3   <head>
4     <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1">
5     <title>The GHC Commentary - Template Haskell</title>
6   </head>
7
8   <body BGCOLOR="FFFFFF">
9     <h1>The GHC Commentary - Template Haskell</h1>
10     <p>
11       The Template Haskell (TH) extension to GHC adds a meta-programming
12       facility in which all meta-level code is executed at compile time.  The
13       design of this extension is detailed in "Template Meta-programming for
14       Haskell", Tim Sheard and Simon Peyton Jones, <a
15       href="http://portal.acm.org/toc.cfm?id=581690&type=proceeding&coll=portal&dl=ACM&part=series&WantType=proceedings&idx=unknown&title=unknown">ACM
16       SIGPLAN 2002 Haskell Workshop,</a> 2002.  However, some of the details
17       changed after the paper was published.
18     </p>
19
20     <h2>Meta Sugar</h2>
21     <p>
22       The extra syntax of TH (quasi-quote brackets, splices, and reification)
23       is handled in the module <a
24       href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/deSugar/DsMeta.hs"><code>DsMeta</code></a>.
25       In particular, the function <code>dsBracket</code> desugars the four
26       types of quasi-quote brackets (<code>[|...|]</code>,
27       <code>[p|...|]</code>, <code>[d|...|]</code>, and <code>[t|...|]</code>)
28       and <code>dsReify</code> desugars the three types of reification
29       operations (<code>reifyType</code>, <code>reifyDecl</code>, and
30       <code>reifyFixity</code>).
31     </p>
32
33     <h3>Desugaring of Quasi-Quote Brackets</h3>
34     <p>
35       A term in quasi-quote brackets needs to be translated into Core code
36       that, when executed, yields a <em>representation</em> of that term in
37       the form of the abstract syntax trees defined in <a
38       href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/libraries/haskell-src/Language/Haskell/THSyntax.hs"><code>Language.Haskell.THSyntax</code></a>.
39       Within <code>DsMeta</code>, this is achieved by four functions
40       corresponding to the four types of quasi-quote brackets:
41       <code>repE</code> (for <code>[|...|]</code>), <code>repP</code> (for
42       <code>[p|...|]</code>), <code>repTy</code> (for <code>[t|...|]</code>),
43       and <code>repTopDs</code> (for <code>[d|...|]</code>).  All four of
44       these functions receive as an argument the GHC-internal Haskell AST of
45       the syntactic form that they quote (i.e., arguments of type <a
46       href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/hsSyn/HsExpr.lhs"><code>HsExpr</code></a><code>.HsExpr
47         Name</code>, <a href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/hsSyn/HsPat.lhs"><code>HsPat</code></a><code>.HsPat Name</code>, 
48       <a
49       href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/hsSyn/HsTypes.lhs"><code>HsType</code></a><code>.HsType 
50         Name</code>, and <a
51         href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/hsSyn/HsDecls.lhs"><code>HsDecls</code></a><code>.HsGroup 
52         Name</code>, respectively). 
53     </p>
54     <p>
55       To increase the static type safety in <code>DsMeta</code>, the functions
56       constructing representations do not just return plain values of type <a
57       href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/coreSyn/CoreSyn.lhs"><code>CoreSyn</code></a>
58       <code>.CoreExpr</code>; instead, <code>DsMeta</code> introduces a
59       parametrised type <code>Core</code> whose dummy type parameter indicates
60       the source-level type of the value computed by the corresponding Core
61       expression.  All construction of Core fragments in <code>DsMeta</code>
62       is performed by smart constructors whose type signatures use the dummy
63       type parameter to constrain the contexts in which they are applicable.
64       For example, a function that builds a Core expression that evaluates to
65       a TH type representation, which has type
66       <code>Language.Haskell.THSyntax.Type</code>, would return a value of
67       type 
68     </p>
69     <blockquote>
70       <pre>
71 Core Language.Haskell.THSyntax.Type</pre>
72     </blockquote>
73
74     <h3>Desugaring of Reification Operators</h3>
75     <p>
76       The TH paper introduces four reification operators:
77       <code>reifyType</code>, <code>reifyDecl</code>,
78       <code>reifyFixity</code>, and <code>reifyLocn</code>.  Of these,
79       currently (= 9 Nov 2002), only the former two are implemented.
80     </p>
81     <p>
82       The operator <code>reifyType</code> receives the name of a function or
83       data constructor as its argument and yields a representation of this
84       entity's type in the form of a value of type
85       <code>THSyntax.Type</code>.  Similarly, <code>reifyDecl</code> receives
86       the name of a type and yields a representation of the type's declaration
87       as a value of type <code>THSyntax.Decl</code>.  The name of the reified
88       entity is mapped to the GHC-internal representation of the entity by
89       using the function <code>lookupOcc</code> on the name.
90     </p>
91     
92     <h3>Binders Versus Occurences</h3>
93     <p>
94       Name lookups in the meta environment of the desugarer use two functions
95       with slightly different behaviour, namely <code>DsMeta.lookupOcc</code>
96       and <code>lookupBinder</code>.  The module <code>DsMeta</code> contains
97       the following explanation as to the difference of these functions:
98     </p>
99     <blockquote>
100       <pre>
101 When we desugar [d| data T = MkT |]
102 we want to get
103         Data "T" [] [Con "MkT" []] []
104 and *not*
105         Data "Foo:T" [] [Con "Foo:MkT" []] []
106 That is, the new data decl should fit into whatever new module it is
107 asked to fit in.   We do *not* clone, though; no need for this:
108         Data "T79" ....
109
110 But if we see this:
111         data T = MkT 
112         foo = reifyDecl T
113
114 then we must desugar to
115         foo = Data "Foo:T" [] [Con "Foo:MkT" []] []
116
117 So in repTopDs we bring the binders into scope with mkGenSyms and addBinds,
118 but in dsReify we do not.  And we use lookupOcc, rather than lookupBinder
119 in repTyClD and repC.</pre>
120     </blockquote>
121     <p>
122       This implies that <code>lookupOcc</code>, when it does not find the name
123       in the meta environment, uses the function <code>DsMeta.globalVar</code>
124       to construct the <em>original name</em> of the entity.  This name
125       uniquely identifies the entity in the whole program and is in scope
126       <em>independent</em> of whether the user name of the same entity is in
127       scope or not (i.e., it may be defined in a different module without
128       being explicitly imported).  <strong>NB:</strong> Incidentally, the
129       current implementation of this mechanisms facilitates breaking any
130       abstraction barrier.
131     </p>
132     
133     <h3>Known-key Names for Template Haskell</h3>
134     <p>
135       During the construction of representations, the desugarer needs to use a
136       large number of functions defined in the library
137       <code>Language.Haskell.THSyntax</code>.  The names of these functions
138       need to be made available to the compiler in the way outlined <a
139       href="../the-beast/prelude.html">Primitives and the Prelude.</a>
140       Unfortunately, any change to <a
141       href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/prelude/PrelNames.lhs"><code>PrelNames</code></a>
142       triggers a significant amount of recompilation.  Hence, the names needed
143       for TH are defined in <code>DsMeta</code> instead (at the end of the
144       module).
145     </p>
146     
147     <p><small>
148 <!-- hhmts start -->
149 Last modified: Sat Nov  9 20:27:46 EST 2002
150 <!-- hhmts end -->
151     </small>
152   </body>
153 </html>