1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2<html>
3<head>
4<title>Pretty Printing</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6  <link rel="stylesheet" type="text/css" href="main.css">
7</head>
8
9<body>
10<H2><STRONG><font face="Arial, Helvetica, sans-serif">Pretty Printing</font></STRONG></H2>
11<P>The way pretty printing is handled in Poly/ML changed in version 5.3. This 
12  describes the functions and datatypes that were added in that version. The old 
13  mechanism, using <code>PolyML.install_pp</code>, is deprecated and may be removed 
14  in a future release.</P>
15<P>The basic model, described in the paper by D.C. Oppen ACM ToPLAS Vol. 2 No. 
16  4 Oct 1980, is unchanged but instead of a set of imperative functions pretty 
17  printing is structured around the <code>PolyML.pretty</code> datatype and the 
18  pretty printing algorithm is now functional rather than imperative.</P>
19<pre><code><strong>datatype</strong> pretty =
20     PrettyBlock of int * bool * context list * pretty list
21   | PrettyBreak of int * int
22   | PrettyString of string
23
24<strong>and</strong> context =
25    ContextLocation of location
26  | ContextParentStructure of string * context list
27  | ContextProperty of string * string
28
29<strong>withtype</strong> location =
30   { file: string, startLine: int, startPosition: int, endLine: int, endPosition: int }</code></pre>
31<P><code>PrettyString s</code> contains a string to be printed. <code>PrettyBlock(indent, 
32  consistent, context, items)</code> defines a block of <code>items</code> which 
33  may be strings, breaks or blocks. The items will be retained on a single line 
34  if possible. The <code>indent</code> parameter is an indentation that will be 
35  added to the current indentation if the block has to be broken. Note that this 
36  does not apply to the first item in the block which will always be printed with 
37  the current indentation. The <code>consistent</code> parameter indicates whether 
38  the block is to be broken consistently (true) or not (false). If it is true 
39  then if the block will not all fit on a line and must be broken then it will 
40  be broken at all the breaks in the block whether this is necessary or not. If 
41  it is false it will only be broken where necessary. Neither of these parameters 
42  are used if the block will fit on a line. <code>PrettyBreak(blanks, breakOffset)</code> 
43  indicates a break between items. If the line is not broken at this point then 
44  <code>blanks</code> is the number of space characters that will be inserted. 
45  If the line is broken at that point then instead the following item is indented 
46  by an extra <code>breakOffset</code> spaces.</P>
47<P>The context and location types are primarily used by the IDE when providing 
48  error messages. For most purposes the <code>context</code> argument to <code>PrettyBlock</code> 
49  can be the empty list. <code>ContextProperty</code> can be used by a user-supplied 
50  pretty printer to provide extra information which may be useful if the result 
51  of pretty printing is to be processed by a user function. It is not produced 
52  by Poly/ML pretty printers and the default printers ignore this item.<code> 
53  ContextParentStructure</code> was used to deal with types inside structures 
54  in an early draft and will probably be removed.</P>
55<P>A pretty printer can be associated with a datatype using <code>PolyML.addPrettyPrinter</code>.
56  
57<pre><code><strong>val</strong> addPrettyPrinter: (int -&gt; 'a -&gt; 'b -&gt; pretty)-&gt; unit</code></pre>
58<p>This function has a polymorphic type but is specially handled by the compiler. 
59  <code>addPrettyPrinter pp</code> installs a pretty printer <code>pp</code> where 
60  <code>pp</code> has arguments <code>depth printArgTypes value</code>. The first 
61  argument, <code>depth</code>, is the print depth. This is a value that indicates 
62  how much of the data structure should be displayed. If this value is zero or 
63  negative the pretty printer should always print a simple string such as <code>PrettyString 
64  &quot;...&quot;</code>. The third argument, <code>value</code>, is a value of 
65  the datatype. When installing a pretty printer there must be sufficient type 
66  constraint so that the compiler is able to determine the type unambiguiously. 
67  The second argument, <code>printArgTypes</code>, is only used for polytypes 
68  i.e. datatypes defined as <code>'a t</code> or <code>('a, 'b', 'c ...) t</code>. 
69  It is not used for monotypes. If the type takes a single argument then <code>printArgTypes</code> 
70  has type <code>'a * int -&gt; pretty</code> and is the function that will generate 
71  the pretty data structure for the argument type. The <code>int</code> argument 
72  is the adjusted print depth and should normally be one less than the value of 
73  <code>depth</code>. If the type takes multiple arguments then <code>printArgTypes</code> 
74  is a tuple with each field being a function of type <code>'a * int -&gt; pretty</code> 
75  that is used for the corresponding argument of the datatype.</p> </P>
76<p>As well as PolyML.addPrettyPrinter there some other functions in the PolyML 
77  structure that may be useful. </p>
78<pre><code><strong>val</strong> prettyRepresentation : 'a * int -&gt; pretty</code></pre>
79<p>This function returns the <code>pretty</code> structure that can be used to 
80  print a value of the given type up to the specified depth. It is similar to 
81  <code>PolyML.print</code> in being infinitely overloaded. It can be useful when 
82  writing a pretty printer for a datatype that includes types that already have 
83  pretty printers installed or where they will be installed later since it uses 
84  any pretty printers for the types when it is actually called.</p>
85<pre><code><strong>val</strong> prettyPrint: (string -&gt; unit) * int -&gt; pretty -&gt; unit</code></pre>
86<p>This function takes an output function and a line length and outputs a pretty 
87  structure, interpretting the layout information.</p>
88<p><br>
89</p>
90</body>
91</html>
92