Commit 06a2a669 authored by chak's avatar chak
Browse files

[project @ 2002-11-09 09:31:36 by chak]

Some documentation covering the extra desugaring that is needed for Template
Haskell.
parent 410e4850
<!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 - Template Haskell</title>
</head>
<body BGCOLOR="FFFFFF">
<h1>The GHC Commentary - Template Haskell</h1>
<p>
The Template Haskell (TH) extension to GHC adds a meta-programming
facility in which all meta-level code is executed at compile time. The
design of this extension is detailed in "Template Meta-programming for
Haskell", Tim Sheard and Simon Peyton Jones, <a
href="http://portal.acm.org/toc.cfm?id=581690&type=proceeding&coll=portal&dl=ACM&part=series&WantType=proceedings&idx=unknown&title=unknown">ACM
SIGPLAN 2002 Haskell Workshop,</a> 2002. However, some of the details
changed after the paper was published.
</p>
<h2>Meta Sugar</h2>
<p>
The extra syntax of TH (quasi-quote brackets, splices, and reification)
is handled in the module <a
href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/deSugar/DsMeta.hs"><code>DsMeta</code></a>.
In particular, the function <code>dsBracket</code> desugars the four
types of quasi-quote brackets (<code>[|...|]</code>,
<code>[p|...|]</code>, <code>[d|...|]</code>, and <code>[t|...|]</code>)
and <code>dsReify</code> desugars the three types of reification
operations (<code>reifyType</code>, <code>reifyDecl</code>, and
<code>reifyFixity</code>).
</p>
<h3>Desugaring of Quasi-Quote Brackets</h3>
<p>
A term in quasi-quote brackets needs to be translated into Core code
that, when executed, yields a <em>representation</em> of that term in
the form of the abstract syntax trees defined in <a
href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/libraries/haskell-src/Language/Haskell/THSyntax.hs"><code>Language.Haskell.THSyntax</code></a>.
Within <code>DsMeta</code>, this is achieved by four functions
corresponding to the four types of quasi-quote brackets:
<code>repE</code> (for <code>[|...|]</code>), <code>repP</code> (for
<code>[p|...|]</code>), <code>repTy</code> (for <code>[t|...|]</code>),
and <code>repTopDs</code> (for <code>[d|...|]</code>). All four of
these functions receive as an argument the GHC-internal Haskell AST of
the syntactic form that they quote (i.e., arguments of type <a
href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/hsSyn/HsExpr.lhs"><code>HsExpr</code></a><code>.HsExpr
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>,
<a
href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/hsSyn/HsTypes.lhs"><code>HsType</code></a><code>.HsType
Name</code>, and <a
href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/hsSyn/HsDecls.lhs"><code>HsDecls</code></a><code>.HsGroup
Name</code>, respectively).
</p>
<p>
To increase the static type safety in <code>DsMeta</code>, the functions
constructing representations do not just return plain values of type <a
href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/coreSyn/CoreSyn.lhs"><code>CoreSyn</code></a>
<code>.CoreExpr</code>; instead, <code>DsMeta</code> introduces a
parametrised type <code>Core</code> whose dummy type parameter indicates
the source-level type of the value computed by the corresponding Core
expression. All construction of Core fragments in <code>DsMeta</code>
is performed by smart constructors whose type signatures use the dummy
type parameter to constrain the contexts in which they are applicable.
For example, a function that builds a Core expression that evaluates to
a TH type representation, which has type
<code>Language.Haskell.THSyntax.Type</code>, would return a value of
type
</p>
<blockquote>
<pre>
Core Language.Haskell.THSyntax.Type</pre>
</blockquote>
<h3>Desugaring of Reification Operators</h3>
<p>
The TH paper introduces four reification operators:
<code>reifyType</code>, <code>reifyDecl</code>,
<code>reifyFixity</code>, and <code>reifyLocn</code>. Of these,
currently (= 9 Nov 2002), only the former two are implemented.
</p>
<p>
The operator <code>reifyType</code> receives the name of a function or
data constructor as its argument and yields a representation of this
entity's type in the form of a value of type
<code>THSyntax.Type</code>. Similarly, <code>reifyDecl</code> receives
the name of a type and yields a representation of the type's declaration
as a value of type <code>THSyntax.Decl</code>. The name of the reified
entity is mapped to the GHC-internal representation of the entity by
using the function <code>lookupOcc</code> on the name.
</p>
<h3>Binders Versus Occurences</h3>
<p>
Name lookups in the meta environment of the desugarer use two functions
with slightly different behaviour, namely <code>DsMeta.lookupOcc</code>
and <code>lookupBinder</code>. The module <code>DsMeta</code> contains
the following explanation as to the difference of these functions:
</p>
<blockquote>
<pre>
When we desugar [d| data T = MkT |]
we want to get
Data "T" [] [Con "MkT" []] []
and *not*
Data "Foo:T" [] [Con "Foo:MkT" []] []
That is, the new data decl should fit into whatever new module it is
asked to fit in. We do *not* clone, though; no need for this:
Data "T79" ....
But if we see this:
data T = MkT
foo = reifyDecl T
then we must desugar to
foo = Data "Foo:T" [] [Con "Foo:MkT" []] []
So in repTopDs we bring the binders into scope with mkGenSyms and addBinds,
but in dsReify we do not. And we use lookupOcc, rather than lookupBinder
in repTyClD and repC.</pre>
</blockquote>
<p>
This implies that <code>lookupOcc</code>, when it does not find the name
in the meta environment, uses the function <code>DsMeta.globalVar</code>
to construct the <em>original name</em> of the entity. This name
uniquely identifies the entity in the whole program and is in scope
<em>independent</em> of whether the user name of the same entity is in
scope or not (i.e., it may be defined in a different module without
being explicitly imported). <strong>NB:</strong> Incidentally, the
current implementation of this mechanisms facilitates breaking any
abstraction barrier.
</p>
<h3>Known-key Names for Template Haskell</h3>
<p>
During the construction of representations, the desugarer needs to use a
large number of functions defined in the library
<code>Language.Haskell.THSyntax</code>. The names of these functions
need to be made available to the compiler in the way outlined <a
href="../the-beast/prelude.html">Primitives and the Prelude.</a>
Unfortunately, any change to <a
href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/prelude/PrelNames.lhs"><code>PrelNames</code></a>
triggers a significant amount of recompilation. Hence, the names needed
for TH are defined in <code>DsMeta</code> instead (at the end of the
module).
</p>
<p><small>
<!-- hhmts start -->
Last modified: Sat Nov 9 20:27:46 EST 2002
<!-- hhmts end -->
</small>
</body>
</html>
......@@ -6,7 +6,7 @@
</head>
<body BGCOLOR="FFFFFF">
<h1>The Glasgow Haskell Compiler (GHC) Commentary [v0.12]</h1>
<h1>The Glasgow Haskell Compiler (GHC) Commentary [v0.13]</h1>
<p>
<!-- Contributors: Whoever makes substantial additions or changes to the
document, please add your name and keep the order alphabetic. Moreover,
......@@ -92,6 +92,7 @@
<h2>Extensions, or Making a Complicated System More Complicated</h2>
<p>
<ul>
<li><a href="exts/th.html">Template Haskell</a>
<li><a href="exts/ndp.html">Parallel Arrays</a>
</ul>
......@@ -110,7 +111,7 @@
<p><small>
<!-- hhmts start -->
Last modified: Mon Apr 22 11:00:01 EST 2002
Last modified: Sat Nov 9 15:01:44 EST 2002
<!-- hhmts end -->
</small>
</body>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment