summaryrefslogtreecommitdiff
path: root/ghc/docs/comm/the-beast/prelude.html
blob: 64b607def502de29828ddb276a98ea1124dc53ea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
<!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 - Primitives and the Prelude</title>
  </head>

  <body BGCOLOR="FFFFFF">
    <h1>The GHC Commentary - Primitives and the Prelude</h1>
    <p>
      One of the trickiest aspects of GHC is the delicate interplay
      between what knowledge is baked into the compiler, and what
      knowledge it gets by reading the interface files of library
      modules.  In general, the less that is baked in, the better.
<p>
      Most of what the compiler has to have wired in about primitives and
      prelude definitions is in
      <a
      href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/prelude/"><code>fptools/ghc/compiler/prelude/</code></a>.
    </p>

GHC recognises these main classes of baked-in-ness:
<dl>
<dt><strong>Primitive types.</strong>
<dd>Primitive types cannot be defined in Haskell, and are utterly baked into the compiler.
They are notionally defined in the fictional module <tt>GHC.Prim</tt>.   The <tt>TyCon</tt>s for these types are all defined
in module <tt>TysPrim</tt>; for example,
<pre>
  intPrimTyCon :: TyCon 
  intPrimTyCon = ....
</pre>
Examples:
<tt>Int#, Float#, Addr#, State#</tt>.  
<p>
<dt><strong>Wired-in types.</strong>
<dd>Wired-in types can be defined in Haskell, and indeed are (many are defined in </tt>GHC.Base</tt>).
However, it's very convenient for GHC to be able to use the type constructor for (say) <tt>Int</tt>
without looking it up in any environment.  So module <tt>TysWiredIn</tt> contains many definitions
like this one:
<pre>
  intTyCon :: TyCon
  intTyCon = ....

  intDataCon :: DataCon 
  intDataCon = ....
</pre>
However, since a <tt>TyCon</tt> value contains the entire type definition inside it, it follows
that the complete definition of <tt>Int</tt> is thereby baked into the compiler.  
<p>
Nevertheless, the library module <tt>GHC.Base</tt> still contains a definition for <tt>Int</tt> 
just so that its info table etc get generated somewhere.  Chaos will result if the wired-in definition
in <tt>TysWiredIn</tt> differs from that in <tt>GHC.Base</tt>.
<p>
The rule is that only very simple types should be wired in (for example, <tt>Ratio</tt> is not,
and <tt>IO</tt> is certainly not).  No class is wired in: classes are just too complicated.
<p>
Examples: <tt>Int</tt>, <tt>Float</tt>, <tt>List</tt>, tuples.

<p>
<dt><strong>Known-key things.</strong>
<dd>GHC knows of the existence of many, many other types, classes and values.  <em>But all it knows is
their <tt>Name</tt>.</em>  Remember, a <tt>Name</tt> includes a unique key that identifies the 
thing, plus its defining module and occurrence name 
(see <a href="names.html">The truth about Names</a>).  Knowing a <tt>Name</tt>, therefore, GHC can
run off to the interface file for the module and find out everything else it might need.
<p>
Most of these known-key names are defined in module <tt>PrelNames</tt>; a further swathe concerning
Template Haskell are defined in <tt>DsMeta</tt>.  The allocation of unique keys is done manually;
chaotic things happen if you make a mistake here, which is why they are all together.
</dl>

All the <tt>Name</tt>s from all the above categories are used to initialise the global name cache,
which maps (module,occurrence-name) pairs to the globally-unique <tt>Name</tt> for that
thing.  (See <tt>HscMain.initOrigNames</tt>.)

<p>
The next sections elaborate these three classes a bit.


    <h2>Primitives (module <tt>TysPrim</tt>)</h2>
    <p>
      Some types and functions have to be hardwired into the compiler as they
      are atomic; all other code is essentially built around this primitive
      functionality.  This includes basic arithmetic types, such as integers,
      and their elementary operations as well as pointer types.  Primitive
      types and functions often receive special treatment in the code
      generator, which means that these entities have to be explicitly
      represented in the compiler.  Moreover, many of these types receive some
      explicit treatment in the runtime system, and so, there is some further
      information about <a href="../rts-libs/primitives.html">primitives in
      the RTS section</a> of this document.
    <p>
      The module <a
      href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/prelude/TysPrim.lhs"><code>TysPrim</code></a>
      exports a list of all primitive type constructors as <code>primTyCons ::
      [TyCon]</code>.  All of these type constructors (of type
      <code>TyCon</code>) are also exported as <code>intPrimTyCon</code>,
      <code>stablePtrPrimTyCon</code>, and so on.  In addition, for each
      nullary type constructor the corresponding type (of type
      <code>Type</code>) is also exported; for example, we have
      <code>intPrimTy :: Type</code>.  For all other type constructors, a
      function is exported that constructs the type obtained by applying the
      type constructors to an argument type (of type <code>Type</code>); for
      example, we have <code>mkStablePtrPrimTy :: Type -> Type</code>.
    <p>
      As it is inconvenient to identify type that receive a special treatment
      by the code generator by looking at their name, the module <a
      href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/prelude/PrimRep.lhs"><code>PrimRep</code></a>
      exports a data type <code>PrimRep</code>, which lists all
      machine-manipulable implementation types.  The module also exports a set
      of query functions on <code>PrimRep</code> that define properties, such
      as a type's byte size or whether a primitive type is a pointer type.
      Moreover, the function <code>TysPrim.primRepTyCon :: PrimRep ->
      TyCon</code> converts <code>PrimRep</code> values into the corresponding
      type constructor.

    <h2>Wired in types (module <tt>TysWiredIn</tt>)</h2>
    <p>
      In addition to entities that are primitive, as the compiler has to treat
      them specially in the backend, there is a set of types, functions,
      etc. that the Haskell language definition flags as essential to the
      language by placing them into the special module <code>Prelude</code>
      that is implicitly imported into each Haskell module.  For some of these
      entities it suffices to define them (by standard Haskell definitions) in
      a <code>Prelude</code> module and ensuring that this module is treated
      specially by being always imported .
    <p>
      However, there is a set of entities (such as, for example, the list type
      and the corresponding data constructors) that have an inbetween status:
      They are not truly primitive (lists, for example, can easily be defined
      by a <code>data</code> declaration), but the compiler has to have extra
      knowledge about them, as they are associated with some particular
      features of the language (in the case of lists, there is special syntax,
      such as list comprehensions, associated with the type).  Another
      example, for a special kind of entity are type classes that can be used
      in a <code>deriving</code> clause.  All types that are not-primitive,
      but about which the compiler nonetheless has to have some extra
      knowledge are defined in the module <a
      href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/prelude/TysWiredIn.lhs"><code>TysWiredIn</code></a>.
    <p>
      All wired in type constructors are contained in <code>wiredInTyCons ::
      [TyCon]</code>.  In addition to that list, <code>TysWiredIn</code>
      exports variables bound to representations of all listed type
      constructors and their data constructors.  So, for example, we have
      <code>listTyCon</code> together with <code>nilDataCon</cons> and
      </code>consDataCon</code>.  There are also convenience functions, such
      as <code>mkListTy</code> and <code>mkTupleTy</code>, which construct
      compound types.
    <p>

    <h2>Known-key names (module <tt>PrelNames</tt>)</h2>

      All names of types, functions, etc. known to the compiler are defined in
      <a
      href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/prelude/PrelNames.lhs"><code>PrelNames</code></a>.
      This includes the names of types and functions exported from
      <code>TysWiredIn</code>, but also others.  In particular, this module
      also fixes the names of all prelude modules; i.e., of the modules whose
      name starts with <code>Prel</code>, which GHC's library uses to bring
      some structure into the quite large number of <code>Prelude</code>
      definitions.
    <p>
      <code>PrelNames.knownKeyNames :: [Name]</code> contains all names known
      to the compiler, but the elements of the list are also exported
      individually as variables, such as <code>floatTyConName</code> (having
      the lexeme <code>Float</code>) and <code>floatDataConName</code> (having
      the lexeme <code>F#</code>).  For each of these names,
      <code>PrelNames</code> derfines a unique key with a definition, such as
    <p>
<blockquote><pre>
floatPrimTyConKey = mkPreludeTyConUnique 11</pre>
</blockquote>
    <p>
      that is, all unique keys for known prelude names are hardcoded into
      <code>PrelNames</code> (and uniqueness has to be manually ensured in
      that module).  To simplify matching the types of important groups of
      type constructors, <code>PrelNames</code> also exports lists, such as
      <code>numericTyKeys</code> (keys of all numeric types), that contain the
      unique keys of all names in that group.  In addition, derivable type
      classes and their structure is defined by
      <code>derivableClassKeys</code> and related definitions.
    <p>
      In addition to names that have unique keys, <code>PrelNames</code> also
      defines a set of names without uniqueness information.  These names end
      on the suffix <code>_RDR</code> and are of type <code>RdrName</code> (an
      example, is <code>times_RDR</code>, which represents the lexeme
      <code>*</code>).  The names are used in locations where they pass
      through the renamer anyway (e.g., special constructors encountered by
      the parser, such as [], and code generated from deriving clauses), which
      will take care of adding uniqueness information.
    <p>

<h2>Gathering it all together (module <tt>PrelInfo</tt>)</h2>
      The module
      <a href="http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/prelude/PrelInfo.lhs"><code>PrelInfo</code></a>
      in some sense ties all the above together and provides a reasonably
      restricted interface to these definition to the rest of the compiler.
      However, from what I have seen, this doesn't quite work out and the
      earlier mentioned modules are directly imported in many places.

    <p><small>
<!-- hhmts start -->
Last modified: Tue Dec 11 17:54:07 EST 2001
<!-- hhmts end -->
    </small>
  </body>
</html>