4706671f3ddef49688c4507e4582e5d09a284d89
[ghc-hetmet.git] / ghc / docs / users_guide / primitives.sgml
1 <!-- UNBOXED TYPES AND PRIMITIVE OPERATIONS -->
2
3 <sect1 id="primitives">
4   <title>Unboxed types and primitive operations</title>
5   <indexterm><primary>GHC.Exts module</primary></indexterm>
6
7   <para>This chapter defines all the types which are primitive in
8   Glasgow Haskell, and the operations provided for them. You bring
9   them into scope by importing module <literal>GHC.Exts</literal>.</para>
10
11   <para>Note: while you really can use this stuff to write fast code,
12   we generally find it a lot less painful, and more satisfying in the
13   long run, to use higher-level language features and libraries.  With
14   any luck, the code you write will be optimised to the efficient
15   unboxed version in any case.  And if it isn't, we'd like to know
16   about it.</para>
17   
18 <sect2 id="glasgow-unboxed">
19 <title>Unboxed types
20 </title>
21
22 <para>
23 <indexterm><primary>Unboxed types (Glasgow extension)</primary></indexterm>
24 </para>
25
26 <para>Most types in GHC are <firstterm>boxed</firstterm>, which means
27 that values of that type are represented by a pointer to a heap
28 object.  The representation of a Haskell <literal>Int</literal>, for
29 example, is a two-word heap object.  An <firstterm>unboxed</firstterm>
30 type, however, is represented by the value itself, no pointers or heap
31 allocation are involved.
32 </para>
33
34 <para>
35 Unboxed types correspond to the &ldquo;raw machine&rdquo; types you
36 would use in C: <literal>Int&num;</literal> (long int),
37 <literal>Double&num;</literal> (double), <literal>Addr&num;</literal>
38 (void *), etc.  The <emphasis>primitive operations</emphasis>
39 (PrimOps) on these types are what you might expect; e.g.,
40 <literal>(+&num;)</literal> is addition on
41 <literal>Int&num;</literal>s, and is the machine-addition that we all
42 know and love&mdash;usually one instruction.
43 </para>
44
45 <para>
46 Primitive (unboxed) types cannot be defined in Haskell, and are
47 therefore built into the language and compiler.  Primitive types are
48 always unlifted; that is, a value of a primitive type cannot be
49 bottom.  We use the convention that primitive types, values, and
50 operations have a <literal>&num;</literal> suffix.
51 </para>
52
53 <para>
54 Primitive values are often represented by a simple bit-pattern, such
55 as <literal>Int&num;</literal>, <literal>Float&num;</literal>,
56 <literal>Double&num;</literal>.  But this is not necessarily the case:
57 a primitive value might be represented by a pointer to a
58 heap-allocated object.  Examples include
59 <literal>Array&num;</literal>, the type of primitive arrays.  A
60 primitive array is heap-allocated because it is too big a value to fit
61 in a register, and would be too expensive to copy around; in a sense,
62 it is accidental that it is represented by a pointer.  If a pointer
63 represents a primitive value, then it really does point to that value:
64 no unevaluated thunks, no indirections&hellip;nothing can be at the
65 other end of the pointer than the primitive value.
66 </para>
67
68 <para>
69 There are some restrictions on the use of primitive types, the main
70 one being that you can't pass a primitive value to a polymorphic
71 function or store one in a polymorphic data type.  This rules out
72 things like <literal>[Int&num;]</literal> (i.e. lists of primitive
73 integers).  The reason for this restriction is that polymorphic
74 arguments and constructor fields are assumed to be pointers: if an
75 unboxed integer is stored in one of these, the garbage collector would
76 attempt to follow it, leading to unpredictable space leaks.  Or a
77 <function>seq</function> operation on the polymorphic component may
78 attempt to dereference the pointer, with disastrous results.  Even
79 worse, the unboxed value might be larger than a pointer
80 (<literal>Double&num;</literal> for instance).
81 </para>
82
83 <para>
84 Nevertheless, A numerically-intensive program using unboxed types can
85 go a <emphasis>lot</emphasis> faster than its &ldquo;standard&rdquo;
86 counterpart&mdash;we saw a threefold speedup on one example.
87 </para>
88
89 </sect2>
90
91 <sect2 id="unboxed-tuples">
92 <title>Unboxed Tuples
93 </title>
94
95 <para>
96 Unboxed tuples aren't really exported by <literal>GHC.Exts</literal>,
97 they're available by default with <option>-fglasgow-exts</option>.  An
98 unboxed tuple looks like this:
99 </para>
100
101 <para>
102
103 <programlisting>
104 (# e_1, ..., e_n #)
105 </programlisting>
106
107 </para>
108
109 <para>
110 where <literal>e&lowbar;1..e&lowbar;n</literal> are expressions of any
111 type (primitive or non-primitive).  The type of an unboxed tuple looks
112 the same.
113 </para>
114
115 <para>
116 Unboxed tuples are used for functions that need to return multiple
117 values, but they avoid the heap allocation normally associated with
118 using fully-fledged tuples.  When an unboxed tuple is returned, the
119 components are put directly into registers or on the stack; the
120 unboxed tuple itself does not have a composite representation.  Many
121 of the primitive operations listed in this section return unboxed
122 tuples.
123 </para>
124
125 <para>
126 There are some pretty stringent restrictions on the use of unboxed tuples:
127 </para>
128
129 <para>
130
131 <itemizedlist>
132 <listitem>
133
134 <para>
135  Unboxed tuple types are subject to the same restrictions as
136 other unboxed types; i.e. they may not be stored in polymorphic data
137 structures or passed to polymorphic functions.
138
139 </para>
140 </listitem>
141 <listitem>
142
143 <para>
144  Unboxed tuples may only be constructed as the direct result of
145 a function, and may only be deconstructed with a <literal>case</literal> expression.
146 eg. the following are valid:
147
148
149 <programlisting>
150 f x y = (# x+1, y-1 #)
151 g x = case f x x of { (# a, b #) -&#62; a + b }
152 </programlisting>
153
154
155 but the following are invalid:
156
157
158 <programlisting>
159 f x y = g (# x, y #)
160 g (# x, y #) = x + y
161 </programlisting>
162
163
164 </para>
165 </listitem>
166 <listitem>
167
168 <para>
169  No variable can have an unboxed tuple type.  This is illegal:
170
171
172 <programlisting>
173 f :: (# Int, Int #) -&#62; (# Int, Int #)
174 f x = x
175 </programlisting>
176
177
178 because <literal>x</literal> has an unboxed tuple type.
179
180 </para>
181 </listitem>
182
183 </itemizedlist>
184
185 </para>
186
187 <para>
188 Note: we may relax some of these restrictions in the future.
189 </para>
190
191 <para>
192 The <literal>IO</literal> and <literal>ST</literal> monads use unboxed
193 tuples to avoid unnecessary allocation during sequences of operations.
194 </para>
195
196 </sect2>
197
198 <sect2>
199 <title>Character and numeric types</title>
200
201 <indexterm><primary>character types, primitive</primary></indexterm>
202 <indexterm><primary>numeric types, primitive</primary></indexterm>
203 <indexterm><primary>integer types, primitive</primary></indexterm>
204 <indexterm><primary>floating point types, primitive</primary></indexterm>
205 <para>
206 There are the following obvious primitive types:
207 </para>
208
209 <programlisting>
210 type Char#
211 type Int#
212 type Word#
213 type Addr#
214 type Float#
215 type Double#
216 type Int64#
217 type Word64#
218 </programlisting>
219
220 <indexterm><primary><literal>Char&num;</literal></primary></indexterm>
221 <indexterm><primary><literal>Int&num;</literal></primary></indexterm>
222 <indexterm><primary><literal>Word&num;</literal></primary></indexterm>
223 <indexterm><primary><literal>Addr&num;</literal></primary></indexterm>
224 <indexterm><primary><literal>Float&num;</literal></primary></indexterm>
225 <indexterm><primary><literal>Double&num;</literal></primary></indexterm>
226 <indexterm><primary><literal>Int64&num;</literal></primary></indexterm>
227 <indexterm><primary><literal>Word64&num;</literal></primary></indexterm>
228
229 <para>
230 If you really want to know their exact equivalents in C, see
231 <filename>ghc/includes/StgTypes.h</filename> in the GHC source tree.
232 </para>
233
234 <para>
235 Literals for these types may be written as follows:
236 </para>
237
238 <para>
239
240 <programlisting>
241 1#              an Int#
242 1.2#            a Float#
243 1.34##          a Double#
244 'a'#            a Char#; for weird characters, use e.g. '\o&#60;octal&#62;'#
245 "a"#            an Addr# (a `char *'); only characters '\0'..'\255' allowed
246 </programlisting>
247
248 <indexterm><primary>literals, primitive</primary></indexterm>
249 <indexterm><primary>constants, primitive</primary></indexterm>
250 <indexterm><primary>numbers, primitive</primary></indexterm>
251 </para>
252
253 </sect2>
254
255 <sect2>
256 <title>Comparison operations</title>
257
258 <para>
259 <indexterm><primary>comparisons, primitive</primary></indexterm>
260 <indexterm><primary>operators, comparison</primary></indexterm>
261 </para>
262
263 <para>
264
265 <programlisting>
266 {&#62;,&#62;=,==,/=,&#60;,&#60;=}# :: Int# -&#62; Int# -&#62; Bool
267
268 {gt,ge,eq,ne,lt,le}Char# :: Char# -&#62; Char# -&#62; Bool
269     -- ditto for Word# and Addr#
270 </programlisting>
271
272 <indexterm><primary><literal>&#62;&num;</literal></primary></indexterm>
273 <indexterm><primary><literal>&#62;=&num;</literal></primary></indexterm>
274 <indexterm><primary><literal>==&num;</literal></primary></indexterm>
275 <indexterm><primary><literal>/=&num;</literal></primary></indexterm>
276 <indexterm><primary><literal>&#60;&num;</literal></primary></indexterm>
277 <indexterm><primary><literal>&#60;=&num;</literal></primary></indexterm>
278 <indexterm><primary><literal>gt&lcub;Char,Word,Addr&rcub;&num;</literal></primary></indexterm>
279 <indexterm><primary><literal>ge&lcub;Char,Word,Addr&rcub;&num;</literal></primary></indexterm>
280 <indexterm><primary><literal>eq&lcub;Char,Word,Addr&rcub;&num;</literal></primary></indexterm>
281 <indexterm><primary><literal>ne&lcub;Char,Word,Addr&rcub;&num;</literal></primary></indexterm>
282 <indexterm><primary><literal>lt&lcub;Char,Word,Addr&rcub;&num;</literal></primary></indexterm>
283 <indexterm><primary><literal>le&lcub;Char,Word,Addr&rcub;&num;</literal></primary></indexterm>
284 </para>
285
286 </sect2>
287
288 <sect2>
289 <title>Primitive-character operations</title>
290
291 <para>
292 <indexterm><primary>characters, primitive operations</primary></indexterm>
293 <indexterm><primary>operators, primitive character</primary></indexterm>
294 </para>
295
296 <para>
297
298 <programlisting>
299 ord# :: Char# -&#62; Int#
300 chr# :: Int# -&#62; Char#
301 </programlisting>
302
303 <indexterm><primary><literal>ord&num;</literal></primary></indexterm>
304 <indexterm><primary><literal>chr&num;</literal></primary></indexterm>
305 </para>
306
307 </sect2>
308
309 <sect2>
310 <title>Primitive-<literal>Int</literal> operations</title>
311
312 <para>
313 <indexterm><primary>integers, primitive operations</primary></indexterm>
314 <indexterm><primary>operators, primitive integer</primary></indexterm>
315 </para>
316
317 <para>
318
319 <programlisting>
320 {+,-,*,quotInt,remInt,gcdInt}# :: Int# -&#62; Int# -&#62; Int#
321 negateInt# :: Int# -&#62; Int#
322
323 iShiftL#, iShiftRA#, iShiftRL# :: Int# -&#62; Int# -&#62; Int#
324         -- shift left, right arithmetic, right logical
325
326 addIntC#, subIntC#, mulIntC# :: Int# -> Int# -> (# Int#, Int# #)
327         -- add, subtract, multiply with carry
328 </programlisting>
329
330 <indexterm><primary><literal>+&num;</literal></primary></indexterm>
331 <indexterm><primary><literal>-&num;</literal></primary></indexterm>
332 <indexterm><primary><literal>*&num;</literal></primary></indexterm>
333 <indexterm><primary><literal>quotInt&num;</literal></primary></indexterm>
334 <indexterm><primary><literal>remInt&num;</literal></primary></indexterm>
335 <indexterm><primary><literal>gcdInt&num;</literal></primary></indexterm>
336 <indexterm><primary><literal>iShiftL&num;</literal></primary></indexterm>
337 <indexterm><primary><literal>iShiftRA&num;</literal></primary></indexterm>
338 <indexterm><primary><literal>iShiftRL&num;</literal></primary></indexterm>
339 <indexterm><primary><literal>addIntC&num;</literal></primary></indexterm>
340 <indexterm><primary><literal>subIntC&num;</literal></primary></indexterm>
341 <indexterm><primary><literal>mulIntC&num;</literal></primary></indexterm>
342 <indexterm><primary>shift operations, integer</primary></indexterm>
343 </para>
344
345 <para>
346 <emphasis>Note:</emphasis> No error/overflow checking!
347 </para>
348
349 </sect2>
350
351 <sect2>
352 <title>Primitive-<literal>Double</literal> and <literal>Float</literal> operations</title>
353
354 <para>
355 <indexterm><primary>floating point numbers, primitive</primary></indexterm>
356 <indexterm><primary>operators, primitive floating point</primary></indexterm>
357 </para>
358
359 <para>
360
361 <programlisting>
362 {+,-,*,/}##         :: Double# -&#62; Double# -&#62; Double#
363 {&#60;,&#60;=,==,/=,&#62;=,&#62;}## :: Double# -&#62; Double# -&#62; Bool
364 negateDouble#       :: Double# -&#62; Double#
365 double2Int#         :: Double# -&#62; Int#
366 int2Double#         :: Int#    -&#62; Double#
367
368 {plus,minus,times,divide}Float# :: Float# -&#62; Float# -&#62; Float#
369 {gt,ge,eq,ne,lt,le}Float# :: Float# -&#62; Float# -&#62; Bool
370 negateFloat#        :: Float# -&#62; Float#
371 float2Int#          :: Float# -&#62; Int#
372 int2Float#          :: Int#   -&#62; Float#
373 </programlisting>
374
375 </para>
376
377 <para>
378 <indexterm><primary><literal>+&num;&num;</literal></primary></indexterm>
379 <indexterm><primary><literal>-&num;&num;</literal></primary></indexterm>
380 <indexterm><primary><literal>*&num;&num;</literal></primary></indexterm>
381 <indexterm><primary><literal>/&num;&num;</literal></primary></indexterm>
382 <indexterm><primary><literal>&#60;&num;&num;</literal></primary></indexterm>
383 <indexterm><primary><literal>&#60;=&num;&num;</literal></primary></indexterm>
384 <indexterm><primary><literal>==&num;&num;</literal></primary></indexterm>
385 <indexterm><primary><literal>=/&num;&num;</literal></primary></indexterm>
386 <indexterm><primary><literal>&#62;=&num;&num;</literal></primary></indexterm>
387 <indexterm><primary><literal>&#62;&num;&num;</literal></primary></indexterm>
388 <indexterm><primary><literal>negateDouble&num;</literal></primary></indexterm>
389 <indexterm><primary><literal>double2Int&num;</literal></primary></indexterm>
390 <indexterm><primary><literal>int2Double&num;</literal></primary></indexterm>
391 </para>
392
393 <para>
394 <indexterm><primary><literal>plusFloat&num;</literal></primary></indexterm>
395 <indexterm><primary><literal>minusFloat&num;</literal></primary></indexterm>
396 <indexterm><primary><literal>timesFloat&num;</literal></primary></indexterm>
397 <indexterm><primary><literal>divideFloat&num;</literal></primary></indexterm>
398 <indexterm><primary><literal>gtFloat&num;</literal></primary></indexterm>
399 <indexterm><primary><literal>geFloat&num;</literal></primary></indexterm>
400 <indexterm><primary><literal>eqFloat&num;</literal></primary></indexterm>
401 <indexterm><primary><literal>neFloat&num;</literal></primary></indexterm>
402 <indexterm><primary><literal>ltFloat&num;</literal></primary></indexterm>
403 <indexterm><primary><literal>leFloat&num;</literal></primary></indexterm>
404 <indexterm><primary><literal>negateFloat&num;</literal></primary></indexterm>
405 <indexterm><primary><literal>float2Int&num;</literal></primary></indexterm>
406 <indexterm><primary><literal>int2Float&num;</literal></primary></indexterm>
407 </para>
408
409 <para>
410 And a full complement of trigonometric functions:
411 </para>
412
413 <para>
414
415 <programlisting>
416 expDouble#      :: Double# -&#62; Double#
417 logDouble#      :: Double# -&#62; Double#
418 sqrtDouble#     :: Double# -&#62; Double#
419 sinDouble#      :: Double# -&#62; Double#
420 cosDouble#      :: Double# -&#62; Double#
421 tanDouble#      :: Double# -&#62; Double#
422 asinDouble#     :: Double# -&#62; Double#
423 acosDouble#     :: Double# -&#62; Double#
424 atanDouble#     :: Double# -&#62; Double#
425 sinhDouble#     :: Double# -&#62; Double#
426 coshDouble#     :: Double# -&#62; Double#
427 tanhDouble#     :: Double# -&#62; Double#
428 powerDouble#    :: Double# -&#62; Double# -&#62; Double#
429 </programlisting>
430
431 <indexterm><primary>trigonometric functions, primitive</primary></indexterm>
432 </para>
433
434 <para>
435 similarly for <literal>Float&num;</literal>.
436 </para>
437
438 <para>
439 There are two coercion functions for <literal>Float&num;</literal>/<literal>Double&num;</literal>:
440 </para>
441
442 <para>
443
444 <programlisting>
445 float2Double#   :: Float# -&#62; Double#
446 double2Float#   :: Double# -&#62; Float#
447 </programlisting>
448
449 <indexterm><primary><literal>float2Double&num;</literal></primary></indexterm>
450 <indexterm><primary><literal>double2Float&num;</literal></primary></indexterm>
451 </para>
452
453 <para>
454 The primitive version of <function>decodeDouble</function>
455 (<function>encodeDouble</function> is implemented as an external C
456 function):
457 </para>
458
459 <para>
460
461 <programlisting>
462 decodeDouble#   :: Double# -&#62; PrelNum.ReturnIntAndGMP
463 </programlisting>
464
465 <indexterm><primary><literal>encodeDouble&num;</literal></primary></indexterm>
466 <indexterm><primary><literal>decodeDouble&num;</literal></primary></indexterm>
467 </para>
468
469 <para>
470 (And the same for <literal>Float&num;</literal>s.)
471 </para>
472
473 </sect2>
474
475 <sect2 id="integer-operations">
476 <title>Operations on/for <literal>Integers</literal> (interface to GMP)
477 </title>
478
479 <para>
480 <indexterm><primary>arbitrary precision integers</primary></indexterm>
481 <indexterm><primary>Integer, operations on</primary></indexterm>
482 </para>
483
484 <para>
485 We implement <literal>Integers</literal> (arbitrary-precision
486 integers) using the GNU multiple-precision (GMP) package (version
487 2.0.2).
488 </para>
489
490 <para>
491 The data type for <literal>Integer</literal> is either a small
492 integer, represented by an <literal>Int</literal>, or a large integer
493 represented using the pieces required by GMP's
494 <literal>MP&lowbar;INT</literal> in <filename>gmp.h</filename> (see
495 <filename>gmp.info</filename> in
496 <filename>ghc/includes/runtime/gmp</filename>).  It comes out as:
497 </para>
498
499 <para>
500
501 <programlisting>
502 data Integer = S# Int#             -- small integers
503              | J# Int# ByteArray#  -- large integers
504 </programlisting>
505
506 <indexterm><primary>Integer type</primary></indexterm> The primitive
507 ops to support large <literal>Integers</literal> use the
508 &ldquo;pieces&rdquo; of the representation, and are as follows:
509 </para>
510
511 <para>
512
513 <programlisting>
514 negateInteger#  :: Int# -&#62; ByteArray# -&#62; Integer
515
516 {plus,minus,times}Integer#, gcdInteger#, 
517   quotInteger#, remInteger#, divExactInteger#
518         :: Int# -> ByteArray#
519         -> Int# -> ByteArray#
520         -> (# Int#, ByteArray# #)
521
522 cmpInteger# 
523         :: Int# -> ByteArray#
524         -> Int# -> ByteArray#
525         -> Int# -- -1 for &#60;; 0 for ==; +1 for >
526
527 cmpIntegerInt# 
528         :: Int# -> ByteArray#
529         -> Int#
530         -> Int# -- -1 for &#60;; 0 for ==; +1 for >
531
532 gcdIntegerInt# :: 
533         :: Int# -> ByteArray#
534         -> Int#
535         -> Int#
536
537 divModInteger#, quotRemInteger#
538         :: Int# -> ByteArray#
539         -> Int# -> ByteArray#
540         -> (# Int#, ByteArray#,
541                   Int#, ByteArray# #)
542
543 integer2Int# :: Int# -> ByteArray# -> Int#
544
545 int2Integer#  :: Int#  -> Integer -- NB: no error-checking on these two!
546 word2Integer# :: Word# -> Integer
547
548 addr2Integer# :: Addr# -> Integer
549         -- the Addr# is taken to be a `char *' string
550         -- to be converted into an Integer.
551 </programlisting>
552
553 <indexterm><primary><literal>negateInteger&num;</literal></primary></indexterm>
554 <indexterm><primary><literal>plusInteger&num;</literal></primary></indexterm>
555 <indexterm><primary><literal>minusInteger&num;</literal></primary></indexterm>
556 <indexterm><primary><literal>timesInteger&num;</literal></primary></indexterm>
557 <indexterm><primary><literal>quotInteger&num;</literal></primary></indexterm>
558 <indexterm><primary><literal>remInteger&num;</literal></primary></indexterm>
559 <indexterm><primary><literal>gcdInteger&num;</literal></primary></indexterm>
560 <indexterm><primary><literal>gcdIntegerInt&num;</literal></primary></indexterm>
561 <indexterm><primary><literal>divExactInteger&num;</literal></primary></indexterm>
562 <indexterm><primary><literal>cmpInteger&num;</literal></primary></indexterm>
563 <indexterm><primary><literal>divModInteger&num;</literal></primary></indexterm>
564 <indexterm><primary><literal>quotRemInteger&num;</literal></primary></indexterm>
565 <indexterm><primary><literal>integer2Int&num;</literal></primary></indexterm>
566 <indexterm><primary><literal>int2Integer&num;</literal></primary></indexterm>
567 <indexterm><primary><literal>word2Integer&num;</literal></primary></indexterm>
568 <indexterm><primary><literal>addr2Integer&num;</literal></primary></indexterm>
569 </para>
570
571 </sect2>
572
573 <sect2>
574 <title>Words and addresses</title>
575
576 <para>
577 <indexterm><primary>word, primitive type</primary></indexterm>
578 <indexterm><primary>address, primitive type</primary></indexterm>
579 <indexterm><primary>unsigned integer, primitive type</primary></indexterm>
580 <indexterm><primary>pointer, primitive type</primary></indexterm>
581 </para>
582
583 <para>
584 A <literal>Word&num;</literal> is used for bit-twiddling operations.
585 It is the same size as an <literal>Int&num;</literal>, but has no sign
586 nor any arithmetic operations.
587
588 <programlisting>
589 type Word#      -- Same size/etc as Int# but *unsigned*
590 type Addr#      -- A pointer from outside the "Haskell world" (from C, probably);
591                 -- described under "arrays"
592 </programlisting>
593
594 <indexterm><primary><literal>Word&num;</literal></primary></indexterm>
595 <indexterm><primary><literal>Addr&num;</literal></primary></indexterm>
596 </para>
597
598 <para>
599 <literal>Word&num;</literal>s and <literal>Addr&num;</literal>s have
600 the usual comparison operations.  Other
601 unboxed-<literal>Word</literal> ops (bit-twiddling and coercions):
602 </para>
603
604 <para>
605
606 <programlisting>
607 {gt,ge,eq,ne,lt,le}Word# :: Word# -> Word# -> Bool
608
609 and#, or#, xor# :: Word# -> Word# -> Word#
610         -- standard bit ops.
611
612 quotWord#, remWord# :: Word# -> Word# -> Word#
613         -- word (i.e. unsigned) versions are different from int
614         -- versions, so we have to provide these explicitly.
615
616 not# :: Word# -> Word#
617
618 shiftL#, shiftRL# :: Word# -> Int# -> Word#
619         -- shift left, right logical
620
621 int2Word#       :: Int#  -> Word# -- just a cast, really
622 word2Int#       :: Word# -> Int#
623 </programlisting>
624
625 <indexterm><primary>bit operations, Word and Addr</primary></indexterm>
626 <indexterm><primary><literal>gtWord&num;</literal></primary></indexterm>
627 <indexterm><primary><literal>geWord&num;</literal></primary></indexterm>
628 <indexterm><primary><literal>eqWord&num;</literal></primary></indexterm>
629 <indexterm><primary><literal>neWord&num;</literal></primary></indexterm>
630 <indexterm><primary><literal>ltWord&num;</literal></primary></indexterm>
631 <indexterm><primary><literal>leWord&num;</literal></primary></indexterm>
632 <indexterm><primary><literal>and&num;</literal></primary></indexterm>
633 <indexterm><primary><literal>or&num;</literal></primary></indexterm>
634 <indexterm><primary><literal>xor&num;</literal></primary></indexterm>
635 <indexterm><primary><literal>not&num;</literal></primary></indexterm>
636 <indexterm><primary><literal>quotWord&num;</literal></primary></indexterm>
637 <indexterm><primary><literal>remWord&num;</literal></primary></indexterm>
638 <indexterm><primary><literal>shiftL&num;</literal></primary></indexterm>
639 <indexterm><primary><literal>shiftRA&num;</literal></primary></indexterm>
640 <indexterm><primary><literal>shiftRL&num;</literal></primary></indexterm>
641 <indexterm><primary><literal>int2Word&num;</literal></primary></indexterm>
642 <indexterm><primary><literal>word2Int&num;</literal></primary></indexterm>
643 </para>
644
645 <para>
646 Unboxed-<literal>Addr</literal> ops (C casts, really):
647
648 <programlisting>
649 {gt,ge,eq,ne,lt,le}Addr# :: Addr# -> Addr# -> Bool
650
651 int2Addr#       :: Int#  -> Addr#
652 addr2Int#       :: Addr# -> Int#
653 addr2Integer#   :: Addr# -> (# Int#, ByteArray# #)
654 </programlisting>
655
656 <indexterm><primary><literal>gtAddr&num;</literal></primary></indexterm>
657 <indexterm><primary><literal>geAddr&num;</literal></primary></indexterm>
658 <indexterm><primary><literal>eqAddr&num;</literal></primary></indexterm>
659 <indexterm><primary><literal>neAddr&num;</literal></primary></indexterm>
660 <indexterm><primary><literal>ltAddr&num;</literal></primary></indexterm>
661 <indexterm><primary><literal>leAddr&num;</literal></primary></indexterm>
662 <indexterm><primary><literal>int2Addr&num;</literal></primary></indexterm>
663 <indexterm><primary><literal>addr2Int&num;</literal></primary></indexterm>
664 <indexterm><primary><literal>addr2Integer&num;</literal></primary></indexterm>
665 </para>
666
667 <para>
668 The casts between <literal>Int&num;</literal>,
669 <literal>Word&num;</literal> and <literal>Addr&num;</literal>
670 correspond to null operations at the machine level, but are required
671 to keep the Haskell type checker happy.
672 </para>
673
674 <para>
675 Operations for indexing off of C pointers
676 (<literal>Addr&num;</literal>s) to snatch values are listed under
677 &ldquo;arrays&rdquo;.
678 </para>
679
680 </sect2>
681
682 <sect2>
683 <title>Arrays</title>
684
685 <para>
686 <indexterm><primary>arrays, primitive</primary></indexterm>
687 </para>
688
689 <para>
690 The type <literal>Array&num; elt</literal> is the type of primitive,
691 unpointed arrays of values of type <literal>elt</literal>.
692 </para>
693
694 <para>
695
696 <programlisting>
697 type Array# elt
698 </programlisting>
699
700 <indexterm><primary><literal>Array&num;</literal></primary></indexterm>
701 </para>
702
703 <para>
704 <literal>Array&num;</literal> is more primitive than a Haskell
705 array&mdash;indeed, the Haskell <literal>Array</literal> interface is
706 implemented using <literal>Array&num;</literal>&mdash;in that an
707 <literal>Array&num;</literal> is indexed only by
708 <literal>Int&num;</literal>s, starting at zero.  It is also more
709 primitive by virtue of being unboxed.  That doesn't mean that it isn't
710 a heap-allocated object&mdash;of course, it is.  Rather, being unboxed
711 means that it is represented by a pointer to the array itself, and not
712 to a thunk which will evaluate to the array (or to bottom).  The
713 components of an <literal>Array&num;</literal> are themselves boxed.
714 </para>
715
716 <para>
717 The type <literal>ByteArray&num;</literal> is similar to
718 <literal>Array&num;</literal>, except that it contains just a string
719 of (non-pointer) bytes.
720 </para>
721
722 <para>
723
724 <programlisting>
725 type ByteArray#
726 </programlisting>
727
728 <indexterm><primary><literal>ByteArray&num;</literal></primary></indexterm>
729 </para>
730
731 <para>
732 Arrays of these types are useful when a Haskell program wishes to
733 construct a value to pass to a C procedure. It is also possible to use
734 them to build (say) arrays of unboxed characters for internal use in a
735 Haskell program.  Given these uses, <literal>ByteArray&num;</literal>
736 is deliberately a bit vague about the type of its components.
737 Operations are provided to extract values of type
738 <literal>Char&num;</literal>, <literal>Int&num;</literal>,
739 <literal>Float&num;</literal>, <literal>Double&num;</literal>, and
740 <literal>Addr&num;</literal> from arbitrary offsets within a
741 <literal>ByteArray&num;</literal>.  (For type
742 <literal>Foo&num;</literal>, the $i$th offset gets you the $i$th
743 <literal>Foo&num;</literal>, not the <literal>Foo&num;</literal> at
744 byte-position $i$.  Mumble.)  (If you want a
745 <literal>Word&num;</literal>, grab an <literal>Int&num;</literal>,
746 then coerce it.)
747 </para>
748
749 <para>
750 Lastly, we have static byte-arrays, of type
751 <literal>Addr&num;</literal> &lsqb;mentioned previously].  (Remember
752 the duality between arrays and pointers in C.)  Arrays of this types
753 are represented by a pointer to an array in the world outside Haskell,
754 so this pointer is not followed by the garbage collector.  In other
755 respects they are just like <literal>ByteArray&num;</literal>.  They
756 are only needed in order to pass values from C to Haskell.
757 </para>
758
759 </sect2>
760
761 <sect2>
762 <title>Reading and writing</title>
763
764 <para>
765 Primitive arrays are linear, and indexed starting at zero.
766 </para>
767
768 <para>
769 The size and indices of a <literal>ByteArray&num;</literal>, <literal>Addr&num;</literal>, and
770 <literal>MutableByteArray&num;</literal> are all in bytes.  It's up to the program to
771 calculate the correct byte offset from the start of the array.  This
772 allows a <literal>ByteArray&num;</literal> to contain a mixture of values of different
773 type, which is often needed when preparing data for and unpicking
774 results from C.  (Umm&hellip;not true of indices&hellip;WDP 95/09)
775 </para>
776
777 <para>
778 <emphasis>Should we provide some <literal>sizeOfDouble&num;</literal> constants?</emphasis>
779 </para>
780
781 <para>
782 Out-of-range errors on indexing should be caught by the code which
783 uses the primitive operation; the primitive operations themselves do
784 <emphasis>not</emphasis> check for out-of-range indexes. The intention is that the
785 primitive ops compile to one machine instruction or thereabouts.
786 </para>
787
788 <para>
789 We use the terms &ldquo;reading&rdquo; and &ldquo;writing&rdquo; to refer to accessing
790 <emphasis>mutable</emphasis> arrays (see <xref linkend="sect-mutable">), and
791 &ldquo;indexing&rdquo; to refer to reading a value from an <emphasis>immutable</emphasis>
792 array.
793 </para>
794
795 <para>
796 Immutable byte arrays are straightforward to index (all indices are in
797 units of the size of the object being read):
798
799 <programlisting>
800 indexCharArray#   :: ByteArray# -> Int# -> Char#
801 indexIntArray#    :: ByteArray# -> Int# -> Int#
802 indexAddrArray#   :: ByteArray# -> Int# -> Addr#
803 indexFloatArray#  :: ByteArray# -> Int# -> Float#
804 indexDoubleArray# :: ByteArray# -> Int# -> Double#
805
806 indexCharOffAddr#   :: Addr# -> Int# -> Char#
807 indexIntOffAddr#    :: Addr# -> Int# -> Int#
808 indexFloatOffAddr#  :: Addr# -> Int# -> Float#
809 indexDoubleOffAddr# :: Addr# -> Int# -> Double#
810 indexAddrOffAddr#   :: Addr# -> Int# -> Addr#
811  -- Get an Addr# from an Addr# offset
812 </programlisting>
813
814 <indexterm><primary><literal>indexCharArray&num;</literal></primary></indexterm>
815 <indexterm><primary><literal>indexIntArray&num;</literal></primary></indexterm>
816 <indexterm><primary><literal>indexAddrArray&num;</literal></primary></indexterm>
817 <indexterm><primary><literal>indexFloatArray&num;</literal></primary></indexterm>
818 <indexterm><primary><literal>indexDoubleArray&num;</literal></primary></indexterm>
819 <indexterm><primary><literal>indexCharOffAddr&num;</literal></primary></indexterm>
820 <indexterm><primary><literal>indexIntOffAddr&num;</literal></primary></indexterm>
821 <indexterm><primary><literal>indexFloatOffAddr&num;</literal></primary></indexterm>
822 <indexterm><primary><literal>indexDoubleOffAddr&num;</literal></primary></indexterm>
823 <indexterm><primary><literal>indexAddrOffAddr&num;</literal></primary></indexterm>
824 </para>
825
826 <para>
827 The last of these, <function>indexAddrOffAddr&num;</function>, extracts an <literal>Addr&num;</literal> using an offset
828 from another <literal>Addr&num;</literal>, thereby providing the ability to follow a chain of
829 C pointers.
830 </para>
831
832 <para>
833 Something a bit more interesting goes on when indexing arrays of boxed
834 objects, because the result is simply the boxed object. So presumably
835 it should be entered&mdash;we never usually return an unevaluated
836 object!  This is a pain: primitive ops aren't supposed to do
837 complicated things like enter objects.  The current solution is to
838 return a single element unboxed tuple (see <xref linkend="unboxed-tuples">).
839 </para>
840
841 <para>
842
843 <programlisting>
844 indexArray#       :: Array# elt -> Int# -> (# elt #)
845 </programlisting>
846
847 <indexterm><primary><literal>indexArray&num;</literal></primary></indexterm>
848 </para>
849
850 </sect2>
851
852 <sect2>
853 <title>The state type</title>
854
855 <para>
856 <indexterm><primary><literal>state, primitive type</literal></primary></indexterm>
857 <indexterm><primary><literal>State&num;</literal></primary></indexterm>
858 </para>
859
860 <para>
861 The primitive type <literal>State&num;</literal> represents the state of a state
862 transformer.  It is parameterised on the desired type of state, which
863 serves to keep states from distinct threads distinct from one another.
864 But the <emphasis>only</emphasis> effect of this parameterisation is in the type
865 system: all values of type <literal>State&num;</literal> are represented in the same way.
866 Indeed, they are all represented by nothing at all!  The code
867 generator &ldquo;knows&rdquo; to generate no code, and allocate no registers
868 etc, for primitive states.
869 </para>
870
871 <para>
872
873 <programlisting>
874 type State# s
875 </programlisting>
876
877 </para>
878
879 <para>
880 The type <literal>GHC.RealWorld</literal> is truly opaque: there are no values defined
881 of this type, and no operations over it.  It is &ldquo;primitive&rdquo; in that
882 sense - but it is <emphasis>not unlifted!</emphasis> Its only role in life is to be
883 the type which distinguishes the <literal>IO</literal> state transformer.
884 </para>
885
886 <para>
887
888 <programlisting>
889 data RealWorld
890 </programlisting>
891
892 </para>
893
894 </sect2>
895
896 <sect2>
897 <title>State of the world</title>
898
899 <para>
900 A single, primitive, value of type <literal>State&num; RealWorld</literal> is provided.
901 </para>
902
903 <para>
904
905 <programlisting>
906 realWorld# :: State# RealWorld
907 </programlisting>
908
909 <indexterm><primary>realWorld&num; state object</primary></indexterm>
910 </para>
911
912 <para>
913 (Note: in the compiler, not a <literal>PrimOp</literal>; just a mucho magic
914 <literal>Id</literal>. Exported from <literal>GHC</literal>, though).
915 </para>
916
917 </sect2>
918
919 <sect2 id="sect-mutable">
920 <title>Mutable arrays</title>
921
922 <para>
923 <indexterm><primary>mutable arrays</primary></indexterm>
924 <indexterm><primary>arrays, mutable</primary></indexterm>
925 Corresponding to <literal>Array&num;</literal> and <literal>ByteArray&num;</literal>, we have the types of
926 mutable versions of each.  In each case, the representation is a
927 pointer to a suitable block of (mutable) heap-allocated storage.
928 </para>
929
930 <para>
931
932 <programlisting>
933 type MutableArray# s elt
934 type MutableByteArray# s
935 </programlisting>
936
937 <indexterm><primary><literal>MutableArray&num;</literal></primary></indexterm>
938 <indexterm><primary><literal>MutableByteArray&num;</literal></primary></indexterm>
939 </para>
940
941 <sect3>
942 <title>Allocation</title>
943
944 <para>
945 <indexterm><primary>mutable arrays, allocation</primary></indexterm>
946 <indexterm><primary>arrays, allocation</primary></indexterm>
947 <indexterm><primary>allocation, of mutable arrays</primary></indexterm>
948 </para>
949
950 <para>
951 Mutable arrays can be allocated. Only pointer-arrays are initialised;
952 arrays of non-pointers are filled in by &ldquo;user code&rdquo; rather than by
953 the array-allocation primitive.  Reason: only the pointer case has to
954 worry about GC striking with a partly-initialised array.
955 </para>
956
957 <para>
958
959 <programlisting>
960 newArray#       :: Int# -> elt -> State# s -> (# State# s, MutableArray# s elt #)
961
962 newCharArray#   :: Int# -> State# s -> (# State# s, MutableByteArray# s elt #)
963 newIntArray#    :: Int# -> State# s -> (# State# s, MutableByteArray# s elt #)
964 newAddrArray#   :: Int# -> State# s -> (# State# s, MutableByteArray# s elt #)
965 newFloatArray#  :: Int# -> State# s -> (# State# s, MutableByteArray# s elt #)
966 newDoubleArray# :: Int# -> State# s -> (# State# s, MutableByteArray# s elt #)
967 </programlisting>
968
969 <indexterm><primary><literal>newArray&num;</literal></primary></indexterm>
970 <indexterm><primary><literal>newCharArray&num;</literal></primary></indexterm>
971 <indexterm><primary><literal>newIntArray&num;</literal></primary></indexterm>
972 <indexterm><primary><literal>newAddrArray&num;</literal></primary></indexterm>
973 <indexterm><primary><literal>newFloatArray&num;</literal></primary></indexterm>
974 <indexterm><primary><literal>newDoubleArray&num;</literal></primary></indexterm>
975 </para>
976
977 <para>
978 The size of a <literal>ByteArray&num;</literal> is given in bytes.
979 </para>
980
981 </sect3>
982
983 <sect3>
984 <title>Reading and writing</title>
985
986 <para>
987 <indexterm><primary>arrays, reading and writing</primary></indexterm>
988 </para>
989
990 <para>
991
992 <programlisting>
993 readArray#       :: MutableArray# s elt -> Int# -> State# s -> (# State# s, elt #)
994 readCharArray#   :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Char# #)
995 readIntArray#    :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
996 readAddrArray#   :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Addr# #)
997 readFloatArray#  :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Float# #)
998 readDoubleArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Double# #)
999
1000 writeArray#       :: MutableArray# s elt -> Int# -> elt     -> State# s -> State# s
1001 writeCharArray#   :: MutableByteArray# s -> Int# -> Char#   -> State# s -> State# s
1002 writeIntArray#    :: MutableByteArray# s -> Int# -> Int#    -> State# s -> State# s
1003 writeAddrArray#   :: MutableByteArray# s -> Int# -> Addr#   -> State# s -> State# s
1004 writeFloatArray#  :: MutableByteArray# s -> Int# -> Float#  -> State# s -> State# s
1005 writeDoubleArray# :: MutableByteArray# s -> Int# -> Double# -> State# s -> State# s
1006 </programlisting>
1007
1008 <indexterm><primary><literal>readArray&num;</literal></primary></indexterm>
1009 <indexterm><primary><literal>readCharArray&num;</literal></primary></indexterm>
1010 <indexterm><primary><literal>readIntArray&num;</literal></primary></indexterm>
1011 <indexterm><primary><literal>readAddrArray&num;</literal></primary></indexterm>
1012 <indexterm><primary><literal>readFloatArray&num;</literal></primary></indexterm>
1013 <indexterm><primary><literal>readDoubleArray&num;</literal></primary></indexterm>
1014 <indexterm><primary><literal>writeArray&num;</literal></primary></indexterm>
1015 <indexterm><primary><literal>writeCharArray&num;</literal></primary></indexterm>
1016 <indexterm><primary><literal>writeIntArray&num;</literal></primary></indexterm>
1017 <indexterm><primary><literal>writeAddrArray&num;</literal></primary></indexterm>
1018 <indexterm><primary><literal>writeFloatArray&num;</literal></primary></indexterm>
1019 <indexterm><primary><literal>writeDoubleArray&num;</literal></primary></indexterm>
1020 </para>
1021
1022 </sect3>
1023
1024 <sect3>
1025 <title>Equality</title>
1026
1027 <para>
1028 <indexterm><primary>arrays, testing for equality</primary></indexterm>
1029 </para>
1030
1031 <para>
1032 One can take &ldquo;equality&rdquo; of mutable arrays.  What is compared is the
1033 <emphasis>name</emphasis> or reference to the mutable array, not its contents.
1034 </para>
1035
1036 <para>
1037
1038 <programlisting>
1039 sameMutableArray#     :: MutableArray# s elt -> MutableArray# s elt -> Bool
1040 sameMutableByteArray# :: MutableByteArray# s -> MutableByteArray# s -> Bool
1041 </programlisting>
1042
1043 <indexterm><primary><literal>sameMutableArray&num;</literal></primary></indexterm>
1044 <indexterm><primary><literal>sameMutableByteArray&num;</literal></primary></indexterm>
1045 </para>
1046
1047 </sect3>
1048
1049 <sect3>
1050 <title>Freezing mutable arrays</title>
1051
1052 <para>
1053 <indexterm><primary>arrays, freezing mutable</primary></indexterm>
1054 <indexterm><primary>freezing mutable arrays</primary></indexterm>
1055 <indexterm><primary>mutable arrays, freezing</primary></indexterm>
1056 </para>
1057
1058 <para>
1059 Only unsafe-freeze has a primitive.  (Safe freeze is done directly in Haskell
1060 by copying the array and then using <function>unsafeFreeze</function>.)
1061 </para>
1062
1063 <para>
1064
1065 <programlisting>
1066 unsafeFreezeArray#     :: MutableArray# s elt -> State# s -> (# State# s, Array# s elt #)
1067 unsafeFreezeByteArray# :: MutableByteArray# s -> State# s -> (# State# s, ByteArray# #)
1068 </programlisting>
1069
1070 <indexterm><primary><literal>unsafeFreezeArray&num;</literal></primary></indexterm>
1071 <indexterm><primary><literal>unsafeFreezeByteArray&num;</literal></primary></indexterm>
1072 </para>
1073
1074 </sect3>
1075
1076 </sect2>
1077
1078 <sect2>
1079 <title>Synchronizing variables (M-vars)</title>
1080
1081 <para>
1082 <indexterm><primary>synchronising variables (M-vars)</primary></indexterm>
1083 <indexterm><primary>M-Vars</primary></indexterm>
1084 </para>
1085
1086 <para>
1087 Synchronising variables are the primitive type used to implement
1088 Concurrent Haskell's MVars (see the Concurrent Haskell paper for
1089 the operational behaviour of these operations).
1090 </para>
1091
1092 <para>
1093
1094 <programlisting>
1095 type MVar# s elt        -- primitive
1096
1097 newMVar#    :: State# s -> (# State# s, MVar# s elt #)
1098 takeMVar#   :: SynchVar# s elt -> State# s -> (# State# s, elt #)
1099 putMVar#    :: SynchVar# s elt -> State# s -> State# s
1100 </programlisting>
1101
1102 <indexterm><primary><literal>SynchVar&num;</literal></primary></indexterm>
1103 <indexterm><primary><literal>newSynchVar&num;</literal></primary></indexterm>
1104 <indexterm><primary><literal>takeMVar</literal></primary></indexterm>
1105 <indexterm><primary><literal>putMVar</literal></primary></indexterm>
1106 </para>
1107
1108 </sect2>
1109
1110 <sect2 id="glasgow-prim-arrays">
1111 <title>Primitive arrays, mutable and otherwise
1112 </title>
1113
1114 <para>
1115 <indexterm><primary>primitive arrays (Glasgow extension)</primary></indexterm>
1116 <indexterm><primary>arrays, primitive (Glasgow extension)</primary></indexterm>
1117 </para>
1118
1119 <para>
1120 GHC knows about quite a few flavours of Large Swathes of Bytes.
1121 </para>
1122
1123 <para>
1124 First, GHC distinguishes between primitive arrays of (boxed) Haskell
1125 objects (type <literal>Array&num; obj</literal>) and primitive arrays of bytes (type
1126 <literal>ByteArray&num;</literal>).
1127 </para>
1128
1129 <para>
1130 Second, it distinguishes between&hellip;
1131 <variablelist>
1132
1133 <varlistentry>
1134 <term>Immutable:</term>
1135 <listitem>
1136 <para>
1137 Arrays that do not change (as with &ldquo;standard&rdquo; Haskell arrays); you
1138 can only read from them.  Obviously, they do not need the care and
1139 attention of the state-transformer monad.
1140 </para>
1141 </listitem>
1142 </varlistentry>
1143 <varlistentry>
1144 <term>Mutable:</term>
1145 <listitem>
1146 <para>
1147 Arrays that may be changed or &ldquo;mutated.&rdquo;  All the operations on them
1148 live within the state-transformer monad and the updates happen
1149 <emphasis>in-place</emphasis>.
1150 </para>
1151 </listitem>
1152 </varlistentry>
1153 <varlistentry>
1154 <term>&ldquo;Static&rdquo; (in C land):</term>
1155 <listitem>
1156 <para>
1157 A C routine may pass an <literal>Addr&num;</literal> pointer back into Haskell land.  There
1158 are then primitive operations with which you may merrily grab values
1159 over in C land, by indexing off the &ldquo;static&rdquo; pointer.
1160 </para>
1161 </listitem>
1162 </varlistentry>
1163 <varlistentry>
1164 <term>&ldquo;Stable&rdquo; pointers:</term>
1165 <listitem>
1166 <para>
1167 If, for some reason, you wish to hand a Haskell pointer (i.e.,
1168 <emphasis>not</emphasis> an unboxed value) to a C routine, you first make the
1169 pointer &ldquo;stable,&rdquo; so that the garbage collector won't forget that it
1170 exists.  That is, GHC provides a safe way to pass Haskell pointers to
1171 C.
1172 </para>
1173
1174 <para>
1175 Please see the module <literal>Foreign.StablePtr</literal> in the
1176 library documentation for more details.
1177 </para>
1178 </listitem>
1179 </varlistentry>
1180 <varlistentry>
1181 <term>&ldquo;Foreign objects&rdquo;:</term>
1182 <listitem>
1183 <para>
1184 A &ldquo;foreign object&rdquo; is a safe way to pass an external object (a
1185 C-allocated pointer, say) to Haskell and have Haskell do the Right
1186 Thing when it no longer references the object.  So, for example, C
1187 could pass a large bitmap over to Haskell and say &ldquo;please free this
1188 memory when you're done with it.&rdquo;
1189 </para>
1190
1191 <para>
1192 Please see module <literal>Foreign.ForeignPtr</literal> in the library
1193 documentatation for more details.
1194 </para>
1195 </listitem>
1196 </varlistentry>
1197 </variablelist>
1198 </para>
1199
1200 <para>
1201 The libraries documentatation gives more details on all these
1202 &ldquo;primitive array&rdquo; types and the operations on them.
1203 </para>
1204
1205 </sect2>
1206
1207 </sect1>
1208
1209 <!-- Emacs stuff:
1210      ;;; Local Variables: ***
1211      ;;; mode: sgml ***
1212      ;;; sgml-parent-document: ("users_guide.sgml" "book" "chapter" "sect1") ***
1213      ;;; End: ***
1214  -->