Import Upstream version 20180207
[hcoop/debian/mlton.git] / doc / guide / src / mlton-guide.xml
CommitLineData
7f918cf1
CE
1<?xml version="1.0" encoding="UTF-8"?>\r
2<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">\r
3<?asciidoc-toc?>\r
4<?asciidoc-numbered?>\r
5\r
6<article lang="en">\r
7<articleinfo>\r
8 <title>MLton Guide (20180207)</title>\r
9</articleinfo>\r
10<abstract>\r
11<simpara>This is the guide for MLton, an open-source, whole-program, optimizing Standard ML compiler.</simpara>\r
12<simpara>This guide was generated automatically from the MLton website, available online at <ulink url="http://mlton.org">http://mlton.org</ulink>. It is up to date for MLton 20180207.</simpara>\r
13</abstract>\r
14<section id="Home">\r
15<title>MLton</title>\r
16<section id="_what_is_mlton">\r
17<title>What is MLton?</title>\r
18<simpara>MLton is an open-source, whole-program, optimizing\r
19<link linkend="StandardML">Standard ML</link> compiler.</simpara>\r
20</section>\r
21<section id="_what_8217_s_new">\r
22<title>What&#8217;s new?</title>\r
23<itemizedlist>\r
24<listitem>\r
25<simpara>\r
2620180207: Please try out our latest release, <link linkend="Release20180207">MLton 20180207</link>.\r
27</simpara>\r
28</listitem>\r
29<listitem>\r
30<simpara>\r
3120140730: <ulink url="http://www.cs.rit.edu/%7emtf">Matthew Fluet</ulink> and\r
32 <ulink url="http://www.cse.buffalo.edu/%7elziarek">Lukasz Ziarek</ulink> have been\r
33 awarded an <ulink url="http://www.nsf.gov/funding/pgm_summ.jsp?pims_id=12810">NSF\r
34 CISE Research Infrastructure (CRI)</ulink> grant titled "Positioning MLton\r
35 for Next-Generation Programming Languages Research;" read the award\r
36 abstracts\r
37 (<ulink url="http://www.nsf.gov/awardsearch/showAward?AWD_ID=1405770">Award&#160;#1405770</ulink>\r
38 and\r
39 <ulink url="http://www.nsf.gov/awardsearch/showAward?AWD_ID=1405614">Award&#160;#1405614</ulink>)\r
40 for more details.\r
41</simpara>\r
42</listitem>\r
43</itemizedlist>\r
44</section>\r
45<section id="_next_steps">\r
46<title>Next steps</title>\r
47<itemizedlist>\r
48<listitem>\r
49<simpara>\r
50Read about MLton&#8217;s <link linkend="Features">Features</link>.\r
51</simpara>\r
52</listitem>\r
53<listitem>\r
54<simpara>\r
55Look at <link linkend="Documentation">Documentation</link>.\r
56</simpara>\r
57</listitem>\r
58<listitem>\r
59<simpara>\r
60See some <link linkend="Users">Users</link> of MLton.\r
61</simpara>\r
62</listitem>\r
63<listitem>\r
64<simpara>\r
65<ulink url="https://sourceforge.net/projects/mlton/files/mlton/20180207">Download</ulink> MLton.\r
66</simpara>\r
67</listitem>\r
68<listitem>\r
69<simpara>\r
70Meet the MLton <link linkend="Developers">Developers</link>.\r
71</simpara>\r
72</listitem>\r
73<listitem>\r
74<simpara>\r
75Get involved with MLton <link linkend="Development">Development</link>.\r
76</simpara>\r
77</listitem>\r
78<listitem>\r
79<simpara>\r
80User-maintained <link linkend="FAQ">FAQ</link>.\r
81</simpara>\r
82</listitem>\r
83<listitem>\r
84<simpara>\r
85<link linkend="Contact">Contact</link> us.\r
86</simpara>\r
87</listitem>\r
88</itemizedlist>\r
89<simpara><?asciidoc-pagebreak?></simpara>\r
90</section>\r
91</section>\r
92<section id="AdamGoode">\r
93<title>AdamGoode</title>\r
94<itemizedlist>\r
95<listitem>\r
96<simpara>\r
97I maintain the Fedora package of MLton, in <ulink url="https://admin.fedoraproject.org/pkgdb/packages/name/mlton">Fedora</ulink>.\r
98</simpara>\r
99</listitem>\r
100<listitem>\r
101<simpara>\r
102I have contributed some patches for Makefiles and PDF documentation building.\r
103</simpara>\r
104</listitem>\r
105</itemizedlist>\r
106<simpara><?asciidoc-pagebreak?></simpara>\r
107</section>\r
108<section id="AdmitsEquality">\r
109<title>AdmitsEquality</title>\r
110<simpara>A <link linkend="TypeConstructor">TypeConstructor</link> admits equality if whenever it is applied to\r
111equality types, the result is an <link linkend="EqualityType">EqualityType</link>. This notion enables\r
112one to determine whether a type constructor application yields an\r
113equality type solely from the application, without looking at the\r
114definition of the type constructor. It helps to ensure that\r
115<link linkend="PolymorphicEquality">PolymorphicEquality</link> is only applied to sensible values.</simpara>\r
116<simpara>The definition of admits equality depends on whether the type\r
117constructor was declared by a <literal>type</literal> definition or a\r
118<literal>datatype</literal> declaration.</simpara>\r
119<section id="_type_definitions">\r
120<title>Type definitions</title>\r
121<simpara>For type definition</simpara>\r
122<programlisting language="sml" linenumbering="unnumbered">type ('a1, ..., 'an) t = ...</programlisting>\r
123<simpara>type constructor <literal>t</literal> admits equality if the right-hand side of the\r
124definition is an equality type after replacing <literal>'a1</literal>, &#8230;,\r
125<literal>'an</literal> by equality types (it doesn&#8217;t matter which equality types\r
126are chosen).</simpara>\r
127<simpara>For a nullary type definition, this amounts to the right-hand side\r
128being an equality type. For example, after the definition</simpara>\r
129<programlisting language="sml" linenumbering="unnumbered">type t = bool * int</programlisting>\r
130<simpara>type constructor <literal>t</literal> admits equality because <literal>bool * int</literal> is\r
131an equality type. On the other hand, after the definition</simpara>\r
132<programlisting language="sml" linenumbering="unnumbered">type t = bool * int * real</programlisting>\r
133<simpara>type constructor <literal>t</literal> does not admit equality, because <literal>real</literal>\r
134is not an equality type.</simpara>\r
135<simpara>For another example, after the definition</simpara>\r
136<programlisting language="sml" linenumbering="unnumbered">type 'a t = bool * 'a</programlisting>\r
137<simpara>type constructor <literal>t</literal> admits equality because <literal>bool * int</literal>\r
138is an equality type (we could have chosen any equality type other than\r
139<literal>int</literal>).</simpara>\r
140<simpara>On the other hand, after the definition</simpara>\r
141<programlisting language="sml" linenumbering="unnumbered">type 'a t = real * 'a</programlisting>\r
142<simpara>type constructor <literal>t</literal> does not admit equality because\r
143<literal>real * int</literal> is not equality type.</simpara>\r
144<simpara>We can check that a type constructor admits equality using an\r
145<literal>eqtype</literal> specification.</simpara>\r
146<programlisting language="sml" linenumbering="unnumbered">structure Ok: sig eqtype 'a t end =\r
147 struct\r
148 type 'a t = bool * 'a\r
149 end</programlisting>\r
150<programlisting language="sml" linenumbering="unnumbered">structure Bad: sig eqtype 'a t end =\r
151 struct\r
152 type 'a t = real * int * 'a\r
153 end</programlisting>\r
154<simpara>On <literal>structure Bad</literal>, MLton reports the following error.</simpara>\r
155<screen>Error: z.sml 1.16-1.34.\r
156 Type in structure disagrees with signature (admits equality): t.\r
157 structure: type 'a t = [real] * _ * _\r
158 defn at: z.sml 3.15-3.15\r
159 signature: [eqtype] 'a t\r
160 spec at: z.sml 1.30-1.30</screen>\r
161<simpara>The <literal>structure:</literal> section provides an explanation of why the type\r
162did not admit equality, highlighting the problematic component\r
163(<literal>real</literal>).</simpara>\r
164</section>\r
165<section id="_datatype_declarations">\r
166<title>Datatype declarations</title>\r
167<simpara>For a type constructor declared by a datatype declaration to admit\r
168equality, every <link linkend="Variant">variant</link> of the datatype must admit equality. For\r
169example, the following datatype admits equality because <literal>bool</literal> and\r
170<literal>char * int</literal> are equality types.</simpara>\r
171<programlisting language="sml" linenumbering="unnumbered">datatype t = A of bool | B of char * int</programlisting>\r
172<simpara>Nullary constructors trivially admit equality, so that the following\r
173datatype admits equality.</simpara>\r
174<programlisting language="sml" linenumbering="unnumbered">datatype t = A | B | C</programlisting>\r
175<simpara>For a parameterized datatype constructor to admit equality, we\r
176consider each <link linkend="Variant">variant</link> as a type definition, and require that the\r
177definition admit equality. For example, for the datatype</simpara>\r
178<programlisting language="sml" linenumbering="unnumbered">datatype 'a t = A of bool * 'a | B of 'a</programlisting>\r
179<simpara>the type definitions</simpara>\r
180<programlisting language="sml" linenumbering="unnumbered">type 'a tA = bool * 'a\r
181type 'a tB = 'a</programlisting>\r
182<simpara>both admit equality. Thus, type constructor <literal>t</literal> admits equality.</simpara>\r
183<simpara>On the other hand, the following datatype does not admit equality.</simpara>\r
184<programlisting language="sml" linenumbering="unnumbered">datatype 'a t = A of bool * 'a | B of real * 'a</programlisting>\r
185<simpara>As with type definitions, we can check using an <literal>eqtype</literal>\r
186specification.</simpara>\r
187<programlisting language="sml" linenumbering="unnumbered">structure Bad: sig eqtype 'a t end =\r
188 struct\r
189 datatype 'a t = A of bool * 'a | B of real * 'a\r
190 end</programlisting>\r
191<simpara>MLton reports the following error.</simpara>\r
192<screen>Error: z.sml 1.16-1.34.\r
193 Type in structure disagrees with signature (admits equality): t.\r
194 structure: datatype 'a t = B of [real] * _ | ...\r
195 defn at: z.sml 3.19-3.19\r
196 signature: [eqtype] 'a t\r
197 spec at: z.sml 1.30-1.30</screen>\r
198<simpara>MLton indicates the problematic constructor (<literal>B</literal>), as well as\r
199the problematic component of the constructor&#8217;s argument.</simpara>\r
200<section id="_recursive_datatypes">\r
201<title>Recursive datatypes</title>\r
202<simpara>A recursive datatype like</simpara>\r
203<programlisting language="sml" linenumbering="unnumbered">datatype t = A | B of int * t</programlisting>\r
204<simpara>introduces a new problem, since in order to decide whether <literal>t</literal>\r
205admits equality, we need to know for the <literal>B</literal> <link linkend="Variant">variant</link> whether\r
206<literal>t</literal> admits equality. The <link linkend="DefinitionOfStandardML">Definition</link>\r
207answers this question by requiring a type constructor to admit\r
208equality if it is consistent to do so. So, in our above example, if\r
209we assume that <literal>t</literal> admits equality, then the <link linkend="Variant">variant</link>\r
210<literal>B of int * t</literal> admits equality. Then, since the <literal>A</literal> <link linkend="Variant">variant</link>\r
211trivially admits equality, so does the type constructor <literal>t</literal>.\r
212Thus, it was consistent to assume that <literal>t</literal> admits equality, and\r
213so, <literal>t</literal> does admit equality.</simpara>\r
214<simpara>On the other hand, in the following declaration</simpara>\r
215<programlisting language="sml" linenumbering="unnumbered">datatype t = A | B of real * t</programlisting>\r
216<simpara>if we assume that <literal>t</literal> admits equality, then the <literal>B</literal> <link linkend="Variant">variant</link>\r
217does not admit equality. Hence, the type constructor <literal>t</literal> does not\r
218admit equality, and our assumption was inconsistent. Hence, <literal>t</literal>\r
219does not admit equality.</simpara>\r
220<simpara>The same kind of reasoning applies to mutually recursive datatypes as\r
221well. For example, the following defines both <literal>t</literal> and <literal>u</literal> to\r
222admit equality.</simpara>\r
223<programlisting language="sml" linenumbering="unnumbered">datatype t = A | B of u\r
224and u = C | D of t</programlisting>\r
225<simpara>But the following defines neither <literal>t</literal> nor <literal>u</literal> to admit\r
226equality.</simpara>\r
227<programlisting language="sml" linenumbering="unnumbered">datatype t = A | B of u * real\r
228and u = C | D of t</programlisting>\r
229<simpara>As always, we can check whether a type admits equality using an\r
230<literal>eqtype</literal> specification.</simpara>\r
231<programlisting language="sml" linenumbering="unnumbered">structure Bad: sig eqtype t eqtype u end =\r
232 struct\r
233 datatype t = A | B of u * real\r
234 and u = C | D of t\r
235 end</programlisting>\r
236<simpara>MLton reports the following error.</simpara>\r
237<screen>Error: z.sml 1.16-1.40.\r
238 Type in structure disagrees with signature (admits equality): t.\r
239 structure: datatype t = B of [_str.u] * [real] | ...\r
240 defn at: z.sml 3.16-3.16\r
241 signature: [eqtype] t\r
242 spec at: z.sml 1.27-1.27\r
243Error: z.sml 1.16-1.40.\r
244 Type in structure disagrees with signature (admits equality): u.\r
245 structure: datatype u = D of [_str.t] | ...\r
246 defn at: z.sml 4.11-4.11\r
247 signature: [eqtype] u\r
248 spec at: z.sml 1.36-1.36</screen>\r
249<simpara><?asciidoc-pagebreak?></simpara>\r
250</section>\r
251</section>\r
252</section>\r
253<section id="Alice">\r
254<title>Alice</title>\r
255<simpara><ulink url="http://www.ps.uni-saarland.de/alice">Alice ML</ulink> is an extension of SML with\r
256concurrency, dynamic typing, components, distribution, and constraint\r
257solving.</simpara>\r
258<simpara><?asciidoc-pagebreak?></simpara>\r
259</section>\r
260<section id="AllocateRegisters">\r
261<title>AllocateRegisters</title>\r
262<simpara><link linkend="AllocateRegisters">AllocateRegisters</link> is an analysis pass for the <link linkend="RSSA">RSSA</link>\r
263<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="ToMachine">ToMachine</link>.</simpara>\r
264<section id="_description">\r
265<title>Description</title>\r
266<simpara>Computes an allocation of <link linkend="RSSA">RSSA</link> variables as <link linkend="Machine">Machine</link> register\r
267or stack operands.</simpara>\r
268</section>\r
269<section id="_implementation">\r
270<title>Implementation</title>\r
271<itemizedlist>\r
272<listitem>\r
273<simpara>\r
274<ulink url="https://github.com/MLton/mlton/blob/master/mlton/backend/allocate-registers.sig"><literal>allocate-registers.sig</literal></ulink>\r
275</simpara>\r
276</listitem>\r
277<listitem>\r
278<simpara>\r
279<ulink url="https://github.com/MLton/mlton/blob/master/mlton/backend/allocate-registers.fun"><literal>allocate-registers.fun</literal></ulink>\r
280</simpara>\r
281</listitem>\r
282</itemizedlist>\r
283</section>\r
284<section id="_details_and_notes">\r
285<title>Details and Notes</title>\r
286<simpara></simpara>\r
287<simpara><?asciidoc-pagebreak?></simpara>\r
288</section>\r
289</section>\r
290<section id="AndreiFormiga">\r
291<title>AndreiFormiga</title>\r
292<simpara>I&#8217;m a graduate student just back in academia. I study concurrent and parallel systems, with a great deal of interest in programming languages (theory, design, implementation). I happen to like functional languages.</simpara>\r
293<simpara>I use the nickname tautologico on #sml and my email is andrei DOT formiga AT gmail DOT com.</simpara>\r
294<simpara><?asciidoc-pagebreak?></simpara>\r
295</section>\r
296<section id="ArrayLiteral">\r
297<title>ArrayLiteral</title>\r
298<simpara><link linkend="StandardML">Standard ML</link> does not have a syntax for array literals or\r
299vector literals. The only way to write down an array is like</simpara>\r
300<programlisting language="sml" linenumbering="unnumbered">Array.fromList [w, x, y, z]</programlisting>\r
301<simpara>No SML compiler produces efficient code for the above expression. The\r
302generated code allocates a list and then converts it to an array. To\r
303alleviate this, one could write down the same array using\r
304<literal>Array.tabulate</literal>, or even using <literal>Array.array</literal> and <literal>Array.update</literal>, but\r
305that is syntactically unwieldy.</simpara>\r
306<simpara>Fortunately, using <link linkend="Fold">Fold</link>, it is possible to define constants <literal>A</literal>,\r
307and <literal>&grave;</literal> so that one can write down an array like:</simpara>\r
308<programlisting language="sml" linenumbering="unnumbered">A `w `x `y `z $</programlisting>\r
309<simpara>This is as syntactically concise as the <literal>fromList</literal> expression.\r
310Furthermore, MLton, at least, will generate the efficient code as if\r
311one had written down a use of <literal>Array.array</literal> followed by four uses of\r
312<literal>Array.update</literal>.</simpara>\r
313<simpara>Along with <literal>A</literal> and <literal>&grave;</literal>, one can define a constant <literal>V</literal> that makes\r
314it possible to define vector literals with the same syntax, e.g.,</simpara>\r
315<programlisting language="sml" linenumbering="unnumbered">V `w `x `y `z $</programlisting>\r
316<simpara>Note that the same element indicator, <literal>&grave;</literal>, serves for both array\r
317and vector literals. Of course, the <literal>$</literal> is the end-of-arguments\r
318marker always used with <link linkend="Fold">Fold</link>. The only difference between an\r
319array literal and vector literal is the <literal>A</literal> or <literal>V</literal> at the beginning.</simpara>\r
320<simpara>Here is the implementation of <literal>A</literal>, <literal>V</literal>, and <literal>&grave;</literal>. We place them\r
321in a structure and use signature abstraction to hide the type of the\r
322accumulator. See <link linkend="Fold">Fold</link> for more on this technique.</simpara>\r
323<programlisting language="sml" linenumbering="unnumbered">structure Literal:&gt;\r
324 sig\r
325 type 'a z\r
326 val A: ('a z, 'a z, 'a array, 'd) Fold.t\r
327 val V: ('a z, 'a z, 'a vector, 'd) Fold.t\r
328 val ` : ('a, 'a z, 'a z, 'b, 'c, 'd) Fold.step1\r
329 end =\r
330 struct\r
331 type 'a z = int * 'a option * ('a array -&gt; unit)\r
332\r
333 val A =\r
334 fn z =&gt;\r
335 Fold.fold\r
336 ((0, NONE, ignore),\r
337 fn (n, opt, fill) =&gt;\r
338 case opt of\r
339 NONE =&gt;\r
340 Array.tabulate (0, fn _ =&gt; raise Fail "array0")\r
341 | SOME x =&gt;\r
342 let\r
343 val a = Array.array (n, x)\r
344 val () = fill a\r
345 in\r
346 a\r
347 end)\r
348 z\r
349\r
350 val V = fn z =&gt; Fold.post (A, Array.vector) z\r
351\r
352 val ` =\r
353 fn z =&gt;\r
354 Fold.step1\r
355 (fn (x, (i, opt, fill)) =&gt;\r
356 (i + 1,\r
357 SOME x,\r
358 fn a =&gt; (Array.update (a, i, x); fill a)))\r
359 z\r
360 end</programlisting>\r
361<simpara>The idea of the code is for the fold to accumulate a count of the\r
362number of elements, a sample element, and a function that fills in all\r
363the elements. When the fold is complete, the finishing function\r
364allocates the array, applies the fill function, and returns the array.\r
365The only difference between <literal>A</literal> and <literal>V</literal> is at the very end; <literal>A</literal> just\r
366returns the array, while <literal>V</literal> converts it to a vector using\r
367post-composition, which is further described on the <link linkend="Fold">Fold</link> page.</simpara>\r
368<simpara><?asciidoc-pagebreak?></simpara>\r
369</section>\r
370<section id="AST">\r
371<title>AST</title>\r
372<simpara><link linkend="AST">AST</link> is the <link linkend="IntermediateLanguage">IntermediateLanguage</link> produced by the <link linkend="FrontEnd">FrontEnd</link>\r
373and translated by <link linkend="Elaborate">Elaborate</link> to <link linkend="CoreML">CoreML</link>.</simpara>\r
374<section id="_description_2">\r
375<title>Description</title>\r
376<simpara>The abstract syntax tree produced by the <link linkend="FrontEnd">FrontEnd</link>.</simpara>\r
377</section>\r
378<section id="_implementation_2">\r
379<title>Implementation</title>\r
380<itemizedlist>\r
381<listitem>\r
382<simpara>\r
383<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ast/ast-programs.sig"><literal>ast-programs.sig</literal></ulink>\r
384</simpara>\r
385</listitem>\r
386<listitem>\r
387<simpara>\r
388<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ast/ast-programs.fun"><literal>ast-programs.fun</literal></ulink>\r
389</simpara>\r
390</listitem>\r
391<listitem>\r
392<simpara>\r
393<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ast/ast-modules.sig"><literal>ast-modules.sig</literal></ulink>\r
394</simpara>\r
395</listitem>\r
396<listitem>\r
397<simpara>\r
398<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ast/ast-modules.fun"><literal>ast-modules.fun</literal></ulink>\r
399</simpara>\r
400</listitem>\r
401<listitem>\r
402<simpara>\r
403<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ast/ast-core.sig"><literal>ast-core.sig</literal></ulink>\r
404</simpara>\r
405</listitem>\r
406<listitem>\r
407<simpara>\r
408<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ast/ast-core.fun"><literal>ast-core.fun</literal></ulink>\r
409</simpara>\r
410</listitem>\r
411<listitem>\r
412<simpara>\r
413<ulink url="https://github.com/MLton/mlton/tree/master/mlton/ast"><literal>ast</literal></ulink>\r
414</simpara>\r
415</listitem>\r
416</itemizedlist>\r
417</section>\r
418<section id="_type_checking">\r
419<title>Type Checking</title>\r
420<simpara>The <link linkend="AST">AST</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link> has no independent type\r
421checker. Type inference is performed on an AST program as part of\r
422<link linkend="Elaborate">Elaborate</link>.</simpara>\r
423</section>\r
424<section id="_details_and_notes_2">\r
425<title>Details and Notes</title>\r
426<section id="_source_locations">\r
427<title>Source locations</title>\r
428<simpara>MLton makes use of a relatively clean method for annotating the\r
429abstract syntax tree with source location information. Every source\r
430program phrase is "wrapped" with the <literal>WRAPPED</literal> interface:</simpara>\r
431<programlisting language="sml" linenumbering="unnumbered">signature WRAPPED =\r
432 sig\r
433 type node'\r
434 type obj\r
435\r
436 val dest: obj -&gt; node' * Region.t\r
437 val makeRegion': node' * SourcePos.t * SourcePos.t -&gt; obj\r
438 val makeRegion: node' * Region.t -&gt; obj\r
439 val node: obj -&gt; node'\r
440 val region: obj -&gt; Region.t\r
441 end</programlisting>\r
442<simpara>The key idea is that <literal>node'</literal> is the type of an unannotated syntax\r
443phrase and <literal>obj</literal> is the type of its annotated counterpart. In the\r
444implementation, every <literal>node'</literal> is annotated with a <literal>Region.t</literal>\r
445(<ulink url="https://github.com/MLton/mlton/blob/master/mlton/control/region.sig"><literal>region.sig</literal></ulink>,\r
446<ulink url="https://github.com/MLton/mlton/blob/master/mlton/control/region.sml"><literal>region.sml</literal></ulink>), which describes the\r
447syntax phrase&#8217;s left source position and right source position, where\r
448<literal>SourcePos.t</literal> (<ulink url="https://github.com/MLton/mlton/blob/master/mlton/control/source-pos.sig"><literal>source-pos.sig</literal></ulink>,\r
449<ulink url="https://github.com/MLton/mlton/blob/master/mlton/control/source-pos.sml"><literal>source-pos.sml</literal></ulink>) denotes a\r
450particular file, line, and column. A typical use of the <literal>WRAPPED</literal>\r
451interface is illustrated by the following code:</simpara>\r
452<programlisting language="sml" linenumbering="unnumbered"> datatype node =\r
453 App of Longcon.t * t\r
454 | Const of Const.t\r
455 | Constraint of t * Type.t\r
456 | FlatApp of t vector\r
457 | Layered of {constraint: Type.t option,\r
458 fixop: Fixop.t,\r
459 pat: t,\r
460 var: Var.t}\r
461 | List of t vector\r
462 | Paren of t\r
463 | Or of t vector\r
464 | Record of {flexible: bool,\r
465 items: (Record.Field.t * Region.t * Item.t) vector}\r
466 | Tuple of t vector\r
467 | Var of {fixop: Fixop.t,\r
468 name: Longvid.t}\r
469 | Vector of t vector\r
470 | Wild</programlisting>\r
471<simpara>Thus, AST nodes are cleanly separated from source locations. By way\r
472of contrast, consider the approach taken by <link linkend="SMLNJ">SML/NJ</link> (and also\r
473by the <link linkend="CKitLibrary">CKit Library</link>). Each datatype denoting a syntax\r
474phrase dedicates a special constructor for annotating source\r
475locations:</simpara>\r
476<programlisting language="sml" linenumbering="unnumbered">datatype pat = WildPat (* empty pattern *)\r
477 | AppPat of {constr:pat,argument:pat} (* application *)\r
478 | MarkPat of pat * region (* mark a pattern *)</programlisting>\r
479<simpara>The main drawback of this approach is that static type checking is not\r
480sufficient to guarantee that the AST emitted from the front-end is\r
481properly annotated.</simpara>\r
482<simpara><?asciidoc-pagebreak?></simpara>\r
483</section>\r
484</section>\r
485</section>\r
486<section id="BasisLibrary">\r
487<title>BasisLibrary</title>\r
488<simpara>The <link linkend="StandardML">Standard ML</link> Basis Library is a collection of modules\r
489dealing with basic types, input/output, OS interfaces, and simple\r
490datatypes. It is intended as a portable library usable across all\r
491implementations of SML. For the official online version of the Basis\r
492Library specification, see <ulink url="http://www.standardml.org/Basis">http://www.standardml.org/Basis</ulink>.\r
493<link linkend="References_GansnerReppy04">The Standard ML Basis Library</link> is a book\r
494version that includes all of the online version and more. For a\r
495reverse chronological list of changes to the specification, see\r
496<ulink url="http://www.standardml.org/Basis/history.html">http://www.standardml.org/Basis/history.html</ulink>.</simpara>\r
497<simpara>MLton implements all of the required portions of the Basis Library.\r
498MLton also implements many of the optional structures. You can obtain\r
499a complete and current list of what&#8217;s available using\r
500<literal>mlton -show-basis</literal> (see <link linkend="ShowBasis">ShowBasis</link>). By default, MLton makes the\r
501Basis Library available to user programs. You can also\r
502<link linkend="MLBasisAvailableLibraries">access the Basis Library</link> from\r
503<link linkend="MLBasis">ML Basis</link> files.</simpara>\r
504<simpara>Below is a complete list of what MLton implements.</simpara>\r
505<section id="_top_level_types_and_constructors">\r
506<title>Top-level types and constructors</title>\r
507<simpara><literal>eqtype 'a array</literal></simpara>\r
508<simpara><literal>datatype bool = false | true</literal></simpara>\r
509<simpara><literal>eqtype char</literal></simpara>\r
510<simpara><literal>type exn</literal></simpara>\r
511<simpara><literal>eqtype int</literal></simpara>\r
512<simpara><literal>datatype 'a list = nil | :: of ('a * 'a list)</literal></simpara>\r
513<simpara><literal>datatype 'a option = NONE | SOME of 'a</literal></simpara>\r
514<simpara><literal>datatype order = EQUAL | GREATER | LESS</literal></simpara>\r
515<simpara><literal>type real</literal></simpara>\r
516<simpara><literal>datatype 'a ref = ref of 'a</literal></simpara>\r
517<simpara><literal>eqtype string</literal></simpara>\r
518<simpara><literal>type substring</literal></simpara>\r
519<simpara><literal>eqtype unit</literal></simpara>\r
520<simpara><literal>eqtype 'a vector</literal></simpara>\r
521<simpara><literal>eqtype word</literal></simpara>\r
522</section>\r
523<section id="_top_level_exception_constructors">\r
524<title>Top-level exception constructors</title>\r
525<simpara><literal>Bind</literal></simpara>\r
526<simpara><literal>Chr</literal></simpara>\r
527<simpara><literal>Div</literal></simpara>\r
528<simpara><literal>Domain</literal></simpara>\r
529<simpara><literal>Empty</literal></simpara>\r
530<simpara><literal>Fail of string</literal></simpara>\r
531<simpara><literal>Match</literal></simpara>\r
532<simpara><literal>Option</literal></simpara>\r
533<simpara><literal>Overflow</literal></simpara>\r
534<simpara><literal>Size</literal></simpara>\r
535<simpara><literal>Span</literal></simpara>\r
536<simpara><literal>Subscript</literal></simpara>\r
537</section>\r
538<section id="_top_level_values">\r
539<title>Top-level values</title>\r
540<simpara>MLton does not implement the optional top-level value\r
541<literal>use: string -&gt; unit</literal>, which conflicts with whole-program\r
542compilation because it allows new code to be loaded dynamically.</simpara>\r
543<simpara>MLton implements all other top-level values:</simpara>\r
544<simpara><literal>!</literal>,\r
545<literal>:=</literal>,\r
546<literal>&lt;&gt;</literal>,\r
547<literal>=</literal>,\r
548<literal>@</literal>,\r
549<literal>^</literal>,\r
550<literal>app</literal>,\r
551<literal>before</literal>,\r
552<literal>ceil</literal>,\r
553<literal>chr</literal>,\r
554<literal>concat</literal>,\r
555<literal>exnMessage</literal>,\r
556<literal>exnName</literal>,\r
557<literal>explode</literal>,\r
558<literal>floor</literal>,\r
559<literal>foldl</literal>,\r
560<literal>foldr</literal>,\r
561<literal>getOpt</literal>,\r
562<literal>hd</literal>,\r
563<literal>ignore</literal>,\r
564<literal>implode</literal>,\r
565<literal>isSome</literal>,\r
566<literal>length</literal>,\r
567<literal>map</literal>,\r
568<literal>not</literal>,\r
569<literal>null</literal>,\r
570<literal>o</literal>,\r
571<literal>ord</literal>,\r
572<literal>print</literal>,\r
573<literal>real</literal>,\r
574<literal>rev</literal>,\r
575<literal>round</literal>,\r
576<literal>size</literal>,\r
577<literal>str</literal>,\r
578<literal>substring</literal>,\r
579<literal>tl</literal>,\r
580<literal>trunc</literal>,\r
581<literal>valOf</literal>,\r
582<literal>vector</literal></simpara>\r
583</section>\r
584<section id="_overloaded_identifiers">\r
585<title>Overloaded identifiers</title>\r
586<simpara><literal>*</literal>,\r
587<literal>+</literal>,\r
588<literal>-</literal>,\r
589<literal>/</literal>,\r
590<literal>&lt;</literal>,\r
591<literal>&lt;=</literal>,\r
592<literal>&gt;</literal>,\r
593<literal>&gt;=</literal>,\r
594<literal>~</literal>,\r
595<literal>abs</literal>,\r
596<literal>div</literal>,\r
597<literal>mod</literal></simpara>\r
598</section>\r
599<section id="_top_level_signatures">\r
600<title>Top-level signatures</title>\r
601<simpara><literal>ARRAY</literal></simpara>\r
602<simpara><literal>ARRAY2</literal></simpara>\r
603<simpara><literal>ARRAY_SLICE</literal></simpara>\r
604<simpara><literal>BIN_IO</literal></simpara>\r
605<simpara><literal>BIT_FLAGS</literal></simpara>\r
606<simpara><literal>BOOL</literal></simpara>\r
607<simpara><literal>BYTE</literal></simpara>\r
608<simpara><literal>CHAR</literal></simpara>\r
609<simpara><literal>COMMAND_LINE</literal></simpara>\r
610<simpara><literal>DATE</literal></simpara>\r
611<simpara><literal>GENERAL</literal></simpara>\r
612<simpara><literal>GENERIC_SOCK</literal></simpara>\r
613<simpara><literal>IEEE_REAL</literal></simpara>\r
614<simpara><literal>IMPERATIVE_IO</literal></simpara>\r
615<simpara><literal>INET_SOCK</literal></simpara>\r
616<simpara><literal>INTEGER</literal></simpara>\r
617<simpara><literal>INT_INF</literal></simpara>\r
618<simpara><literal>IO</literal></simpara>\r
619<simpara><literal>LIST</literal></simpara>\r
620<simpara><literal>LIST_PAIR</literal></simpara>\r
621<simpara><literal>MATH</literal></simpara>\r
622<simpara><literal>MONO_ARRAY</literal></simpara>\r
623<simpara><literal>MONO_ARRAY2</literal></simpara>\r
624<simpara><literal>MONO_ARRAY_SLICE</literal></simpara>\r
625<simpara><literal>MONO_VECTOR</literal></simpara>\r
626<simpara><literal>MONO_VECTOR_SLICE</literal></simpara>\r
627<simpara><literal>NET_HOST_DB</literal></simpara>\r
628<simpara><literal>NET_PROT_DB</literal></simpara>\r
629<simpara><literal>NET_SERV_DB</literal></simpara>\r
630<simpara><literal>OPTION</literal></simpara>\r
631<simpara><literal>OS</literal></simpara>\r
632<simpara><literal>OS_FILE_SYS</literal></simpara>\r
633<simpara><literal>OS_IO</literal></simpara>\r
634<simpara><literal>OS_PATH</literal></simpara>\r
635<simpara><literal>OS_PROCESS</literal></simpara>\r
636<simpara><literal>PACK_REAL</literal></simpara>\r
637<simpara><literal>PACK_WORD</literal></simpara>\r
638<simpara><literal>POSIX</literal></simpara>\r
639<simpara><literal>POSIX_ERROR</literal></simpara>\r
640<simpara><literal>POSIX_FILE_SYS</literal></simpara>\r
641<simpara><literal>POSIX_IO</literal></simpara>\r
642<simpara><literal>POSIX_PROCESS</literal></simpara>\r
643<simpara><literal>POSIX_PROC_ENV</literal></simpara>\r
644<simpara><literal>POSIX_SIGNAL</literal></simpara>\r
645<simpara><literal>POSIX_SYS_DB</literal></simpara>\r
646<simpara><literal>POSIX_TTY</literal></simpara>\r
647<simpara><literal>PRIM_IO</literal></simpara>\r
648<simpara><literal>REAL</literal></simpara>\r
649<simpara><literal>SOCKET</literal></simpara>\r
650<simpara><literal>STREAM_IO</literal></simpara>\r
651<simpara><literal>STRING</literal></simpara>\r
652<simpara><literal>STRING_CVT</literal></simpara>\r
653<simpara><literal>SUBSTRING</literal></simpara>\r
654<simpara><literal>TEXT</literal></simpara>\r
655<simpara><literal>TEXT_IO</literal></simpara>\r
656<simpara><literal>TEXT_STREAM_IO</literal></simpara>\r
657<simpara><literal>TIME</literal></simpara>\r
658<simpara><literal>TIMER</literal></simpara>\r
659<simpara><literal>UNIX</literal></simpara>\r
660<simpara><literal>UNIX_SOCK</literal></simpara>\r
661<simpara><literal>VECTOR</literal></simpara>\r
662<simpara><literal>VECTOR_SLICE</literal></simpara>\r
663<simpara><literal>WORD</literal></simpara>\r
664</section>\r
665<section id="_top_level_structures">\r
666<title>Top-level structures</title>\r
667<simpara><literal>structure Array: ARRAY</literal></simpara>\r
668<simpara><literal>structure Array2: ARRAY2</literal></simpara>\r
669<simpara><literal>structure ArraySlice: ARRAY_SLICE</literal></simpara>\r
670<simpara><literal>structure BinIO: BIN_IO</literal></simpara>\r
671<simpara><literal>structure BinPrimIO: PRIM_IO</literal></simpara>\r
672<simpara><literal>structure Bool: BOOL</literal></simpara>\r
673<simpara><literal>structure BoolArray: MONO_ARRAY</literal></simpara>\r
674<simpara><literal>structure BoolArray2: MONO_ARRAY2</literal></simpara>\r
675<simpara><literal>structure BoolArraySlice: MONO_ARRAY_SLICE</literal></simpara>\r
676<simpara><literal>structure BoolVector: MONO_VECTOR</literal></simpara>\r
677<simpara><literal>structure BoolVectorSlice: MONO_VECTOR_SLICE</literal></simpara>\r
678<simpara><literal>structure Byte: BYTE</literal></simpara>\r
679<simpara><literal>structure Char: CHAR</literal></simpara>\r
680<itemizedlist>\r
681<listitem>\r
682<simpara>\r
683<literal>Char</literal> characters correspond to ISO-8859-1. The <literal>Char</literal> functions do not depend on locale.\r
684</simpara>\r
685</listitem>\r
686</itemizedlist>\r
687<simpara><literal>structure CharArray: MONO_ARRAY</literal></simpara>\r
688<simpara><literal>structure CharArray2: MONO_ARRAY2</literal></simpara>\r
689<simpara><literal>structure CharArraySlice: MONO_ARRAY_SLICE</literal></simpara>\r
690<simpara><literal>structure CharVector: MONO_VECTOR</literal></simpara>\r
691<simpara><literal>structure CharVectorSlice: MONO_VECTOR_SLICE</literal></simpara>\r
692<simpara><literal>structure CommandLine: COMMAND_LINE</literal></simpara>\r
693<simpara><literal>structure Date: DATE</literal></simpara>\r
694<itemizedlist>\r
695<listitem>\r
696<simpara>\r
697<literal>Date.fromString</literal> and <literal>Date.scan</literal> accept a space in addition to a zero for the first character of the day of the month. The Basis Library specification only allows a zero.\r
698</simpara>\r
699</listitem>\r
700</itemizedlist>\r
701<simpara><literal>structure FixedInt: INTEGER</literal></simpara>\r
702<simpara><literal>structure General: GENERAL</literal></simpara>\r
703<simpara><literal>structure GenericSock: GENERIC_SOCK</literal></simpara>\r
704<simpara><literal>structure IEEEReal: IEEE_REAL</literal></simpara>\r
705<simpara><literal>structure INetSock: INET_SOCK</literal></simpara>\r
706<simpara><literal>structure IO: IO</literal></simpara>\r
707<simpara><literal>structure Int: INTEGER</literal></simpara>\r
708<simpara><literal>structure Int1: INTEGER</literal></simpara>\r
709<simpara><literal>structure Int2: INTEGER</literal></simpara>\r
710<simpara><literal>structure Int3: INTEGER</literal></simpara>\r
711<simpara><literal>structure Int4: INTEGER</literal></simpara>\r
712<simpara>&#8230;</simpara>\r
713<simpara><literal>structure Int31: INTEGER</literal></simpara>\r
714<simpara><literal>structure Int32: INTEGER</literal></simpara>\r
715<simpara><literal>structure Int64: INTEGER</literal></simpara>\r
716<simpara><literal>structure IntArray: MONO_ARRAY</literal></simpara>\r
717<simpara><literal>structure IntArray2: MONO_ARRAY2</literal></simpara>\r
718<simpara><literal>structure IntArraySlice: MONO_ARRAY_SLICE</literal></simpara>\r
719<simpara><literal>structure IntVector: MONO_VECTOR</literal></simpara>\r
720<simpara><literal>structure IntVectorSlice: MONO_VECTOR_SLICE</literal></simpara>\r
721<simpara><literal>structure Int8: INTEGER</literal></simpara>\r
722<simpara><literal>structure Int8Array: MONO_ARRAY</literal></simpara>\r
723<simpara><literal>structure Int8Array2: MONO_ARRAY2</literal></simpara>\r
724<simpara><literal>structure Int8ArraySlice: MONO_ARRAY_SLICE</literal></simpara>\r
725<simpara><literal>structure Int8Vector: MONO_VECTOR</literal></simpara>\r
726<simpara><literal>structure Int8VectorSlice: MONO_VECTOR_SLICE</literal></simpara>\r
727<simpara><literal>structure Int16: INTEGER</literal></simpara>\r
728<simpara><literal>structure Int16Array: MONO_ARRAY</literal></simpara>\r
729<simpara><literal>structure Int16Array2: MONO_ARRAY2</literal></simpara>\r
730<simpara><literal>structure Int16ArraySlice: MONO_ARRAY_SLICE</literal></simpara>\r
731<simpara><literal>structure Int16Vector: MONO_VECTOR</literal></simpara>\r
732<simpara><literal>structure Int16VectorSlice: MONO_VECTOR_SLICE</literal></simpara>\r
733<simpara><literal>structure Int32: INTEGER</literal></simpara>\r
734<simpara><literal>structure Int32Array: MONO_ARRAY</literal></simpara>\r
735<simpara><literal>structure Int32Array2: MONO_ARRAY2</literal></simpara>\r
736<simpara><literal>structure Int32ArraySlice: MONO_ARRAY_SLICE</literal></simpara>\r
737<simpara><literal>structure Int32Vector: MONO_VECTOR</literal></simpara>\r
738<simpara><literal>structure Int32VectorSlice: MONO_VECTOR_SLICE</literal></simpara>\r
739<simpara><literal>structure Int64Array: MONO_ARRAY</literal></simpara>\r
740<simpara><literal>structure Int64Array2: MONO_ARRAY2</literal></simpara>\r
741<simpara><literal>structure Int64ArraySlice: MONO_ARRAY_SLICE</literal></simpara>\r
742<simpara><literal>structure Int64Vector: MONO_VECTOR</literal></simpara>\r
743<simpara><literal>structure Int64VectorSlice: MONO_VECTOR_SLICE</literal></simpara>\r
744<simpara><literal>structure IntInf: INT_INF</literal></simpara>\r
745<simpara><literal>structure LargeInt: INTEGER</literal></simpara>\r
746<simpara><literal>structure LargeIntArray: MONO_ARRAY</literal></simpara>\r
747<simpara><literal>structure LargeIntArray2: MONO_ARRAY2</literal></simpara>\r
748<simpara><literal>structure LargeIntArraySlice: MONO_ARRAY_SLICE</literal></simpara>\r
749<simpara><literal>structure LargeIntVector: MONO_VECTOR</literal></simpara>\r
750<simpara><literal>structure LargeIntVectorSlice: MONO_VECTOR_SLICE</literal></simpara>\r
751<simpara><literal>structure LargeReal: REAL</literal></simpara>\r
752<simpara><literal>structure LargeRealArray: MONO_ARRAY</literal></simpara>\r
753<simpara><literal>structure LargeRealArray2: MONO_ARRAY2</literal></simpara>\r
754<simpara><literal>structure LargeRealArraySlice: MONO_ARRAY_SLICE</literal></simpara>\r
755<simpara><literal>structure LargeRealVector: MONO_VECTOR</literal></simpara>\r
756<simpara><literal>structure LargeRealVectorSlice: MONO_VECTOR_SLICE</literal></simpara>\r
757<simpara><literal>structure LargeWord: WORD</literal></simpara>\r
758<simpara><literal>structure LargeWordArray: MONO_ARRAY</literal></simpara>\r
759<simpara><literal>structure LargeWordArray2: MONO_ARRAY2</literal></simpara>\r
760<simpara><literal>structure LargeWordArraySlice: MONO_ARRAY_SLICE</literal></simpara>\r
761<simpara><literal>structure LargeWordVector: MONO_VECTOR</literal></simpara>\r
762<simpara><literal>structure LargeWordVectorSlice: MONO_VECTOR_SLICE</literal></simpara>\r
763<simpara><literal>structure List: LIST</literal></simpara>\r
764<simpara><literal>structure ListPair: LIST_PAIR</literal></simpara>\r
765<simpara><literal>structure Math: MATH</literal></simpara>\r
766<simpara><literal>structure NetHostDB: NET_HOST_DB</literal></simpara>\r
767<simpara><literal>structure NetProtDB: NET_PROT_DB</literal></simpara>\r
768<simpara><literal>structure NetServDB: NET_SERV_DB</literal></simpara>\r
769<simpara><literal>structure OS: OS</literal></simpara>\r
770<simpara><literal>structure Option: OPTION</literal></simpara>\r
771<simpara><literal>structure PackReal32Big: PACK_REAL</literal></simpara>\r
772<simpara><literal>structure PackReal32Little: PACK_REAL</literal></simpara>\r
773<simpara><literal>structure PackReal64Big: PACK_REAL</literal></simpara>\r
774<simpara><literal>structure PackReal64Little: PACK_REAL</literal></simpara>\r
775<simpara><literal>structure PackRealBig: PACK_REAL</literal></simpara>\r
776<simpara><literal>structure PackRealLittle: PACK_REAL</literal></simpara>\r
777<simpara><literal>structure PackWord16Big: PACK_WORD</literal></simpara>\r
778<simpara><literal>structure PackWord16Little: PACK_WORD</literal></simpara>\r
779<simpara><literal>structure PackWord32Big: PACK_WORD</literal></simpara>\r
780<simpara><literal>structure PackWord32Little: PACK_WORD</literal></simpara>\r
781<simpara><literal>structure PackWord64Big: PACK_WORD</literal></simpara>\r
782<simpara><literal>structure PackWord64Little: PACK_WORD</literal></simpara>\r
783<simpara><literal>structure Position: INTEGER</literal></simpara>\r
784<simpara><literal>structure Posix: POSIX</literal></simpara>\r
785<simpara><literal>structure Real: REAL</literal></simpara>\r
786<simpara><literal>structure RealArray: MONO_ARRAY</literal></simpara>\r
787<simpara><literal>structure RealArray2: MONO_ARRAY2</literal></simpara>\r
788<simpara><literal>structure RealArraySlice: MONO_ARRAY_SLICE</literal></simpara>\r
789<simpara><literal>structure RealVector: MONO_VECTOR</literal></simpara>\r
790<simpara><literal>structure RealVectorSlice: MONO_VECTOR_SLICE</literal></simpara>\r
791<simpara><literal>structure Real32: REAL</literal></simpara>\r
792<simpara><literal>structure Real32Array: MONO_ARRAY</literal></simpara>\r
793<simpara><literal>structure Real32Array2: MONO_ARRAY2</literal></simpara>\r
794<simpara><literal>structure Real32ArraySlice: MONO_ARRAY_SLICE</literal></simpara>\r
795<simpara><literal>structure Real32Vector: MONO_VECTOR</literal></simpara>\r
796<simpara><literal>structure Real32VectorSlice: MONO_VECTOR_SLICE</literal></simpara>\r
797<simpara><literal>structure Real64: REAL</literal></simpara>\r
798<simpara><literal>structure Real64Array: MONO_ARRAY</literal></simpara>\r
799<simpara><literal>structure Real64Array2: MONO_ARRAY2</literal></simpara>\r
800<simpara><literal>structure Real64ArraySlice: MONO_ARRAY_SLICE</literal></simpara>\r
801<simpara><literal>structure Real64Vector: MONO_VECTOR</literal></simpara>\r
802<simpara><literal>structure Real64VectorSlice: MONO_VECTOR_SLICE</literal></simpara>\r
803<simpara><literal>structure Socket: SOCKET</literal></simpara>\r
804<itemizedlist>\r
805<listitem>\r
806<simpara>\r
807The Basis Library specification requires functions like\r
808<literal>Socket.sendVec</literal> to raise an exception if they fail. However, on some\r
809platforms, sending to a socket that hasn&#8217;t yet been connected causes a\r
810<literal>SIGPIPE</literal> signal, which invokes the default signal handler for\r
811<literal>SIGPIPE</literal> and causes the program to terminate. If you want the\r
812exception to be raised, you can ignore <literal>SIGPIPE</literal> by adding the\r
813following to your program.\r
814</simpara>\r
815<programlisting language="sml" linenumbering="unnumbered">let\r
816 open MLton.Signal\r
817in\r
818 setHandler (Posix.Signal.pipe, Handler.ignore)\r
819end</programlisting>\r
820</listitem>\r
821</itemizedlist>\r
822<simpara><literal>structure String: STRING</literal></simpara>\r
823<itemizedlist>\r
824<listitem>\r
825<simpara>\r
826The <literal>String</literal> functions do not depend on locale.\r
827</simpara>\r
828</listitem>\r
829</itemizedlist>\r
830<simpara><literal>structure StringCvt: STRING_CVT</literal></simpara>\r
831<simpara><literal>structure Substring: SUBSTRING</literal></simpara>\r
832<simpara><literal>structure SysWord: WORD</literal></simpara>\r
833<simpara><literal>structure Text: TEXT</literal></simpara>\r
834<simpara><literal>structure TextIO: TEXT_IO</literal></simpara>\r
835<simpara><literal>structure TextPrimIO: PRIM_IO</literal></simpara>\r
836<simpara><literal>structure Time: TIME</literal></simpara>\r
837<simpara><literal>structure Timer: TIMER</literal></simpara>\r
838<simpara><literal>structure Unix: UNIX</literal></simpara>\r
839<simpara><literal>structure UnixSock: UNIX_SOCK</literal></simpara>\r
840<simpara><literal>structure Vector: VECTOR</literal></simpara>\r
841<simpara><literal>structure VectorSlice: VECTOR_SLICE</literal></simpara>\r
842<simpara><literal>structure Word: WORD</literal></simpara>\r
843<simpara><literal>structure Word1: WORD</literal></simpara>\r
844<simpara><literal>structure Word2: WORD</literal></simpara>\r
845<simpara><literal>structure Word3: WORD</literal></simpara>\r
846<simpara><literal>structure Word4: WORD</literal></simpara>\r
847<simpara>&#8230;</simpara>\r
848<simpara><literal>structure Word31: WORD</literal></simpara>\r
849<simpara><literal>structure Word32: WORD</literal></simpara>\r
850<simpara><literal>structure Word64: WORD</literal></simpara>\r
851<simpara><literal>structure WordArray: MONO_ARRAY</literal></simpara>\r
852<simpara><literal>structure WordArray2: MONO_ARRAY2</literal></simpara>\r
853<simpara><literal>structure WordArraySlice: MONO_ARRAY_SLICE</literal></simpara>\r
854<simpara><literal>structure WordVectorSlice: MONO_VECTOR_SLICE</literal></simpara>\r
855<simpara><literal>structure WordVector: MONO_VECTOR</literal></simpara>\r
856<simpara><literal>structure Word8Array: MONO_ARRAY</literal></simpara>\r
857<simpara><literal>structure Word8Array2: MONO_ARRAY2</literal></simpara>\r
858<simpara><literal>structure Word8ArraySlice: MONO_ARRAY_SLICE</literal></simpara>\r
859<simpara><literal>structure Word8Vector: MONO_VECTOR</literal></simpara>\r
860<simpara><literal>structure Word8VectorSlice: MONO_VECTOR_SLICE</literal></simpara>\r
861<simpara><literal>structure Word16Array: MONO_ARRAY</literal></simpara>\r
862<simpara><literal>structure Word16Array2: MONO_ARRAY2</literal></simpara>\r
863<simpara><literal>structure Word16ArraySlice: MONO_ARRAY_SLICE</literal></simpara>\r
864<simpara><literal>structure Word16Vector: MONO_VECTOR</literal></simpara>\r
865<simpara><literal>structure Word16VectorSlice: MONO_VECTOR_SLICE</literal></simpara>\r
866<simpara><literal>structure Word32Array: MONO_ARRAY</literal></simpara>\r
867<simpara><literal>structure Word32Array2: MONO_ARRAY2</literal></simpara>\r
868<simpara><literal>structure Word32ArraySlice: MONO_ARRAY_SLICE</literal></simpara>\r
869<simpara><literal>structure Word32Vector: MONO_VECTOR</literal></simpara>\r
870<simpara><literal>structure Word32VectorSlice: MONO_VECTOR_SLICE</literal></simpara>\r
871<simpara><literal>structure Word64Array: MONO_ARRAY</literal></simpara>\r
872<simpara><literal>structure Word64Array2: MONO_ARRAY2</literal></simpara>\r
873<simpara><literal>structure Word64ArraySlice: MONO_ARRAY_SLICE</literal></simpara>\r
874<simpara><literal>structure Word64Vector: MONO_VECTOR</literal></simpara>\r
875<simpara><literal>structure Word64VectorSlice: MONO_VECTOR_SLICE</literal></simpara>\r
876</section>\r
877<section id="_top_level_functors">\r
878<title>Top-level functors</title>\r
879<simpara><literal>ImperativeIO</literal></simpara>\r
880<simpara><literal>PrimIO</literal></simpara>\r
881<simpara><literal>StreamIO</literal></simpara>\r
882<itemizedlist>\r
883<listitem>\r
884<simpara>\r
885MLton&#8217;s <literal>StreamIO</literal> functor takes structures <literal>ArraySlice</literal> and\r
886<literal>VectorSlice</literal> in addition to the arguments specified in the Basis\r
887Library specification.\r
888</simpara>\r
889</listitem>\r
890</itemizedlist>\r
891</section>\r
892<section id="_type_equivalences">\r
893<title>Type equivalences</title>\r
894<simpara>The following types are equivalent.</simpara>\r
895<screen>FixedInt = Int64.int\r
896LargeInt = IntInf.int\r
897LargeReal.real = Real64.real\r
898LargeWord = Word64.word</screen>\r
899<simpara>The default <literal>int</literal>, <literal>real</literal>, and <literal>word</literal> types may be set by the\r
900<literal>-default-type <emphasis>type</emphasis></literal> <link linkend="CompileTimeOptions">compile-time option</link>.\r
901By default, the following types are equivalent:</simpara>\r
902<screen>int = Int.int = Int32.int\r
903real = Real.real = Real64.real\r
904word = Word.word = Word32.word</screen>\r
905</section>\r
906<section id="_real_and_math_functions">\r
907<title>Real and Math functions</title>\r
908<simpara>The <literal>Real</literal>, <literal>Real32</literal>, and <literal>Real64</literal> modules are implemented\r
909using the <literal>C</literal> math library, so the SML functions will reflect the\r
910behavior of the underlying library function. We have made some effort\r
911to unify the differences between the math libraries on different\r
912platforms, and in particular to handle exceptional cases according to\r
913the Basis Library specification. However, there will be differences\r
914due to different numerical algorithms and cases we may have missed.\r
915Please submit a <link linkend="Bug">bug report</link> if you encounter an error in\r
916the handling of an exceptional case.</simpara>\r
917<simpara>On x86, real arithmetic is implemented internally using 80 bits of\r
918precision. Using higher precision for intermediate results in\r
919computations can lead to different results than if all the computation\r
920is done at 32 or 64 bits. If you require strict IEEE compliance, you\r
921can compile with <literal>-ieee-fp true</literal>, which will cause intermediate\r
922results to be stored after each operation. This may cause a\r
923substantial performance penalty.</simpara>\r
924<simpara><?asciidoc-pagebreak?></simpara>\r
925</section>\r
926</section>\r
927<section id="Bug">\r
928<title>Bug</title>\r
929<simpara>To report a bug, please send mail to\r
930<ulink url="mailto:mlton-devel@mlton.org"><literal>mlton-devel@mlton.org</literal></ulink>. Please include\r
931the complete SML program that caused the problem and a log of a\r
932compile of the program with <literal>-verbose 2</literal>. For large programs (over\r
933256K), please send an email containing the discussion text and a link\r
934to any large files.</simpara>\r
935<simpara>There are some <link linkend="UnresolvedBugs">UnresolvedBugs</link> that we don&#8217;t plan to fix.</simpara>\r
936<simpara>We also maintain a list of bugs found with each release.</simpara>\r
937<itemizedlist>\r
938<listitem>\r
939<simpara>\r
940<link linkend="Bugs20130715">Bugs20130715</link>\r
941</simpara>\r
942</listitem>\r
943<listitem>\r
944<simpara>\r
945<link linkend="Bugs20100608">Bugs20100608</link>\r
946</simpara>\r
947</listitem>\r
948<listitem>\r
949<simpara>\r
950<link linkend="Bugs20070826">Bugs20070826</link>\r
951</simpara>\r
952</listitem>\r
953<listitem>\r
954<simpara>\r
955<link linkend="Bugs20051202">Bugs20051202</link>\r
956</simpara>\r
957</listitem>\r
958<listitem>\r
959<simpara>\r
960<link linkend="Bugs20041109">Bugs20041109</link>\r
961</simpara>\r
962</listitem>\r
963</itemizedlist>\r
964<simpara><?asciidoc-pagebreak?></simpara>\r
965</section>\r
966<section id="Bugs20041109">\r
967<title>Bugs20041109</title>\r
968<simpara>Here are the known bugs in <link linkend="Release20041109">MLton 20041109</link>, listed\r
969in reverse chronological order of date reported.</simpara>\r
970<itemizedlist>\r
971<listitem>\r
972<simpara>\r
973<anchor id="Bugs20041109_bug17" xreflabel="[Bugs20041109_bug17]"/>\r
974 <literal>MLton.Finalizable.touch</literal> doesn&#8217;t necessarily keep values alive\r
975 long enough. Our SVN has a patch to the compiler. You must rebuild\r
976 the compiler in order for the patch to take effect.\r
977</simpara>\r
978<simpara>Thanks to Florian Weimer for reporting this bug.</simpara>\r
979</listitem>\r
980<listitem>\r
981<simpara>\r
982<anchor id="Bugs20041109_bug16" xreflabel="[Bugs20041109_bug16]"/>\r
983 A bug in an optimization pass may incorrectly transform a program\r
984 to flatten ref cells into their containing data structure, yielding a\r
985 type-error in the transformed program. Our CVS has a\r
986 <ulink url="http://mlton.org/cgi-bin/viewcvs.cgi/mlton/mlton/mlton/ssa/ref-flatten.fun.diff?r1=1.35&amp;r2=1.37">patch</ulink>\r
987 to the compiler. You must rebuild the compiler in order for the\r
988 patch to take effect.\r
989</simpara>\r
990<simpara>Thanks to <link linkend="VesaKarvonen">VesaKarvonen</link> for reporting this bug.</simpara>\r
991</listitem>\r
992<listitem>\r
993<simpara>\r
994<anchor id="Bugs20041109_bug15" xreflabel="[Bugs20041109_bug15]"/>\r
995 A bug in the front end mistakenly allows unary constructors to be\r
996 used without an argument in patterns. For example, the following\r
997 program is accepted, and triggers a large internal error.\r
998</simpara>\r
999<programlisting language="sml" linenumbering="unnumbered">fun f x = case x of SOME =&gt; true | _ =&gt; false</programlisting>\r
1000<simpara>We have fixed the problem in our CVS.</simpara>\r
1001<simpara>Thanks to William Lovas for reporting this bug.</simpara>\r
1002</listitem>\r
1003<listitem>\r
1004<simpara>\r
1005<anchor id="Bugs20041109_bug14" xreflabel="[Bugs20041109_bug14]"/>\r
1006 A bug in <literal>Posix.IO.{getlk,setlk,setlkw}</literal> causes a link-time error:\r
1007 <literal>undefined reference to Posix_IO_FLock_typ</literal>\r
1008 Our CVS has a\r
1009 <ulink url="http://mlton.org/cgi-bin/viewcvs.cgi/mlton/mlton/basis-library/posix/primitive.sml.diff?r1=1.34&amp;r2=1.35">patch</ulink>\r
1010 to the Basis Library implementation.\r
1011</simpara>\r
1012<simpara>Thanks to Adam Chlipala for reporting this bug.</simpara>\r
1013</listitem>\r
1014<listitem>\r
1015<simpara>\r
1016<anchor id="Bugs20041109_bug13" xreflabel="[Bugs20041109_bug13]"/>\r
1017 A bug can cause programs compiled with <literal>-profile alloc</literal> to\r
1018 segfault. Our CVS has a\r
1019 <ulink url="http://mlton.org/cgi-bin/viewcvs.cgi/mlton/mlton/mlton/backend/ssa-to-rssa.fun.diff?r1=1.106&amp;r2=1.107">patch</ulink>\r
1020 to the compiler. You must rebuild the compiler in order for the\r
1021 patch to take effect.\r
1022</simpara>\r
1023<simpara>Thanks to John Reppy for reporting this bug.</simpara>\r
1024</listitem>\r
1025<listitem>\r
1026<simpara>\r
1027<anchor id="Bugs20041109_bug12" xreflabel="[Bugs20041109_bug12]"/>\r
1028 A bug in an optimization pass may incorrectly flatten ref cells\r
1029 into their containing data structure, breaking the sharing between\r
1030 the cells. Our CVS has a\r
1031 <ulink url="http://mlton.org/cgi-bin/viewcvs.cgi/mlton/mlton/mlton/ssa/ref-flatten.fun.diff?r1=1.32&amp;r2=1.33">patch</ulink>\r
1032 to the compiler. You must rebuild the compiler in order for the\r
1033 patch to take effect.\r
1034</simpara>\r
1035<simpara>Thanks to Paul Govereau for reporting this bug.</simpara>\r
1036</listitem>\r
1037<listitem>\r
1038<simpara>\r
1039<anchor id="Bugs20041109_bug11" xreflabel="[Bugs20041109_bug11]"/>\r
1040 Some arrays or vectors, such as <literal>(char * char) vector</literal>, are\r
1041 incorrectly implemented, and will conflate the first and second\r
1042 components of each element. Our CVS has a\r
1043 <ulink url="http://mlton.org/cgi-bin/viewcvs.cgi/mlton/mlton/mlton/backend/packed-representation.fun.diff?r1=1.32&amp;r2=1.33">patch</ulink>\r
1044 to the compiler. You must rebuild the compiler in order for the\r
1045 patch to take effect.\r
1046</simpara>\r
1047<simpara>Thanks to Scott Cruzen for reporting this bug.</simpara>\r
1048</listitem>\r
1049<listitem>\r
1050<simpara>\r
1051<anchor id="Bugs20041109_bug10" xreflabel="[Bugs20041109_bug10]"/>\r
1052 <literal>Socket.Ctl.getLINGER</literal> and <literal>Socket.Ctl.setLINGER</literal>\r
1053 mistakenly raise <literal>Subscript</literal>.\r
1054 Our CVS has a\r
1055 <ulink url="http://mlton.org/cgi-bin/viewcvs.cgi/mlton/mlton/basis-library/net/socket.sml.diff?r1=1.14&amp;r2=1.15">patch</ulink>\r
1056 to the Basis Library implementation.\r
1057</simpara>\r
1058<simpara>Thanks to Ray Racine for reporting the bug.</simpara>\r
1059</listitem>\r
1060<listitem>\r
1061<simpara>\r
1062<anchor id="Bugs20041109_bug09" xreflabel="[Bugs20041109_bug09]"/>\r
1063 <link linkend="ConcurrentML">CML</link> <literal>Mailbox.send</literal> makes a call in the wrong atomic context.\r
1064 Our CVS has a <ulink url="http://mlton.org/cgi-bin/viewcvs.cgi/mlton/mlton/lib/cml/core-cml/mailbox.sml.diff?r1=1.3&amp;r2=1.4">patch</ulink>\r
1065 to the CML implementation.\r
1066</simpara>\r
1067</listitem>\r
1068<listitem>\r
1069<simpara>\r
1070<anchor id="Bugs20041109_bug08" xreflabel="[Bugs20041109_bug08]"/>\r
1071 <literal>OS.Path.joinDirFile</literal> and <literal>OS.Path.toString</literal> did not\r
1072 raise <literal>InvalidArc</literal> when they were supposed to. They now do.\r
1073 Our CVS has a <ulink url="http://mlton.org/cgi-bin/viewcvs.cgi/mlton/mlton/basis-library/system/path.sml.diff?r1=1.8&amp;r2=1.11">patch</ulink>\r
1074 to the Basis Library implementation.\r
1075</simpara>\r
1076<simpara>Thanks to Andreas Rossberg for reporting the bug.</simpara>\r
1077</listitem>\r
1078<listitem>\r
1079<simpara>\r
1080<anchor id="Bugs20041109_bug07" xreflabel="[Bugs20041109_bug07]"/>\r
1081 The front end incorrectly disallows sequences of expressions\r
1082 (separated by semicolons) after a topdec has already been processed.\r
1083 For example, the following is incorrectly rejected.\r
1084</simpara>\r
1085<programlisting language="sml" linenumbering="unnumbered">val x = 0;\r
1086ignore x;\r
1087ignore x;</programlisting>\r
1088<simpara>We have fixed the problem in our CVS.</simpara>\r
1089<simpara>Thanks to Andreas Rossberg for reporting the bug.</simpara>\r
1090</listitem>\r
1091<listitem>\r
1092<simpara>\r
1093<anchor id="Bugs20041109_bug06" xreflabel="[Bugs20041109_bug06]"/>\r
1094 The front end incorrectly disallows expansive <literal>val</literal>\r
1095 declarations that bind a type variable that doesn&#8217;t occur in the\r
1096 type of the value being bound. For example, the following is\r
1097 incorrectly rejected.\r
1098</simpara>\r
1099<programlisting language="sml" linenumbering="unnumbered">val 'a x = let exception E of 'a in () end</programlisting>\r
1100<simpara>We have fixed the problem in our CVS.</simpara>\r
1101<simpara>Thanks to Andreas Rossberg for reporting this bug.</simpara>\r
1102</listitem>\r
1103<listitem>\r
1104<simpara>\r
1105<anchor id="Bugs20041109_bug05" xreflabel="[Bugs20041109_bug05]"/>\r
1106 The x86 codegen fails to account for the possibility that a 64-bit\r
1107 move could interfere with itself (as simulated by 32-bit moves). We\r
1108 have fixed the problem in our CVS.\r
1109</simpara>\r
1110<simpara>Thanks to Scott Cruzen for reporting this bug.</simpara>\r
1111</listitem>\r
1112<listitem>\r
1113<simpara>\r
1114<anchor id="Bugs20041109_bug04" xreflabel="[Bugs20041109_bug04]"/>\r
1115 <literal>NetHostDB.scan</literal> and <literal>NetHostDB.fromString</literal> incorrectly\r
1116 raise an exception on internet addresses whose last component is a\r
1117 zero, e.g <literal>0.0.0.0</literal>. Our CVS has a\r
1118 <ulink url="http://mlton.org/cgi-bin/viewcvs.cgi/mlton/mlton/basis-library/net/net-host-db.sml.diff?r1=1.12&amp;r2=1.13">patch</ulink> to the Basis Library implementation.\r
1119</simpara>\r
1120<simpara>Thanks to Scott Cruzen for reporting this bug.</simpara>\r
1121</listitem>\r
1122<listitem>\r
1123<simpara>\r
1124<anchor id="Bugs20041109_bug03" xreflabel="[Bugs20041109_bug03]"/>\r
1125 <literal>StreamIO.inputLine</literal> has an off-by-one error causing it to drop\r
1126 the first character after a newline in some situations. Our CVS has a\r
1127 <ulink url="http://mlton.org/cgi-bin/viewcvs.cgi/mlton/mlton/basis-library/io/stream-io.fun.diff?r1=text&amp;tr1=1.29&amp;r2=text&amp;tr2=1.30&amp;diff_format=h">patch</ulink>.\r
1128 to the Basis Library implementation.\r
1129</simpara>\r
1130<simpara>Thanks to Scott Cruzen for reporting this bug.</simpara>\r
1131</listitem>\r
1132<listitem>\r
1133<simpara>\r
1134<anchor id="Bugs20041109_bug02" xreflabel="[Bugs20041109_bug02]"/>\r
1135 <literal>BinIO.getInstream</literal> and <literal>TextIO.getInstream</literal> are\r
1136 implemented incorrectly. This also impacts the behavior of\r
1137 <literal>BinIO.scanStream</literal> and <literal>TextIO.scanStream</literal>. If you (directly\r
1138 or indirectly) realize a <literal>TextIO.StreamIO.instream</literal> and do not\r
1139 (directly or indirectly) call <literal>TextIO.setInstream</literal> with a derived\r
1140 stream, you may lose input data. We have fixed the problem in our\r
1141 CVS.\r
1142</simpara>\r
1143<simpara>Thanks to <link linkend="WesleyTerpstra">WesleyTerpstra</link> for reporting this bug.</simpara>\r
1144</listitem>\r
1145<listitem>\r
1146<simpara>\r
1147<anchor id="Bugs20041109_bug01" xreflabel="[Bugs20041109_bug01]"/>\r
1148 <literal>Posix.ProcEnv.setpgid</literal> doesn&#8217;t work. If you compile a program\r
1149 that uses it, you will get a link time error\r
1150</simpara>\r
1151<screen>undefined reference to `Posix_ProcEnv_setpgid'</screen>\r
1152<simpara>The bug is due to <literal>Posix_ProcEnv_setpgid</literal> being omitted from the\r
1153 MLton runtime. We fixed the problem in our CVS by adding the\r
1154 following definition to <literal>runtime/Posix/ProcEnv/ProcEnv.c</literal></simpara>\r
1155<programlisting language="c" linenumbering="unnumbered">Int Posix_ProcEnv_setpgid (Pid p, Gid g) {\r
1156 return setpgid (p, g);\r
1157}</programlisting>\r
1158<simpara>Thanks to Tom Murphy for reporting this bug.</simpara>\r
1159</listitem>\r
1160</itemizedlist>\r
1161<simpara><?asciidoc-pagebreak?></simpara>\r
1162</section>\r
1163<section id="Bugs20051202">\r
1164<title>Bugs20051202</title>\r
1165<simpara>Here are the known bugs in <link linkend="Release20051202">MLton 20051202</link>, listed\r
1166in reverse chronological order of date reported.</simpara>\r
1167<itemizedlist>\r
1168<listitem>\r
1169<simpara>\r
1170<anchor id="Bugs20051202_bug16" xreflabel="[Bugs20051202_bug16]"/>\r
1171Bug in the <ulink url="http://www.standardml.org/Basis/real.html#SIG:REAL.fmt:VAL"><literal>Real<emphasis>&lt;N&gt;</emphasis>.fmt</literal></ulink>, <ulink url="http://www.standardml.org/Basis/real.html#SIG:REAL.fromString:VAL"><literal>Real<emphasis>&lt;N&gt;</emphasis>.fromString</literal></ulink>, <ulink url="http://www.standardml.org/Basis/real.html#SIG:REAL.scan:VAL"><literal>Real<emphasis>&lt;N&gt;</emphasis>.scan</literal></ulink>, and <ulink url="http://www.standardml.org/Basis/real.html#SIG:REAL.toString:VAL"><literal>Real<emphasis>&lt;N&gt;</emphasis>.toString</literal></ulink> functions of the <link linkend="BasisLibrary">Basis Library</link> implementation. These functions were using <literal>TO_NEAREST</literal> semantics, but should obey the current rounding mode. (Only <literal>Real<emphasis>&lt;N&gt;</emphasis>.fmt StringCvt.EXACT</literal>, <literal>Real<emphasis>&lt;N&gt;</emphasis>.fromDecimal</literal>, and <literal>Real<emphasis>&lt;N&gt;</emphasis>.toDecimal</literal> are specified to override the current rounding mode with <literal>TO_NEAREST</literal> semantics.)\r
1172</simpara>\r
1173<simpara>Thanks to Sean McLaughlin for the bug report.</simpara>\r
1174<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r5827"><literal>r5827</literal></ulink>.</simpara>\r
1175</listitem>\r
1176<listitem>\r
1177<simpara>\r
1178<anchor id="Bugs20051202_bug15" xreflabel="[Bugs20051202_bug15]"/>\r
1179Bug in the treatment of floating-point operations. Floating-point operations depend on the current rounding mode, but were being treated as pure.\r
1180</simpara>\r
1181<simpara>Thanks to Sean McLaughlin for the bug report.</simpara>\r
1182<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r5794"><literal>r5794</literal></ulink>.</simpara>\r
1183</listitem>\r
1184<listitem>\r
1185<simpara>\r
1186<anchor id="Bugs20051202_bug14" xreflabel="[Bugs20051202_bug14]"/>\r
1187Bug in the <ulink url="http://www.standardml.org/Basis/real.html#SIG:REAL.toInt:VAL"><literal>Real32.toInt</literal></ulink> function of the <link linkend="BasisLibrary">Basis Library</link> implementation could lead incorrect results when applied to a <literal>Real32.real</literal> value numerically close to <literal>valOf(Int.maxInt)</literal>.\r
1188</simpara>\r
1189<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r5764"><literal>r5764</literal></ulink>.</simpara>\r
1190</listitem>\r
1191<listitem>\r
1192<simpara>\r
1193<anchor id="Bugs20051202_bug13" xreflabel="[Bugs20051202_bug13]"/>\r
1194The <ulink url="http://www.standardml.org/Basis/socket.html"><literal>Socket</literal></ulink> structure of the <link linkend="BasisLibrary">Basis Library</link> implementation used <literal>andb</literal> rather than <literal>orb</literal> to unmarshal socket options (for <literal>Socket.Ctl.get<emphasis>&lt;OPT&gt;</emphasis></literal> functions).\r
1195</simpara>\r
1196<simpara>Thanks to Anders Petersson for the bug report and patch.</simpara>\r
1197<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r5735"><literal>r5735</literal></ulink>.</simpara>\r
1198</listitem>\r
1199<listitem>\r
1200<simpara>\r
1201<anchor id="Bugs20051202_bug12" xreflabel="[Bugs20051202_bug12]"/>\r
1202Bug in the <ulink url="http://www.standardml.org/Basis/date.html"><literal>Date</literal></ulink> structure of the <link linkend="BasisLibrary">Basis Library</link> implementation yielded some functions that would erroneously raise <literal>Date</literal> when applied to a year before 1900.\r
1203</simpara>\r
1204<simpara>Thanks to Joe Hurd for the bug report.</simpara>\r
1205<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r5732"><literal>r5732</literal></ulink>.</simpara>\r
1206</listitem>\r
1207<listitem>\r
1208<simpara>\r
1209<anchor id="Bugs20051202_bug11" xreflabel="[Bugs20051202_bug11]"/>\r
1210Bug in monomorphisation pass could exhibit the error <literal>Type error: type mismatch</literal>.\r
1211</simpara>\r
1212<simpara>Thanks to Vesa Karvonen for the bug report.</simpara>\r
1213<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r5731"><literal>r5731</literal></ulink>.</simpara>\r
1214</listitem>\r
1215<listitem>\r
1216<simpara>\r
1217<anchor id="Bugs20051202_bug10" xreflabel="[Bugs20051202_bug10]"/>\r
1218The <ulink url="http://www.standardml.org/Basis/pack-float.html#SIG:PACK_REAL.toBytes:VAL"><literal>PackReal<emphasis>&lt;N&gt;</emphasis>.toBytes</literal></ulink> function in the <link linkend="BasisLibrary">Basis Library</link> implementation incorrectly shared (and mutated) the result vector.\r
1219</simpara>\r
1220<simpara>Thanks to Eric McCorkle for the bug report and patch.</simpara>\r
1221<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r5281"><literal>r5281</literal></ulink>.</simpara>\r
1222</listitem>\r
1223<listitem>\r
1224<simpara>\r
1225<anchor id="Bugs20051202_bug09" xreflabel="[Bugs20051202_bug09]"/>\r
1226Bug in elaboration of FFI forms. Using a unary FFI types (e.g., <literal>array</literal>, <literal>ref</literal>, <literal>vector</literal>) in places where <literal>MLton.Pointer.t</literal> was required would lead to an internal error <literal>TypeError</literal>.\r
1227</simpara>\r
1228<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r4890"><literal>r4890</literal></ulink>.</simpara>\r
1229</listitem>\r
1230<listitem>\r
1231<simpara>\r
1232<anchor id="Bugs20051202_bug08" xreflabel="[Bugs20051202_bug08]"/>\r
1233The <ulink url="http://www.standardml.org/Basis/mono-vector.html"><literal>MONO_VECTOR</literal></ulink> signature of the <link linkend="BasisLibrary">Basis Library</link> implementation incorrectly omits the specification of <literal>find</literal>.\r
1234</simpara>\r
1235<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r4707"><literal>r4707</literal></ulink>.</simpara>\r
1236</listitem>\r
1237<listitem>\r
1238<simpara>\r
1239<anchor id="Bugs20051202_bug07" xreflabel="[Bugs20051202_bug07]"/>\r
1240The optimizer reports an internal error (<literal>TypeError</literal>) when an imported C function is called but not used.\r
1241</simpara>\r
1242<simpara>Thanks to "jq" for the bug report.</simpara>\r
1243<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r4690"><literal>r4690</literal></ulink>.</simpara>\r
1244</listitem>\r
1245<listitem>\r
1246<simpara>\r
1247<anchor id="Bugs20051202_bug06" xreflabel="[Bugs20051202_bug06]"/>\r
1248Bug in pass to flatten data structures.\r
1249</simpara>\r
1250<simpara>Thanks to Joe Hurd for the bug report.</simpara>\r
1251<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r4662"><literal>r4662</literal></ulink>.</simpara>\r
1252</listitem>\r
1253<listitem>\r
1254<simpara>\r
1255<anchor id="Bugs20051202_bug05" xreflabel="[Bugs20051202_bug05]"/>\r
1256The native codegen&#8217;s implementation of the C-calling convention failed to widen 16-bit arguments to 32-bits.\r
1257</simpara>\r
1258<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r4631"><literal>r4631</literal></ulink>.</simpara>\r
1259</listitem>\r
1260<listitem>\r
1261<simpara>\r
1262<anchor id="Bugs20051202_bug04" xreflabel="[Bugs20051202_bug04]"/>\r
1263The <ulink url="http://www.standardml.org/Basis/pack-float.html"><literal>PACK_REAL</literal></ulink> structures of the <link linkend="BasisLibrary">Basis Library</link> implementation used byte, rather than element, indexing.\r
1264</simpara>\r
1265<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r4411"><literal>r4411</literal></ulink>.</simpara>\r
1266</listitem>\r
1267<listitem>\r
1268<simpara>\r
1269<anchor id="Bugs20051202_bug03" xreflabel="[Bugs20051202_bug03]"/>\r
1270<literal>MLton.share</literal> could cause a segmentation fault.\r
1271</simpara>\r
1272<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r4400"><literal>r4400</literal></ulink>.</simpara>\r
1273</listitem>\r
1274<listitem>\r
1275<simpara>\r
1276<anchor id="Bugs20051202_bug02" xreflabel="[Bugs20051202_bug02]"/>\r
1277The SSA simplifier could eliminate an irredundant test.\r
1278</simpara>\r
1279<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r4370"><literal>r4370</literal></ulink>.</simpara>\r
1280</listitem>\r
1281<listitem>\r
1282<simpara>\r
1283<anchor id="Bugs20051202_bug01" xreflabel="[Bugs20051202_bug01]"/>\r
1284A program with a very large number of functors could exhibit the error <literal>ElaborateEnv.functorClosure: firstTycons</literal>.\r
1285</simpara>\r
1286<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r4344"><literal>r4344</literal></ulink>.</simpara>\r
1287</listitem>\r
1288</itemizedlist>\r
1289<simpara><?asciidoc-pagebreak?></simpara>\r
1290</section>\r
1291<section id="Bugs20070826">\r
1292<title>Bugs20070826</title>\r
1293<simpara>Here are the known bugs in <link linkend="Release20070826">MLton 20070826</link>, listed\r
1294in reverse chronological order of date reported.</simpara>\r
1295<itemizedlist>\r
1296<listitem>\r
1297<simpara>\r
1298<anchor id="Bugs20070826_bug25" xreflabel="[Bugs20070826_bug25]"/>\r
1299Bug in the mark-compact garbage collector where the C library&#8217;s <literal>memcpy</literal> was used to move objects during the compaction phase; this could lead to heap corruption and segmentation faults with newer versions of gcc and/or glibc, which assume that src and dst in a <literal>memcpy</literal> do not overlap.\r
1300</simpara>\r
1301<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r7461"><literal>r7461</literal></ulink>.</simpara>\r
1302</listitem>\r
1303<listitem>\r
1304<simpara>\r
1305<anchor id="Bugs20070826_bug24" xreflabel="[Bugs20070826_bug24]"/>\r
1306Bug in elaboration of <literal>datatype</literal> declarations with <literal>withtype</literal> bindings.\r
1307</simpara>\r
1308<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r7434"><literal>r7434</literal></ulink>.</simpara>\r
1309</listitem>\r
1310<listitem>\r
1311<simpara>\r
1312<anchor id="Bugs20070826_bug23" xreflabel="[Bugs20070826_bug23]"/>\r
1313Performance bug in <link linkend="RefFlatten">RefFlatten</link> optimization pass.\r
1314</simpara>\r
1315<simpara>Thanks to Reactive Systems for the bug report.</simpara>\r
1316<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r7379"><literal>r7379</literal></ulink>.</simpara>\r
1317</listitem>\r
1318<listitem>\r
1319<simpara>\r
1320<anchor id="Bugs20070826_bug22" xreflabel="[Bugs20070826_bug22]"/>\r
1321Performance bug in <link linkend="SimplifyTypes">SimplifyTypes</link> optimization pass.\r
1322</simpara>\r
1323<simpara>Thanks to Reactive Systems for the bug report.</simpara>\r
1324<simpara>Fixed by revisions <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r7377"><literal>r7377</literal></ulink> and <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r7378"><literal>r7378</literal></ulink>.</simpara>\r
1325</listitem>\r
1326<listitem>\r
1327<simpara>\r
1328<anchor id="Bugs20070826_bug21" xreflabel="[Bugs20070826_bug21]"/>\r
1329Bug in amd64 codegen register allocation of indirect C calls.\r
1330</simpara>\r
1331<simpara>Thanks to David Hansel for the bug report.</simpara>\r
1332<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r7368"><literal>r7368</literal></ulink>.</simpara>\r
1333</listitem>\r
1334<listitem>\r
1335<simpara>\r
1336<anchor id="Bugs20070826_bug20" xreflabel="[Bugs20070826_bug20]"/>\r
1337Bug in <literal>IntInf.scan</literal> and <literal>IntInf.fromString</literal> where leading spaces were only accepted if the stream had an explicit sign character.\r
1338</simpara>\r
1339<simpara>Thanks to David Hansel for the bug report.</simpara>\r
1340<simpara>Fixed by revisions <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r7227"><literal>r7227</literal></ulink> and <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r7230"><literal>r7230</literal></ulink>.</simpara>\r
1341</listitem>\r
1342<listitem>\r
1343<simpara>\r
1344<anchor id="Bugs20070826_bug19" xreflabel="[Bugs20070826_bug19]"/>\r
1345Bug in <literal>IntInf.~&gt;&gt;</literal> that could cause a <literal>glibc</literal> assertion.\r
1346</simpara>\r
1347<simpara>Fixed by revisions <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r7083"><literal>r7083</literal></ulink>, <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r7084"><literal>r7084</literal></ulink>, and <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r7085"><literal>r7085</literal></ulink>.</simpara>\r
1348</listitem>\r
1349<listitem>\r
1350<simpara>\r
1351<anchor id="Bugs20070826_bug18" xreflabel="[Bugs20070826_bug18]"/>\r
1352Bug in the return type of <literal>MLton.Process.reap</literal>.\r
1353</simpara>\r
1354<simpara>Thanks to Risto Saarelma for the bug report.</simpara>\r
1355<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r7029"><literal>r7029</literal></ulink>.</simpara>\r
1356</listitem>\r
1357<listitem>\r
1358<simpara>\r
1359<anchor id="Bugs20070826_bug17" xreflabel="[Bugs20070826_bug17]"/>\r
1360Bug in <literal>MLton.size</literal> and <literal>MLton.share</literal> when tracing the current stack.\r
1361</simpara>\r
1362<simpara>Fixed by revisions <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r6978"><literal>r6978</literal></ulink>, <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r6981"><literal>r6981</literal></ulink>, <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r6988"><literal>r6988</literal></ulink>, <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r6989"><literal>r6989</literal></ulink>, and <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r6990"><literal>r6990</literal></ulink>.</simpara>\r
1363</listitem>\r
1364<listitem>\r
1365<simpara>\r
1366<anchor id="Bugs20070826_bug16" xreflabel="[Bugs20070826_bug16]"/>\r
1367Bug in nested <literal>_export</literal>/<literal>_import</literal> functions.\r
1368</simpara>\r
1369<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r6919"><literal>r6919</literal></ulink>.</simpara>\r
1370</listitem>\r
1371<listitem>\r
1372<simpara>\r
1373<anchor id="Bugs20070826_bug15" xreflabel="[Bugs20070826_bug15]"/>\r
1374Bug in the name mangling of <literal>_import</literal>-ed functions with the <literal>stdcall</literal> convention.\r
1375</simpara>\r
1376<simpara>Thanks to Lars Bergstrom for the bug report.</simpara>\r
1377<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r6672"><literal>r6672</literal></ulink>.</simpara>\r
1378</listitem>\r
1379<listitem>\r
1380<simpara>\r
1381<anchor id="Bugs20070826_bug14" xreflabel="[Bugs20070826_bug14]"/>\r
1382Bug in Windows code to page the heap to disk when unable to grow the heap to a desired size.\r
1383</simpara>\r
1384<simpara>Thanks to Sami Evangelista for the bug report.</simpara>\r
1385<simpara>Fixed by revisions <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r6600"><literal>r6600</literal></ulink> and <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r6624"><literal>r6624</literal></ulink>.</simpara>\r
1386</listitem>\r
1387<listitem>\r
1388<simpara>\r
1389<anchor id="Bugs20070826_bug13" xreflabel="[Bugs20070826_bug13]"/>\r
1390Bug in \*NIX code to page the heap to disk when unable to grow the heap to a desired size.\r
1391</simpara>\r
1392<simpara>Thanks to Nicolas Bertolotti for the bug report and patch.</simpara>\r
1393<simpara>Fixed by revisions <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r6596"><literal>r6596</literal></ulink> and <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r6600"><literal>r6600</literal></ulink>.</simpara>\r
1394</listitem>\r
1395<listitem>\r
1396<simpara>\r
1397<anchor id="Bugs20070826_bug12" xreflabel="[Bugs20070826_bug12]"/>\r
1398Space-safety bug in pass to <link linkend="RefFlatten">flatten refs</link> into containing data structure.\r
1399</simpara>\r
1400<simpara>Thanks to Daniel Spoonhower for the bug report and initial diagnosis and patch.</simpara>\r
1401<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r6395"><literal>r6395</literal></ulink>.</simpara>\r
1402</listitem>\r
1403<listitem>\r
1404<simpara>\r
1405<anchor id="Bugs20070826_bug11" xreflabel="[Bugs20070826_bug11]"/>\r
1406Bug in the frontend that rejected <literal>op longvid</literal> patterns and expressions.\r
1407</simpara>\r
1408<simpara>Thanks to Florian Weimer for the bug report.</simpara>\r
1409<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r6347"><literal>r6347</literal></ulink>.</simpara>\r
1410</listitem>\r
1411<listitem>\r
1412<simpara>\r
1413<anchor id="Bugs20070826_bug10" xreflabel="[Bugs20070826_bug10]"/>\r
1414Bug in the <ulink url="http://www.standardml.org/Basis/imperative-io.html#SIG:IMPERATIVE_IO.canInput:VAL"><literal>IMPERATIVE_IO.canInput</literal></ulink> function of the <link linkend="BasisLibrary">Basis Library</link> implementation.\r
1415</simpara>\r
1416<simpara>Thanks to Ville Laurikari for the bug report.</simpara>\r
1417<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r6261"><literal>r6261</literal></ulink>.</simpara>\r
1418</listitem>\r
1419<listitem>\r
1420<simpara>\r
1421<anchor id="Bugs20070826_bug09" xreflabel="[Bugs20070826_bug09]"/>\r
1422Bug in algebraic simplification of real primitives. <ulink url="http://www.standardml.org/Basis/real.html#SIG:REAL.\|@LTE\|:VAL"><literal>REAL<emphasis>&lt;N&gt;</emphasis>.&lt;=(x, x)</literal></ulink> is <literal>false</literal> when <literal>x</literal> is NaN.\r
1423</simpara>\r
1424<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r6242"><literal>r6242</literal></ulink>.</simpara>\r
1425</listitem>\r
1426<listitem>\r
1427<simpara>\r
1428<anchor id="Bugs20070826_bug08" xreflabel="[Bugs20070826_bug08]"/>\r
1429Bug in the FFI visible representation of <literal>Int16.int ref</literal> (and references of other primitive types smaller than 32-bits) on big-endian platforms.\r
1430</simpara>\r
1431<simpara>Thanks to Dave Herman for the bug report.</simpara>\r
1432<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r6267"><literal>r6267</literal></ulink>.</simpara>\r
1433</listitem>\r
1434<listitem>\r
1435<simpara>\r
1436<anchor id="Bugs20070826_bug07" xreflabel="[Bugs20070826_bug07]"/>\r
1437Bug in type inference of flexible records. This would later cause the compiler to raise the <literal>TypeError</literal> exception.\r
1438</simpara>\r
1439<simpara>Thanks to Wesley Terpstra for the bug report.</simpara>\r
1440<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r6229"><literal>r6229</literal></ulink>.</simpara>\r
1441</listitem>\r
1442<listitem>\r
1443<simpara>\r
1444<anchor id="Bugs20070826_bug06" xreflabel="[Bugs20070826_bug06]"/>\r
1445Bug in cross-compilation of <literal>gdtoa</literal> library.\r
1446</simpara>\r
1447<simpara>Thanks to Wesley Terpstra for the bug report and patch.</simpara>\r
1448<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r6620"><literal>r6620</literal></ulink>.</simpara>\r
1449</listitem>\r
1450<listitem>\r
1451<simpara>\r
1452<anchor id="Bugs20070826_bug05" xreflabel="[Bugs20070826_bug05]"/>\r
1453Bug in pass to <link linkend="RefFlatten">flatten refs</link> into containing data structure.\r
1454</simpara>\r
1455<simpara>Thanks to Ruy Ley-Wild for the bug report.</simpara>\r
1456<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r6191"><literal>r6191</literal></ulink>.</simpara>\r
1457</listitem>\r
1458<listitem>\r
1459<simpara>\r
1460<anchor id="Bugs20070826_bug04" xreflabel="[Bugs20070826_bug04]"/>\r
1461Bug in the handling of weak pointers by the mark-compact garbage collector.\r
1462</simpara>\r
1463<simpara>Thanks to Sean McLaughlin for the bug report and Florian Weimer for the initial diagnosis.</simpara>\r
1464<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r6183"><literal>r6183</literal></ulink>.</simpara>\r
1465</listitem>\r
1466<listitem>\r
1467<simpara>\r
1468<anchor id="Bugs20070826_bug03" xreflabel="[Bugs20070826_bug03]"/>\r
1469Bug in the elaboration of structures with signature constraints. This would later cause the compiler to raise the <literal>TypeError</literal> exception.\r
1470</simpara>\r
1471<simpara>Thanks to Vesa Karvonen for the bug report.</simpara>\r
1472<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r6046"><literal>r6046</literal></ulink>.</simpara>\r
1473</listitem>\r
1474<listitem>\r
1475<simpara>\r
1476<anchor id="Bugs20070826_bug02" xreflabel="[Bugs20070826_bug02]"/>\r
1477Bug in the interaction of <literal>_export</literal>-ed functions and signal handlers.\r
1478</simpara>\r
1479<simpara>Thanks to Sean McLaughlin for the bug report.</simpara>\r
1480<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r6013"><literal>r6013</literal></ulink>.</simpara>\r
1481</listitem>\r
1482<listitem>\r
1483<simpara>\r
1484<anchor id="Bugs20070826_bug01" xreflabel="[Bugs20070826_bug01]"/>\r
1485Bug in the implementation of <literal>_export</literal>-ed functions using the <literal>char</literal> type, leading to a linker error.\r
1486</simpara>\r
1487<simpara>Thanks to Katsuhiro Ueno for the bug report.</simpara>\r
1488<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r5999"><literal>r5999</literal></ulink>.</simpara>\r
1489</listitem>\r
1490</itemizedlist>\r
1491<simpara><?asciidoc-pagebreak?></simpara>\r
1492</section>\r
1493<section id="Bugs20100608">\r
1494<title>Bugs20100608</title>\r
1495<simpara>Here are the known bugs in <link linkend="Release20100608">MLton 20100608</link>, listed\r
1496in reverse chronological order of date reported.</simpara>\r
1497<itemizedlist>\r
1498<listitem>\r
1499<simpara>\r
1500<anchor id="Bugs20100608_bug11" xreflabel="[Bugs20100608_bug11]"/>\r
1501Bugs in <literal>REAL.signBit</literal>, <literal>REAL.copySign</literal>, and <literal>REAL.toDecimal</literal>/<literal>REAL.fromDecimal</literal>.\r
1502</simpara>\r
1503<simpara>Thanks to Phil Clayton for the bug report and examples.</simpara>\r
1504<simpara>Fixed by revisions <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r7571"><literal>r7571</literal></ulink>, <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r7572"><literal>r7572</literal></ulink>, and <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r7573"><literal>r7573</literal></ulink>.</simpara>\r
1505</listitem>\r
1506<listitem>\r
1507<simpara>\r
1508<anchor id="Bugs20100608_bug10" xreflabel="[Bugs20100608_bug10]"/>\r
1509Bug in elaboration of type variables with and without equality status.\r
1510</simpara>\r
1511<simpara>Thanks to Rob Simmons for the bug report and examples.</simpara>\r
1512<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r7565"><literal>r7565</literal></ulink>.</simpara>\r
1513</listitem>\r
1514<listitem>\r
1515<simpara>\r
1516<anchor id="Bugs20100608_bug09" xreflabel="[Bugs20100608_bug09]"/>\r
1517Bug in <link linkend="Redundant">redundant</link> <link linkend="SSA">SSA</link> optimization.\r
1518</simpara>\r
1519<simpara>Thanks to Lars Magnusson for the bug report and example.</simpara>\r
1520<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r7561"><literal>r7561</literal></ulink>.</simpara>\r
1521</listitem>\r
1522<listitem>\r
1523<simpara>\r
1524<anchor id="Bugs20100608_bug08" xreflabel="[Bugs20100608_bug08]"/>\r
1525Bug in <link linkend="SSA">SSA</link>/<link linkend="SSA2">SSA2</link> <link linkend="Shrink">shrinker</link> that could erroneously turn a non-tail function call with a <literal>Bug</literal> transfer as its continuation into a tail function call.\r
1526</simpara>\r
1527<simpara>Thanks to Lars Bergstrom for the bug report.</simpara>\r
1528<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r7546"><literal>r7546</literal></ulink>.</simpara>\r
1529</listitem>\r
1530<listitem>\r
1531<simpara>\r
1532<anchor id="Bugs20100608_bug07" xreflabel="[Bugs20100608_bug07]"/>\r
1533Bug in translation from <link linkend="SSA2">SSA2</link> to <link linkend="RSSA">RSSA</link> with <literal>case</literal> expressions over non-primitive-sized words.\r
1534</simpara>\r
1535<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r7544"><literal>r7544</literal></ulink>.</simpara>\r
1536</listitem>\r
1537<listitem>\r
1538<simpara>\r
1539<anchor id="Bugs20100608_bug06" xreflabel="[Bugs20100608_bug06]"/>\r
1540Bug with <link linkend="SSA">SSA</link>/<link linkend="SSA2">SSA2</link> type checking of case expressions over words.\r
1541</simpara>\r
1542<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r7542"><literal>r7542</literal></ulink>.</simpara>\r
1543</listitem>\r
1544<listitem>\r
1545<simpara>\r
1546<anchor id="Bugs20100608_bug05" xreflabel="[Bugs20100608_bug05]"/>\r
1547Bug with treatment of <literal>as</literal>-patterns, which should not allow the redefinition of constructor status.\r
1548</simpara>\r
1549<simpara>Thanks to Michael Norrish for the bug report.</simpara>\r
1550<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r7530"><literal>r7530</literal></ulink>.</simpara>\r
1551</listitem>\r
1552<listitem>\r
1553<simpara>\r
1554<anchor id="Bugs20100608_bug04" xreflabel="[Bugs20100608_bug04]"/>\r
1555Bug with treatment of <literal>nan</literal> in <link linkend="CommonSubexp">common subexpression elimination</link> <link linkend="SSA">SSA</link> optimization.\r
1556</simpara>\r
1557<simpara>Thanks to Alexandre Hamez for the bug report.</simpara>\r
1558<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r7503"><literal>r7503</literal></ulink>.</simpara>\r
1559</listitem>\r
1560<listitem>\r
1561<simpara>\r
1562<anchor id="Bugs20100608_bug03" xreflabel="[Bugs20100608_bug03]"/>\r
1563Bug in translation from <link linkend="SSA2">SSA2</link> to <link linkend="RSSA">RSSA</link> with weak pointers.\r
1564</simpara>\r
1565<simpara>Thanks to Alexandre Hamez for the bug report.</simpara>\r
1566<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r7502"><literal>r7502</literal></ulink>.</simpara>\r
1567</listitem>\r
1568<listitem>\r
1569<simpara>\r
1570<anchor id="Bugs20100608_bug02" xreflabel="[Bugs20100608_bug02]"/>\r
1571Bug in amd64 codegen calling convention for varargs C calls.\r
1572</simpara>\r
1573<simpara>Thanks to <link linkend="HenryCejtin">HenryCejtin</link> for the bug report and <link linkend="WesleyTerpstra">WesleyTerpstra</link> for the initial diagnosis.</simpara>\r
1574<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r7501"><literal>r7501</literal></ulink>.</simpara>\r
1575</listitem>\r
1576<listitem>\r
1577<simpara>\r
1578<anchor id="Bugs20100608_bug01" xreflabel="[Bugs20100608_bug01]"/>\r
1579Bug in comment-handling in lexer for <link linkend="MLYacc">MLYacc</link>'s input language.\r
1580</simpara>\r
1581<simpara>Thanks to Michael Norrish for the bug report and patch.</simpara>\r
1582<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r7500"><literal>r7500</literal></ulink>.</simpara>\r
1583</listitem>\r
1584<listitem>\r
1585<simpara>\r
1586<anchor id="Bugs20100608_bug00" xreflabel="[Bugs20100608_bug00]"/>\r
1587Bug in elaboration of function clauses with different numbers of arguments that would raise an uncaught <literal>Subscript</literal> exception.\r
1588</simpara>\r
1589<simpara>Fixed by revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r75497"><literal>r75497</literal></ulink>.</simpara>\r
1590</listitem>\r
1591</itemizedlist>\r
1592<simpara><?asciidoc-pagebreak?></simpara>\r
1593</section>\r
1594<section id="Bugs20130715">\r
1595<title>Bugs20130715</title>\r
1596<simpara>Here are the known bugs in <link linkend="Release20130715">MLton 20130715</link>, listed\r
1597in reverse chronological order of date reported.</simpara>\r
1598<itemizedlist>\r
1599<listitem>\r
1600<simpara>\r
1601<anchor id="Bugs20130715_bug06" xreflabel="[Bugs20130715_bug06]"/>\r
1602Bug with simultaneous <literal>sharing</literal> of multiple structures.\r
1603</simpara>\r
1604<simpara>Fixed by commit <ulink url="https://github.com/MLton/mlton/commit/9cb5164f6"><literal>9cb5164f6</literal></ulink>.</simpara>\r
1605</listitem>\r
1606<listitem>\r
1607<simpara>\r
1608<anchor id="Bugs20130715_bug05" xreflabel="[Bugs20130715_bug05]"/>\r
1609Minor bug with exception replication.\r
1610</simpara>\r
1611<simpara>Fixed by commit <ulink url="https://github.com/MLton/mlton/commit/1c89c42f6"><literal>1c89c42f6</literal></ulink>.</simpara>\r
1612</listitem>\r
1613<listitem>\r
1614<simpara>\r
1615<anchor id="Bugs20130715_bug04" xreflabel="[Bugs20130715_bug04]"/>\r
1616Minor bug erroneously accepting symbolic identifiers for strid, sigid, and fctid\r
1617and erroneously accepting symbolic identifiers before <literal>.</literal> in long identifiers.\r
1618</simpara>\r
1619<simpara>Fixed by commit <ulink url="https://github.com/MLton/mlton/commit/9a56be647"><literal>9a56be647</literal></ulink>.</simpara>\r
1620</listitem>\r
1621<listitem>\r
1622<simpara>\r
1623<anchor id="Bugs20130715_bug03" xreflabel="[Bugs20130715_bug03]"/>\r
1624Minor bug in precedence parsing of function clauses.\r
1625</simpara>\r
1626<simpara>Fixed by commit <ulink url="https://github.com/MLton/mlton/commit/1a6d25ec9"><literal>1a6d25ec9</literal></ulink>.</simpara>\r
1627</listitem>\r
1628<listitem>\r
1629<simpara>\r
1630<anchor id="Bugs20130715_bug02" xreflabel="[Bugs20130715_bug02]"/>\r
1631Performance bug in creation of worker threads to service calls of <literal>_export</literal>-ed\r
1632functions.\r
1633</simpara>\r
1634<simpara>Thanks to Bernard Berthomieu for the bug report.</simpara>\r
1635<simpara>Fixed by commit <ulink url="https://github.com/MLton/mlton/commit/97c2bdf1d"><literal>97c2bdf1d</literal></ulink>.</simpara>\r
1636</listitem>\r
1637<listitem>\r
1638<simpara>\r
1639<anchor id="Bugs20130715_bug01" xreflabel="[Bugs20130715_bug01]"/>\r
1640Bug in <literal>MLton.IntInf.fromRep</literal> that could yield values that violate the <literal>IntInf</literal>\r
1641representation invariants.\r
1642</simpara>\r
1643<simpara>Thanks to Rob Simmons for the bug report.</simpara>\r
1644<simpara>Fixed by commit <ulink url="https://github.com/MLton/mlton/commit/3add91eda"><literal>3add91eda</literal></ulink>.</simpara>\r
1645</listitem>\r
1646<listitem>\r
1647<simpara>\r
1648<anchor id="Bugs20130715_bug00" xreflabel="[Bugs20130715_bug00]"/>\r
1649Bug in equality status of some arrays, vectors, and slices in Basis Library\r
1650implementation.\r
1651</simpara>\r
1652<simpara>Fixed by commit <ulink url="https://github.com/MLton/mlton/commit/a7ed9cbf1"><literal>a7ed9cbf1</literal></ulink>.</simpara>\r
1653</listitem>\r
1654</itemizedlist>\r
1655<simpara><?asciidoc-pagebreak?></simpara>\r
1656</section>\r
1657<section id="Bugs20180207">\r
1658<title>Bugs20180207</title>\r
1659<simpara>Here are the known bugs in <link linkend="Release20180207">MLton 20180207</link>, listed\r
1660in reverse chronological order of date reported.</simpara>\r
1661<simpara><?asciidoc-pagebreak?></simpara>\r
1662</section>\r
1663<section id="CallGraph">\r
1664<title>CallGraph</title>\r
1665<simpara>For easier visualization of <link linkend="Profiling">profiling</link> data, <literal>mlprof</literal> can\r
1666create a call graph of the program in dot format, from which you can\r
1667use the <ulink url="http://www.research.att.com/sw/tools/graphviz/">graphviz</ulink>\r
1668software package to create a PostScript or PNG graph. For example,</simpara>\r
1669<screen>mlprof -call-graph foo.dot foo mlmon.out</screen>\r
1670<simpara>will create <literal>foo.dot</literal> with a complete call graph. For each source\r
1671function, there will be one node in the graph that contains the\r
1672function name (and source position with <literal>-show-line true</literal>), as\r
1673well as the percentage of ticks. If you want to create a call graph\r
1674for your program without any profiling data, you can simply call\r
1675<literal>mlprof</literal> without any <literal>mlmon.out</literal> files, as in</simpara>\r
1676<screen>mlprof -call-graph foo.dot foo</screen>\r
1677<simpara>Because SML has higher-order functions, the call graph is is dependent\r
1678on MLton&#8217;s analysis of which functions call each other. This analysis\r
1679depends on many implementation details and might display spurious\r
1680edges that a human could conclude are impossible. However, in\r
1681practice, the call graphs tend to be very accurate.</simpara>\r
1682<simpara>Because call graphs can get big, <literal>mlprof</literal> provides the <literal>-keep</literal> option\r
1683to specify the nodes that you would like to see. This option also\r
1684controls which functions appear in the table that <literal>mlprof</literal> prints.\r
1685The argument to <literal>-keep</literal> is an expression describing a set of source\r
1686functions (i.e. graph nodes). The expression <emphasis>e</emphasis> should be of the\r
1687following form.</simpara>\r
1688<itemizedlist>\r
1689<listitem>\r
1690<simpara>\r
1691<literal>all</literal>\r
1692</simpara>\r
1693</listitem>\r
1694<listitem>\r
1695<simpara>\r
1696<literal>"<emphasis>s</emphasis>"</literal>\r
1697</simpara>\r
1698</listitem>\r
1699<listitem>\r
1700<simpara>\r
1701<literal>(and <emphasis>e &#8230;</emphasis>)</literal>\r
1702</simpara>\r
1703</listitem>\r
1704<listitem>\r
1705<simpara>\r
1706<literal>(from <emphasis>e</emphasis>)</literal>\r
1707</simpara>\r
1708</listitem>\r
1709<listitem>\r
1710<simpara>\r
1711<literal>(not <emphasis>e</emphasis>)</literal>\r
1712</simpara>\r
1713</listitem>\r
1714<listitem>\r
1715<simpara>\r
1716<literal>(or <emphasis>e</emphasis>)</literal>\r
1717</simpara>\r
1718</listitem>\r
1719<listitem>\r
1720<simpara>\r
1721<literal>(pred <emphasis>e</emphasis>)</literal>\r
1722</simpara>\r
1723</listitem>\r
1724<listitem>\r
1725<simpara>\r
1726<literal>(succ <emphasis>e</emphasis>)</literal>\r
1727</simpara>\r
1728</listitem>\r
1729<listitem>\r
1730<simpara>\r
1731<literal>(thresh <emphasis>x</emphasis>)</literal>\r
1732</simpara>\r
1733</listitem>\r
1734<listitem>\r
1735<simpara>\r
1736<literal>(thresh-gc <emphasis>x</emphasis>)</literal>\r
1737</simpara>\r
1738</listitem>\r
1739<listitem>\r
1740<simpara>\r
1741<literal>(thresh-stack <emphasis>x</emphasis>)</literal>\r
1742</simpara>\r
1743</listitem>\r
1744<listitem>\r
1745<simpara>\r
1746<literal>(to <emphasis>e</emphasis>)</literal>\r
1747</simpara>\r
1748</listitem>\r
1749</itemizedlist>\r
1750<simpara>In the grammar, <literal>all</literal> denotes the set of all nodes. <literal>"<emphasis>s</emphasis>"</literal> is\r
1751a regular expression denoting the set of functions whose name\r
1752(followed by a space and the source position) has a prefix matching\r
1753the regexp. The <literal>and</literal>, <literal>not</literal>, and <literal>or</literal> expressions denote\r
1754intersection, complement, and union, respectively. The <literal>pred</literal> and\r
1755<literal>succ</literal> expressions add the set of immediate predecessors or successors\r
1756to their argument, respectively. The <literal>from</literal> and <literal>to</literal> expressions\r
1757denote the set of nodes that have paths from or to the set of nodes\r
1758denoted by their arguments, respectively. Finally, <literal>thresh</literal>,\r
1759<literal>thresh-gc</literal>, and <literal>thresh-stack</literal> denote the set of nodes whose\r
1760percentage of ticks, gc ticks, or stack ticks, respectively, is\r
1761greater than or equal to the real number <emphasis>x</emphasis>.</simpara>\r
1762<simpara>For example, if you want to see the entire call graph for a program,\r
1763you can use <literal>-keep all</literal> (this is the default). If you want to see\r
1764all nodes reachable from function <literal>foo</literal> in your program, you would\r
1765use <literal>-keep '(from "foo")'</literal>. Or, if you want to see all the\r
1766functions defined in subdirectory <literal>bar</literal> of your project that used\r
1767at least 1% of the ticks, you would use</simpara>\r
1768<screen>-keep '(and ".*/bar/" (thresh 1.0))'</screen>\r
1769<simpara>To see all functions with ticks above a threshold, you can also use\r
1770<literal>-thresh x</literal>, which is an abbreviation for <literal>-keep '(thresh x)'</literal>. You\r
1771can not use multiple <literal>-keep</literal> arguments or both <literal>-keep</literal> and <literal>-thresh</literal>.\r
1772When you use <literal>-keep</literal> to display a subset of the functions, <literal>mlprof</literal>\r
1773will add dashed edges to the call graph to indicate a path in the\r
1774original call graph from one function to another.</simpara>\r
1775<simpara>When compiling with <literal>-profile-stack true</literal>, you can use <literal>mlprof -gray\r
1776true</literal> to make the nodes darker or lighter depending on whether their\r
1777stack percentage is higher or lower.</simpara>\r
1778<simpara>MLton&#8217;s optimizer may duplicate source functions for any of a number\r
1779of reasons (functor duplication, monomorphisation, polyvariance,\r
1780inlining). By default, all duplicates of a function are treated as\r
1781one. If you would like to treat the duplicates separately, you can\r
1782use <literal>mlprof -split <emphasis>regexp</emphasis></literal>, which will cause all duplicates of\r
1783functions whose name has a prefix matching the regular expression to\r
1784be treated separately. This can be especially useful for higher-order\r
1785utility functions like <literal>General.o</literal>.</simpara>\r
1786<section id="_caveats">\r
1787<title>Caveats</title>\r
1788<simpara>Technically speaking, <literal>mlprof</literal> produces a call-stack graph rather than\r
1789a call graph, because it describes the set of possible call stacks.\r
1790The difference is in how tail calls are displayed. For example if <literal>f</literal>\r
1791nontail calls <literal>g</literal> and <literal>g</literal> tail calls <literal>h</literal>, then the call-stack graph\r
1792has edges from <literal>f</literal> to <literal>g</literal> and <literal>f</literal> to <literal>h</literal>, while the call graph has\r
1793edges from <literal>f</literal> to <literal>g</literal> and <literal>g</literal> to <literal>h</literal>. That is, a tail call from <literal>g</literal>\r
1794to <literal>h</literal> removes <literal>g</literal> from the call stack and replaces it with <literal>h</literal>.</simpara>\r
1795<simpara><?asciidoc-pagebreak?></simpara>\r
1796</section>\r
1797</section>\r
1798<section id="CallingFromCToSML">\r
1799<title>CallingFromCToSML</title>\r
1800<simpara>MLton&#8217;s <link linkend="ForeignFunctionInterface">ForeignFunctionInterface</link> allows programs to <emphasis>export</emphasis> SML\r
1801functions to be called from C. Suppose you would like export from SML\r
1802a function of type <literal>real * char -&gt; int</literal> as the C function <literal>foo</literal>.\r
1803MLton extends the syntax of SML to allow expressions like the\r
1804following:</simpara>\r
1805<screen>_export "foo": (real * char -&gt; int) -&gt; unit;</screen>\r
1806<simpara>The above expression exports a C function named <literal>foo</literal>, with\r
1807prototype</simpara>\r
1808<programlisting language="c" linenumbering="unnumbered">Int32 foo (Real64 x0, Char x1);</programlisting>\r
1809<simpara>The <literal>_export</literal> expression denotes a function of type\r
1810<literal>(real * char -&gt; int) -&gt; unit</literal> that when called with a function\r
1811<literal>f</literal>, arranges for the exported <literal>foo</literal> function to call <literal>f</literal>\r
1812when <literal>foo</literal> is called. So, for example, the following exports and\r
1813defines <literal>foo</literal>.</simpara>\r
1814<programlisting language="sml" linenumbering="unnumbered">val e = _export "foo": (real * char -&gt; int) -&gt; unit;\r
1815val _ = e (fn (x, c) =&gt; 13 + Real.floor x + Char.ord c)</programlisting>\r
1816<simpara>The general form of an <literal>_export</literal> expression is</simpara>\r
1817<screen>_export "C function name" attr... : cFuncTy -&gt; unit;</screen>\r
1818<simpara>The type and the semicolon are not optional. As with <literal>_import</literal>, a\r
1819sequence of attributes may follow the function name.</simpara>\r
1820<simpara>MLton&#8217;s <literal>-export-header</literal> option generates a C header file with\r
1821prototypes for all of the functions exported from SML. Include this\r
1822header file in your C files to type check calls to functions exported\r
1823from SML. This header file includes <literal>typedef</literal>s for the\r
1824<link linkend="ForeignFunctionInterfaceTypes">types that can be passed between SML and C</link>.</simpara>\r
1825<section id="_example">\r
1826<title>Example</title>\r
1827<simpara>Suppose that <literal>export.sml</literal> is</simpara>\r
1828<programlisting language="sml" linenumbering="unnumbered">val e = _export "f": (int * real * char -&gt; char) -&gt; unit;\r
1829val _ = e (fn (i, r, _) =&gt;\r
1830 (print (concat ["i = ", Int.toString i,\r
1831 " r = ", Real.toString r, "\n"])\r
1832 ; #"g"))\r
1833val g = _import "g" public reentrant: unit -&gt; unit;\r
1834val _ = g ()\r
1835val _ = g ()\r
1836\r
1837val e = _export "f2": (Word8.word -&gt; word array) -&gt; unit;\r
1838val _ = e (fn w =&gt;\r
1839 Array.tabulate (10, fn _ =&gt; Word.fromLargeWord (Word8.toLargeWord w)))\r
1840val g2 = _import "g2" public reentrant: unit -&gt; word array;\r
1841val a = g2 ()\r
1842val _ = print (concat ["0wx", Word.toString (Array.sub (a, 0)), "\n"])\r
1843\r
1844val e = _export "f3": (unit -&gt; unit) -&gt; unit;\r
1845val _ = e (fn () =&gt; print "hello\n");\r
1846val g3 = _import "g3" public reentrant: unit -&gt; unit;\r
1847val _ = g3 ()\r
1848\r
1849(* This example demonstrates mutual recursion between C and SML. *)\r
1850val e = _export "f4": (int -&gt; unit) -&gt; unit;\r
1851val g4 = _import "g4" public reentrant: int -&gt; unit;\r
1852val _ = e (fn i =&gt; if i = 0 then () else g4 (i - 1))\r
1853val _ = g4 13\r
1854\r
1855val (_, zzzSet) = _symbol "zzz" alloc: (unit -&gt; int) * (int -&gt; unit);\r
1856val () = zzzSet 42\r
1857val g5 = _import "g5" public: unit -&gt; unit;\r
1858val _ = g5 ()\r
1859\r
1860val _ = print "success\n"</programlisting>\r
1861<simpara>Note that the the <literal>reentrant</literal> attribute is used for <literal>_import</literal>-ing the\r
1862C functions that will call the <literal>_export</literal>-ed SML functions.</simpara>\r
1863<simpara>Create the header file with <literal>-export-header</literal>.</simpara>\r
1864<screen>% mlton -default-ann 'allowFFI true' \\r
1865 -export-header export.h \\r
1866 -stop tc \\r
1867 export.sml</screen>\r
1868<simpara><literal>export.h</literal> now contains the following C prototypes.</simpara>\r
1869<screen>Int8 f (Int32 x0, Real64 x1, Int8 x2);\r
1870Pointer f2 (Word8 x0);\r
1871void f3 ();\r
1872void f4 (Int32 x0);\r
1873extern Int32 zzz;</screen>\r
1874<simpara>Use <literal>export.h</literal> in a C program, <literal>ffi-export.c</literal>, as follows.</simpara>\r
1875<programlisting language="c" linenumbering="unnumbered">#include &lt;stdio.h&gt;\r
1876#include "export.h"\r
1877\r
1878/* Functions in C are by default PUBLIC symbols */\r
1879void g () {\r
1880 Char8 c;\r
1881\r
1882 fprintf (stderr, "g starting\n");\r
1883 c = f (13, 17.15, 'a');\r
1884 fprintf (stderr, "g done char = %c\n", c);\r
1885}\r
1886\r
1887Pointer g2 () {\r
1888 Pointer res;\r
1889 fprintf (stderr, "g2 starting\n");\r
1890 res = f2 (0xFF);\r
1891 fprintf (stderr, "g2 done\n");\r
1892 return res;\r
1893}\r
1894\r
1895void g3 () {\r
1896 fprintf (stderr, "g3 starting\n");\r
1897 f3 ();\r
1898 fprintf (stderr, "g3 done\n");\r
1899}\r
1900\r
1901void g4 (Int32 i) {\r
1902 fprintf (stderr, "g4 (%d)\n", i);\r
1903 f4 (i);\r
1904}\r
1905\r
1906void g5 () {\r
1907 fprintf (stderr, "g5 ()\n");\r
1908 fprintf (stderr, "zzz = %i\n", zzz);\r
1909 fprintf (stderr, "g5 done\n");\r
1910}</programlisting>\r
1911<simpara>Compile <literal>ffi-export.c</literal> and <literal>export.sml</literal>.</simpara>\r
1912<screen>% gcc -c ffi-export.c\r
1913% mlton -default-ann 'allowFFI true' \\r
1914 export.sml ffi-export.o</screen>\r
1915<simpara>Finally, run <literal>export</literal>.</simpara>\r
1916<screen>% ./export\r
1917g starting\r
1918...\r
1919g4 (0)\r
1920success</screen>\r
1921</section>\r
1922<section id="_download">\r
1923<title>Download</title>\r
1924<itemizedlist>\r
1925<listitem>\r
1926<simpara>\r
1927<ulink url="https://raw.github.com/MLton/mlton/master/doc/examples/ffi/export.sml"><literal>export.sml</literal></ulink>\r
1928</simpara>\r
1929</listitem>\r
1930<listitem>\r
1931<simpara>\r
1932<ulink url="https://raw.github.com/MLton/mlton/master/doc/examples/ffi/ffi-export.c"><literal>ffi-export.c</literal></ulink>\r
1933</simpara>\r
1934</listitem>\r
1935</itemizedlist>\r
1936<simpara><?asciidoc-pagebreak?></simpara>\r
1937</section>\r
1938</section>\r
1939<section id="CallingFromSMLToC">\r
1940<title>CallingFromSMLToC</title>\r
1941<simpara>MLton&#8217;s <link linkend="ForeignFunctionInterface">ForeignFunctionInterface</link> allows an SML program to <emphasis>import</emphasis>\r
1942C functions. Suppose you would like to import from C a function with\r
1943the following prototype:</simpara>\r
1944<programlisting language="c" linenumbering="unnumbered">int foo (double d, char c);</programlisting>\r
1945<simpara>MLton extends the syntax of SML to allow expressions like the following:</simpara>\r
1946<screen>_import "foo": real * char -&gt; int;</screen>\r
1947<simpara>This expression denotes a function of type <literal>real * char -&gt; int</literal> whose\r
1948behavior is implemented by calling the C function whose name is <literal>foo</literal>.\r
1949Thinking in terms of C, imagine that there are C variables <literal>d</literal> of type\r
1950<literal>double</literal>, <literal>c</literal> of type <literal>unsigned char</literal>, and <literal>i</literal> of type <literal>int</literal>. Then,\r
1951the C statement <literal>i = foo (d, c)</literal> is executed and <literal>i</literal> is returned.</simpara>\r
1952<simpara>The general form of an <literal>_import</literal> expression is:</simpara>\r
1953<screen>_import "C function name" attr... : cFuncTy;</screen>\r
1954<simpara>The type and the semicolon are not optional.</simpara>\r
1955<simpara>The function name is followed by a (possibly empty) sequence of\r
1956attributes, analogous to C <literal>__attribute__</literal> specifiers.</simpara>\r
1957<section id="_example_2">\r
1958<title>Example</title>\r
1959<simpara><literal>import.sml</literal> imports the C function <literal>ffi</literal> and the C variable <literal>FFI_INT</literal>\r
1960as follows.</simpara>\r
1961<programlisting language="sml" linenumbering="unnumbered">(* main.sml *)\r
1962\r
1963(* Declare ffi to be implemented by calling the C function ffi. *)\r
1964val ffi = _import "ffi" public: real array * int * int ref * char ref * int -&gt; char;\r
1965open Array\r
1966\r
1967val size = 10\r
1968val a = tabulate (size, fn i =&gt; real i)\r
1969val ri = ref 0\r
1970val rc = ref #"0"\r
1971val n = 17\r
1972\r
1973(* Call the C function *)\r
1974val c = ffi (a, Array.length a, ri, rc, n)\r
1975\r
1976(* FFI_INT is declared as public in ffi-import.c *)\r
1977val (nGet, nSet) = _symbol "FFI_INT" public: (unit -&gt; int) * (int -&gt; unit);\r
1978\r
1979val _ = print (concat [Int.toString (nGet ()), "\n"])\r
1980\r
1981val _ =\r
1982 print (if c = #"c" andalso !ri = 45 andalso !rc = c\r
1983 then "success\n"\r
1984 else "fail\n")</programlisting>\r
1985<simpara><literal>ffi-import.c</literal> is</simpara>\r
1986<programlisting language="c" linenumbering="unnumbered">#include "export.h"\r
1987\r
1988Int32 FFI_INT = 13;\r
1989Word32 FFI_WORD = 0xFF;\r
1990Bool FFI_BOOL = 1;\r
1991Real64 FFI_REAL = 3.14159;\r
1992\r
1993Char8 ffi (Pointer a1, Int32 a1len, Pointer a2, Pointer a3, Int32 n) {\r
1994 double *ds = (double*)a1;\r
1995 int *pi = (int*)a2;\r
1996 char *pc = (char*)a3;\r
1997 int i;\r
1998 double sum;\r
1999\r
2000 sum = 0.0;\r
2001 for (i = 0; i &lt; a1len; ++i) {\r
2002 sum += ds[i];\r
2003 ds[i] += n;\r
2004 }\r
2005 *pi = (int)sum;\r
2006 *pc = 'c';\r
2007 return 'c';\r
2008}</programlisting>\r
2009<simpara>Compile and run the program.</simpara>\r
2010<screen>% mlton -default-ann 'allowFFI true' -export-header export.h import.sml ffi-import.c\r
2011% ./import\r
201213\r
2013success</screen>\r
2014</section>\r
2015<section id="_download_2">\r
2016<title>Download</title>\r
2017<itemizedlist>\r
2018<listitem>\r
2019<simpara>\r
2020<ulink url="https://raw.github.com/MLton/mlton/master/doc/examples/ffi/import.sml"><literal>import.sml</literal></ulink>\r
2021</simpara>\r
2022</listitem>\r
2023<listitem>\r
2024<simpara>\r
2025<ulink url="https://raw.github.com/MLton/mlton/master/doc/examples/ffi/ffi-import.c"><literal>ffi-import.c</literal></ulink>\r
2026</simpara>\r
2027</listitem>\r
2028</itemizedlist>\r
2029</section>\r
2030<section id="_next_steps_2">\r
2031<title>Next Steps</title>\r
2032<itemizedlist>\r
2033<listitem>\r
2034<simpara>\r
2035<link linkend="CallingFromSMLToCFunctionPointer">CallingFromSMLToCFunctionPointer</link>\r
2036</simpara>\r
2037</listitem>\r
2038</itemizedlist>\r
2039<simpara><?asciidoc-pagebreak?></simpara>\r
2040</section>\r
2041</section>\r
2042<section id="CallingFromSMLToCFunctionPointer">\r
2043<title>CallingFromSMLToCFunctionPointer</title>\r
2044<simpara>Just as MLton can <link linkend="CallingFromSMLToC">directly call C functions</link>, it\r
2045is possible to make indirect function calls; that is, function calls\r
2046through a function pointer. MLton extends the syntax of SML to allow\r
2047expressions like the following:</simpara>\r
2048<screen>_import * : MLton.Pointer.t -&gt; real * char -&gt; int;</screen>\r
2049<simpara>This expression denotes a function of type</simpara>\r
2050<programlisting language="sml" linenumbering="unnumbered">MLton.Pointer.t -&gt; real * char -&gt; int</programlisting>\r
2051<simpara>whose behavior is implemented by calling the C function at the address\r
2052denoted by the <literal>MLton.Pointer.t</literal> argument, and supplying the C\r
2053function two arguments, a <literal>double</literal> and an <literal>int</literal>. The C function\r
2054pointer may be obtained, for example, by the dynamic linking loader\r
2055(<literal>dlopen</literal>, <literal>dlsym</literal>, &#8230;).</simpara>\r
2056<simpara>The general form of an indirect <literal>_import</literal> expression is:</simpara>\r
2057<screen>_import * attr... : cPtrTy -&gt; cFuncTy;</screen>\r
2058<simpara>The type and the semicolon are not optional.</simpara>\r
2059<section id="_example_3">\r
2060<title>Example</title>\r
2061<simpara>This example uses <literal>dlopen</literal> and friends (imported using normal\r
2062<literal>_import</literal>) to dynamically load the math library (<literal>libm</literal>) and call the\r
2063<literal>cos</literal> function. Suppose <literal>iimport.sml</literal> contains the following.</simpara>\r
2064<programlisting language="sml" linenumbering="unnumbered">signature DYN_LINK =\r
2065 sig\r
2066 type hndl\r
2067 type mode\r
2068 type fptr\r
2069\r
2070 val dlopen : string * mode -&gt; hndl\r
2071 val dlsym : hndl * string -&gt; fptr\r
2072 val dlclose : hndl -&gt; unit\r
2073\r
2074 val RTLD_LAZY : mode\r
2075 val RTLD_NOW : mode\r
2076 end\r
2077\r
2078structure DynLink :&gt; DYN_LINK =\r
2079 struct\r
2080 type hndl = MLton.Pointer.t\r
2081 type mode = Word32.word\r
2082 type fptr = MLton.Pointer.t\r
2083\r
2084 (* These symbols come from a system libray, so the default import scope\r
2085 * of external is correct.\r
2086 *)\r
2087 val dlopen =\r
2088 _import "dlopen" : string * mode -&gt; hndl;\r
2089 val dlerror =\r
2090 _import "dlerror": unit -&gt; MLton.Pointer.t;\r
2091 val dlsym =\r
2092 _import "dlsym" : hndl * string -&gt; fptr;\r
2093 val dlclose =\r
2094 _import "dlclose" : hndl -&gt; Int32.int;\r
2095\r
2096 val RTLD_LAZY = 0wx00001 (* Lazy function call binding. *)\r
2097 val RTLD_NOW = 0wx00002 (* Immediate function call binding. *)\r
2098\r
2099 val dlerror = fn () =&gt;\r
2100 let\r
2101 val addr = dlerror ()\r
2102 in\r
2103 if addr = MLton.Pointer.null\r
2104 then NONE\r
2105 else let\r
2106 fun loop (index, cs) =\r
2107 let\r
2108 val w = MLton.Pointer.getWord8 (addr, index)\r
2109 val c = Byte.byteToChar w\r
2110 in\r
2111 if c = #"\000"\r
2112 then SOME (implode (rev cs))\r
2113 else loop (index + 1, c::cs)\r
2114 end\r
2115 in\r
2116 loop (0, [])\r
2117 end\r
2118 end\r
2119\r
2120 val dlopen = fn (filename, mode) =&gt;\r
2121 let\r
2122 val filename = filename ^ "\000"\r
2123 val hndl = dlopen (filename, mode)\r
2124 in\r
2125 if hndl = MLton.Pointer.null\r
2126 then raise Fail (case dlerror () of\r
2127 NONE =&gt; "???"\r
2128 | SOME s =&gt; s)\r
2129 else hndl\r
2130 end\r
2131\r
2132 val dlsym = fn (hndl, symbol) =&gt;\r
2133 let\r
2134 val symbol = symbol ^ "\000"\r
2135 val fptr = dlsym (hndl, symbol)\r
2136 in\r
2137 case dlerror () of\r
2138 NONE =&gt; fptr\r
2139 | SOME s =&gt; raise Fail s\r
2140 end\r
2141\r
2142 val dlclose = fn hndl =&gt;\r
2143 if MLton.Platform.OS.host = MLton.Platform.OS.Darwin\r
2144 then () (* Darwin reports the following error message if you\r
2145 * try to close a dynamic library.\r
2146 * "dynamic libraries cannot be closed"\r
2147 * So, we disable dlclose on Darwin.\r
2148 *)\r
2149 else\r
2150 let\r
2151 val res = dlclose hndl\r
2152 in\r
2153 if res = 0\r
2154 then ()\r
2155 else raise Fail (case dlerror () of\r
2156 NONE =&gt; "???"\r
2157 | SOME s =&gt; s)\r
2158 end\r
2159 end\r
2160\r
2161val dll =\r
2162 let\r
2163 open MLton.Platform.OS\r
2164 in\r
2165 case host of\r
2166 Cygwin =&gt; "cygwin1.dll"\r
2167 | Darwin =&gt; "libm.dylib"\r
2168 | _ =&gt; "libm.so"\r
2169 end\r
2170\r
2171val hndl = DynLink.dlopen (dll, DynLink.RTLD_LAZY)\r
2172\r
2173local\r
2174 val double_to_double =\r
2175 _import * : DynLink.fptr -&gt; real -&gt; real;\r
2176 val cos_fptr = DynLink.dlsym (hndl, "cos")\r
2177in\r
2178 val cos = double_to_double cos_fptr\r
2179end\r
2180\r
2181val _ = print (concat [" Math.cos(2.0) = ", Real.toString (Math.cos 2.0), "\n",\r
2182 "libm.so::cos(2.0) = ", Real.toString (cos 2.0), "\n"])\r
2183\r
2184val _ = DynLink.dlclose hndl</programlisting>\r
2185<simpara>Compile and run <literal>iimport.sml</literal>.</simpara>\r
2186<screen>% mlton -default-ann 'allowFFI true' \\r
2187 -target-link-opt linux -ldl \\r
2188 -target-link-opt solaris -ldl \\r
2189 iimport.sml\r
2190% iimport\r
2191 Math.cos(2.0) = ~0.416146836547\r
2192libm.so::cos(2.0) = ~0.416146836547</screen>\r
2193<simpara>This example also shows the <literal>-target-link-opt</literal> option, which uses the\r
2194switch when linking only when on the specified platform. Compile with\r
2195<literal>-verbose 1</literal> to see in more detail what&#8217;s being passed to <literal>gcc</literal>.</simpara>\r
2196</section>\r
2197<section id="_download_3">\r
2198<title>Download</title>\r
2199<itemizedlist>\r
2200<listitem>\r
2201<simpara>\r
2202<ulink url="https://raw.github.com/MLton/mlton/master/doc/examples/ffi/iimport.sml"><literal>iimport.sml</literal></ulink>\r
2203</simpara>\r
2204</listitem>\r
2205</itemizedlist>\r
2206<simpara><?asciidoc-pagebreak?></simpara>\r
2207</section>\r
2208</section>\r
2209<section id="CCodegen">\r
2210<title>CCodegen</title>\r
2211<simpara>The <link linkend="CCodegen">CCodegen</link> is a <link linkend="Codegen">code generator</link> that translates the\r
2212<link linkend="Machine">Machine</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link> to C, which is further optimized\r
2213and compiled to native object code by <literal>gcc</literal> (or another C compiler).</simpara>\r
2214<section id="_implementation_3">\r
2215<title>Implementation</title>\r
2216<itemizedlist>\r
2217<listitem>\r
2218<simpara>\r
2219<ulink url="https://github.com/MLton/mlton/blob/master/mlton/codegen/c-codegen/c-codegen.sig"><literal>c-codegen.sig</literal></ulink>\r
2220</simpara>\r
2221</listitem>\r
2222<listitem>\r
2223<simpara>\r
2224<ulink url="https://github.com/MLton/mlton/blob/master/mlton/codegen/c-codegen/c-codegen.fun"><literal>c-codegen.fun</literal></ulink>\r
2225</simpara>\r
2226</listitem>\r
2227</itemizedlist>\r
2228</section>\r
2229<section id="_details_and_notes_3">\r
2230<title>Details and Notes</title>\r
2231<simpara>The <link linkend="CCodegen">CCodegen</link> is the original <link linkend="Codegen">code generator</link> for MLton.</simpara>\r
2232<simpara><?asciidoc-pagebreak?></simpara>\r
2233</section>\r
2234</section>\r
2235<section id="Changelog">\r
2236<title>Changelog</title>\r
2237<itemizedlist>\r
2238<listitem>\r
2239<simpara>\r
2240<ulink url="https://github.com/MLton/mlton/blob/master/CHANGELOG.adoc"><literal>CHANGELOG.adoc</literal></ulink>\r
2241</simpara>\r
2242</listitem>\r
2243</itemizedlist>\r
2244<screen>= CHANGELOG\r
2245\r
2246== Version 20180206\r
2247\r
2248Here are the changes from version 20130715 to version 20180206.\r
2249\r
2250=== Summary\r
2251\r
2252* Compiler.\r
2253 ** Added an experimental LLVM codegen (`-codegen llvm`); requires LLVM tools\r
2254 (`llvm-as`, `opt`, `llc`) version &amp;ge; 3.7.\r
2255 ** Made many substantial cosmetic improvements to front-end diagnostic\r
2256 messages, especially with respect to source location regions, type inference\r
2257 for `fun` and `val rec` declarations, signature constraints applied to a\r
2258 structure, `sharing type` specifications and `where type` signature\r
2259 expressions, type constructor or type variable escaping scope, and\r
2260 nonexhaustive pattern matching.\r
2261 ** Fixed minor bugs with exception replication, precedence parsing of function\r
2262 clauses, and simultaneous `sharing` of multiple structures.\r
2263 ** Made compilation deterministic (eliminate output executable name from\r
2264 compile-time specified `@MLton` runtime arguments; deterministically generate\r
2265 magic constant for executable).\r
2266 ** Updated `-show-basis` (recursively expand structures in environments,\r
2267 displaying components with long identifiers; append `(* @ region *)`\r
2268 annotations to items shown in environment).\r
2269 ** Forced amd64 codegen to generate PIC on amd64-linux targets.\r
2270* Runtime.\r
2271 ** Added `gc-summary-file file` runtime option.\r
2272 ** Reorganized runtime support for `IntInf` operations so that programs that\r
2273 do not use `IntInf` compile to executables with no residual dependency on GMP.\r
2274 ** Changed heap representation to store forwarding pointer for an object in\r
2275 the object header (rather than in the object data and setting the header to a\r
2276 sentinel value).\r
2277* Language.\r
2278 ** Added support for selected SuccessorML features; see\r
2279 http://mlton.org/SuccessorML for details.\r
2280 ** Added `(*#showBasis "file" *)` directive; see\r
2281 http://mlton.org/ShowBasisDirective for details.\r
2282 ** FFI:\r
2283 *** Added `pure`, `impure`, and `reentrant` attributes to `_import`. An\r
2284 unattributed `_import` is treated as `impure`. A `pure` `_import` may be\r
2285 subject to more aggressive optimizations (common subexpression elimination,\r
2286 dead-code elimination). An `_import`-ed C function that (directly or\r
2287 indirectly) calls an `_export`-ed SML function should be attributed\r
2288 `reentrant`.\r
2289 ** ML Basis annotations.\r
2290 *** Added `allowSuccessorML {false|true}` to enable all SuccessorML features\r
2291 and other annotations to enable specific SuccessorML features; see\r
2292 http://mlton.org/SuccessorML for details.\r
2293 *** Split `nonexhaustiveMatch {warn|error|igore}` and `redundantMatch\r
2294 {warn|error|ignore}` into `nonexhaustiveMatch` and `redundantMatch`\r
2295 (controls diagnostics for `case` expressions, `fn` expressions, and `fun`\r
2296 declarations (which may raise `Match` on failure)) and `nonexhaustiveBind`\r
2297 and `redundantBind` (controls diagnostics for `val` declarations (which may\r
2298 raise `Bind` on failure)).\r
2299 *** Added `valrecConstr {warn|error|ignore}` to report when a `val rec` (or\r
2300 `fun`) declaration redefines an identifier that previously had constructor\r
2301 status.\r
2302* Libraries.\r
2303 ** Basis Library.\r
2304 *** Improved performance of `Array.copy`, `Array.copyVec`, `Vector.append`,\r
2305 `String.^`, `String.concat`, `String.concatWith`, and other related\r
2306 functions by using `memmove` rather than element-by-element constructions.\r
2307 ** `Unsafe` structure.\r
2308 *** Added unsafe operations for array uninitialization and raw arrays; see\r
2309 https://github.com/MLton/mlton/pull/207 for details.\r
2310 ** Other libraries.\r
2311 *** Updated: ckit library, MLLPT library, MLRISC library, SML/NJ library\r
2312* Tools.\r
2313 ** mlnlffigen\r
2314 *** Updated to warn and skip (rather than abort) when encountering functions\r
2315 with `struct`/`union` argument or return type.\r
2316\r
2317=== Details\r
2318\r
2319* 2018-02-6\r
2320 ** Remove ancient and unused `cmcat` tool.\r
2321\r
2322* 2018-02-03\r
2323 ** Upgrade `gdtoa.tgz`.\r
2324\r
2325* 2018-02-02\r
2326 ** Remove docs from `all` target of `./Makefile`; this eliminates the\r
2327 `all-no-docs` target (which was frequently used in favor of `all`).\r
2328\r
2329* 2018-01-31\r
2330 ** Use C compiler with `-std=gnu11` (rather than `-std=gnu99`).\r
2331 ** Revert rudimentary support for `./configure`; the support was so minimal\r
2332 that it seems unhelpful to pretend that there are exhaustive compatibility\r
2333 checks being performed. All of the basic configuration can be accomplished\r
2334 with simple `make` variable definitions.\r
2335\r
2336* 2018-01-25\r
2337 ** Remove (expert, undocumented) `-debug-format` option; the same effect can\r
2338 be achieved with `-as-opt` and `-cc-opt`.\r
2339 ** Propagate C compiler from `./configure` to `mlton` script.\r
2340\r
2341* 2018-01-24\r
2342 ** Extend `-target-*-opt` options to support `arch-os` pairs.\r
2343 ** Remove `./package/rpm/*` and corresponding targets in `./Makefile`;\r
2344 upstream MLton has not produced RPMs for years.\r
2345\r
2346* 2018-01-24\r
2347 ** Slightly improve performance of `Vector.concat` and\r
2348 `String.{concat,concatWith,tokens,fields}` by avoiding `List.map`-s.\r
2349\r
2350* 2018-01-23\r
2351 ** Restore, but deprecate, `-drop-pass` compile-time expert option.\r
2352\r
2353* 2018-01-19\r
2354 ** Update SML/NJ libraries to SML/NJ 110.82.\r
2355\r
2356* 2017-12-29\r
2357 ** Add support for `(*#showBasis "file" *)` directives. This feature is\r
2358 meant to facilitate auto-completion via\r
2359 https://github.com/MatthewFluet/company-mlton[`company-mlton`] and similar\r
2360 tools.\r
2361\r
2362* 2017-12-20\r
2363 ** Update performance comparison on website. Thanks to Curtis Dunham for the\r
2364 pull request.\r
2365\r
2366* 2017-12-17\r
2367 ** Updates to `-show-basis`:\r
2368 *** `-show-basis-flat`: Recursively expand structures in environments,\r
2369 displaying components with long identifiers.\r
2370 *** `-show-basis-def`: Appends `(* @ region *)` annotations to items shown\r
2371 in environment.\r
2372 *** `-show-basis-compact`: Tries to optimize vertical space (at the expense\r
2373 of long lines).\r
2374\r
2375* 2017-12-11\r
2376 ** Drop `_BSD_SOURCE` and `_POSIX_C_SOURCE` feature macros in\r
2377 `./runtime/cenv.h`.\r
2378\r
2379* 2017-12-10\r
2380 ** Add a `Dockerfile` to build/test MLton. Thanks to Richard Laughlin for the\r
2381 pull request.\r
2382\r
2383* 2017-12-06\r
2384 ** Remove `$PREFIX` and `$prefix` from top-level `Makefile.in`; use\r
2385 `./configure --prefix path`. Thanks to Richard Laughlin for the pull\r
2386 request.\r
2387\r
2388* 2017-12-03\r
2389 ** Fix heap invariant predicates.\r
2390\r
2391* 2017-11-15\r
2392 ** Eliminate the use of (some) global mutable state for signal handling.\r
2393\r
2394* 2017-11-14\r
2395 ** Store forwarding pointer for an object in the object header (rather than in\r
2396 the object data and setting the header to a sentinel value).\r
2397\r
2398* 2017-11-02\r
2399 ** Updates to stack management in backend:\r
2400 *** Improve `Allocation.Stack.get`.\r
2401 *** Do not force `Cont` block arguments to stack.\r
2402\r
2403* 2017-10-30\r
2404 ** In `signature SSA_TO_RSSA_STRUCTS` share by `Rssa.Atoms = Ssa.Atoms`. This\r
2405 is the idiom used elsewhere in the compiler, rather than sharing individual\r
2406 sub-structures of `Atoms`.\r
2407 ** Minor updates to `DirectedGraph` and `Tree` in MLton library.\r
2408\r
2409* 2017-10-23\r
2410 ** Add `-seed-rand w` compile-time option, to seed the pseudo-random number\r
2411 generator.\r
2412 ** Add a new MachineShuffle pass (disabled by default) that shuffles the\r
2413 collection of chunks within the program and shuffles the collection of blocks\r
2414 within a chunk. With the `-seed-rand w` compile-time option, can be used to\r
2415 generate executables with distinct code placements.\r
2416\r
2417* 2017-10-23\r
2418 ** Use a relative path in the `mlton` script, rather than an absolute path.\r
2419 The absolute path needed to be set to the intended installation directory,\r
2420 which made it difficult to install a binary release in a local directory.\r
2421 Undertaken by Maksim Yegorov at RIT supported by NSF CISE Research\r
2422 Infrastructure (CRI) award.\r
2423\r
2424* 2017-10-21\r
2425 ** Add unsafe operations for array uninitialization and raw arrays.\r
2426 *** Rename `Array_uninit: SeqIndex.int -&gt; 'a array` primitive to\r
2427 `Array_alloc: SeqIndex.int -&gt; 'a array`.\r
2428 *** Add `Array_uninit: 'a array * SeqIndex.int -&gt; unit` primitive to set all\r
2429 objptrs in the element at the given index to a bogus non-objptr value\r
2430 (`0wx1`). One motivation for this primitive is to support space-efficient\r
2431 polymorphic resizeable arrays. When shrinking a resizeable array, we would\r
2432 like to "`NULL`" out the elements that are no longer part of the logical\r
2433 array, in order to avoid a (logical) space leak.\r
2434 *** Add `Array_uninitIsNop: 'a array -&gt; bool` primitive to answer if the\r
2435 `Array_uninit` primitive applied to the same array would be a nop (i.e., if\r
2436 the array has no objptrs in the elements). This can be used to skip a\r
2437 bulk-`Array_uninit` loop when it is known that the `Array_uninit` operations\r
2438 would be nops.\r
2439 *** Add `Array_allocRaw: SeqIndex.int -&gt; 'a array` primitive to allocate an\r
2440 array, but with a header that indicates that the array has no objptrs. Add\r
2441 `Array_toArray: 'a array -&gt; 'a array` primitive to update the header of an\r
2442 `Array_allocRaw` allocated array to reveal the objptrs. One motiviation for\r
2443 this primitive is that, in a parallel setting, the uninitialization of an\r
2444 array can be a sequential bottleneck. The `Array_allocRaw` is a constant\r
2445 time operation and the subsequent `Array_uninit` operations can be performed\r
2446 in parallel.\r
2447 *** Extend `structure Unsafe.Array` with additional operations. See\r
2448 `./basis-library/sml-nj/unsafe.sig`.\r
2449\r
2450* 2017-10-20\r
2451 ** Introduce ShareZeroVec SSA optimization to share zero-length vectors after\r
2452 coercion-based optimizations. Undertaken by Maksim Yegorov at RIT supported\r
2453 by NSF CISE Research Infrastructure (CRI) award.\r
2454\r
2455* 2017-10-18\r
2456 ** New canonicalization strategy for CommonSubexp SSA optimization.\r
2457 Previously, the canonicalization of commutative arithmetic primitives was\r
2458 sensitive to variable hashes (created by an unseeded pseudo-random number\r
2459 generator); now, the canonicalization of commutative arithmetic primitives is\r
2460 sensitive to relative definition order of variables.\r
2461\r
2462* 2017-10-12\r
2463 ** Fix bug in runtime argument option parsing.\r
2464\r
2465* 2017-10-05\r
2466 ** Many updates and improvements to diagnostic messages. See\r
2467 https://github.com/MLton/mlton/pull/195 for details.\r
2468\r
2469* 2017-09-27\r
2470 ** Add rudimentary support for `./configure`; in particular, support\r
2471 `--with-gmp-lib` and `--with-gmp-include` to set location of GMP and\r
2472 `--prefix` to specify an install prefix. Undertaken by Maksim Yegorov at RIT\r
2473 supported by NSF CISE Research Infrastructure (CRI) award.\r
2474\r
2475* 2017-08-21\r
2476 ** Introduce `Array_copyArray: 'a array * SeqIndex.int * 'a array *\r
2477 SeqIndex.int * SeqIndex.int -&gt; unit` and `Array_copyVector: 'a array *\r
2478 SeqIndex.int * 'a vector * SeqIndex.int * SeqIndex.int -&gt; unit` primitives\r
2479 which are used to implement a number of array and vector construction\r
2480 functions, particularly `append`, `concat`, and `concatWith`. The primitives\r
2481 compile to `memmove` operations, which (significantly) outperforms MLton's\r
2482 element-by-element construction for large sequences. Undertaken by Bryan Camp\r
2483 at RIT supported by NSF CISE Research Infrastructure (CRI) award.\r
2484\r
2485* 2017-07-25\r
2486 ** Force PIC generation on amd64-linux targets. Thanks to Kuen-Bang Hou\r
2487 (Favonia) for the pull request.\r
2488\r
2489* 2017-07-11\r
2490 ** Generalize the `subWord` primitives to\r
2491+\r
2492----\r
2493 | WordArray_subWord of {seqSize:WordSize.t, eleSize: WordSize.t}\r
2494 | WordArray_updateWord of {seqSize: WordSize.t, eleSize: WordSize.t}\r
2495 | WordVector_subWord of {seqSize: WordSize.t, eleSize: WordSize.t}\r
2496----\r
2497+\r
2498Undertaken by Bryan Camp at RIT supported by NSF CISE Research Infrastructure\r
2499(CRI) award.\r
2500\r
2501* 2017-07-11\r
2502 ** Add a parser combinator library (`structure StreamParser`) to the MLton\r
2503 Library. Undertaken by Jason Carr at RIT supported by NSF CISE Research\r
2504 Infrastructure (CRI) award.\r
2505 ** Add a parser for the SXML IR (`structure ParseSxml`). Undertaken by Jason\r
2506 Carr at RIT supported by NSF CISE Research Infrastructure (CRI) award.\r
2507 ** Allow compilation to start with a `.sxml` file. Undertaken by Jason Carr\r
2508 at RIT supported by NSF CISE Research Infrastructure (CRI) award.\r
2509\r
2510* 2017-06-29\r
2511 ** Replace `-drop-pass regex` compile-time option with `-disable-pass regex`\r
2512 compile option and add `-enable-pass regex` compile option. Various XML,\r
2513 SXML, SSA, SSA2, RSSA, and Machine IR optimization passes are initialized with\r
2514 a default status, which can be overriden by `-{disable,enable}-pass`. In\r
2515 particular, it is now easy to add a work-in-progress (and potentially buggy)\r
2516 pass to the simplification pipeline with `execute = false` default status, to\r
2517 be selectively executed with `-enable-pass`. Undertaken by Bryan Camp at RIT\r
2518 supported by NSF CISE Research Infrastructure (CRI) award.\r
2519 ** Add LoopUnswitch and LoopUnroll SSA optimizations (undertaken by Matthew\r
2520 Surawski as an RIT CS MS Capstone Project). Initial evaluation demonstrates\r
2521 some non-trivial performance gains, no non-trivial performance losses, and\r
2522 only minor code size increases, but currently disabled pending a more thorough\r
2523 evaluation.\r
2524\r
2525* 2017-05-23\r
2526 ** Expand the set of MLB annotations:\r
2527 *** `nonexhaustiveBind`, `nonexhaustiveExnBind`, `redundantBind`: controls\r
2528 diagnostics for `val` declarations (which may raise `Bind` on failure).\r
2529 *** `nonexhaustiveMatch`, `nonexhaustiveExnMatch`, `redundantMatch`:\r
2530 controls diagnostics for `case` expressions, `fn` expressions, and `fun`\r
2531 declarations (which may raise `Match` on failure).\r
2532 *** `nonexhaustiveRaise`, `nonexhaustiveExnRaise`, `redundantRaise`:\r
2533 controls diagnostics for `handle` expressions (which implicitly re-raise on\r
2534 failure). Note that `nonexhaustiveRaise` and `nonexhaustiveExnRaise`\r
2535 default to `ignore`. The combination of `nonexhaustiveRaise warn` and\r
2536 `nonexhaustiveExnRaise ignore` can be useful for finding handlers that\r
2537 handle some, but not all, values of an exception variant.\r
2538 ** Make a number of improvements to diagnostic messages:\r
2539 *** Display nonexhaustive exception patterns as `_ : exn`, rather than\r
2540 `e`.\r
2541 *** Normalize nonexhaustive patterns by sorting (e.g., by `ConApp` name).\r
2542 *** Report complete enumeration of unhandled constants, rather than a single\r
2543 example.\r
2544 *** Report nonexhaustive patterns of record type as records, rather than as\r
2545 tuples.\r
2546\r
2547* 2017-04-20\r
2548 ** Updates to SSA, SSA2, and RSSA IR support infrastructure\r
2549 *** Display more context when reporting SSA and SSA2 IR type errors.\r
2550 *** Add `-layout-width n` compile expert option to control the target width\r
2551 for the pretty printer.\r
2552 *** Make cosmetic improvments to SSA and SSA2 IR display (uses of global\r
2553 variables bound to small constants and conapps are commented with the\r
2554 corresponding value; include loop forest for functions with `-keep dot`).\r
2555 *** Improve RSSA constant folding and copy propagation.\r
2556 *** Limit Machine IR `Globals` to variables used outside of the `main`\r
2557 function.\r
2558\r
2559* 2017-04-15\r
2560 ** Add `gc-summary-file file` runtime option.\r
2561\r
2562* 2017-04-15\r
2563 ** Rename and add `smlnj-mlton-x{2,4,8,16}` top-level `Makefile` targets.\r
2564 ** Update SML/NJ librarys to SML/NJ 110.80 (making use of supported\r
2565 SuccessorML features).\r
2566 ** Not support for SML/NJ extensions via SuccessorML MLB annotations on\r
2567 website.\r
2568\r
2569* 2017-04-14\r
2570 ** Add support for vector expressions (`#[e1, e2, ..., en]`) and vector\r
2571 patterns (`#[p1, p2, ..., pn]`) and add `Vector_vector` n-ary primitive.\r
2572 Initial support for vector expressions and the `Vector_vector` primitive were\r
2573 undertaken by Krishna Ravikumar as an RIT CS MS Capstone Project.\r
2574\r
2575* 2017-03-29\r
2576 ** Update DOS eol handling and tweak error messages in lexer.\r
2577\r
2578* 2017-03-27\r
2579 ** Correct off-by-one error in column numbers. Thanks to Jacob Zimmerman for\r
2580 the error report and pull request.\r
2581\r
2582* 2017-03-15\r
2583 ** Updates to SuccessorML support:\r
2584 *** Add an `allowSuccessorML {false|true}` MLB annotation to enable all\r
2585 Successor ML features with a single annotation.\r
2586 *** Fix parsing of numeric labels to only accept an INT token that does not\r
2587 begin with 0, is not an extended literal, is not negative, and is decimal.\r
2588 *** Drop the alternate word prefixes (`0xw` and `0bw`).\r
2589 *** Unconditionally allow line comments in MLB files.\r
2590 *** Allow UTF-8 byte sequences in text constants.\r
2591 *** Refactor `ml.lex` and `mlb.lex` to be more maintainable.\r
2592 *** Rename `allowRecPunning` annotation to `allowRecordPunExps`.\r
2593\r
2594* 2017-02-27\r
2595 ** Update ML-Yacc examples (`calc`, `fol`, `pascal`) to comply with MLton\r
2596 build process. Thanks to Hai Nguyen Van for the pull request.\r
2597\r
2598* 2017-01-25\r
2599 ** Update PortingMLton documentation and `./bin/add-cross` script. Thanks to\r
2600 Daniel Moerner for the pull request.\r
2601\r
2602* 2016-09-29\r
2603 ** Constant fold `CPointer_equal(NULL, NULL)` to `true`.\r
2604\r
2605* 2016-09-29\r
2606 ** Introduce `NEEDS_SIGALTSTACK_EXEC` config in runtime system.\r
2607\r
2608* 2016-09-27\r
2609 ** Construct a devel build version string from last commit time and last\r
2610 commit hash.\r
2611 ** Omit build date and build node from version banner; makes self-compiles\r
2612 deterministic.\r
2613 ** Remove `upgrade-basis.sml` from build. The generated `upgrade-basis.sml`\r
2614 was introduced to handle incompatibilities in the Basis Library provided by an\r
2615 old version of MLton and the Basis Library assumed by the current sources.\r
2616 However, there are no incompatibilities with MLton 20130715, MLton 20100608,\r
2617 or MLton 20070826. Nonetheless, the feature testing performed by\r
2618 `./bin/upgrade-basis` to generate `upgrade-basis.sml` is time consuming,\r
2619 especially when trying to simply type check the compiler sources.\r
2620\r
2621* 2016-06-20\r
2622 ** Do not `gzip` man pages on OpenBSD. Thanks to Alexander Abushkevich for\r
2623 the pull request.\r
2624\r
2625* 2016-06-20\r
2626 ** Generate position independent code for OpenBSD. Thanks to Alexander\r
2627 Abushkevich for the pull request.\r
2628\r
2629* 2016-06-20\r
2630 ** Fix profiling for amd64-openbsd and x86-openbsd. Thanks to Alexander\r
2631 Abushkevich for the pull request.\r
2632\r
2633* 2016-04-06\r
2634 ** Update SML/NJ librarys to SML/NJ 110.79.\r
2635\r
2636* 2016-03-22\r
2637 ** Update LLVM codegen to support (and require) &gt;= llvm-3.7. Thanks to Eugene\r
2638 Akentyev for the pull request.\r
2639\r
2640* 2016-02-26\r
2641 ** Configure GMP location via `Makefile`.\r
2642\r
2643* 2016-01-10\r
2644 ** Fix typo in `mlb-formal.tex`. Thanks to Jon Sterling for the pull request.\r
2645\r
2646* 2015-11-10\r
2647 ** Update SML/NJ librarys to SML/NJ 110.78. Use `allowOrPats` and\r
2648 `allowSigWithtype` to minimize diffs.\r
2649\r
2650* 2015-10-20\r
2651 ** Fix elaboration of `withtype` in signature.\r
2652\r
2653* 2015-10-06\r
2654 ** Add support for setting CM anchor bindings in `cm2mlb` tool.\r
2655\r
2656* 2015-10-06\r
2657 ** Fix non-exhaustive match warnings with or-patterns. Thanks to Rob Simmons\r
2658 for the bug report.\r
2659 ** Distinguish between partial and fully redundant matches.\r
2660 ** Report partial redundancy in `val` declarations.\r
2661 ** Lower precedence of or-patterns in parser.\r
2662 ** Make a variety of cosmetic improvements to non-exhaustive and redundant\r
2663 error/warning messages, primarily to be consistent in formatting between\r
2664 quoted AST and generated messages.\r
2665\r
2666* 2015-07-10\r
2667 ** Extend support for arm64 (aarch64). Thanks to Edmund Evans for the patch.\r
2668\r
2669* 2015-06-22\r
2670 ** Introduce `valrecConstr {warn|error|ignore}` MLB annotation to report when\r
2671 a `val rec` (or `fun`) declaration redefines an identifier that previously had\r
2672 constructor status.\r
2673\r
2674* 2015-06-19\r
2675 ** Add support for selected SuccessorML features (undertaken by Kevin Bradley\r
2676 as an RIT CS MS Capstone Project).\r
2677 *** `do`-declarations (`allowDoDecls`)\r
2678 *** extended literals (`allowExtendedLiterals`)\r
2679 *** line comments (`allowLineComments`)\r
2680 *** optional leading bar in matches, fun decls, and datatype decls\r
2681 (`allowOptBar`)\r
2682 *** optional trailing semicolon in sequence expressions (`allowOptSemicolon`)\r
2683 *** or patterns (`allowOrPats`)\r
2684 *** record expression punning (`allowRecPunning`)\r
2685 *** withtype in signatures (`allowSigWithtype`)\r
2686\r
2687* 2015-06-10\r
2688 ** Hide equality status of poly (and mono) vector and array slices.\r
2689 ** Hide type equality of mono and poly `Word8.word` arrays and vectors.\r
2690\r
2691* 2015-06-08\r
2692 ** Added `reentrant` attribute to `_import`. An `_import`-ed C function that\r
2693 (directly or indirectly) calls an `_export`-ed SML function should be\r
2694 attributed `reentrant`.\r
2695\r
2696* 2015-06-08\r
2697 ** Make compilation deterministic:\r
2698 *** Eliminate output executable name from compile-time specified `@MLton`\r
2699 arguments.\r
2700 *** Deterministically generate magic constant for executable.\r
2701\r
2702* 2015-06-08\r
2703 ** Add `-keep ast` compile option. Undertaken by Ross Bayer at RIT supported\r
2704 by NSF CISE Research Infrastructure (CRI) award.\r
2705\r
2706* 2015-06-02\r
2707 ** Updates to Debian packaging. Thanks to Christopher Cramer for the pull\r
2708 request.\r
2709\r
2710* 2015-03-30\r
2711 ** Use `LANG=en_us` when computing version and build date. Thanks to Eugene\r
2712 Akentyev for the pull request.\r
2713\r
2714* 2015-02-17\r
2715 ** Update `mlnlffigen` to warn and skip functions with `struct`/`union`\r
2716 arguments. Thanks to Armando Doval for the pull request.\r
2717\r
2718* 2014-12-22\r
2719 ** Move pervasive constructs from `./mlton/ast` to `./mlton/atoms`, so that\r
2720 `./mlton/ast/sources.mlb` depends on `./mlton/atoms/sources.mlb` (and not the\r
2721 other way around). Undertaken by Vedant Raiththa at RIT supported by NSF CISE\r
2722 Research Infrastructure (CRI) award.\r
2723\r
2724* 2014-12-17\r
2725 ** Cache a worker thread to service calls of `_export`-ed functions. Thanks\r
2726 to Bernard Berthomieu for the bug report.\r
2727\r
2728* 2014-12-02\r
2729 ** Post-process generated front-end files for compatibility with SML/NJ's\r
2730 recent `ml-lex` and `ml-yacc` tools that generate log identifiers rather than\r
2731 unqualified (top-level environment) identifiers.\r
2732 ** Corrected documentation for SML/NJ `Makefile` target and fixed\r
2733 `bootstrap-nj` target. Thanks to Daniel Rosenwasser for the pull request.\r
2734\r
2735* 2014-11-21\r
2736 ** Reorganized runtime support for `IntInf` operations so that programs that\r
2737 do not use `IntInf` compile to executables with no residual dependency on GMP.\r
2738 ** Fixed bug in `MLton.IntInf.fromRep` that could yield values that violate\r
2739 the `IntInf` representation invariants. Thanks to Rob Simmons for the bug\r
2740 report.\r
2741\r
2742* 2014-10-24\r
2743 ** Added `pure` and `impure` attributes to `_import`. An unattributed\r
2744 `_import` is treated as `impure`. A `pure` `_import` may be subject to more\r
2745 aggressive optimizations (common subexpression elimination, dead-code\r
2746 elimination). Undertaken by Vedant Raiththa at RIT supported by NSF CISE\r
2747 Research Infrastructure (CRI) award.\r
2748\r
2749* 2014-10-22\r
2750 ** Various updates to treatment of `IntInf` constants in the compiler.\r
2751 *** Recognize both `Big` and `Small` representations of `IntInf`-s.\r
2752 *** Translate `IntInf` consts to `Big` and `Small` representations in\r
2753 conversion from SSA to RSSA. This is consistent with the treatment of other\r
2754 `IntInf` operations in the conversion. After the conversion, `IntInf` is no\r
2755 longer treated as a primitive.\r
2756 *** Remove `initIntInfs` from program initialization.\r
2757 *** Constant fold `IntInf_toVector` and `WordVector_toIntInf` primitives.\r
2758\r
2759* 2014-10-20\r
2760 ** Various updates to `structure WordXVector` in compiler proper.\r
2761 *** Update the `WordXVector.layout` function. If the `elementSize` is\r
2762 `WordX.word8` and more than 90% of the characters satisfy `Char.isGraph\r
2763 orelse Char.isSpace`, then display as an SML string constant (with\r
2764 non-printable characters SML-escaped). Otherwise, display as an SML/NJ-style\r
2765 `#[0x0, 0xF]` vector literal.\r
2766 *** Update initialization of `static struct GC_vectorInit vectorInits[]`\r
2767 constants in runtime. If the `WordXVector`'s (primitive) `elementSize` is\r
2768 `WordSize.W8`, then emit a C-escaped string constant. Otherwise, emit a\r
2769 C-array initialization.\r
2770\r
2771* 2014-08-15\r
2772 ** More updates to benchmark infrastructure.\r
2773 *** Make `update-counts.sh` script more robust.\r
2774 *** Update `hamlet.sml` benchmark program to close input file after each\r
2775 loop.\r
2776 *** Update `fft.sml` benchmark program to only invoke `test` function with\r
2777 power-of-2 arguments.\r
2778 *** Update `model-elimination.sml` benchmark program to iterate `main ()`\r
2779 according to `doit` size parameter.\r
2780\r
2781* 2014-08-11\r
2782 ** Include `winsock2.h` before `windows.h` in MinGW port. Thanks to Shu-Hung\r
2783 You for the pull request.\r
2784\r
2785* 2014-07-31\r
2786 ** Refactor array and vector implementation in Basis Library into a primitive\r
2787 implementation (using `SeqInt.int` for indexing) and a wrapper implementation\r
2788 (using the default `Int.int` for indexing). Thanks to Rob Simmons for the\r
2789 pull request.\r
2790 ** Correct description of `MLton.{Vector,Array}.unfoldi` on website. Thanks\r
2791 to Rob Simmons for the pull request.\r
2792\r
2793* 2014-07-14\r
2794 ** Updates to benchmark infrastructure.\r
2795 *** Add `even-odd.sml` benchmark that exercises mutual tail recursion.\r
2796 *** Add `update-counts.sh` script to calculate appropriate benchmark\r
2797 iteration counts and update benchmark iteration counts so that all\r
2798 benchmarks run for at least 30 seconds.\r
2799 *** Updates to benchmark driver program.\r
2800\r
2801* 2014-07-07\r
2802 ** Change `./basis-library/integer/int-inf.sml` to reduce dependency on\r
2803 GMP-specific details of `./basis-library/integer/int-inf0.sml`. Thanks to Rob\r
2804 Simmons for the pull request.\r
2805 ** Correct type and description of `MLton.IntInf.fromRep` on website. Thanks\r
2806 to Rob Simmons for the pull request.\r
2807\r
2808* 2014-07-01\r
2809 ** Add experimental LLVM codegen (undertaken by Brian Leibig as an RIT CS MS\r
2810 Project).\r
2811\r
2812* 2014-06-09\r
2813 ** Update `CallingFromSMLToC` page on website. Thanks to Bikal Gurung for the\r
2814 pull request.\r
2815\r
2816* 2014-03-18\r
2817 ** Updates for MinGW port.\r
2818\r
2819* 2014-02-07\r
2820 ** Update AsciiDoc sources for website.\r
2821\r
2822* 2013-10-31\r
2823 ** Various updates to website. Thanks to Mauricio C Antunes for the pull\r
2824 request.\r
2825 *** Add Tofte's tutorial and Rossberg's grammar.\r
2826 *** Fix links to implementations.\r
2827\r
2828* 2013-10-10\r
2829 ** Update links from `References` page on website. Thanks to Mauricio C\r
2830 Antunes for the pull request.\r
2831\r
2832* 2013-09-02\r
2833 ** Fix example for `Lazy` page on website. Thanks to Daniel Rosenwasser for\r
2834 the pull request.\r
2835\r
2836== Version 20130715\r
2837\r
2838Here are the changes from version 20100608 to version 20130715.\r
2839\r
2840=== Summary\r
2841\r
2842* Compiler.\r
2843 ** Cosmetic improvements to type-error messages.\r
2844 ** Removed features:\r
2845 *** Bytecode codegen: The bytecode codegen had not seen significant use and\r
2846 it was not well understood by any of the active developers.\r
2847 *** Support for `.cm` files as input: The ML Basis system provides much\r
2848 better infrastructure for "programming in the very large" than the (very)\r
2849 limited support for CM. The `cm2mlb` tool (available in the source\r
2850 distribution) can be used to convert CM projects to MLB projects, preserving\r
2851 the CM scoping of module identifiers.\r
2852 ** Bug fixes: see changelog\r
2853* Runtime.\r
2854 ** Bug fixes: see changelog\r
2855* Language.\r
2856 ** Interpret `(*#line line:col "file" *)` directives as relative\r
2857 file names.\r
2858 ** ML Basis annotations.\r
2859 *** Added: `resolveScope`\r
2860* Libraries.\r
2861 ** Basis Library.\r
2862 *** Improved performance of `String.concatWith`.\r
2863 *** Use bit operations for `REAL.class` and other low-level operations.\r
2864 *** Support additional variables with `Posix.ProcEnv.sysconf`.\r
2865 *** Bug fixes: see changelog\r
2866 ** `MLton` structure.\r
2867 *** Removed: `MLton.Socket`\r
2868 ** Other libraries.\r
2869 *** Updated: ckit library, MLRISC library, SML/NJ library\r
2870 *** Added: MLLPT library\r
2871* Tools.\r
2872 ** mllex\r
2873 *** Generate `(*#line line:col "file.lex" *)` directives with simple\r
2874 (relative) file names, rather than absolute paths.\r
2875 ** mlyacc\r
2876 *** Generate `(*#line line:col "file.grm" *)` directives with simple\r
2877 (relative) file names, rather than absolute paths.\r
2878 *** Fixed bug in comment-handling in lexer.\r
2879\r
2880=== Details\r
2881\r
2882* 2013-07-06\r
2883 ** Update SML/NJ libraries to SML/NJ 110.76.\r
2884\r
2885* 2013-06-19\r
2886 ** Upgrade `gdtoa.tgz`; fixed bug in `Real32.{fmt,toDecimal,toString}`, which\r
2887 in some cases produced too many digits\r
2888\r
2889* 2013-06-18\r
2890 ** Removed `MLton.Socket` structure (deprecated in last release).\r
2891\r
2892* 2013-06-10\r
2893 ** Improved performance of `String.concatWith`.\r
2894\r
2895* 2013-05-22\r
2896 ** Update SML/NJ libraries to SML/NJ 110.75.\r
2897\r
2898* 2013-04-30\r
2899 ** Detect PowerPC 64 architecture.\r
2900\r
2901* 2012-10-09\r
2902 ** Fixed bug in elaboration that erroneously accepted the following:\r
2903\r
2904 signature S = sig structure A : sig type t end\r
2905 and B : sig type t end where type t = A.t end\r
2906\r
2907* 2012-09-04\r
2908 ** Introduce an MLB annotation to control overload and flex record resolution\r
2909 scope: `resolveScope {strdec|dec|topdec|program}`.\r
2910\r
2911* 2012-07-04\r
2912 ** Simplify use of `getsockopt` and `setsockopt` in Basis Library.\r
2913 ** Direct implementation of `Socket.Ctl.{getATMARK,getNREAD}` in runtime\r
2914 system, rather than indirect implementation in Basis Library via `ioctl`.\r
2915 ** Replace use of casting through a union with `memcpy` in runtime.\r
2916\r
2917* 2012-06-11\r
2918 ** Use bit operations for `REAL.class` and other low-level operations.\r
2919 ** Fixed bugs in `REAL.copySign`, `REAL.signBit`, and `REAL.{to,from}Decimal`.\r
2920\r
2921* 2012-06-01\r
2922 ** Cosmetic improvements to type-error messages.\r
2923 ** Fixed bug in elaboration that erroneously rejected the following:\r
2924\r
2925 datatype ('a, ''a) t = T\r
2926 type ('a, ''a) u = unit\r
2927\r
2928 and erroneously accepted the following:\r
2929\r
2930 fun f (x: 'a) : ''a = x\r
2931 fun g (x: 'a) : ''a = if x = x then x else x\r
2932\r
2933* 2012-02-24\r
2934 ** Fixed bug in redundant SSA optimization.\r
2935\r
2936* 2011-06-20\r
2937 ** Support additional variables with `Posix.ProcEnv.sysconf`.\r
2938\r
2939* 2011-06-17\r
2940 ** Change `mllex` and `mlyacc` to generate `#line` directives with simple file\r
2941 names, rather than absolute paths.\r
2942 ** Interpret `#line` directives as relative file names.\r
2943\r
2944* 2011-06-14\r
2945 ** Fixed bug in SSA/SSA2 shrinker that could erroneously turn a non-tail\r
2946 function call with a `Bug` transfer as its continuation into a tail function\r
2947 call.\r
2948\r
2949* 2011-06-11\r
2950 ** Update SML/NJ libraries to SML/NJ 110.73 and add ML-LPT library.\r
2951\r
2952* 2011-06-10\r
2953 ** Fixed bug in translation from SSA2 to RSSA with case expressions over\r
2954 non-primitive-sized words.\r
2955 ** Fixed bug in SSA/SSA2 type checking of case expressions over words.\r
2956\r
2957* 2011-06-04\r
2958 ** Upgrade `gdtoa.tgz`.\r
2959 ** Remove bytecode codegen.\r
2960 ** Remove support for `.cm` files as input.\r
2961\r
2962* 2011-05-03\r
2963 ** Fixed a bug with the treatment of `as`-patterns, which should not allow the\r
2964 redefinition of constructor status.\r
2965\r
2966* 2011-02-18\r
2967 ** Fixed bug with treatment of nan in common subexpression elimination SSA\r
2968 optimization.\r
2969\r
2970* 2011-02-18\r
2971 ** Fixed bug in translation from SSA2 to RSSA with weak pointers.\r
2972\r
2973* 2011-02-05\r
2974 ** Fixed bug in amd64 codegen calling convention for varargs C calls.\r
2975\r
2976* 2011-01-17\r
2977 ** Fixed bug in comment-handling in lexer for `mlyacc`'s input language.\r
2978\r
2979* 2010-06-22\r
2980 ** Fixed bug in elaboration of function clauses with different numbers of\r
2981 arguments that would raise an uncaught `Subscript` exception.\r
2982\r
2983\r
2984== Version 20100608\r
2985\r
2986Here are the changes from version 20070826 to version 20100608.\r
2987\r
2988=== Summary\r
2989\r
2990* New platforms.\r
2991 ** ia64-hpux\r
2992 ** powerpc64-aix\r
2993* Compiler.\r
2994 ** Command-line switches.\r
2995 *** Added: `-mlb-path-var '&lt;name&gt; &lt;value&gt;'`\r
2996 *** Removed: `-keep sml`, `-stop sml`\r
2997 ** Improved constant folding of floating-point operations.\r
2998 ** Experimental: Support for compiling to a C library; see wiki documentation.\r
2999 ** Extended `-show-def-use` output to include types of variable definitions.\r
3000 ** Deprecated features (to be removed in a future release)\r
3001 *** Bytecode codegen: The bytecode codegen has not seen significant use and\r
3002 it is not well understood by any of the active developers.\r
3003 *** Support for `.cm` files as input: The ML Basis system provides much\r
3004 better infrastructure for "programming in the very large" than the (very)\r
3005 limited support for CM. The `cm2mlb` tool (available in the source\r
3006 distribution) can be used to convert CM projects to MLB projects, preserving\r
3007 the CM scoping of module identifiers.\r
3008 ** Bug fixes: see changelog\r
3009* Runtime.\r
3010 ** `@MLton` switches.\r
3011 *** Added: `may-page-heap {false|true}`\r
3012 ** `may-page-heap`: By default, MLton will not page the heap to disk when\r
3013 unable to grow the heap to accomodate an allocation. (Previously, this\r
3014 behavior was the default, with no means to disable, with security an\r
3015 least-surprise issues.)\r
3016 ** Bug fixes: see changelog\r
3017* Language.\r
3018 ** Allow numeric characters in ML Basis path variables.\r
3019* Libraries.\r
3020 ** Basis Library.\r
3021 *** Bug fixes: see changelog.\r
3022 ** `MLton` structure.\r
3023 *** Added: `MLton.equal`, `MLton.hash`, `MLton.Cont.isolate`,\r
3024 `MLton.GC.Statistics, `MLton.Pointer.sizeofPointer`,\r
3025 `MLton.Socket.Address.toVector`\r
3026 *** Changed:\r
3027 *** Deprecated: `MLton.Socket`\r
3028 ** `Unsafe` structure.\r
3029 *** Added versions of all of the monomorphic array and vector structures.\r
3030 ** Other libraries.\r
3031 *** Updated: ckit library, MLRISC library, SML/NJ library.\r
3032* Tools.\r
3033 ** `mllex`\r
3034 *** Eliminated top-level `type int = Int.int` in output.\r
3035 *** Include `(*#line line:col "file.lex" *)` directives in output.\r
3036 *** Added `%posint` command, to set the `yypos` type and allow the lexing of\r
3037 multi-gigabyte files.\r
3038 ** `mlnlffigen`\r
3039 *** Added command-line switches `-linkage archive` and `-linkage shared`.\r
3040 *** Deprecated command-line switch `-linkage static`.\r
3041 *** Added support for ia64 and hppa targets.\r
3042 ** `mlyacc`\r
3043 *** Eliminated top-level `type int = Int.int` in output.\r
3044 *** Include `(*#line line:col "file.grm" *)` directives in output.\r
3045\r
3046=== Details\r
3047\r
3048* 2010-05-12\r
3049 ** Fixed bug in the mark-compact garbage collector where the C library's\r
3050 `memcpy` was used to move objects during the compaction phase; this could lead\r
3051 to heap corruption and segmentation faults with newer versions of `gcc` and/or\r
3052 `glibc`, which assume that src and dst in a `memcpy` do not overlap.\r
3053\r
3054* 2010-03-12\r
3055 ** Fixed bug in elaboration of `datatype` declarations with `withtype`\r
3056 bindings.\r
3057\r
3058* 2009-12-11\r
3059 ** Fixed performance bug in RefFlatten SSA2 optimization.\r
3060\r
3061* 2009-12-09\r
3062 ** Fixed performance bug in SimplifyTypes SSA optimization.\r
3063\r
3064* 2009-12-02\r
3065 ** Fixed bug in amd64 codegen register allocation of indirect C calls.\r
3066\r
3067* 2009-09-17\r
3068 ** Fixed bug in `IntInf.scan` and `IntInf.fromString` where leading spaces\r
3069 were only accepted if the stream had an explicit sign character.\r
3070\r
3071* 2009-07-10\r
3072 ** Added CombineConversions SSA optimization.\r
3073\r
3074* 2009-06-09\r
3075 ** Removed deprecated command line switch `-show-anns {false, true}`.\r
3076\r
3077* 2009-04-18\r
3078 ** Removed command line switches `-keep sml` and `-stop sml`. Their meaning\r
3079 was unclear with `.mlb` files; their effect with `.cm` files can be achieved\r
3080 with `-stop f`.\r
3081\r
3082* 2009-04-16\r
3083 ** Fixed bug in `IntInf.~&gt;&gt;` that could cause a `glibc` assertion failure.\r
3084\r
3085* 2009-04-01\r
3086 ** Fixed exported type of `MLton.Process.reap`.\r
3087\r
3088* 2009-01-27\r
3089 ** Added `MLton.Socket.Address.toVector` to get the network-byte-order\r
3090 representation of an IP address.\r
3091\r
3092* 2008-11-10\r
3093 ** Fixed bug in `MLton.size` and `MLton.share` when tracing the current stack.\r
3094\r
3095* 2008-10-27\r
3096 ** Fixed phantom typing of sockets by hiding the representation of socket\r
3097 types. Previously the representation of sockets was revealed rendering the\r
3098 phantom types useless.\r
3099\r
3100* 2008-10-10\r
3101 ** Fixed bug in nested `_export`/`_import` functions.\r
3102\r
3103* 2008-09-12\r
3104 ** Improved constant folding of floating point operations.\r
3105\r
3106* 2008-08-20\r
3107 ** Store the card/cross map at the end of the allocated ML heap; avoids\r
3108 possible out of memory errors when resizing the ML heap cannot be followed by\r
3109 a card/cross map allocation.\r
3110\r
3111* 2008-07-24\r
3112 ** Added support for compiling to a C library. The relevant new compiler\r
3113 options are `-ar` and `-format`. Libraries are named based on the name of the\r
3114 `-export-header` file. Libraries have two extra methods:\r
3115 *** `NAME_open(argc, argv)` initializes the library and runs the SML code\r
3116 until it reaches the end of the program. If the SML code exits or raises an\r
3117 uncaught exception, the entire program will terminate.\r
3118 *** `NAME_close()` will execute any registered atExit functions, any\r
3119 outstanding finalizers, and frees the ML heap.\r
3120\r
3121* 2008-07-16\r
3122 ** Fixed bug in the name mangling of `_import`-ed functions with the `stdcall`\r
3123 convention.\r
3124\r
3125* 2008-06-12\r
3126 ** Added `MLton.Pointer.sizeofPointer`.\r
3127\r
3128* 2008-06-06\r
3129 ** Added expert command line switch `-emit-main {true|false}`.\r
3130\r
3131* 2008-05-17\r
3132 ** Fixed bug in Windows code to page the heap to disk when unable to grow the\r
3133 heap to a desired size. Thanks to Sami Evangelista for the bug report.\r
3134\r
3135* 2008-05-10\r
3136 ** Implemented `MLton.Cont.isolate`.\r
3137\r
3138* 2008-04-20\r
3139 ** Fixed bug in *NIX code to page the heap to disk when unable to grow the\r
3140 heap to a desired size. Thanks to Nicolas Bertolotti for the bug report and\r
3141 patch.\r
3142\r
3143* 2008-04-07\r
3144 ** More flexible active/paused stack resizing policy. +\r
3145 Removed `thread-shrink-ratio` runtime option. + Added\r
3146 `stack-current-grow-ratio`, `stack-current-max-reserved-ratio`,\r
3147 `stack-current-permit-ratio`, `stack-current-shrink-ratio`,\r
3148 `stack-max-reserved-ratio`, and `stack-shrink-ratio` runtime options.\r
3149\r
3150* 2008-04-07\r
3151 ** Fixed bugs in Basis Library where the representations of `OS.IO.iodesc`,\r
3152 `Posix.IO.file_desc`, `Posix.Signal.signal`, `Socket.sock`,\r
3153 `Socket.SOGK.sock_type` as integers were exposed.\r
3154\r
3155* 2008-03-14\r
3156 ** Added unsafe versions of all of the monomorphic array and vector\r
3157 structures.\r
3158\r
3159* 2008-03-02\r
3160 ** Fixed bug in Basis Library where the representation of `OS.Process.status`\r
3161 as an integer was exposed.\r
3162\r
3163* 2008-02-13\r
3164 ** Fixed space-safety bug in RefFlatten optimization (to flatten refs into\r
3165 containing data structure). Thanks to Daniel Spoonhower for the bug report and\r
3166 initial diagnosis and patch.\r
3167\r
3168* 2008-01-25\r
3169 ** Various updates to GC statistics gathering. Some basic GC statistics can\r
3170 be accessed from SML by `MLton.GC.Statistics.*` functions.\r
3171\r
3172* 2008-01-24\r
3173 ** Added primitive (structural) polymorphic hash.\r
3174\r
3175* 2008-01-21\r
3176 ** Fixed frontend to accept `op _longvid_` patterns and expressions. Thanks to\r
3177 Florian Weimer for the bug report.\r
3178\r
3179* 2008-01-17\r
3180 ** Extended `-show-def-use` output to include types of variable definitions.\r
3181\r
3182* 2008-01-09\r
3183 ** Extended `MLton_equal` to be a structural equality on all types, including\r
3184 `real` and `-&gt;` types.\r
3185\r
3186* 2007-12-18\r
3187 ** Changed ML-Yacc and ML-Lex to output line directives so that MLton's\r
3188 def-use information points to the source files (`.grm` and `.lex`) instead of\r
3189 the generated implementations (`.grm.sml` and `.lex.sml`).\r
3190\r
3191* 2007-12-14\r
3192 ** Added runtime option `may-page-heap {false|true}`. By default, MLton will\r
3193 not page the heap to disk when unable to grow the heap to a desired size.\r
3194 (Previously, this behavior was the default, with no means to disable, with\r
3195 security and least-surprise concerns.) Thanks to Wesley Terpstra for the\r
3196 patch.\r
3197 ** Fixed bug the FFI visible representation of `Int16.int ref` (and references\r
3198 of other primitive types smaller than 32-bits) on big-endian platforms. Thanks\r
3199 to Dave Herman for the bug report.\r
3200\r
3201* 2007-12-13\r
3202 ** Fixed bug in `ImperativeIOExtra.canInput` (`TextIO.canInput`). Thanks to\r
3203 Ville Laurikari for the bug report.\r
3204\r
3205* 2007-12-09\r
3206 ** Better constant folding of `IntInf` operations.\r
3207\r
3208* 2007-12-07\r
3209 ** Fixed bug in algebraic simplification of `RealX` primitives. `Real.&lt;= (x,\r
3210 x)` is `false` when `x` is `NaN`.\r
3211\r
3212* 2007-11-29\r
3213 ** Fixed bug in type inference of flexible records. This would later cause\r
3214 the compiler to raise the `TypeError` exception. Thanks to Wesley Terpstra for\r
3215 the bug report.\r
3216\r
3217* 2007-11-28\r
3218 ** Fixed bug in cross-compilation of `gdtoa` library. Thanks to Wesley\r
3219 Terpstra for the bug report and patch.\r
3220\r
3221* 2007-11-20\r
3222 ** Fixed bug in RefFlatten optimization (pass to flatten refs into containing\r
3223 data structure). Thanks to Ruy LeyWild for the bug report.\r
3224\r
3225* 2007-11-19\r
3226 ** Fixed bug in the handling of weak pointers by the mark-compact garbage\r
3227 collector. Thanks to Sean McLaughlin for the bug report and Florian Weimer for\r
3228 the initial diagnosis.\r
3229\r
3230* 2007-11-07\r
3231 ** Added `%posint` command to `ml-lex`, to set the `yypos` type and allow the\r
3232 lexing of multi-gigabyte input files. Thanks to Florian Weimer for the feature\r
3233 concept and original patch.\r
3234\r
3235* 2007-11-07\r
3236 ** Added command-line switch `-mlb-path-var '&lt;name&gt; &lt;value&gt;'` for specifying\r
3237 MLB path variables.\r
3238\r
3239* 2007-11-06\r
3240 ** Allow numeric characters in MLB path variables.\r
3241\r
3242* 2007-09-20\r
3243 ** Fixed bug in elaboration of structures with signature constraints. This\r
3244 would later cause the compiler to raise the `TypeError` exception. Thanks to\r
3245 Vesa Karvonen for the bug report.\r
3246\r
3247* 2007-09-11\r
3248 ** Fixed bug in interaction of `_export`-ed functions and signal\r
3249 handlers. Thanks to Sean McLaughlin for the bug report.\r
3250\r
3251* 2007-09-03\r
3252 ** Fixed bug in implementation of `_export`-ed functions using `char`\r
3253 type. Thanks to Katsuhiro Ueno for the bug report.\r
3254\r
3255\r
3256== Version 20070826\r
3257\r
3258Here are the changes from version 20051202 to version 20070826.\r
3259\r
3260=== Summary\r
3261\r
3262* New platforms:\r
3263 ** amd64-linux, amd64-freebsd\r
3264 ** hppa-hpux\r
3265 ** powerpc-aix\r
3266 ** x86-darwin (Mac OS X)\r
3267* Compiler.\r
3268 ** Support for 64-bit platforms.\r
3269 *** Native amd64 codegen.\r
3270 ** Command-line switches.\r
3271 *** Added: `-codegen amd64`, `-codegen x86`, `-default-type &lt;type&gt;`,\r
3272 `-profile-val {false|true}`.\r
3273 *** Changed: `-stop f` (file listing now includes `.mlb` files)\r
3274 ** Bytecode codegen.\r
3275 *** Support for profiling.\r
3276 *** Support for exception history.\r
3277* Language.\r
3278 ** ML Basis annotations.\r
3279 *** Removed: `allowExport`, `allowImport`, `sequenceUnit`, `warnMatch`.\r
3280* Libraries.\r
3281 ** Basis Library.\r
3282 *** Added: `PackWord16Big, `PackWord16Little`, `PackWord64Big`,\r
3283 `PackWord64Little`.\r
3284 *** Bug Fixes: see changelog.\r
3285 ** `MLton` structure.\r
3286 *** Added: `MLTON_MONO_ARRAY`, `MLTON_MONO_VECTOR`, `MLTON_REAL`,\r
3287 `MLton.BinIO.tempPrefix`, `MLton.CharArray`, `MLton.CharVector`,\r
3288 `MLton.IntInf.BigWord`, `MLton.IntInf.SmallInt`,\r
3289 `MLton.Exn.defaultTopLevelHandler`, `MLton.Exn.getTopLevelHandler`,\r
3290 `MLton.Exn.setTopLevelHandler`, `MLton.LargeReal`, `MLton.LargeWord`,\r
3291 `MLton.Real`, `MLton.Real32`, `MLton.Real64`, `MLton.Rlimit.Rlim`,\r
3292 `MLton.TextIO.tempPrefix`, `MLton.Vector.create`, `MLton.Word.bswap`,\r
3293 `MLton.Word8.bswap`, `MLton.Word16`, `MLton.Word32`, `MLton.Word64`,\r
3294 `MLton.Word8Array`, `MLton.Word8Vector`.\r
3295 *** Changed: `MLton.Array.unfoldi`, `MLton.IntInf.rep`, `MLton.Rlimit`,\r
3296 `MLton.Vector.unfoldi`.\r
3297 *** Deprecated: `MLton.Socket`\r
3298 ** Other libraries.\r
3299 *** Added: MLRISC libary.\r
3300 *** Updated: ckit library, SML/NJ library.\r
3301* Tools.\r
3302\r
3303=== Details\r
3304\r
3305* 2007-08-12\r
3306 ** Removed deprecated ML Basis annotations.\r
3307\r
3308* 2007-08-06\r
3309 ** Fixed bug in treatment of `Real&lt;N&gt;.{scan,fromString}` operations.\r
3310 `Real&lt;N&gt;.{scan,fromString}` were using `TO_NEAREST` semantics, but should obey\r
3311 current rounding mode. (Only `Real&lt;N&gt;.fromDecimal` is specified to always\r
3312 have `TO_NEAREST` semantics.) Thanks to Sean McLaughlin for the bug report.\r
3313\r
3314* 2007-07-27\r
3315 ** Fixed bugs in constant-folding of floating-point operations with C codegen.\r
3316\r
3317* 2007-07-26\r
3318 ** Fixed bug in treatment of floating-point operations. Floating-point\r
3319 operations depend on the current rounding mode, but were being treated as\r
3320 pure. Thanks to Sean McLaughlin for the bug report.\r
3321\r
3322* 2007-07-13\r
3323 ** Added `MLton.Exn.{default,get,set}TopLevelHandler`.\r
3324\r
3325* 2007-07-12\r
3326 ** Restored `native` option to `-codegen` flag.\r
3327\r
3328* 2007-07-11\r
3329 ** Fixed bug in `Real32.toInt`: conversion of real values close to\r
3330 `Int.maxInt` could be incorrect.\r
3331\r
3332* 2007-07-07\r
3333 ** Updates to bytecode code generator: support for amd64-* targets, support\r
3334 for profiling (including exception history).\r
3335 ** Fixed bug in `Socket` module of Basis Library; unmarshalling of socket\r
3336 options (for `get*` functions) used `andb` rather than `orb`. Thanks to Anders\r
3337 Petersson for the bug report (and patch).\r
3338\r
3339* 2007-07-06\r
3340 ** Fixed bug in `Date` module of Basis Library; some functions would\r
3341 erroneously raise `Date` when given a year &lt;= 1900. Thanks to Joe Hurd for the\r
3342 bug report.\r
3343 ** Fixed a long-standing bug in monomorphisation pass. Thanks to Vesa Karvonen\r
3344 for the bug report.\r
3345\r
3346* 2007-05-18\r
3347 ** Native amd64 code generator for amd64-* targets.\r
3348 ** Eliminate `native` option from `-codegen` flag.\r
3349 ** Add `x86` and `amd64` options to `-codegen` flag.\r
3350\r
3351* 2007-04-29\r
3352 ** Improved type checking of RSSA and Machine ILs.\r
3353\r
3354* 2007-04-14\r
3355 ** Fixed aliasing issues with `basis/Real/*.c` files.\r
3356 ** Added real/word casts in `MLton` structure.\r
3357\r
3358* 2007-04-12\r
3359 ** Added primitives for bit cast of word to/from real.\r
3360 ** Implement `PackReal&lt;N&gt;{Big,Little}` using `PackWord&lt;N&gt;{Big,Little}` and bit\r
3361 casts.\r
3362\r
3363* 2007-04-11\r
3364 ** Move all system header `#include`-s to `platform/` os headers.\r
3365 ** Use C99 `&lt;assert.h&gt;`, rather than custom `"assert.{h,c}"`.\r
3366\r
3367* 2007-03-13\r
3368 ** Implement `PackWord&lt;N&gt;{Big,Little}` entirely in ML, using an ML byte swap\r
3369 function.\r
3370\r
3371* 2007-02-25\r
3372 ** Change amd64-* target platforms from 32-bit compatibility mode (i.e.,\r
3373 `-m32`) to 64-bit mode (i.e., `-m64`). Currently, only the C codegen is able\r
3374 to generate 64-bit executables.\r
3375\r
3376* 2007-02-23\r
3377 ** Removed expert command line switch `-coalesce &lt;n&gt;`.\r
3378 ** Added expert command line switch `-chunkify {coalesce&lt;n&gt;|func|one}`.\r
3379\r
3380* 2007-02-20\r
3381 ** Fixed bug in `PackReal&lt;N&gt;.toBytes`. Thanks to Eric McCorkle for the bug\r
3382 report (and patch).\r
3383\r
3384* 2007-02-18\r
3385 ** Added command line switch `-profile-val`, to profile the evaluation of\r
3386 `val` bindings; this is particularly useful with exception history for\r
3387 debugging uncaught exceptions at the top-level.\r
3388\r
3389* 2006-12-29\r
3390 ** Added command line switch `-show {anns|path-map}` and deprecated command\r
3391 line switch `-show-anns {false|true}`. Use `-show path-map` to see the\r
3392 complete MLB path map as seen by the compiler.\r
3393\r
3394* 2006-12-20\r
3395 ** Changed the output of command line switch `-stop f` to include `.mlb`\r
3396 files. This is useful for generating Makefile dependencies. The old output\r
3397 is easy to recover if necessary (e.g. `grep -v '\.mlb$'`).\r
3398\r
3399* 2006-12-08\r
3400 ** Added command line switches `-{,target}-{as,cc,link}-opt-quote`, which pass\r
3401 their argument as a single argument to `gcc` (i.e., without tokenization at\r
3402 spaces). These options support using headers and libraries (including the\r
3403 MLton runtime headers and libraries) from a path with spaces.\r
3404\r
3405* 2006-12-02\r
3406 ** Extensive reorganization of garbage collector, runtime system, and Basis\r
3407 Library implementation. (This is in preparation for future 64bit support.)\r
3408 They should be more C standards compliant and easier to port to new systems.\r
3409 ** FFI revisions\r
3410 *** Disallow nested indirect types (e.g., `int array array`).\r
3411\r
3412* 2006-11-30\r
3413 ** Fixed a bug in elaboration of FFI forms; unary FFI types (e.g., `array`,\r
3414 `ref`, `vector`) could be used in places where `MLton.Pointer.t` was required.\r
3415 This would later cause the compiler to raise the `TypeError` exception, along\r
3416 with a lot of XML IL.\r
3417\r
3418* 2006-11-19\r
3419 ** On *-darwin, work with GnuMP installed via Fink or MacPorts.\r
3420\r
3421* 2006-10-30\r
3422 ** Ported to x86-darwin.\r
3423\r
3424* 2006-09-23\r
3425 ** Added missing specification of `find` to the `MONO_VECTOR` signature.\r
3426\r
3427* 2006-08-03\r
3428 ** Fixed a bug in Useless SSA optimization, caused by calling an imported C\r
3429 function and then ignoring the result.\r
3430\r
3431* 2006-06-24\r
3432 ** Fixed a bug in pass to flatten data structures. Thanks to Joe Hurd for the\r
3433 bug report.\r
3434\r
3435* 2006-06-08\r
3436 ** Fixed a bug in the native codegen's implementation of the C-calling\r
3437 convention.\r
3438\r
3439* 2006-05-11\r
3440 ** Ported to PowerPC-AIX.\r
3441 ** Fixed a bug in the runtime for the cases where nonblocking IO with sockets\r
3442 was implemented using `MSG_DONTWAIT`. This flag does not exist on AIX,\r
3443 Cygwin, HPUX, and MinGW and was previously just ignored. Now the runtime\r
3444 simulates the flag for these platforms (except MinGW, yet, where it's still\r
3445 ignored).\r
3446\r
3447* 2006-05-06\r
3448 ** Added `-default-type '&lt;ty&gt;&lt;N&gt;'` for specifying the binding of default types\r
3449 in the Basis Library (e.g., `Int.int`).\r
3450\r
3451* 2006-04-25\r
3452 ** Ported to HPPA-HPUX.\r
3453 ** Fixed `PackReal{,32,64}{Big,Little}` to follow the Basis Library\r
3454 specification.\r
3455\r
3456* 2006-04-19\r
3457 ** Fixed a bug in `MLton.share` that could cause a segfault.\r
3458\r
3459* 2006-03-30\r
3460 ** Changed `MLton.Vector.unfoldi` to return the state in addition to the\r
3461 result vector.\r
3462\r
3463* 2006-03-30\r
3464 ** Added `MLton.Vector.create`, a more powerful vector-creation function than\r
3465 is available in the basis library.\r
3466\r
3467* 2006-03-04\r
3468 ** Added MLRISC from SML/NJ 110.57 to standard distribution.\r
3469\r
3470* 2006-03-03\r
3471 ** Fixed bug in SSA simplifier that could eliminate an irredundant test.\r
3472\r
3473* 2006-03-02\r
3474 ** Ported a bugfix from SML/NJ for a bug with the combination of `withNack`\r
3475 and `never` in CML.\r
3476\r
3477* 2006-02-09\r
3478 ** Support compiler specific annotations in ML Basis files. If an annotation\r
3479 contains `:`, then the text preceding the `:` is meant to denote a compiler.\r
3480 For MLton, if the text preceding the `:` is equal to `mlton`, then the\r
3481 remaining annotation is scanned as a normal annotation. If the text preceding\r
3482 the `:` is not-equal to `mlton`, then the annotation is ignored, and no\r
3483 warning is issued.\r
3484\r
3485* 2006-02-04\r
3486 ** Fixed bug in elaboration of functors; a program with a very large number of\r
3487 functors could exhibit the error `ElaborateEnv.functorClosure: firstTycons`.\r
3488\r
3489\r
3490== Version 20051202\r
3491\r
3492Here are the changes from version 20041109 to version 20051202.\r
3493\r
3494=== Summary\r
3495\r
3496* New license: BSD-style instead of GPL.\r
3497* New platforms:\r
3498 ** hppa: Debian Linux.\r
3499 ** x86: MinGW.\r
3500* Compiler.\r
3501 ** improved exception history.\r
3502 ** Command-line switches.\r
3503 *** Added: `-as-opt`, `-mlb-path-map`, `-target-as-opt`, `-target-cc-opt`.\r
3504 *** Deprecated: none.\r
3505 *** Removed: `-native`, `-sequence-unit`, `-warn-match`, `-warn-unused`.\r
3506* Language.\r
3507 ** FFI syntax changes and extensions.\r
3508 *** Added: `_symbol`.\r
3509 *** Changed: `_export`, `_import`.\r
3510 *** Removed: `_ffi`.\r
3511 ** ML Basis annotations.\r
3512 *** Added: `allowFFI`, `nonexhaustiveExnMatch`, `nonexhaustiveMatch`,\r
3513 `redundantMatch`, `sequenceNonUnit`.\r
3514 *** Deprecated: `allowExport`, `allowImport`, `sequenceUnit`, `warnMatch`.\r
3515* Libraries.\r
3516 ** Basis Library.\r
3517 *** Added: `Int1`, `Word1`.\r
3518 ** `MLton` structure.\r
3519 *** Added: `Process.create`, `ProcEnv.setgroups`, `Rusage.measureGC`,\r
3520 `Socket.fdToSock`, `Socket.Ctl.getError`.\r
3521 *** Changed: `MLton.Platform.Arch`.\r
3522 ** Other libraries.\r
3523 *** Added: ckit library, ML-NLFFI library, SML/NJ library.\r
3524* Tools.\r
3525 ** updates of `mllex` and `mlyacc` from SML/NJ.\r
3526 ** added `mlnlffigen`.\r
3527 ** profiling supports better inclusion/exclusion of code.\r
3528\r
3529=== Details\r
3530\r
3531* 2005-11-19\r
3532 ** Updated SML/NJ Library and CKit Library from SML/NJ 110.57.\r
3533\r
3534* 2005-11-15\r
3535 ** Fixed a bug in `MLton.ProcEnv.setgroups`.\r
3536\r
3537* 2005-11-11\r
3538 ** Fixed a bug in the interleaving of lexing/parsing and elaborating of ML\r
3539 Basis files, which would raise an unhandled `Force` exception on cyclic basis\r
3540 references. Thanks to John Dias for the bug report.\r
3541\r
3542* 2005-11-10\r
3543 ** Fixed two bugs in `Time.scan`. One would raise `Time` on a string with a\r
3544 large fractional component. Thanks to Carsten Varming for the bug report.\r
3545 The other failed to scan strings with an explicit sign followed by a decimal\r
3546 point.\r
3547\r
3548* 2005-11-03\r
3549 ** Removed `MLton.GC.setRusage`.\r
3550 ** Added `MLton.Rusage.measureGC`.\r
3551\r
3552* 2005-09-11\r
3553 ** Fixed bug in display of types with large numbers of type variables, which\r
3554 could cause unhandled exception `Chr`.\r
3555\r
3556* 2005-09-08\r
3557 ** Fixed bug in type inference of flexible records that would show up as\r
3558 `"Type error: variable applied to wrong number of type args"`.\r
3559\r
3560* 2005-09-06\r
3561 ** Fixed bug in `Real.signBit`, which had assumed that the underlying C\r
3562 signbit returned 0 or 1, when in fact any nonzero value is allowed to indicate\r
3563 the signbit is set.\r
3564\r
3565* 2005-09-05\r
3566 ** Added `-mlb-path-map` switch.\r
3567\r
3568* 2005-08-25\r
3569 ** Fixed bug in `MLton.Finalizable.touch`, which was not keeping alive\r
3570 finalizable values in all cases.\r
3571\r
3572* 2005-08-18\r
3573 ** Added SML/NJ Library and CKit Library from SML/NJ 110.55 to standard\r
3574 distribution.\r
3575 ** Fixed bug in `Socket.Ctl.*`, which got the endianness wrong on big-endian\r
3576 machines. Thanks to Wesley Terpstra for the bug report and fix.\r
3577 ** Added `MLton.GC.setRusage`.\r
3578 ** Fixed bug in `mllex`, which had file positions starting at 2. They now\r
3579 start at zero.\r
3580\r
3581* 2005-08-15\r
3582 ** Fixed bug in `LargeInt.scan`, which should skip leading `"0x"` and `"0X"`.\r
3583 Thanks to Wesley Terpstra for the bug report and fix.\r
3584\r
3585* 2005-08-06\r
3586 ** Additional revisions of FFI:\r
3587 *** Deprecated `_export` with incomplete annotation.\r
3588 *** Added `_address` for address of C objects.\r
3589 *** Eliminated address component of `_symbol`.\r
3590 *** Changed the type of the `_symbol*` expression.\r
3591 *** See documentation for more detail.\r
3592\r
3593* 2005-08-06\r
3594 ** Annotation changes:\r
3595 *** Deprecated: `sequenceUnit`\r
3596 *** Added: `sequenceNonUnit`\r
3597\r
3598* 2005-08-03\r
3599 ** Annotation changes:\r
3600 *** Deprecated: `allowExport`, `allowImport`, `warnMatch`\r
3601 *** Added: `allowFFI`, `nonexhaustiveExnMatch`, `nonexhaustiveMatch`,\r
3602 `redundantMatch`\r
3603\r
3604* 2005-08-01\r
3605 ** Update `mllex` and `mlyacc` with SML/NJ 110.55+ versions. This\r
3606 incorporates a small number of minor bug fixes.\r
3607\r
3608* 2005-07-23\r
3609 ** Fixed bug in pass to flatten refs into containing data structure.\r
3610\r
3611* 2005-07-23\r
3612 ** Overhaul of FFI:\r
3613 *** Deprecated `_import` of C base types.\r
3614 *** Added `_symbol` for address, getter, and setter of C base types.\r
3615 *** See documentation for more detail.\r
3616\r
3617* 2005-07-21\r
3618 ** Update `mllex` and `mlyacc` with SML/NJ 110.55 versions. This incorporates\r
3619 a small number of minor bug fixes.\r
3620\r
3621* 2005-07-20\r
3622 ** Fixed bug in front end that allowed unary constructors to be used without\r
3623 an argument in patterns.\r
3624\r
3625* 2005-07-19\r
3626 ** Eliminated `_ffi`, which has been deprecated for some time.\r
3627\r
3628* 2005-07-14\r
3629 ** Fixed bug in runtime that caused getrusage to be called on every GC, even\r
3630 if timing info isn't needed.\r
3631\r
3632* 2005-07-13\r
3633 ** Fixed bug in closure conversion tickled by making a weak pointer to a\r
3634 closure.\r
3635\r
3636* 2005-07-12\r
3637 ** Changed `{OS,Posix}.Process.sleep` to call `nanosleep()` instead of\r
3638 `sleep()`.\r
3639 ** Added `MLton.ProcEnv.setgroups`.\r
3640\r
3641* 2005-07-11\r
3642 ** `InetSock.{any,toAddr}` raise `SysErr` if port is not in [0, 2^16^).\r
3643\r
3644* 2005-07-02\r
3645 ** Fixed bug in `Socket.recvVecFrom{,',NB,NB'}`. The type was too polymorphic\r
3646 and allowed the creation of a bogus `sock_addr`.\r
3647\r
3648* 2005-06-28\r
3649 ** The front end now reports errors on encountering undefined or cyclicly\r
3650 defined MLB path variables.\r
3651\r
3652* 2005-05-22\r
3653 ** Fixed bug in `Posix.IO.{getlk,setlk,setlkw}` that caused a link-time error:\r
3654 undefined reference to `Posix_IO_FLock_typ`.\r
3655 ** Improved exception history so that the first entry in the history is the\r
3656 source position of the raise, and the rest is the call stack.\r
3657\r
3658* 2005-05-19\r
3659 ** Improved exception history for `Overflow` exceptions.\r
3660\r
3661* 2005-04-20\r
3662 ** Fixed a bug in pass to flatten refs into containing data structure.\r
3663\r
3664* 2005-04-14\r
3665 ** Fixed a front-end bug that could cause an internal bug message of the form\r
3666 `"missing flexInst"`.\r
3667\r
3668* 2005-04-13\r
3669 ** Fixed a bug in the representation of flat arrays/vectors that caused\r
3670 incorrect behavior when the element size was 2 or 4 bytes and there were\r
3671 multiple components to the element (e.g. `(char * char) vector`).\r
3672\r
3673* 2005-04-01\r
3674 ** Fixed a bug in `GC_arrayAllocate` that could cause a segfault.\r
3675\r
3676* 2005-03-22\r
3677 ** Added structures `Int1`, `Word1`.\r
3678\r
3679* 2005-03-19\r
3680 ** Fixed a bug that caused `Socket.Ctl.{get,set}LINGER` to raise `Subscript`.\r
3681 The problem was in the use of `PackWord32Little.update`, which scales the\r
3682 supplied index by `bytesPerElem`.\r
3683\r
3684* 2005-03-13\r
3685 ** Fixed a bug in CML mailboxes.\r
3686\r
3687* 2005-02-26\r
3688 ** Fixed an off-by-one error in `mkstemp` defined in `mingw.c`.\r
3689\r
3690* 2005-02-13\r
3691 ** Added `mlnlffigen` tool (heavily adapted from SML/NJ).\r
3692\r
3693* 2005-02-12\r
3694 ** Added MLNLFFI Library (heavily adapted from SML/NJ) to standard\r
3695 distribution.\r
3696\r
3697* 2005-02-04\r
3698 ** Fixed a bug in `OS.path.toString`, which did not raise `InvalidArc` when\r
3699 needed.\r
3700\r
3701* 2005-02-03\r
3702 ** Fixed a bug in `OS.Path.joinDirFile`, which did not raise `InvalidArc` when\r
3703 passed a file that was not an arc.\r
3704\r
3705* 2005-01-26\r
3706 ** Fixed a front end bug that incorrectly rejected expansive __valbind__s with\r
3707 useless bound type variables.\r
3708\r
3709* 2005-01-22\r
3710 ** Fixed x86 codegen bug which failed to account for the possibility that a\r
3711 64-bit move could interfere with itself (as simulated by 32-bit moves).\r
3712\r
3713* 2004-12-22\r
3714 ** Fixed `Real32.fmt StringCvt.EXACT`, which had been producing too many\r
3715 digits of precision because it was converting to a `Real64.real`.\r
3716\r
3717* 2004-12-15\r
3718 ** Replaced MLB path variable `MLTON_ROOT` with `SML_LIB`, to use a more\r
3719 compiler-independent name. We will keep `MLTON_ROOT` aliased to `SML_LIB`\r
3720 until after the next release.\r
3721\r
3722* 2004-12-02\r
3723 ** `Unix.create` now works on all platforms (including Cygwin and MinGW).\r
3724\r
3725* 2004-11-24\r
3726 ** Added support for `MLton.Process.create`, which works on all platforms\r
3727 (including Windows-based ones like Cygwin and MinGW) and allows better control\r
3728 over `std{in,out,err}` for child process.\r
3729\r
3730\r
3731== Version 20041109\r
3732\r
3733Here are the changes from version 20040227 to 20041109.\r
3734\r
3735=== Summary\r
3736\r
3737* New platforms:\r
3738 ** x86: FreeBSD 5.x, OpenBSD\r
3739 ** PowerPC: Darwin (MacOSX)\r
3740* Support for MLBasis files.\r
3741* Support for dynamic libraries.\r
3742* Support for Concurrent ML (CML).\r
3743* New structures: `Int2`, `Int3`, ..., `Int31` and `Word2`, `Word3`, ..., `Word31`.\r
3744* A new form of profiling: `-profile count`.\r
3745* A bytecode generator.\r
3746* Data representation improvements.\r
3747* `MLton` structure changes.\r
3748 ** Added: `share`, `shareAll`\r
3749 ** Changed: `Exn`, `IntInf`, `Signal`, `Thread`.\r
3750* Command-line switch changes.\r
3751 ** Deprecated:\r
3752 *** `-native` (use `-codegen`)\r
3753 *** `-sequence-unit` (use `-default-ann`)\r
3754 *** `-warn-match` (use `-default-ann`)\r
3755 *** `-warn-unused` (use `-default-ann`)\r
3756 ** Removed:\r
3757 *** `-detect-overflow`\r
3758 *** `-exn-history` (use `-const`)\r
3759 *** `-safe`\r
3760 *** `-show-basis-used`\r
3761 ** Added:\r
3762 *** `-codegen`\r
3763 *** `-const`\r
3764 *** `-default-ann`\r
3765 *** `-disable-ann`\r
3766 *** `-profile-branch`\r
3767 *** `-target-link-opt`\r
3768\r
3769=== Details\r
3770\r
3771* 2004-09-22\r
3772 ** Extended `_import` to support indirect function calls.\r
3773\r
3774* 2004-09-13\r
3775 ** Made `Date.{fromString,scan}` accept a space (treated as zero) in the first\r
3776 character of the day of the month.\r
3777\r
3778* 2004-09-12\r
3779 ** Fixed bug in `IntInf` that could cause a segfault.\r
3780 ** Remove `MLton.IntInf.size`.\r
3781\r
3782* 2004-09-05\r
3783 ** Made `-detect-overflow` and `-safe` expert options.\r
3784\r
3785* 2004-08-30\r
3786 ** Added `val MLton.share: 'a -&gt; unit`, which maximizes sharing in a heap\r
3787 object.\r
3788\r
3789* 2004-08-27\r
3790 ** Fixed bug in `Real.toLargeInt`. It would incorrectly raise `Option`\r
3791 instead of `Overflow` in the case when the real was not an `INF`, but rounding\r
3792 produced an `INF`.\r
3793 ** Fixed bugs in `Date.{fmt,fromString,scan,toString}`. They incorrectly\r
3794 allowed a space for the first character in the day of the month.\r
3795\r
3796* 2004-08-18\r
3797 ** Changed `MLton.{Thread,Signal,World}` to distinguish between implicitly and\r
3798 explicitly paused threads.\r
3799\r
3800* 2004-07-28\r
3801 ** Added support for programming in the large using the ML Basis system.\r
3802\r
3803* 2004-07-11\r
3804 ** Fixed bugs in `ListPair.*Eq` functions, which incorrectly raised the\r
3805 `UnequalLengths` exception.\r
3806\r
3807* 2004-07-01\r
3808 ** Added `val MLton.Exn.addExnMessager: (exn -&gt; string option) -&gt; unit`.\r
3809\r
3810* 2004-06-23\r
3811 ** Runtime system options that take memory sizes now accept a "`g`" suffix\r
3812 indicating gigabytes. They also now take a real instead of an integer,\r
3813 e.g. `fixed-heap 0.5g`. They also now accept uppercase, e.g. `150M`.\r
3814\r
3815* 2004-06-12\r
3816 ** Added support for OpenBSD.\r
3817\r
3818* 2004-06-10\r
3819 ** Added support for FreeBSD 5.x.\r
3820\r
3821* 2004-05-28\r
3822 ** Deprecated the `-native` flag. Instead, use the new flag `-codegen\r
3823 {native|bytecode|C}`. This is in anticipation of adding a bytecode compiler.\r
3824\r
3825* 2004-05-26\r
3826 ** Fixed a front-end bug that could cause cascading error to print a very\r
3827 large and unreadable internal bug message of the form `"datatype ... realized\r
3828 with scheme Unknown"`.\r
3829\r
3830* 2004-05-17\r
3831 ** Automatically restart functions in the Basis Library that correspond\r
3832 directly to interruptable system calls.\r
3833\r
3834* 2004-05-13\r
3835 ** Added `-profile count`, for dynamic counts of function calls and branches.\r
3836 ** Equate the types `Posix.Signal.signal` and `Unix.signal`.\r
3837\r
3838* 2004-05-11\r
3839 ** Fixed a bug with `-basis 1997` that would cause type errors due to\r
3840 differences between types in the MLton structure and types in the rest of the\r
3841 basis library.\r
3842\r
3843* 2004-05-01\r
3844 ** Fixed a bug with sharing constraints in signatures that would sometimes\r
3845 mistakenly treat two structures as identical when they shouldn't have been.\r
3846 This would cause some programs to be mistakenly rejected.\r
3847\r
3848* 2004-04-30\r
3849 ** Added `MLton.Signal.{handled,restart}`.\r
3850\r
3851* 2004-04-23\r
3852 ** Added `Timer.checkCPUTimes`, and updated the `Timer` structure to match the\r
3853 latest basis spec. Also fixed `totalCPUTimer` and `totalRealTimer`, which\r
3854 were wrong.\r
3855\r
3856* 2004-04-13\r
3857 ** Added `MLton.Signal.Mask.{getBlocked,isMember}`.\r
3858\r
3859* 2004-04-12\r
3860 ** Fix bug that mistakenly generalized variable types containing unknown types\r
3861 when matching against a signature.\r
3862 ** Reasonable front-end error message when unification causes recursive\r
3863 (circular) type.\r
3864\r
3865* 2004-04-03\r
3866 ** Fixed bug in sharing constraints so that `sharing A = B = C` means that all\r
3867 pairs `A = B`, `A = C`, `B = C` are shared, not just `A = B` and `B = C`.\r
3868 This matters in some situations.\r
3869\r
3870* 2004-03-20\r
3871 ** Fixed `Time.now` which was treating microseconds as nanoseconds.\r
3872\r
3873* 2004-03-14\r
3874 ** Fixed SSA optimizer bug that could cause the error `"&lt;type&gt; has no\r
3875 tyconInfo property"`.\r
3876\r
3877* 2004-03-11\r
3878 ** Fixed `Time.fromReal` to raise `Time`, not `Overflow`, on unrepresentable\r
3879 times.\r
3880\r
3881* 2004-03-04\r
3882 ** Added structures `Word2`, `Word3`, ..., `Word31`.\r
3883\r
3884* 2004-03-03\r
3885 ** Added structures `Int2`, `Int3`, ..., `Int31`.\r
3886 ** Fixed bug in elaboration of `and` with signatures, structures, and functors\r
3887 so that it now evaluates all right-hand sides before binding any left-hand\r
3888 sides.\r
3889\r
3890\r
3891== Version 20040227\r
3892\r
3893Here are the changes from version 20030716 to 20040227.\r
3894\r
3895=== Summary\r
3896\r
3897* The front end now follows the Definition of SML and produces readable error\r
3898messages.\r
3899* Added support for NetBSD.\r
3900* Basis library changes tracking revisions to the specification.\r
3901* Added structures: `Int64`, `Real32`, `Word64`.\r
3902* File positions use `Int64`.\r
3903* Major improvements to `-show-basis`, which now displays the basis in a very\r
3904readable way with full type information.\r
3905* Command-line switch changes.\r
3906 ** Deprecated: `-basis`.\r
3907 ** Removed: `-lib-search`, `-link`, `-may-load-world`, `-static`.\r
3908 ** Added: `-link-opt`, `-runtime`, `-sequence-unit`, `-show-def-use`,\r
3909 `-stop tc`, `-warn-match`, `-warn-unused`.\r
3910 ** Changed: `-export-header`, `-show-basis`, `-show-basis-used`.\r
3911 ** Renamed: `-host` to `-target`.\r
3912* FFI changes.\r
3913 ** Renamed `_ffi` as `_import`.\r
3914 ** Added `cdecl` and `stdcall` attributes to `_import` and `_export`\r
3915 expressions.\r
3916* MLton structure changes.\r
3917 ** Added: Pointer.\r
3918 ** Removed: Ptrace.\r
3919 ** Changed: `Finalizable`, `IntInf`, `Platform`, `Random`, `Signal`, `Word`.\r
3920\r
3921=== Details\r
3922\r
3923* 2004-02-16\r
3924 ** Changed `-export-header`, `-show-basis`, `-show-basis-used` to take a file\r
3925 name argument, and they no longer force compilation to halt.\r
3926 ** Added `-show-def-use` and `-warn-unused`, which deal with def-use\r
3927 information.\r
3928\r
3929* 2004-02-13\r
3930 ** Added flag `-sequence-unit`, which imposes the constraint that in the\r
3931 sequence expression `(e1; e2)`, `e1` must be of type `unit`.\r
3932\r
3933* 2004-02-10\r
3934 ** Lots of changes to `MLton.Signal`: name changes, removal of superfluous\r
3935 functions, additional functions.\r
3936\r
3937* 2004-02-09\r
3938 ** Extended `-show-basis` so that when used with an input program, it shows\r
3939 the basis defined by the input program.\r
3940 ** Added `stop` runtime argument.\r
3941 ** Made `-call-graph {false|true}` an option to `mlprof` that determines\r
3942 whether or not a call graph file is written.\r
3943\r
3944* 2004-01-20\r
3945 ** Fixed a bug in `IEEEReal.{fromString,scan}`, which would improperly return\r
3946 `INF` instead of `ZERO` for things like `"0.0000e123456789012345"`.\r
3947 ** Fixed a bug in `Real.{fromDecimal,fromString,scan}`, which didn't return an\r
3948 appropriately signed zero for `~0.0`.\r
3949 ** Fixed a bug in `Real.{toDecimal,fmt}`, which didn't correctly handle\r
3950 `~0.0`.\r
3951 ** Report a compile-time error on unrepresentable real constants.\r
3952\r
3953* 2004-01-05\r
3954 ** Removed option `-may-load-world`. You can now use `-runtime no-load-world`\r
3955 instead.\r
3956 ** Removed option `-static`. You can now use `-link-opt -static` instead.\r
3957 ** Changed `MLton.IntInf.size` to return 0 instead of 1 on small ints.\r
3958\r
3959* 2003-12-28\r
3960 ** Fixed horrible bug in `MLton.Random.alphaNumString` that caused it to\r
3961 return 0 for all characters beyond position 11.\r
3962\r
3963* 2003-12-17\r
3964 ** Removed `-basis` as a normal flag. It is still available as an expert\r
3965 flag, but its use is deprecated. It will almost certainly disappear after the\r
3966 next release.\r
3967\r
3968* 2003-12-10\r
3969 ** Allow multiple `@MLton --` runtime args in sequnce. This makes it easier\r
3970 for scripts to prefix `@MLton` args without having to splice them with other\r
3971 ones.\r
3972\r
3973* 2003-12-04\r
3974 ** Added support for files larger than 2G. This included changing\r
3975 `Position` from `Int32` to `Int64`.\r
3976\r
3977* 2003-12-01\r
3978 ** Added `structure MLton.Pointer`, which includes a `type t` for pointers\r
3979 (memory addresses, not SML heap pointers) and operations for loading from and\r
3980 storing to memory.\r
3981\r
3982* 2003-11-03\r
3983 ** Fixed `Timer.checkGCTime` so that only the GC user time is included, not GC\r
3984 system time.\r
3985\r
3986* 2003-10-13\r
3987 ** Added `-warn-match` to control display nonexhaustive and redundant\r
3988 match warnings.\r
3989 ** Fixed space leak in `StreamIO` causing the entire stream to be retained.\r
3990 Thanks to Jared Showalter for the bug report and fix.\r
3991\r
3992* 2003-10-10\r
3993 ** Added `-stop tc` switch to stop after type checking.\r
3994\r
3995* 2003-09-25\r
3996 ** Fixed `Posix.IO.getfl`, which had mistakenly called `fcntl` with `F_GETFD`\r
3997 instead of `F_GETFL`.\r
3998 ** Tracking basis library changes:\r
3999 *** `Socket` module datagram functions no longer return amount written,\r
4000 since they always write the entire amount or fail. So,\r
4001 `send{Arr,Vec}To{,'}` now return `unit` instead of `int`.\r
4002 *** Added nonblocking versions of all the send and recv functions, as well\r
4003 as accept and connect. So, we now have: `acceptNB`, `connectNB`,\r
4004 `recv{Arr,Vec}{,From}NB{,'}`, `send{Arr,Vec}{,To}NB{,'}`.\r
4005\r
4006* 2003-09-24\r
4007 ** Tracking basis library changes:\r
4008 *** `TextIO.inputLine` now returns a `string option`.\r
4009 *** Slices used in `Byte`, `PRIM_IO`, `PrimIO`, `Posix.IO`, `StreamIO`.\r
4010 *** `Posix.IO.readVec` raises `Size`, not `Subscript`, with negative\r
4011 argument.\r
4012\r
4013* 2003-09-22\r
4014 ** Fixed `Real.toManExp` so that the mantissa is in [0.5, 1), not [1, 2). The\r
4015 spec says that 1.0 &lt;= man * radix &lt; radix, which since radix is 2, implies\r
4016 that the mantissa is in [0.5, 1).\r
4017 ** Added `Time.{from,to}Nanoseconds`.\r
4018\r
4019* 2003-09-11\r
4020 ** Added `Real.realRound`.\r
4021 ** Added `Char{Array,Vector}Slice` to `Text`.\r
4022\r
4023* 2003-09-11\r
4024 ** `OS.IO.poll` and `Socket.select` now raise errors on negative timeouts.\r
4025 ** `Time.time` is now implemented using `IntInf` instead of `Int`, which means\r
4026 that a much larger range of time values is representable.\r
4027\r
4028* 2003-09-10\r
4029 ** `Word64` is now there.\r
4030\r
4031* 2003-09-09\r
4032 ** Replaced `Pack32{Big,Little}` with `PackWord32{Big,Little}`.\r
4033 ** Fixed bug in `OS.FileSys.fullPath`, which mistakenly stopped as soon as it\r
4034 hit a symbolic link.\r
4035\r
4036* 2003-09-08\r
4037 ** Fixed `@MLton max-heap`, which was mistakenly ignored. Cleaned up `@MLton\r
4038 fixed-heap`. Both `fixed-heap` and `max-heap` can use copying or mark-compact\r
4039 collection.\r
4040\r
4041* 2003-09-06\r
4042 ** `Int64` is completely there.\r
4043 ** Fixed `OS.FileSys.tmpName` so that it creates the file, and doesn't use\r
4044 `tmpnam`. This eliminates an annoying linker warning message.\r
4045\r
4046* 2003-09-05\r
4047 ** Added structures `{LargeInt,LargeReal,LargeWord,Word}{Array,Array2,ArraySlice,Vector,VectorSlice}`\r
4048 ** Fixed bug in `Real.toDecimal`, which return class `NORMAL` for subnormals.\r
4049 ** Fixed bug in `Real.toLargeInt`, which didn't return as precise an integer\r
4050 as possible.\r
4051\r
4052* 2003-09-03\r
4053 ** Lots of fixes to `REAL` functions.\r
4054 *** `Real32` is now completely in place, except for `Real32.nextAfter` on\r
4055 SunOS.\r
4056 *** Fixed `Real.Math.exp` on x86 to return the right value when applied to\r
4057 `posInf` and `negInf`.\r
4058 *** Changed `Real.Math.{cos,sin,tan}` on x86 to always use a call to the C\r
4059 math library instead of using the x86 instruction. This eliminates some\r
4060 anomalies between compiling `-native false` and `-native true`.\r
4061 *** Change `Real.Math.pow` to handle exceptional cases in the SML code.\r
4062 *** Fixed `Real.signBit` on Sparcs.\r
4063\r
4064* 2003-08-28\r
4065 ** Fixed `PackReal{,64}Little` to work correctly on Sparc.\r
4066 ** Added `PackReal{,64}Big`, `PackReal32{Big,Little}`.\r
4067 ** Added `-runtime` switch, which passes arguments to the runtime via\r
4068 `@MLton`. These arguments are processed before command line switches.\r
4069 ** Eliminated MLton switch `-may-load-world`. Can use `-runtime` combined\r
4070 with new runtime switch `-no-load-world` to disable load world in an\r
4071 executable.\r
4072\r
4073* 2003-08-26\r
4074 ** Changed `-host` to `-target`.\r
4075 ** Split `MLton.Platform.{arch,os}` into `MLton.Platform.{Arch,OS}.t`.\r
4076\r
4077* 2003-08-21\r
4078 ** Fixed bug in C codegen that would cause undefined references to\r
4079 `Real_{fetch,move,store}` when compiling on Sparcs with `-align 4`.\r
4080\r
4081* 2003-08-17\r
4082 ** Eliminated `-link` and `-lib-search`, which are no longer needed.\r
4083 Eliminated support for passing `-l*`, `-L*`, and `*.a` on the command line.\r
4084 Use `-link-opt` instead.\r
4085\r
4086* 2003-08-16\r
4087 ** Added `-link-opt`, for passing options to `gcc` when linking.\r
4088\r
4089* 2003-07-19\r
4090 ** Renamed `_ffi` as `_import`. The old `_ffi` will remain for a while, but\r
4091 is deprecated and should be replaced with `_import`.\r
4092 ** Added attributes to `_export` and `_import`. For now, the only attributes\r
4093 are `cdecl` and `stdcall`.\r
4094\r
4095\r
4096== Version 20030716\r
4097\r
4098Here are the changes from version 20030711 to 20030716.\r
4099\r
4100== Summary\r
4101\r
4102* Fixed several serious bugs with the 20030711 release.\r
4103\r
4104== Details\r
4105\r
4106* 2003-07-15\r
4107 ** Fixed bug that caused a segfault when attempting to create an\r
4108 array that was too large, e.g\r
4109\r
4110 1 + Array.sub (Array.tabulate (valOf Int.maxInt, fn i =&gt; i), 0)\r
4111\r
4112 ** mlton now checks the command line arguments following the file to compile\r
4113 that are passed to the linker to make sure they are reasonable.\r
4114\r
4115* 2003-07-14\r
4116 ** Fixed packaging for Cygwin and Sparc to include `libgmp.a`.\r
4117 ** Eliminated bootstrap target. The `Makefile` automatically determines\r
4118 whether to bootstrap or not.\r
4119 ** Fixed XML type checker bug that could cause error: `"empty tyvars in\r
4120 PolyVal dec"`.\r
4121\r
4122* 2003-07-12\r
4123 ** Turned off `FORCE_GENERATIONAL` in gc. It had been set, which caused the\r
4124 gc to always use generational collection. This could seriously slow apps down\r
4125 that don't need it.\r
4126\r
4127\r
4128== Version 20030711\r
4129\r
4130Here are the changes from version 20030312 to 20030711.\r
4131\r
4132=== Summary\r
4133\r
4134* Added support for Sparc/SunOS using the C code generator.\r
4135* Completed the basis library implementation. At this point, the only missing\r
4136basis library function is `use`.\r
4137* Added `_export`, which allows one to call SML functions from C.\r
4138* Added weak pointers (via `MLton.Weak`) and finalization (via\r
4139`MLton.Finalizable`).\r
4140* Added new integer modules: `Int8`, `Int16`.\r
4141* Better profiling call graphs\r
4142* Fixed conversions between reals and their decimal representations to be\r
4143correct using the gdtoa library.\r
4144\r
4145=== Details\r
4146\r
4147* 2003-07-07\r
4148 ** Profiling improvements:\r
4149 *** Eliminated `mlton -profile-split`. Added `mlprof -split`. Now the\r
4150 profiling infrastructure keeps track of the splits and allows one to decide\r
4151 which splits to make (if any) when `mlprof` is run, which is much better\r
4152 than having to decide at compile time.\r
4153 *** Changed `mlprof -graph` to `mlprof -keep`, and changed the behavior so\r
4154 that `-keep` also controls which functions are displayed in the table.\r
4155 *** Eliminated `mlprof -ignore`: it's behavior is now subsumed by `-keep`,\r
4156 whose meaning has changed to be more like -ignore on nodes that are not\r
4157 kept.\r
4158 ** When calling `gcc` for linking, put `-link` args in same order as they\r
4159 appeared on the MLton command line (they used to be reversed).\r
4160\r
4161* 2003-07-03\r
4162 ** Making `OS.Process.{atExit,exit}` conform to the basis library spec in that\r
4163 exceptions raised during cleaners are caught and ignored. Also, calls to\r
4164 `exit` from cleaners cause the rest of cleaners to run.\r
4165\r
4166* 2003-07-02\r
4167 ** Fixed bug with negative `IntInf` constants that could cause compile time\r
4168 error message: `"x86Translate.translateChunk ... strange Offset: base: ..."`\r
4169 ** Changed argument type of `MLton.IntInf.Small` from `word` to `int`.\r
4170 ** Added fix to profiling so that the `mlmon.out` file is written even when\r
4171 the program terminates due to running out of memory.\r
4172\r
4173* 2003-06-25\r
4174 ** Added `{Int{8,16},Word8}{,Array,ArraySlice,Vector,VectorSlice,Array2}`\r
4175 structures.\r
4176\r
4177* 2003-06-25\r
4178 ** Fixed bug in `IntInf.sign`, which returned the wrong value for zero.\r
4179\r
4180* 2003-06-24\r
4181 ** Added `_export`, for calling from C to SML.\r
4182\r
4183* 2003-06-18\r
4184 ** Regularization of options:\r
4185 *** `-diag` --&gt; `-diag-pass`\r
4186 *** `-drop-pass` takes a regexp\r
4187\r
4188* 2003-06-06\r
4189 ** Fixed bug in `OS.IO.poll` that caused it to return the input event types\r
4190 polled for instead of what was actually available.\r
4191\r
4192* 2003-06-04\r
4193 ** Fixed bug in KnownCase SSA optimization that could case incorrect results\r
4194 in compiled programs.\r
4195\r
4196* 2003-06-03\r
4197 ** Fixed bug in SSA optimizer that could cause the error message:\r
4198\r
4199 Type error: Type.equals\r
4200 {from = char vector, to = unit vector}\r
4201 Type error: analyze raised exception loopStatement: ...\r
4202 unhandled exception: TypeError\r
4203\r
4204* 2003-06-02\r
4205 ** Fixed `Real.rem` to work correctly on `inf`-s and `nan`-s.\r
4206 ** Fixed bug in profiling that caused the function name to be omitted on\r
4207 functions defined by `val rec`.\r
4208\r
4209* 2003-05-31\r
4210 ** `Fixed Real.{fmt,fromString,scan,toString}` to match the basis library\r
4211 spec.\r
4212 ** Added `IEEEReal.{fromString,scan}`.\r
4213 ** Added `Real.{from,to}Decimal`.\r
4214\r
4215* 2003-05-25\r
4216 ** Added `Real.nextAfter`.\r
4217 ** Added `OS.Path.{from,to}UnixPath`, which are the identity function on Unix.\r
4218\r
4219* 2003-05-20\r
4220 ** Added type `MLton.pointer`, the type of C pointers, for use with the FFI.\r
4221\r
4222* 2003-05-18\r
4223 ** Fixed two bugs in type inference that could cause the compiler to raise the\r
4224 `TypeError` exception, along with a lot of XML IL. The `type-check.sml`\r
4225 regression contains simple examples of what failed.\r
4226 ** Fixed a bug in the simplifier that could cause the message: `"shrinker\r
4227 raised Prim.apply raised assertion failure: SmallIntInf.fromWord"`.\r
4228\r
4229* 2003-05-15\r
4230 ** Fixed bug in `Real.class` introduced on 04-28 that cause many regression\r
4231 failures with reals when using newer `gcc`-s.\r
4232 ** Replaced `MLton.Finalize` with `MLton.Finalizable`, which has a more robust\r
4233 approach to finalization.\r
4234\r
4235* 2003-05-13\r
4236 ** Fixed bug in `MLton.FFI` on Cygwin that caused `Thread_returnToC` to be\r
4237 undefined.\r
4238\r
4239* 2003-05-12\r
4240 ** Added support for finalization with `MLton.Finalize`.\r
4241\r
4242* 2003-05-09\r
4243 ** Fixed a runtime system bug that could cause a segfault. This bug would\r
4244 happen after a GC during heap resizing when copying a heap, if the heap was\r
4245 allocated at a very low (&lt;10M) address. The bug actually showed up on a\r
4246 Cygwin system.\r
4247\r
4248* 2003-05-08\r
4249 ** Fixed bug in `HashType` that raised `"Vector.forall2"` when the arity of a\r
4250 type constructor is changed by `SimplifyTypes`, but a newly constructed type\r
4251 has the same hash value.\r
4252\r
4253* 2003-05-02\r
4254 ** Switched over to new layered IO implementation, which completes the\r
4255 implementation of the `BinIO` and `TextIO` modules.\r
4256\r
4257* 2003-04-28\r
4258 ** Fixed bug that caused an assertion failure when generating a jump table for\r
4259 a case dispatch on a non-word sized index with non-zero lower bound on the\r
4260 range.\r
4261\r
4262* 2003-04-24\r
4263 ** Added `-align {4|8}`, which controls alignment of objects. With `-align\r
4264 8`, memory accesses to doubles are guaranteed to be aligned mod 8, and so\r
4265 don't need special routines to load or store.\r
4266\r
4267* 2003-04-22\r
4268 ** Fixed bug that caused a total failure of time profiling with `-native\r
4269 false`. The bug was introduced with the C codegen improvements that split the\r
4270 C into multiple files. Now, the C codegen declares all profile labels used in\r
4271 each file so that they are global symbols.\r
4272\r
4273* 2003-04-18\r
4274 ** Added `MLton.Weak`, which supports weak pointers.\r
4275\r
4276* 2003-04-10\r
4277 ** Replaced the basis library's `MLton.hostType` with `MLton.Platform.arch`\r
4278 and `MLton.Platform.os`.\r
4279\r
4280* 2003-04\r
4281 ** Added support for SPARC/SunOS using the C codegen.\r
4282\r
4283* 2003-03-25\r
4284 ** Added `MLton.FFI`, which allows callbacks to SML from C.\r
4285\r
4286* 2003-03-21\r
4287 ** Fixed `mlprof` so that the default `-graph arg` for data from\r
4288 `-profile-stack true` is `(thresh-stack x)`, not `(thresh x)`.\r
4289\r
4290\r
4291== Version 20030312\r
4292\r
4293Here are the changes from version 20020923 to 20030312.\r
4294\r
4295=== Summary\r
4296\r
4297* Added source-level profiling of both time and allocation.\r
4298* Updated basis library to 2002 specification. To obtain the old\r
4299library, compile with `-basis 1997`.\r
4300* Added many modules to basis library:\r
4301 ** `BinPrimIO`, `GenericSock`, `ImperativeIO`, `INetSock`, `NetHostDB`,\r
4302 `NetProtDB`, `NetServDB`, `Socket`, `StreamIO`, `TextPrimIO`, `UnixSock`.\r
4303* Completed implementation of `IntInf` and `OS.IO`.\r
4304\r
4305=== Details\r
4306\r
4307* 2003-02-23\r
4308 ** Replaced `-profile-combine` wih `-profile-split`.\r
4309\r
4310* 2003-02-11\r
4311 ** Regularization of options:\r
4312 *** `-l` --&gt; `-link`\r
4313 *** `-L` --&gt; `-lib-search`\r
4314 *** `-o` --&gt; `-output`\r
4315 *** `-v` --&gt; `-verbose`\r
4316\r
4317* 2003-02-10\r
4318 ** Added option to `mlton`: `-profile-combine {false|true}`\r
4319\r
4320* 2003-02-09\r
4321 ** Added options to `mlprof`: `-graph-title`, `-gray`, `-ignore`, `-mlmon`,\r
4322 `-tolerant`.\r
4323\r
4324* 2002-11 - 2003-01\r
4325 ** Added source-level allocation and time profiling. This includes the new\r
4326 options to mlton: `-profile` and `-profile-stack`.\r
4327\r
4328* 2002-12-28\r
4329 ** Added `NetHostDB`, `NetProtDB`, `NetServDB` structures.\r
4330 ** Added `Socket`, `GenericSock`, `INetSock`, `UnixSock` structures.\r
4331\r
4332* 2002-12-19\r
4333 ** Fixed bug in signal check insertion that could cause some signals to be\r
4334 missed. The fix was to add a signal check on entry to each function in\r
4335 addition to at each loop header.\r
4336\r
4337* 2002-12-10\r
4338 ** Fixed bug in runtime that might cause the message `"Unable to set\r
4339 cardMapForMutator"`.\r
4340\r
4341* 2002-11-23\r
4342 ** Added support for the latest Basis Library specification.\r
4343 ** Added option `-basis` to choose Basis Library version. Currently available\r
4344 basis libraries are `2002`, `2002-strict`, `1997`, and `none`.\r
4345 ** Added `IntInf.{orb,xorb,andb,notb,&lt;&lt;,~&gt;&gt;}` values.\r
4346 ** Added `OS.IO.{poll_desc,poll_info}` types.\r
4347 ** Added `OS.IO.{pollDesc,pollToIODesc,infoToPollDesc,Poll}` values.\r
4348 ** Added `OS.IO.{pollIn,pollOut,pollPri,poll,isIn,isOut,isPri}` values.\r
4349 ** Added `BinPrimIO`, `TextPrimIO` structures.\r
4350 ** Added `StreamIO`, `ImperativeIO` functors.\r
4351\r
4352* 2002-11-22\r
4353 ** Fixed bug that caused time profiling to fail (with a segfault) when\r
4354 resuming a saved world.\r
4355\r
4356* 2002-11-07\r
4357 ** Fixed bug in `MLton.eq` that could arise when using `eq` on functions.\r
4358\r
4359* 2002-11-05\r
4360 ** Improvements to polymorphic equality. Equality on IntInfs, vectors, and\r
4361 dataypes all do an `eq` test first before a more expensive comparison.\r
4362\r
4363* 2002-11-01\r
4364 ** Added allocation profiling. Now, can compile with either `-profile alloc`\r
4365 or `-profile time`. Renamed `MLton.Profile` as `MLton.ProfileTime`. Added\r
4366 `MLton.ProfileAlloc`. Cleaned up and changed most `mlprof` option names.\r
4367\r
4368* 2002-10-31\r
4369 ** Eliminated `MLton.debug`.\r
4370 ** Fixed bug in the optimizer that affected `IntInf.fmt`. The optimizer had\r
4371 been always using base 10, instead of the passed in radix.\r
4372\r
4373* 2002-10-22\r
4374 ** Fixed `Real.toManExp` so that the mantissa is in [1, 2), not [0.5, 1).\r
4375 ** Added `Real.fromLargeInt`, `Real.toLargeInt`.\r
4376 ** Fixed `Real.split`, which would return an incorrect whole part due to the\r
4377 underlying primitive, `Real_modf`, being treated as functional instead of\r
4378 side-effecting.\r
4379\r
4380* 2002-09-30\r
4381 ** Fixed `rpath` problem with packaging. All executables in packages\r
4382 previously made had included a setting for `RPATH`.\r
4383\r
4384\r
4385== Version 20020923\r
4386\r
4387Here are the changes from version 20020410 to 20020923.\r
4388\r
4389=== Summary\r
4390\r
4391* MLton now runs on FreeBSD.\r
4392* Major runtime system improvements. The runtime now implements mark-compact\r
4393and generational collection, in addition to the copying collection that was\r
4394there before. It automatically switches between the the collection strategies\r
4395to improve performance and to try to avoid paging.\r
4396* Performance when compiling `-exn-history true` has been improved.\r
4397* Added `IntInf.log2`, `MLton.GC.pack`, `MLton.GC.unpack`.\r
4398* Fixed bug in load world that could cause "sread failed" on Cygwin.\r
4399* Fixed optimizer bug that could cause `"no analyze var value property"`\r
4400message.\r
4401\r
4402=== Details\r
4403\r
4404* 2002-09\r
4405 ** Integrated Sam Rushing's changes to port MLton to FreeBSD.\r
4406\r
4407* 2002-08-25\r
4408 ** Changed the implementation of exception history to be completely\r
4409 functional. Now, the extra field in exceptions (when compiling `-exn-history\r
4410 true`) is a `string list` instead of a `string list ref`, and `raise` conses a\r
4411 new exception with a new element in the list instead of assigning to the list.\r
4412 This changes the semantics of exception history (for the better) on some\r
4413 programs. See `regression/exnHistory3.sml` for an example. It also\r
4414 significantly improves performance when compiling `-exn-history true`.\r
4415\r
4416* 2002-07 and 2002-08\r
4417 ** Added generational GC, and code to the runtime that automatically turns it\r
4418 on and off.\r
4419\r
4420* 2002-08-20\r
4421 ** Fixed SSA optimizer bug that could cause the following error message: `"x_0\r
4422 has no analyze var value property"`\r
4423\r
4424* 2002-07-28\r
4425 ** Added `MLton.GC.{pack,unpack}`. `pack` shrinks the heap so that other\r
4426 processes can use the RAM, and its dual, `unpack`, resizes the heap to the\r
4427 desired size.\r
4428\r
4429* 2002-06 and 2002-07\r
4430 ** Added mark compact GC.\r
4431 ** Changed array layout so that arrays have three, not two header words. The\r
4432 new word is a counter word that preceeds the array length and header.\r
4433 ** Changed all header words to be indices into an array of object descriptors.\r
4434\r
4435* 2002-06-27\r
4436 ** Added patches from Michael Neumann to port runtime to FreeBSD 4.5.\r
4437\r
4438* 2002-06-05\r
4439 ** Output file and intermediate file are now saved in the current directory\r
4440 instead of in the directory containing the input file.\r
4441\r
4442* 2002-05-31\r
4443 ** Fixed bug in overloading of `/` so that the following now type checks:\r
4444\r
4445 fun f (x, y) = x + y / y\r
4446\r
4447* 2002-04-26\r
4448 ** Added back `max-heap` runtime option.\r
4449\r
4450* 2002-04-25\r
4451 ** Fixed load/save world so that they use binary mode. This should fix the\r
4452 `sread failed` problem that Byron Hale saw on Cygwin that caused `mlton` to\r
4453 fail to start.\r
4454 ** Added `IntInf.log2`.\r
4455 ** Changed call to linker to use `libgmp.a` (if it exists) instead of\r
4456 `libgmp.so`. This is because the linker adds a dependency to a shared library\r
4457 even if there are no references to it\r
4458\r
4459* 2002-04-23\r
4460 ** Rewrote heap resizing code. This fixed bug that was triggered with large\r
4461 heaps and could cause a spurious out of memory error.\r
4462 ** Removed GnuMP from MLton sources (again :-).\r
4463\r
4464\r
4465== Version 20020410\r
4466\r
4467Here are the changes from version 20011006 to version 20020410.\r
4468\r
4469=== Details\r
4470\r
4471* 2002-03-28\r
4472 ** Added BinIO.\r
4473\r
4474* 2002-03-27\r
4475 ** Regularization of options\r
4476 *** `-g` --&gt; `-degug {false|true}`\r
4477 *** `-h n` --&gt; `-fixed-heap n`\r
4478 *** `-p` --&gt; `-profile {false|true}`\r
4479\r
4480* 2002-03-22\r
4481 ** Set up the stubs so that MLton can be compiled in the standard basis\r
4482 library, with no `MLton` structure. Thus it is now easy to compile MLton with\r
4483 an older (or newer) version of itself that has a different `MLton` structure.\r
4484\r
4485* 2002-03-17\r
4486 ** Added `MLton.Process.{spawn,spawne,spawnp}`, which use primitives when\r
4487 running on Cygwin and fork/exec when running on Linux.\r
4488\r
4489* 2002-02 - 2002-03\r
4490 ** Added the ability to cross-compile to Cygwin/Windows.\r
4491\r
4492* 2002-02-24\r
4493 ** Added GnuMP back for use with Cygwin.\r
4494\r
4495* 2002-02-10\r
4496 ** Reworked object header words so that `Array.maxLen = valOf Int.maxInt`.\r
4497 Also fixed a long-standing minor bug in MLton, where `Array.array\r
4498 (Array.maxLen, ...)` would raise `Size` instead of attempting to allocate the\r
4499 array. It was an off-by-one error in the meaning of `Array.maxLen`.\r
4500\r
4501* 2002-02-08\r
4502 ** Modifications to runtime to behave better in situations where the amount of\r
4503 live data is a signifant fraction of the amount of RAM, based on code from\r
4504 PolySpace. MLton executables by default can now use more than the available\r
4505 amount of RAM. Executables will still respect the `max-heap` runtime arg if\r
4506 it is set.\r
4507\r
4508* 2002-02-04\r
4509 ** Improvements to runtime so that it fails to get space, it attempts to get\r
4510 less space instead of failing. Based on PolySpace's modifications.\r
4511 ** Added `MLton.eq`.\r
4512\r
4513* 2002-02-03\r
4514 ** Added `MLton.IntInf.gcd`.\r
4515 ** Removed GnuMP from MLton sources. We now link with `/usr/lib/libgmp.a`.\r
4516 ** Added `TextIO.getPosOut`.\r
4517 ** Renamed type `MLton.Itimer.which` to `MLton.Itimer.t` and\r
4518 `MLton.Itimer.whichSignal` to `MLton.Itimer.signal`.\r
4519 ** Added `-coalesce` flag, for use with the C backend.\r
4520\r
4521* 2002-01-26\r
4522 ** Added `-show-basis-used`, which prints out the parts of the basis library\r
4523 that the input program uses.\r
4524 ** Changed several other flags (`-print-at-fun-entry`, `-show-basis`,\r
4525 `-static`) to follow the `{false|true}` convention.\r
4526\r
4527* 2002-01-22\r
4528 ** Improved `MLton.profile` so that multiple profile arrays can exist\r
4529 simultaneously and so that the current one being used can be set from the SML\r
4530 side.\r
4531\r
4532* 2002-01-18\r
4533 ** The Machine IL has been replaced with an RSSA (representation explicit SSA)\r
4534 IL and an improved Machine IL.\r
4535\r
4536* 2002-01-16\r
4537 ** Added KnownCase SSA optimization\r
4538\r
4539* 2002-01-14\r
4540 ** Added rudimentary profiling control from with a MLton compile program via\r
4541 the `MLton.Profile` structure.\r
4542\r
4543* 2002-01-09\r
4544 ** Fixed bug in match compiler that caused case expressions on datatypes with\r
4545 redundant cases to be compiled incorrectly.\r
4546\r
4547* 2002-01-08\r
4548 ** Added redundant tuple construction elimination to SSA shrinker.\r
4549 ** Improved Flatten SSA optimization.\r
4550\r
4551* 2001-12-06\r
4552 ** Changed the interface for `MLton.Signal`. There is no longer a separate\r
4553 `Handler` substructure. This was done so that programs that just use\r
4554 `default` and `ignore` signal handlers don't bring in the entire thread\r
4555 mechanism.\r
4556\r
4557* 2001-12-05\r
4558 ** Added LocalRef elimination SSA optimization.\r
4559\r
4560* 2001-11-19\r
4561 ** The CPS IL has been replaced with an SSA (static-single assignment) IL.\r
4562 All of the optimizations have been ported from CPS to SSA.\r
4563\r
4564* 2001-10-24\r
4565 ** Fixed bug in `Thread_atomicEnd` -- `limit` was mistakenly set to `base`\r
4566 instead of to 0. This caused assertion failures when for executables compiled\r
4567 `-g` because `GC_enter` didn't reset `limit`.\r
4568 ** Fixed bug in register allocation of byte registers.\r
4569\r
4570* 2001-10-23\r
4571 ** Added `-D` option to `cmcat` for preprocessor defines. Thanks to Anoq for\r
4572 sending the code.\r
4573 ** Changed limit check insertion so that limit checks are only coalesced\r
4574 within a single basic block -- not across blocks. This slows many benchmarks\r
4575 down, but is needed to fix a bug in the way that limit checks were coalesced\r
4576 across blocks. Hopefully we will figure out a better fix soon.\r
4577\r
4578* 2001-10-18\r
4579 ** Fixed type inference of flexrecord so that it now follows the Definition.\r
4580 Many programs containing flexrecords were incorrectly rejected. Added many\r
4581 new tests to regression/flexrecord.sml.\r
4582 ** Changed the behavior of `-keep dot` combined with `-keep pass` for SSA\r
4583 passes. Dot files are now saved for the program before and after, instead of\r
4584 just after.\r
4585\r
4586* 2001-10-11\r
4587 ** Fixed a bug in the type inference that caused type variables to be\r
4588 mistakenly generalized. The bug was exposed in Norman Ramsey's `sled.sml`.\r
4589 Added a test to `regression/flexrecord.sml` to catch the problem.\r
4590\r
4591\r
4592== Version 20011006\r
4593\r
4594Here are the changes from version 20010806 to version 20011006.\r
4595\r
4596=== Summary\r
4597\r
4598* Added `MLton.Exn.history`, which is similar to `SMLofNJ.exnHistory`.\r
4599* Support for `#line` directives of the form `(*#line line.col "file"*)`.\r
4600* Performance improvements in native codegenerator.\r
4601* Bug fixes in front-end, optimizer, register allocator,\r
4602`Real.{maxFinite,minPos,toManExp}`, and in heap save and restore.\r
4603\r
4604=== Details\r
4605\r
4606* 2001-10-05\r
4607 ** Fixed a bug in polymorphic layered patterns, like\r
4608\r
4609 val 'a a as b = []\r
4610\r
4611 These would always fail due to the variable `a` not being handled correctly.\r
4612 ** Fixed the syntax of `val rec` so that a pattern is allowed on the left-hand\r
4613 side of the `=`. Thus, we used to reject, but now accept, the following.\r
4614\r
4615 val rec a as b as c = fn _ =&gt; ()\r
4616 val rec a : unit -&gt; unit : unit -&gt; unit = fn () =&gt; ()\r
4617\r
4618 Thanks again to Andreas Rossberg's test files. This is now tested for in\r
4619 `valrec.sml`.\r
4620 ** Fixed dynamic semantics of `val rec` so that if `val rec` is used to\r
4621 override constructor status, then at run time, the `Bind` exception is raised\r
4622 as per rule 126 of the Definition. So, for example, the following program\r
4623 type checks and compiles, but raises `Bind` at run time.\r
4624\r
4625 val rec NONE = fn () =&gt; ()\r
4626 val _ = NONE ()\r
4627\r
4628 Again, this is checked in `valrec.sml`.\r
4629 ** Added `\r\n` to ml.lex so that Windows style newlines are acceptable in\r
4630 input files.\r
4631\r
4632* 2001-10-04\r
4633 ** Fixed bug in the implementation of `open` declarations, which in the case\r
4634 of `open A B` had opened `A` and then looked up `B` in the resulting\r
4635 environment. The correct behaviour (see rule 22 of the Definition) is to\r
4636 lookup each _longstrid_ in the current environment, and then open them all in\r
4637 sequence. This is now checked for in the `open.sml` regression test. Thanks\r
4638 to Andreas Rossberg for pointing this bug out.\r
4639 ** Fixed bug that caused tyvars of length 1 (i.e. `'`) to be rejected. This\r
4640 is now checked in the `id.sml` regression test. Again, thanks to Andreas\r
4641 Rossberg for the test.\r
4642\r
4643* 2001-10-02\r
4644 ** Fixed bugs in `Real.toManExp` (which always returned the wrong result\r
4645 because the call to `frexp` was not treated as side-effecting by the\r
4646 optimizer) and in `Real.minPos`, which was zero because of a mistake with\r
4647 extra precision bits.\r
4648\r
4649* 2001-10-01\r
4650 ** Added `MLton.Exn.history`.\r
4651 ** Fixed register allocation bug with `fucom` instruction. Was allowing\r
4652 `fucomp` when the first source was not removable.\r
4653 ** Changed `Real.isFinite` to use the C `math.h` `finite` function. This\r
4654 fixed the nontermination bug which occurred in any program that used\r
4655 `Real.maxFinite`.\r
4656\r
4657* 2001-09-22\r
4658 ** Bug fixes found from Ramsey's `lrtl` in `contify.fun` and\r
4659 `unused-args.fun`, both of which caused compile-time exceptions to be raised.\r
4660\r
4661* 2001-09-21\r
4662 ** Fixed `MLton.World.{load,save}` so that the saved world does not store the\r
4663 max heap size. Instead, the max heap size is computed upon load world in\r
4664 exactly the same way as at program startup. This fixes a long-standing (but\r
4665 only recently noticed) problem in which `mlton` (which uses a saved world)\r
4666 would attempt to use as much memory as was on the machine used to build\r
4667 `world.mlton`.\r
4668\r
4669* 2001-08-29\r
4670 ** Overlow checking is now on by default in the C backend. This is a huge\r
4671 performance hit, but who cares, since we never use the C backend except for\r
4672 testing anyways.\r
4673\r
4674* 2001-08-22\r
4675 ** Added support for #line directives of the form\r
4676\r
4677 (*#line line.col "file"*)\r
4678\r
4679 These directives only affect error messages produced by the parser and\r
4680 elaborator.\r
4681\r
4682* 2001-08-17\r
4683 ** Fixed bug in RemoveUnused optimzation that caused the following program to\r
4684 fail to compile.\r
4685\r
4686 fun f l = case l of [] =&gt; f l | _ :: l =&gt; f l\r
4687 val _ = f [13]\r
4688\r
4689* 2001-08-14\r
4690 ** New x86-codegen infrastructure.\r
4691 *** support for tracking liveness of stack slots and carrying them in\r
4692 registers across basic blocks\r
4693 *** more specific `Entry` and `Transfer` datatypes to make calling convention\r
4694 distinctions more explicit\r
4695 *** new heuristic for carrying values in registers across basic blocks (look\r
4696 Ma, no Overflows!)\r
4697 *** new "predict" model for generating register allocation hints\r
4698 *** additional bug fixes\r
4699\r
4700* 2001-08-07\r
4701 ** `MLton.Socket.shutdownWrite` flushes the outstream.\r
4702\r
4703\r
4704== Version 20010806\r
4705\r
4706Here are the changes from version 20010706 to version 20010806.\r
4707\r
4708=== Summary\r
4709\r
4710* `Word.andb (w, 0xFF)` now works correctly\r
4711* `MLton.Rusage.rusage` has a patch to work around a linux kernel bug\r
4712* Programs of the form `_exp_ ; _program_` are now accepted\r
4713* Added the `MLton.Rlimit` structure\r
4714* Added the `-keep dot` flag, which produces call graphs, intraprocedural\r
4715control-flow graphs, and dominator trees\r
4716\r
4717=== Details\r
4718\r
4719* 2001-08-06\r
4720 ** Added simple CommonBlock elimination CPS optimization.\r
4721\r
4722* 2001-08-02\r
4723 ** Took out `-keep il`.\r
4724\r
4725* 2001-07-31\r
4726 ** Performance improvements to `TextIO.{input, output, output1}`.\r
4727\r
4728* 2001-07-25\r
4729 ** Added RedundantTest elimination CPS optimization.\r
4730\r
4731* 2001-07-21\r
4732 ** Added CommonSubexp elimination CPS optimization.\r
4733\r
4734* 2001-07-20\r
4735 ** Bug fix to x86 codegen. The `commuteBinALMD` peephole optimization would\r
4736 rewrite `mov 2,Y; add Y,Y` as `mov Y,Y; add 2,Y`. Now the appropriate\r
4737 interference checks are made.\r
4738 ** Added intraprocedural unused argument removal.\r
4739 ** Added intraprocedural flattener. This avoids some stupid tuple allocations\r
4740 in loops. Decent speedup on a few benchmarks (`count-graphs`, `psdes-random`,\r
4741 `wc-scanStream`) and no noticeable slowdowns.\r
4742 ** Added `-keep dot` flag.\r
4743\r
4744* 2001-07-17\r
4745 ** Modified grammar to properly handle `val rec`. There were several problems.\r
4746 *** MLton had accepted `val rec 'a ...` instead of `val 'a rec ...`\r
4747 *** MLton had not accepted `val x = 13 and rec f = fn () =&gt; ()`\r
4748 *** MLton had not accepted `val rec rec f = fn () =&gt; ()`\r
4749 *** MLton had not accepted `val rec f = fn () =&gt; () and rec g = fn () =&gt; ()`\r
4750\r
4751* 2001-07-16\r
4752 ** Workaround for Linux kernel bug that can cause `getrusage` to return a wrong\r
4753 system time value (low by one second). See `fixedGetrusage` in `gc.c`.\r
4754 ** Bug fix to x86 codegen. The register allocator could get confused when\r
4755 doing comparisons of floating point numbers and use the wrong operand. The\r
4756 bug seems to have never been detected because it only happens when both of the\r
4757 operands are already on the floating point stack, which is rare, since one is\r
4758 almost always in memory since we don't carry floating point values in the\r
4759 stack across basic blocks.\r
4760 ** Added production to the grammar on page 58 of the Definition that had been\r
4761 missing from MLton since day one.\r
4762\r
4763 program ::= exp ; &lt;program&gt;\r
4764\r
4765 Also updated docs to reflect change.\r
4766 ** Modified grammar to accept the empty program.\r
4767 ** Added `-type-check` expert flag to turn on type checking in ILs.\r
4768\r
4769* 2001-07-15\r
4770 ** Bug fix to the algebraic simplifier. It had been rewriting\r
4771 `Word32.andb (w, 0wxFF)` to `w` instead of\r
4772 `Word32.andb (w, 0wxFFFFFFFF)` to `w`.\r
4773\r
4774* 2001-07-13\r
4775 ** Improved CPS shrinker so that `if`-tests where the `then` and `else` branch\r
4776 jump to the same label is turned into a direct jump.\r
4777 ** Improved CPS shrinker (`Prim.apply`) to handle constructors\r
4778 *** `A = A` --&gt; `true`\r
4779 *** `A = B` --&gt; `false`\r
4780 *** `A x` = `B y` --&gt; `false`\r
4781 ** Rewrote a lot of loops in the basis library to use inequalities instead of\r
4782 equality for the loop termination test so that the (forthcoming) overflow\r
4783 detection elimination will work on the loop index variable.\r
4784\r
4785* 2001-07-11\r
4786 ** Fixed minor bugs in `Array2.{array,tabulate}`, `Substring.{slice}` that\r
4787 caused the `Overflow` exception to be raised instead of `Size` or `Subscript`\r
4788 ** Fixed bug in `Pack32Big.update` that caused the wrong location to be updated.\r
4789 ** Fixed several bugs in `Pack32{Big,Little}.{subArr,subVec,update}` that\r
4790 caused `Overflow` to be raised instead of `Subscript`. Also, improved the\r
4791 implementation so that bounds checking only occurs once per call (instead of\r
4792 four times, which was sometimes happening.\r
4793 ** Fixed bugs in `Time.{toMilliseconds,toMicroseconds}` that could cause a\r
4794 spurious `Overflow` exception.\r
4795 ** Fixed bugs in `Time.{fromMilliseconds,fromMicroseconds}` that could cause a\r
4796 spurious `Time` exception.\r
4797 ** Improved `Pack32.sub*` by reordering the `orb`-s.\r
4798 ** Improved `{Int,IntInf}.mod` to increase chances of constant folding.\r
4799 ** Switched many uses of `+`, `-`, `*` in basis library to the non-overflow\r
4800 checked versions. Modules changed were: `Array`, `Array2`, `Byte`, `Char`,\r
4801 `Int`, `IntInf`, `List`, `Pack32{Big,Little}`, `Util`, `String`, `StringCvt`,\r
4802 `Substring`, `TextIO`, `Time`, `Vector`.\r
4803 ** Added regression tests for `Array2`, `Int` (overflow checking), `Pack32`,\r
4804 `Substring`, `Time`.\r
4805 ** Changed CPS output so that it includes a dot graph for each CPS function.\r
4806\r
4807* 2001-07-09\r
4808 ** Change `OS.Process.exit` so that it raises an exception if the exit status\r
4809 is not in [0, 256).\r
4810 ** Added `MLton.Rlimit` to provide access to `getrlimit` and `setrlimit`.\r
4811\r
4812\r
4813== Version 20010706\r
4814\r
4815Here are the changes from the 20000906 version to the 20010706 version.\r
4816\r
4817=== Summary\r
4818\r
4819* Native X86 code generator (instead of using `gcc`)\r
4820* Significantly improved compile times\r
4821* Significantly improved run times for generated executables\r
4822* Many bug fixes\r
4823* Correct raising of the `Overflow` exception for integer arithmetic\r
4824* New modules in the `MLton` structure\r
4825\r
4826=== Details\r
4827\r
4828* 2001-07-06\r
4829 ** GC mods from Henry. Mostly adding `inline` declarations.\r
4830\r
4831* 2001-07-05\r
4832 ** Fixed several runtime bugs involving threads, critical sections, and\r
4833 signals.\r
4834\r
4835* 2001-06-29\r
4836 ** Fixed performance bug in `cps/two-point-lattice.fun` that caused quadratic\r
4837 behavior. This affects the raise-to-jump and useless analayses. In\r
4838 particular, the useless analysis was blowing up when compiling `fxp`.\r
4839\r
4840* 2001-06-27\r
4841 ** Henry improved `wordAlign` -- this sped up GC by 27% (during a self\r
4842 compile).\r
4843\r
4844* 2001-06-20\r
4845 ** Moved `MLton.random` to `MLton.Random.rand` and added other stuff to\r
4846 `MLton.Random`\r
4847 ** Added `MLton.TextIO.mkstemp`.\r
4848 ** Made `Int.{div,quot}` respect the `-detect-overflow` switch.\r
4849\r
4850* 2001-06-20\r
4851 ** Added `MLton.Syslog`.\r
4852\r
4853* 2001-06-07\r
4854 ** Fixed bug in `MLton.Socket.accept` that was in the runtime implementation\r
4855 `Socket_accept`. It did a `setsockopt SO_REUSEADDR` after the `accept`. It\r
4856 should have been after the call to `socket` in `Socket_listen`. Thanks to\r
4857 Doug Bagley for the fix.\r
4858\r
4859* 2001-05-30\r
4860 ** Fixed bug in remove-unused that caused polymorphic equality to return\r
4861 `true` sometimes when constructors were never used in a pattern match. For\r
4862 example, the following (in which `A` and `B` are not used as patterns):\r
4863\r
4864 datatype t = A | B\r
4865 datatype u = C of t\r
4866 val _ = if C A = C B then raise Fail "bug" else ()\r
4867\r
4868* 2001-03-27\r
4869 ** Fixed bug that caused all of the following to fail:\r
4870 `{LargeWord,Word,SysWord}.{toLargeInt,toLargeIntX,fromLargeInt}` The problem\r
4871 was the basis library file `integer/patch.sml` which fixed `Word32` but not\r
4872 the other structures that are the same.\r
4873\r
4874* 2001-02-12\r
4875 ** Fixed bug in match compiler that caused it to spend a lot of extra time in\r
4876 deep patterns. It still could be exponential however. Hopefully this will\r
4877 get fixed in the release after next. This bug could cause very slow compile\r
4878 times in some cases. Anyways, this fix cut the `finish infer` time of a self\r
4879 compile down from 22 to under 4 seconds. I.E. most of the time used to be\r
4880 spent due to this bug.\r
4881\r
4882* 2001-02-06\r
4883 ** Fixed bug in frontend that caused the wrong file and line number to be\r
4884 reported with errors in functor bodys.\r
4885\r
4886* 2001-01-03 - 2000-02-05\r
4887 ** Changes to CoreML, XML, SXML, and CPS ILs to replace lists by vectors in\r
4888 order to decrease space usage.\r
4889\r
4890* 2001-01-16\r
4891 ** Fixed a bug in constant propagation where the length of vectors was not\r
4892 propagated properly.\r
4893\r
4894* 2000-12-11 - 2001-01-03\r
4895 ** Major rewrite of elaborator to use a single hash table for each namespace\r
4896 instead of a hash table for every environment.\r
4897\r
4898* 2000-12-20\r
4899 ** Fixed some bugs in the SML/NJ compatibility library,\r
4900 `src/lib/mlton-subs-in-smlnj`.\r
4901\r
4902* 2000-12-08\r
4903 ** More careful removal of tracing code when compiling `MLton_debug=0`. This\r
4904 cut down self compile data size by 100k and compile time by a few seconds.\r
4905 ** Added built in character and word cases propagated throughout all ILs.\r
4906\r
4907* 2000-12-06\r
4908 ** Added max stack size information to `gc-summary`.\r
4909\r
4910* 2000-12-05\r
4911 ** Added `src/benchmark`, which contains an SML program that benchmarks all of\r
4912 the SML compilers I have my hands on. The script has lots of hardwired paths\r
4913 for now.\r
4914\r
4915* 2000-12-04\r
4916 ** Fixed bug in `Posix.ProcEnv.environ,` which did not work correctly in a\r
4917 saved world (the original `environ` was saved). In fact, it did not work at\r
4918 all because the ML primitive expected a constant and the C was a nullary\r
4919 function. This caused a segfault with any program using\r
4920 `Posix.ProcEnv.environ`.\r
4921 ** `Added MLton.ProcEnv.setenv`, since there doesn't seem to be any `setenv`\r
4922 in the basis library.\r
4923\r
4924* 2000-11-29\r
4925 ** Changed backend so that it should no longer generate machine programs with\r
4926 `void` operands.\r
4927 ** Added `-detect-overflow` and `-safe` flags.\r
4928\r
4929* 2000-11-27 - 2000-11-28\r
4930 ** Changes in many places to use `List.revMap` instead of `List.map` to cut\r
4931 down on allocation.\r
4932\r
4933* 2000-11-21\r
4934 ** Added `MLton.Word.~` and `MLton.Word8.~` to the `MLton` structure.\r
4935\r
4936* 2000-11-20\r
4937 ** Fixed a bug in the CPS shrinker that could cause a compile-time failure.\r
4938 It was maintaining occurrence counts incorrectly.\r
4939\r
4940* 2000-11-15\r
4941 ** Fixed a (performance) bug in constant propagation that caused the hashing\r
4942 to be bad.\r
4943 ** Improved translation to XML so that the match compiler isn't called on\r
4944 tuple or if expressions. This should speed up the translation and make the\r
4945 output smaller.\r
4946 ** Fixed a bug in the match compiler that caused it to not generate integer\r
4947 case statements. This should speed up the mlyacc benchmark and the MLton\r
4948 front end.\r
4949\r
4950* 2000-11-09\r
4951 ** Added `IntInf_equal` and `IntInf_compare` primitives.\r
4952 ** Took out the automatic `-keep c` when compiling `-g`.\r
4953\r
4954* 2000-11-08\r
4955 ** Added a whole bunch of algebraic laws to the CPS shrinker, including some\r
4956 specifically targeted to `IntInf` primitives.\r
4957\r
4958* 2000-11-03\r
4959 ** Improved implementation of properties so that sets don't allocate.\r
4960 ** Improved implementation of type homomorphism in type inference. What was\r
4961 there before appears to have been a bug -- it didn't use the property on\r
4962 types.\r
4963\r
4964* 2000-11-02\r
4965 ** Fixed timers used with `-v` option to use user + sys time.\r
4966\r
4967* 2000-10-27\r
4968 ** Split the runtime basis library C files into many separate files so that\r
4969 only the needed code would be included by the linker.\r
4970 ** Fixed several bugs in the front end grammar and elaborator that caused type\r
4971 specifications to be handled incorrectly. The following three programs used\r
4972 to be handled incorrectly, but are now handled correctly.\r
4973\r
4974 signature S = sig type t and u = int end (* reject *)\r
4975 signature S = sig type t = int and u = t end (* accept *)\r
4976 signature S = sig eqtype t and u = int end (* reject *)\r
4977\r
4978* 2000-10-25\r
4979 ** Changes to `main.sml` to run complete compiles with `-native` switch.\r
4980\r
4981* 2000-10-24\r
4982 ** Removed defunctorizer.\r
4983\r
4984* 2000-10-20\r
4985 ** Fixed bug in `cps-tree.fun` with `PrimExp.maySideEffect`. This bug could\r
4986 cause `"no operand"` failures in the backend.\r
4987 ** Fixed bug in the runtime implementation of `MLton.size`. The size for\r
4988 stack objects was using the `used` instead of `reserved`, and so was too low.\r
4989\r
4990* 2000-10-19\r
4991 ** Replaced automatically generated dependencies in `src/runtime/Makefile`\r
4992 with hand generated ones. Took out `make depend` from `src/Makefile`. `make\r
4993 depend` was behaving really badly on RHAT 7.0.\r
4994 ** Tweaked compiler to shorten width of C output lines to work around bug in\r
4995 RHAT 7.0 `cpp` which silently truncates (very) long lines.\r
4996 ** Fixed bug in grammar that didn't allow `op` to occur in datatype and\r
4997 exception bindings, causing the following to fail\r
4998\r
4999 datatype t = op T\r
5000 exception op E = op Fail\r
5001\r
5002 ** Improved error messages in CM processor. Fixed bug in CM Alias handling.\r
5003\r
5004* 2000-10-18\r
5005 ** Fixed two bugs in the gc that did comparisons with `(s-&gt;limit -\r
5006 s-&gt;frontier)`, which of course doesn't work if `frontier` is beyond `limit`,\r
5007 since these are unsigned. This could have caused segfaults, except that the\r
5008 mutator checks the `frontier` upon return from the GC.\r
5009\r
5010* 2000-10-17\r
5011 ** Fixed bug in backend in the calculation of `maxFrameSize`. It could be\r
5012 wrong (low) in some situations.\r
5013 ** Improved CPS inliner's estimate of function sizes. The size of a function\r
5014 now takes into account other inlined functions that the function calls. This\r
5015 also changed the meaning of the size argument to the `-inline` switch. It now\r
5016 corresponds (roughly) to the product of the size of the function and the\r
5017 number of calls. In general, it should be larger than before.\r
5018\r
5019* 2000-10-13\r
5020 ** Made some calls to `Array.sub` unsafe in the implementation of `Array2`.\r
5021 ** Integrated Matthew's new x86 backend with floating point support.\r
5022\r
5023* 2000-10-09\r
5024 ** Fixed CM file processor so that MLton works if it is run from a different\r
5025 directory than the main CM file.\r
5026\r
5027* 2000-10-04\r
5028 ** Changed LimitCheck so it loops on the `frontier &gt; limit` check. This fixed\r
5029 a potential bug in threads caused when there is enough space available for a\r
5030 thread, `t`, before switching to another thread but not enough space when it\r
5031 resumes. This could have caused a segfault.\r
5032\r
5033* 2000-10-03\r
5034 ** More rewrites of `TextIO.StreamIO` to improve speed.\r
5035 ** Changed `TextIO` so that only `TextIO.stdErr` is unbuffered.\r
5036 ** Changed `TextIO` so that FIFOs and sockets are buffered.\r
5037\r
5038* 2000-10-02\r
5039 ** Combined remove-unused-constructors, remove-unused-functions, and\r
5040 remove-unused-globals into a single pass that runs to fixed-point and produces\r
5041 results at least as good as running the previous three in (any) sequence.\r
5042\r
5043* 2000-09-29\r
5044 ** Added `GC_FIRST_CHECK`, which does a gc at each limit check the first time\r
5045 it reached.\r
5046 ** Reimplemented `TextIO.StreamIO` (from 2000-09-12) to use lists of strings\r
5047 instead of lists of characters so that the per char space overhead is small.\r
5048\r
5049* 2000-09-21\r
5050 ** Fixed bug in profiling labels in C code. The label was always the basic\r
5051 block label instead of the cps function label.\r
5052 ** Added `-b` switch to `mlprof` to gather data at the basic block level.\r
5053 ** Improved performance of `TextIO.input1` by about 3X.\r
5054\r
5055* 2000-09-15 - 2000-09-19\r
5056 ** Added overflow exceptions to CPS and Machine ILs.\r
5057\r
5058* 2000-09-12\r
5059 ** Fixed `TextIO.scanStream`. It was very broken.\r
5060 ** Added `TextIO.{getInstream,mkInstream,setInstream}` and\r
5061 `TextIO.StreamIO.{canInput,closeIn,endOfStream,input1,input,inputAll,inputLine,inputN}`.\r
5062\r
5063* 2000-09-11\r
5064 ** Fixed `Real_qequal` in `mlton-lib.h`. It was missing a paren that caused\r
5065 code using it to not even compile. It was also semantically incorrect.\r
5066 ** Noted that `Real_{equal,lt,le,gt,ge}` may not follow basis library spec,\r
5067 since ANSI does not require IEEE compliance, and hence these could return\r
5068 wrong results when nans are involved.\r
5069\r
5070\r
5071== Version 20000906\r
5072\r
5073Here are the changes from the 20000712 version to the 20000906 version.\r
5074\r
5075=== Summary\r
5076\r
5077* Version 20000906 is mostly a bugfix release over 20000712. The other major\r
5078changes are that `mllex` and `mlyacc` are now included and that `mlton` can now\r
5079process a limited subset of CM files as input.\r
5080\r
5081=== Details\r
5082\r
5083* 2000-09-06\r
5084 ** Fixed `Socket_listen` in `mlton-lib.c` so that it closes the socket if the\r
5085 `bind`, `listen`, or `getsockname` fails. This could have caused a file\r
5086 descriptor leak.\r
5087\r
5088* 2000-09-05\r
5089 ** Added `-static` commandline switch.\r
5090 ** Changed default max heap size to .85 RAM from .95 RAM.\r
5091 ** Added `PackRealLittle` structure to basis library.\r
5092\r
5093* 2000-08-25\r
5094 ** Added cases on integers to ILs (instead of using sequences of tests) so\r
5095 that backend can emit more efficient test (jump table, binary tree, ...).\r
5096\r
5097* 2000-08-24\r
5098 ** Fixed bug in `gc.c`. `dfsInitializeStack` would `smummap` a `NULL` pointer\r
5099 whenver `toSpace` was `NULL`. This could cause `MLton.size` to segfault.\r
5100 ** Fixed bug in `Popt` that caused `-k` to fail with no keeps.\r
5101\r
5102* 2000-08-22 - 2000-08-23\r
5103 ** Ported `mllex` and `mlyacc` from SML/NJ\r
5104\r
5105* 2000-08-20 - 2000-08-21\r
5106 ** Added ability to use a `.cm` file as input to MLton.\r
5107\r
5108* 2000-08-16\r
5109 ** Ported `mlprof` to SML.\r
5110 ** Fixed bug in `library/basic/assert.sml` that caused asserts to be run even\r
5111 when `MLton.debug = false`.\r
5112\r
5113* 2000-08-15\r
5114 ** Fixed bug in backend -- computation of `maxFrameSize` was wrong. It didn't\r
5115 count slots in frames that didn't make nontail calls. This could lead to the\r
5116 stack being overwritten because a stack limit check didn't guarantee enough\r
5117 space, and lead to a segfault.\r
5118 ** Fixed bug in `gc.c` `newThreadOfSize`. If the thread allocation caused a\r
5119 gc, then the stack wasn't forwarded, leading to a segfault. The solution was\r
5120 to ensure enough memory all at once, and then fill in both objects.\r
5121\r
5122* 2000-08-14\r
5123 ** Changed limit checks so that checks &lt; 512 bytes are replaced by a check for\r
5124 0 bytes. The runtime also moves the limit down by 512. This is done so that\r
5125 the common case, a small limit check, has less code and is faster.\r
5126 ** Fixed bug in `cps/cps-tree.fun`. `Program.hasPrim` returned `true` for any\r
5127 program that had *any* primapp, not just programs satisfying the predicate.\r
5128 This caused `cps/once.fun` to be overly conservative, since it thought that\r
5129 every program used continuations.\r
5130\r
5131* 2000-08-10\r
5132 ** Fixed bug in CPS typechecker. It didn't enforce that handlers should be\r
5133 defined before any reference to them -- including implicit references in\r
5134 `HandlerPops`. This caused an evil bug in the liveness analysis where a\r
5135 variable that was only live in the handler was missed in a continuation\r
5136 because the liveness for the handler wasn't computed yet.\r
5137 ** Limited the size for moving up limit checks for arrays whose size is known\r
5138 at compile time to avoid huge limit checks getting moved into loops.\r
5139 ** added `-indent`, `-kp`, `-show-types` switches.\r
5140 ** Put optimization in CPS IL suggested by Neal Glew. It determines for each\r
5141 toplevel function if it can raise an exception to its caller. Also, it\r
5142 removes `HanderPush` and `HandlerPop` for handlers that are not on top of the\r
5143 stack for any nontail call.\r
5144\r
5145* 2000-08-08\r
5146 ** Changed register allocator so that continuation formals can be allocated in\r
5147 pseudo registers -- they aren't necessarily forced to the stack.\r
5148\r
5149* 2000-08-03\r
5150 ** Fixed bug in constant folding. `Word8.&gt;&gt;` had been used to implement\r
5151 `Word8.~&gt;&gt;`.\r
5152 ** Fixed bug in allocate registers that was not forcing the size argument to\r
5153 `Primitive.Array.array` to be a stack slot. This could cause problems if\r
5154 there was a thread switch in the limit check, since upon return the size\r
5155 pseudo register would have a bogus value.\r
5156\r
5157* 2000-08-01\r
5158 ** Turned back on XML simplification after monomorphisation.\r
5159\r
5160* 2000-07-31\r
5161 ** Fixed bug in `MLton.Itimer.set` that caused the time to be doubled.\r
5162 ** Fixed bug in `MLton.Thread` that made it look like asynchronous exceptions\r
5163 were allowed by `throw`-ing an exception raising thunk to an interrupted\r
5164 thread obtained via a signal handler. Attempting asynchronous exceptions will\r
5165 now cause process death, with a helpful error message.\r
5166\r
5167* 2000-07-27\r
5168 ** Updated docs to include `structure World: MLTON_WORLD` in `MLton`\r
5169 structure.\r
5170 ** Added toplevel signatures `MLTON_{CONT, ..., WORLD}` to basis library.\r
5171 ** Fixed broken link in docs to CM in `cmcat` section.\r
5172\r
5173* 2000-07-26\r
5174 ** Eliminated `GC_switchToThread` and `Thread_switchTo1`, since the inlined\r
5175 version `Thread_switchTo` is all that's needed, and Matt's X86 backend now\r
5176 handles it.\r
5177 ** Added `MLton.Signal.vtalrm`, needed for `Itimer.Set{which =\r
5178 Itimer.Virtual, ...}`.\r
5179\r
5180* 2000-07-25\r
5181 ** Added `MLton.Socket.shutdownWrite`.\r
5182\r
5183* 2000-07-21\r
5184 ** Updated `mlton-lib.c` `MLton_bug` with new email (MLton@sourcelight.com).\r
5185\r
5186* 2000-07-19\r
5187 ** Fixed `Posix.Process.kill` to check for errors.\r
5188\r
5189* 2000-07-18\r
5190 ** Fixed the following `Posix.ProcEnv` functions to check for errors:\r
5191 `setgid`, `setpgid`, `setsid`, `setuid`.\r
5192 ** Fixed `doc/examples/callcc.sml`.\r
5193\r
5194\r
5195== Version 20000712\r
5196\r
5197Here are the changes from the 1999-07-12 to the 20000712 version.\r
5198\r
5199=== Details\r
5200\r
5201* 2000-06-10 - 2000-07-12\r
5202 ** Too many changes to count: bug fixes, new basis library modules, optimizer\r
5203 improvements.\r
5204\r
5205* 2000-06-30\r
5206 ** Fixed bug in monomorphiser that caused programs with non-value carrying\r
5207 exception declarations in polymorphic functions to have a compile-time error\r
5208 because of a duplicate label. The problem was that the exception constructor\r
5209 wasn't duplicated.\r
5210\r
5211* 2000-05-22 - 2000-06-10\r
5212 ** Finished the changes for the new CPS IL.\r
5213\r
5214* 2000-01-01\r
5215 ** Fixed some errors in the basis library:\r
5216 *** `Real.copySign`\r
5217 *** `Posix.FileSys.fpathconf`\r
5218 *** `Posix.IO.{lseek, getlk, setlk, setlkw}`\r
5219 *** `Posix.ProcEnv.setpgid`\r
5220 *** `Posix.TTY.getattr`\r
5221 *** `System.FileSys.realPath`\r
5222\r
5223* 1999-12-22\r
5224 ** Fixed bug in `src/closure-convert/abstract-value.fun` that caused a\r
5225 compiler failure whenever a program had a vector where the element type\r
5226 contained an `-&gt;`.\r
5227\r
5228* 1999-12-10\r
5229 ** Changed dead code elimination in `core-ml/dead-code.fun` so that wildcard\r
5230 declarations (`val _ = ...`) in the basis are kept. Changed places in the\r
5231 basis library to take advantage of this.\r
5232 ** Added `setTopLevelHander` primitive so that the basis library code can\r
5233 define the toplevel handler.\r
5234 ** Changed `basis-library/misc/suffix.sml` to call `OS.Process.exit`. Took\r
5235 out `Halt` transfer from CPS, since the program never should reach it.\r
5236 ** Cleaned up `basis-library/system/{process.sml, unix.sml}` to use the new\r
5237 signal handling stuff.\r
5238\r
5239* 1999-11-28 - 1999-12-20\r
5240 ** Added support for threads and cleaned up signal handling. This involved a\r
5241 number of changes:\r
5242 *** The stack is now allocated as just another kind of heap object.\r
5243 *** Limit checks are inserted at all loop headers, whether or not there is\r
5244 any allocation. This is to ensure that the signal handler always has a\r
5245 chance to get called.\r
5246 *** The register allocator puts more variables in stack slots. The new rule\r
5247 is that a variable goes in a stack slot if it is ever live across a nontail\r
5248 call, in a handler, or (this is the new part) across a limit check.\r
5249 *** Arguments are passed on the stack, with the convention determined by\r
5250 argument types.\r
5251 *** The "locals" array of pointers that was copied to/from for GC is now\r
5252 gone, because no registers (in particular no pointer valued registers) can\r
5253 be live at a limit check point.\r
5254\r
5255* 1999-11-21\r
5256 ** Runtime system\r
5257 *** Fixed a bug introduced by the signal code (presumably on 1999-08-09)\r
5258 that caused a gc to *not* be performed when doing a save world. This caused\r
5259 the heaps created by save world to be the same size as the heap -- not the\r
5260 live data. This was quite bad.\r
5261 *** Cleaned up the `Makefile`. Add make depend.\r
5262 *** Added max gc pause to `gc-summary` info.\r
5263 *** Move heap translation variables that had been file statics into the\r
5264 `GC_state`.\r
5265 ** Made `structure Position` available at toplevel.\r
5266 ** Basis Library\r
5267 *** Added `MLton.loadWorld`\r
5268 ** Added `Primitive.usesCallcc`\r
5269 ** Added `Primitive.safe`\r
5270 ** Removed special size functions from `cps/save-world` -- they are no longer\r
5271 necessary since size doesn't do a gc.\r
5272 ** Fixed another (sigh) bug in `cps/simplify-types.fun` that could cause it to\r
5273 not terminate.\r
5274\r
5275* 1999-11-16\r
5276 ** Cleaned up `backend/machine.fun` a bit so that it spits out macros for\r
5277 allocation of objects and bumping of frontier. Added macros `MLTON_object`\r
5278 and `MLTON_incFrontier` to `include/mlton-lib.h`.\r
5279 ** Fixed a bug in `backend/limit-check.fun` that caused loops to not be\r
5280 detected if they were only reached by a case branch. This could cause there\r
5281 to be loop that allocates with no limit check. Needless to say, this could\r
5282 cause a segfault if the loop ran for long enough.\r
5283\r
5284* 1999-10-18\r
5285 ** Added basis library function `Array2.copy`.\r
5286\r
5287* 1999-08-15\r
5288 ** Turned off globalization of ref cells (`closure-convert/globalize.fun`)\r
5289 because it interacts badly with serialization.\r
5290\r
5291* 1999-08-13\r
5292 ** Fixed bug in `mlton-lib.h` in `MLTON_allocArrayNoPointers` that was\r
5293 triggered when `bytesPerElt == 0`. The problem was that it wasn't reserving\r
5294 space for the forwarding pointer. This could cause a segfault.\r
5295\r
5296* 1999-08-08 and 1999-08-09\r
5297 ** Added support for signal handling.\r
5298\r
5299* 1999-08-07\r
5300 ** Fixed bugs in `Array.tabulate` (and other `tabulate` variants) caused if\r
5301 the function argument used `callcc`.\r
5302\r
5303* 1999-08-01\r
5304 ** Added serialization, which was mostly code in `src/runtime/gc.c`. +\r
5305 `GC_serialize` converts an object to a `Word8Vector.vector`. +\r
5306 `GC_deserialize` undoes the conversion. + (de)Serialization should work for\r
5307 all objects except for functions, because I haven't yet added the support in\r
5308 the flow analysis.\r
5309\r
5310* 1999-07-31\r
5311 ** Cleaned up the GC. Changed headers, by stealing a bit from the number of\r
5312 non pointers and making it a mark bit (used in `GC_size`).\r
5313 ** Rewrote `GC_size` so that it runs in time proportional to the number of\r
5314 pointers in the object. It does a depth-first-search now, using toSpace to\r
5315 hold the stack.\r
5316\r
5317* 1999-07-30\r
5318 ** Fixed bug in `SUBSTRING`. `getc` had the wrong type. This bug wasn't\r
5319 noticed because MLton doesn't do enough type checking.\r
5320 ** Fixed bug (segfault) caused when a GC immediately followed a throw.\r
5321\r
5322* 1999-07-29\r
5323 ** Fixed bug in `Date.fmt` (`basis-library/system/date.sml`). It was not\r
5324 setting `Tm.buf`, and hence the time was always 0 unless there had been a\r
5325 previous call to `setTmBuf`.\r
5326\r
5327* 1999-07-28\r
5328 ** Fixed bugs in `Posix.IO.FLock.{getlk,setlk,setlkw}`, which would cause\r
5329 compilation to fail because `FLock.toInt` was defined as the C `castInt`,\r
5330 which no longer exists. Instead, expand `FLock.toInt` to\r
5331 `MLTON_pointerToInt`, which was added to `include/mlton-lib.h`.\r
5332 ** Changed `Posix.Primitive.Flock` to `Posix.Primitive.FLock`.\r
5333 ** Added `MLTON_chown`, `MLTON_ftruncate` to `include/mlton-posix.h`. They\r
5334 were missing. This would cause compilation of any program using\r
5335 `Posix.FileSys.{chown,ftruncate}` to fail. Also made it so all of the\r
5336 primitives in `basis-library/posix/primitive.sml` use `MLTON_` versions of\r
5337 functions, even if a wrapper is unnecessary.\r
5338\r
5339* 1999-07-25\r
5340 ** Added some other missing signature definitions to toplevel.\r
5341\r
5342* 1999-07-24\r
5343 ** Added missing `OS_*` signature definitions to\r
5344 `basis-library/top-level/top-level.sml`.\r
5345\r
5346* 1999-07-19\r
5347 ** Fixed bug in `basis-library/arrays-and-vectors/mono-array.sml`. Used `:&gt;`\r
5348 instead of `:` so that the monomorphic array types are abstract.\r
5349\r
5350\r
5351== Version 19990712\r
5352\r
5353Here are the changes from the 1999-03-19 version to the 1999-07-12 version.\r
5354\r
5355=== Details\r
5356\r
5357* 1999-07-12\r
5358 ** Changed `src/backend/machine.fun` so that the 'pointer locals' array is\r
5359 only as large as neccessary in order to copy all pointer-valued locals, not as\r
5360 large as the number of pointer-valued locals.\r
5361\r
5362* 1999-07-11\r
5363 ** Rewrote `src/backend/allocate-registers.fun` so that it does a better job\r
5364 of sharing "registers" (i.e. C local variables) and stack slots. This should\r
5365 cut down on the amount of copying that has to happen before and after a gc.\r
5366 It should also cut down on the size of stack slots.\r
5367\r
5368* 1999-07-10\r
5369 ** Fixed a bug in `src/backend/parallel-move.fun` that should have been\r
5370 triggered on most any parallel move. I guess parallel moves almost never\r
5371 happened due to the old register allocation strategy -- but, with the new one\r
5372 (see note for 1999-07-12) parallel moves will be frequent.\r
5373\r
5374* 1999-06-27\r
5375 ** Fixed `src/main.sml` so that when compiling `-p`, the `.c` file is compiled\r
5376 `-g` and the `.o` is linked `-p`.\r
5377 ** In `bakend/machine.fun`, added profiling comments before chunkswitches and\r
5378 put in an optimization to avoid printing repeated profiling comments. Also,\r
5379 profiling comments are only output when compiling `-p`.\r
5380\r
5381* 1999-06-17\r
5382 ** Changed `-i` to `-inline`, `-f` to `-flatten`, `-np` to `-no-polyvariance`,\r
5383 `-u` to `-unsafe`.\r
5384 ** Added `-i`, `-I`, `-l`, `-L` flags for includes and libraries.\r
5385 ** Updated documentation for these options and for ffi.\r
5386\r
5387* 1999-06-16\r
5388 ** Hardwired version number in `src/control/control.sml`. As it stood, the\r
5389 version number was computed when MLton was built after someone downloaded it,\r
5390 which was clearly wrong.\r
5391\r
5392* 1999-06-16\r
5393 ** Fixed undefined variable `time` in `GC_done` in `src/runtime/gc.c`.\r
5394\r
5395* 19990-06-08\r
5396 ** in `include/mlton-lib.h`:\r
5397 *** removed `#include &lt;huge_val.h&gt;`\r
5398 *** added `#include &lt;math.h&gt;`\r
5399 *** and deleted all of the function signatures I had copied from `math.h`\r
5400 ** Changed `Real.{minNormalPos, minPos, maxFinite}` so that they are computed\r
5401 in `real.sml` instead of appearing as constants in the C.\r
5402\r
5403* 1999-06-07\r
5404 `IntInf.pow` added to basis library.\r
5405\r
5406* 1999-06-04\r
5407 ** `bin/mlton` changed to use `.arch-n-opsys` if it exists.\r
5408\r
5409* 1999-06-03\r
5410 ** `src/Makefile` changed to use `sml-cm` instead of `sml`\r
5411\r
5412* 1999-05-10\r
5413 ** Patch to `src/atoms/small-int-inf.fun` to work around a bug in the SML/NJ\r
5414 implementation of bignums. This bug was causing some hex bignum constants to\r
5415 be lexed incorrectly.\r
5416\r
5417* 1999-04-15\r
5418 ** Comments emitted in C code for profiling. The comments identify the CPS\r
5419 function responsible for each C statement.\r
5420\r
5421* 1999-04-15\r
5422 ** `callcc` and `throw` added.\r
5423\r
5424* 1999-04-15\r
5425 ** Bug in `src/cps/simplify-types` fixed. The bug caused nontermination\r
5426 whenever there was a circular datatype with a vector on the rhs.\r
5427 E.g. `datatype t = T of t vector`\r
5428\r
5429\r
5430== Version 19990319\r
5431\r
5432Here are the changes from the 1998-08-26 version to the 1999-03-19 version.\r
5433\r
5434=== Summary\r
5435\r
5436* Compile time and code size have decreased.\r
5437* Runtime performance of executables has improved.\r
5438* Large programs can now be compiled.\r
5439* MLton is self hosting.\r
5440* The basis library is mostly complete and many bugs have been fixed.\r
5441* The monomorphiser (`-m`) is no longer available.\r
5442* The heap and stack are automatically resized.\r
5443* There are now facilities for heap checkpointing (`MLton.saveWorld`) and object\r
5444size computation (`MLton.size`).\r
5445* MLton uses the GNU multiprecision (GnuMP) library to provide a fast\r
5446implementation of `IntInf`.</screen>\r
5447<simpara><?asciidoc-pagebreak?></simpara>\r
5448</section>\r
5449<section id="ChrisClearwater">\r
5450<title>ChrisClearwater</title>\r
5451<simpara></simpara>\r
5452<simpara><?asciidoc-pagebreak?></simpara>\r
5453</section>\r
5454<section id="Chunkify">\r
5455<title>Chunkify</title>\r
5456<simpara><link linkend="Chunkify">Chunkify</link> is an analysis pass for the <link linkend="RSSA">RSSA</link>\r
5457<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="ToMachine">ToMachine</link>.</simpara>\r
5458<section id="_description_3">\r
5459<title>Description</title>\r
5460<simpara>It partitions all the labels (function and block) in an <link linkend="RSSA">RSSA</link>\r
5461program into disjoint sets, referred to as chunks.</simpara>\r
5462</section>\r
5463<section id="_implementation_4">\r
5464<title>Implementation</title>\r
5465<itemizedlist>\r
5466<listitem>\r
5467<simpara>\r
5468<ulink url="https://github.com/MLton/mlton/blob/master/mlton/backend/chunkify.sig"><literal>chunkify.sig</literal></ulink>\r
5469</simpara>\r
5470</listitem>\r
5471<listitem>\r
5472<simpara>\r
5473<ulink url="https://github.com/MLton/mlton/blob/master/mlton/backend/chunkify.fun"><literal>chunkify.fun</literal></ulink>\r
5474</simpara>\r
5475</listitem>\r
5476</itemizedlist>\r
5477</section>\r
5478<section id="_details_and_notes_4">\r
5479<title>Details and Notes</title>\r
5480<simpara>Breaking large <link linkend="RSSA">RSSA</link> functions into chunks is necessary for\r
5481reasonable compile times with the <link linkend="CCodegen">CCodegen</link> and the <link linkend="LLVMCodegen">LLVMCodegen</link>.</simpara>\r
5482<simpara><?asciidoc-pagebreak?></simpara>\r
5483</section>\r
5484</section>\r
5485<section id="CKitLibrary">\r
5486<title>CKitLibrary</title>\r
5487<simpara>The <ulink url="http://www.smlnj.org/doc/ckit">ckit Library</ulink> is a C front end\r
5488written in SML that translates C source code (after preprocessing)\r
5489into abstract syntax represented as a set of SML datatypes. The ckit\r
5490Library is distributed with SML/NJ. Due to differences between SML/NJ\r
5491and MLton, this library will not work out-of-the box with MLton.</simpara>\r
5492<simpara>As of 20180119, MLton includes a port of the ckit Library synchronized\r
5493with SML/NJ version 110.82.</simpara>\r
5494<section id="_usage">\r
5495<title>Usage</title>\r
5496<itemizedlist>\r
5497<listitem>\r
5498<simpara>\r
5499You can import the ckit Library into an MLB file with:\r
5500</simpara>\r
5501<informaltable\r
5502frame="all"\r
5503rowsep="1" colsep="1"\r
5504>\r
5505<tgroup cols="2">\r
5506<colspec colname="col_1" colwidth="50*"/>\r
5507<colspec colname="col_2" colwidth="50*"/>\r
5508<thead>\r
5509<row>\r
5510<entry align="left" valign="top">MLB file</entry>\r
5511<entry align="left" valign="top">Description</entry>\r
5512</row>\r
5513</thead>\r
5514<tbody>\r
5515<row>\r
5516<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/ckit-lib/ckit-lib.mlb</literal></simpara></entry>\r
5517<entry align="left" valign="top"><simpara></simpara></entry>\r
5518</row>\r
5519</tbody>\r
5520</tgroup>\r
5521</informaltable>\r
5522</listitem>\r
5523<listitem>\r
5524<simpara>\r
5525If you are porting a project from SML/NJ&#8217;s <link linkend="CompilationManager">CompilationManager</link> to\r
5526MLton&#8217;s <link linkend="MLBasis">ML Basis system</link> using <literal>cm2mlb</literal>, note that the\r
5527following map is included by default:\r
5528</simpara>\r
5529<screen># ckit Library\r
5530$ckit-lib.cm $(SML_LIB)/ckit-lib\r
5531$ckit-lib.cm/ckit-lib.cm $(SML_LIB)/ckit-lib/ckit-lib.mlb</screen>\r
5532<simpara>This will automatically convert a <literal>$/ckit-lib.cm</literal> import in an input\r
5533<literal>.cm</literal> file into a <literal>$(SML_LIB)/ckit-lib/ckit-lib.mlb</literal> import in the\r
5534output <literal>.mlb</literal> file.</simpara>\r
5535</listitem>\r
5536</itemizedlist>\r
5537</section>\r
5538<section id="_details">\r
5539<title>Details</title>\r
5540<simpara>The following changes were made to the ckit Library, in addition to\r
5541deriving the <literal>.mlb</literal> file from the <literal>.cm</literal> file:</simpara>\r
5542<itemizedlist>\r
5543<listitem>\r
5544<simpara>\r
5545<literal>ast/pp/pp-ast-adornment-sig.sml</literal> (modified): Rewrote use of <literal>signature</literal> in <literal>local</literal>.\r
5546</simpara>\r
5547</listitem>\r
5548<listitem>\r
5549<simpara>\r
5550<literal>ast/pp/pp-ast-ext-sig.sml</literal> (modified): Rewrote use of <literal>signature</literal> in <literal>local</literal>.\r
5551</simpara>\r
5552</listitem>\r
5553<listitem>\r
5554<simpara>\r
5555<literal>ast/type-util-sig.sml</literal> (modified): Rewrote use of <literal>signature</literal> in <literal>local</literal>.\r
5556</simpara>\r
5557</listitem>\r
5558<listitem>\r
5559<simpara>\r
5560<literal>parser/parse-tree-sig.sml</literal> (modified): Rewrote use of (sequential) <literal>withtype</literal> in signature.\r
5561</simpara>\r
5562</listitem>\r
5563<listitem>\r
5564<simpara>\r
5565<literal>parser/parse-tree.sml</literal> (modified): Rewrote use of (sequential) <literal>withtype</literal>.\r
5566</simpara>\r
5567</listitem>\r
5568</itemizedlist>\r
5569</section>\r
5570<section id="_patch">\r
5571<title>Patch</title>\r
5572<itemizedlist>\r
5573<listitem>\r
5574<simpara>\r
5575<ulink url="https://github.com/MLton/mlton/blob/master/lib/ckit-lib/ckit.patch"><literal>ckit.patch</literal></ulink>\r
5576</simpara>\r
5577</listitem>\r
5578</itemizedlist>\r
5579<simpara><?asciidoc-pagebreak?></simpara>\r
5580</section>\r
5581</section>\r
5582<section id="Closure">\r
5583<title>Closure</title>\r
5584<simpara>A closure is a data structure that is the run-time representation of a\r
5585function.</simpara>\r
5586<section id="_typical_implementation">\r
5587<title>Typical Implementation</title>\r
5588<simpara>In a typical implementation, a closure consists of a <emphasis>code pointer</emphasis>\r
5589(indicating what the function does) and an <emphasis>environment</emphasis> containing\r
5590the values of the free variables of the function. For example, in the\r
5591expression</simpara>\r
5592<programlisting language="sml" linenumbering="unnumbered">let\r
5593 val x = 5\r
5594in\r
5595 fn y =&gt; x + y\r
5596end</programlisting>\r
5597<simpara>the closure for <literal>fn y =&gt; x + y</literal> contains a pointer to a piece of code\r
5598that knows to take its argument and add the value of <literal>x</literal> to it, plus\r
5599the environment recording the value of <literal>x</literal> as <literal>5</literal>.</simpara>\r
5600<simpara>To call a function, the code pointer is extracted and jumped to,\r
5601passing in some agreed upon location the environment and the argument.</simpara>\r
5602</section>\r
5603<section id="_mlton_8217_s_implementation">\r
5604<title>MLton&#8217;s Implementation</title>\r
5605<simpara>MLton does not implement closures traditionally. Instead, based on\r
5606whole-program higher-order control-flow analysis, MLton represents a\r
5607function as an element of a sum type, where the variant indicates\r
5608which function it is and carries the free variables as arguments. See\r
5609<link linkend="ClosureConvert">ClosureConvert</link> and <link linkend="References_CejtinEtAl00">CejtinEtAl00</link> for details.</simpara>\r
5610<simpara><?asciidoc-pagebreak?></simpara>\r
5611</section>\r
5612</section>\r
5613<section id="ClosureConvert">\r
5614<title>ClosureConvert</title>\r
5615<simpara><link linkend="ClosureConvert">ClosureConvert</link> is a translation pass from the <link linkend="SXML">SXML</link>\r
5616<link linkend="IntermediateLanguage">IntermediateLanguage</link> to the <link linkend="SSA">SSA</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link>.</simpara>\r
5617<section id="_description_4">\r
5618<title>Description</title>\r
5619<simpara>It converts an <link linkend="SXML">SXML</link> program into an <link linkend="SSA">SSA</link> program.</simpara>\r
5620<simpara><link linkend="Defunctionalization">Defunctionalization</link> is the technique used to eliminate\r
5621<link linkend="Closure">Closure</link>s (see <link linkend="References_CejtinEtAl00">CejtinEtAl00</link>).</simpara>\r
5622<simpara>Uses <link linkend="Globalize">Globalize</link> and <link linkend="LambdaFree">LambdaFree</link> analyses.</simpara>\r
5623</section>\r
5624<section id="_implementation_5">\r
5625<title>Implementation</title>\r
5626<itemizedlist>\r
5627<listitem>\r
5628<simpara>\r
5629<ulink url="https://github.com/MLton/mlton/blob/master/mlton/closure-convert/closure-convert.sig"><literal>closure-convert.sig</literal></ulink>\r
5630</simpara>\r
5631</listitem>\r
5632<listitem>\r
5633<simpara>\r
5634<ulink url="https://github.com/MLton/mlton/blob/master/mlton/closure-convert/closure-convert.fun"><literal>closure-convert.fun</literal></ulink>\r
5635</simpara>\r
5636</listitem>\r
5637</itemizedlist>\r
5638</section>\r
5639<section id="_details_and_notes_5">\r
5640<title>Details and Notes</title>\r
5641<simpara></simpara>\r
5642<simpara><?asciidoc-pagebreak?></simpara>\r
5643</section>\r
5644</section>\r
5645<section id="CMinusMinus">\r
5646<title>CMinusMinus</title>\r
5647<simpara><ulink url="http://cminusminus.org">C--</ulink> is a portable assembly language intended\r
5648to make it easy for compilers for different high-level languages to\r
5649share the same backend. An experimental version of MLton has been\r
5650made to generate C--.</simpara>\r
5651<itemizedlist>\r
5652<listitem>\r
5653<simpara>\r
5654<ulink url="http://www.mlton.org/pipermail/mlton/2005-March/026850.html">http://www.mlton.org/pipermail/mlton/2005-March/026850.html</ulink>\r
5655</simpara>\r
5656</listitem>\r
5657</itemizedlist>\r
5658<section id="_also_see">\r
5659<title>Also see</title>\r
5660<itemizedlist>\r
5661<listitem>\r
5662<simpara>\r
5663<link linkend="LLVM">LLVM</link>\r
5664</simpara>\r
5665</listitem>\r
5666</itemizedlist>\r
5667<simpara><?asciidoc-pagebreak?></simpara>\r
5668</section>\r
5669</section>\r
5670<section id="Codegen">\r
5671<title>Codegen</title>\r
5672<simpara><link linkend="Codegen">Codegen</link> is a translation pass from the <link linkend="Machine">Machine</link>\r
5673<link linkend="IntermediateLanguage">IntermediateLanguage</link> to one or more compilation units that can be\r
5674compiled to native object code by an external tool.</simpara>\r
5675<section id="_implementation_6">\r
5676<title>Implementation</title>\r
5677<itemizedlist>\r
5678<listitem>\r
5679<simpara>\r
5680<ulink url="https://github.com/MLton/mlton/tree/master/mlton/codegen"><literal>codegen</literal></ulink>\r
5681</simpara>\r
5682</listitem>\r
5683</itemizedlist>\r
5684</section>\r
5685<section id="_details_and_notes_6">\r
5686<title>Details and Notes</title>\r
5687<simpara>The following <link linkend="Codegen">codegens</link> are implemented:</simpara>\r
5688<itemizedlist>\r
5689<listitem>\r
5690<simpara>\r
5691<link linkend="AMD64Codegen">AMD64Codegen</link>\r
5692</simpara>\r
5693</listitem>\r
5694<listitem>\r
5695<simpara>\r
5696<link linkend="CCodegen">CCodegen</link>\r
5697</simpara>\r
5698</listitem>\r
5699<listitem>\r
5700<simpara>\r
5701<link linkend="LLVMCodegen">LLVMCodegen</link>\r
5702</simpara>\r
5703</listitem>\r
5704<listitem>\r
5705<simpara>\r
5706<link linkend="X86Codegen">X86Codegen</link>\r
5707</simpara>\r
5708</listitem>\r
5709</itemizedlist>\r
5710<simpara><?asciidoc-pagebreak?></simpara>\r
5711</section>\r
5712</section>\r
5713<section id="CombineConversions">\r
5714<title>CombineConversions</title>\r
5715<simpara><link linkend="CombineConversions">CombineConversions</link> is an optimization pass for the <link linkend="SSA">SSA</link>\r
5716<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="SSASimplify">SSASimplify</link>.</simpara>\r
5717<section id="_description_5">\r
5718<title>Description</title>\r
5719<simpara>This pass looks for and simplifies nested calls to (signed)\r
5720extension/truncation.</simpara>\r
5721</section>\r
5722<section id="_implementation_7">\r
5723<title>Implementation</title>\r
5724<itemizedlist>\r
5725<listitem>\r
5726<simpara>\r
5727<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/combine-conversions.fun"><literal>combine-conversions.fun</literal></ulink>\r
5728</simpara>\r
5729</listitem>\r
5730</itemizedlist>\r
5731</section>\r
5732<section id="_details_and_notes_7">\r
5733<title>Details and Notes</title>\r
5734<simpara>It processes each block in dfs order (visiting definitions before uses):</simpara>\r
5735<itemizedlist>\r
5736<listitem>\r
5737<simpara>\r
5738If the statement is not a <literal>PrimApp</literal> with <literal>Word_extdToWord</literal>, skip it.\r
5739</simpara>\r
5740</listitem>\r
5741<listitem>\r
5742<simpara>\r
5743After processing a conversion, it tags the <literal>Var</literal> for subsequent use.\r
5744</simpara>\r
5745</listitem>\r
5746<listitem>\r
5747<simpara>\r
5748When inspecting a conversion, check if the <literal>Var</literal> operand is also the\r
5749result of a conversion. If it is, try to combine the two operations.\r
5750Repeatedly simplify until hitting either a non-conversion <literal>Var</literal> or a\r
5751case where the conversion cannot be simplified.\r
5752</simpara>\r
5753</listitem>\r
5754</itemizedlist>\r
5755<simpara>The optimization rules are very simple:</simpara>\r
5756<screen>x1 = ...\r
5757x2 = Word_extdToWord (W1, W2, {signed=s1}) x1\r
5758x3 = Word_extdToWord (W2, W3, {signed=s2}) x2</screen>\r
5759<itemizedlist>\r
5760<listitem>\r
5761<simpara>\r
5762If <literal>W1 = W2</literal>, then there is no conversions before <literal>x_1</literal>.\r
5763</simpara>\r
5764<simpara>This is guaranteed because <literal>W2 = W3</literal> will always trigger optimization.</simpara>\r
5765</listitem>\r
5766<listitem>\r
5767<simpara>\r
5768Case <literal>W1 &lt;= W3 &lt;= W2</literal>:\r
5769</simpara>\r
5770<screen>x3 = Word_extdToWord (W1, W3, {signed=s1}) x1</screen>\r
5771</listitem>\r
5772<listitem>\r
5773<simpara>\r
5774Case <literal>W1 &lt; W2 &lt; W3 AND ((NOT s1) OR s2)</literal>:\r
5775</simpara>\r
5776<screen>x3 = Word_extdToWord (W1, W3, {signed=s1}) x1</screen>\r
5777</listitem>\r
5778<listitem>\r
5779<simpara>\r
5780Case <literal>W1 = W2 &lt; W3</literal>:\r
5781</simpara>\r
5782<simpara>unoptimized, because there are no conversions past <literal>W1</literal> and <literal>x2 = x1</literal></simpara>\r
5783</listitem>\r
5784<listitem>\r
5785<simpara>\r
5786Case <literal>W3 &lt;= W2 &lt;= W1 OR W3 &lt;= W1 &lt;= W2</literal>:\r
5787</simpara>\r
5788<screen>x_3 = Word_extdToWord (W1, W3, {signed=_}) x1</screen>\r
5789<simpara>because <literal>W3 &lt;= W1 &amp;&amp; W3 &lt;= W2</literal>, just clip <literal>x1</literal></simpara>\r
5790</listitem>\r
5791<listitem>\r
5792<simpara>\r
5793Case <literal>W2 &lt; W1 &lt;= W3 OR W2 &lt; W3 &lt;= W1</literal>:\r
5794</simpara>\r
5795<simpara>unoptimized, because <literal>W2 &lt; W1 &amp;&amp; W2 &lt; W3</literal>, has truncation effect</simpara>\r
5796</listitem>\r
5797<listitem>\r
5798<simpara>\r
5799Case <literal>W1 &lt; W2 &lt; W3 AND (s1 AND (NOT s2))</literal>:\r
5800</simpara>\r
5801<simpara>unoptimized, because each conversion affects the result separately</simpara>\r
5802</listitem>\r
5803</itemizedlist>\r
5804<simpara><?asciidoc-pagebreak?></simpara>\r
5805</section>\r
5806</section>\r
5807<section id="CommonArg">\r
5808<title>CommonArg</title>\r
5809<simpara><link linkend="CommonArg">CommonArg</link> is an optimization pass for the <link linkend="SSA">SSA</link>\r
5810<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="SSASimplify">SSASimplify</link>.</simpara>\r
5811<section id="_description_6">\r
5812<title>Description</title>\r
5813<simpara>It optimizes instances of <literal>Goto</literal> transfers that pass the same\r
5814arguments to the same label; e.g.</simpara>\r
5815<screen>L_1 ()\r
5816 ...\r
5817 z1 = ?\r
5818 ...\r
5819 L_3 (x, y, z1)\r
5820L_2 ()\r
5821 ...\r
5822 z2 = ?\r
5823 ...\r
5824 L_3 (x, y, z2)\r
5825L_3 (a, b, c)\r
5826 ...</screen>\r
5827<simpara>This code can be simplified to:</simpara>\r
5828<screen>L_1 ()\r
5829 ...\r
5830 z1 = ?\r
5831 ...\r
5832 L_3 (z1)\r
5833L_2 ()\r
5834 ...\r
5835 z2 = ?\r
5836 ...\r
5837 L_3 (z2)\r
5838L_3 (c)\r
5839 a = x\r
5840 b = y</screen>\r
5841<simpara>which saves a number of resources: time of setting up the arguments\r
5842for the jump to <literal>L_3</literal>, space (either stack or pseudo-registers) for\r
5843the arguments of <literal>L_3</literal>, etc. It may also expose some other\r
5844optimizations, if more information is known about <literal>x</literal> or <literal>y</literal>.</simpara>\r
5845</section>\r
5846<section id="_implementation_8">\r
5847<title>Implementation</title>\r
5848<itemizedlist>\r
5849<listitem>\r
5850<simpara>\r
5851<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/common-arg.fun"><literal>common-arg.fun</literal></ulink>\r
5852</simpara>\r
5853</listitem>\r
5854</itemizedlist>\r
5855</section>\r
5856<section id="_details_and_notes_8">\r
5857<title>Details and Notes</title>\r
5858<simpara>Three analyses were originally proposed to drive the optimization\r
5859transformation. Only the <emphasis>Dominator Analysis</emphasis> is currently\r
5860implemented. (Implementations of the other analyses are available in\r
5861the <link linkend="Sources">repository history</link>.)</simpara>\r
5862<section id="_syntactic_analysis">\r
5863<title>Syntactic Analysis</title>\r
5864<simpara>The simplest analysis I could think of maintains</simpara>\r
5865<screen>varInfo: Var.t -&gt; Var.t option list ref</screen>\r
5866<simpara>initialized to <literal>[]</literal>.</simpara>\r
5867<itemizedlist>\r
5868<listitem>\r
5869<simpara>\r
5870For each variable <literal>v</literal> bound in a <literal>Statement.t</literal> or in the\r
5871<literal>Function.t</literal> args, then <literal>List.push(varInfo v, NONE)</literal>.\r
5872</simpara>\r
5873</listitem>\r
5874<listitem>\r
5875<simpara>\r
5876For each <literal>L (x1, ..., xn)</literal> transfer where <literal>(a1, ..., an)</literal> are the\r
5877formals of <literal>L</literal>, then <literal>List.push(varInfo ai, SOME xi)</literal>.\r
5878</simpara>\r
5879</listitem>\r
5880<listitem>\r
5881<simpara>\r
5882For each block argument a used in an unknown context (e.g.,\r
5883arguments of blocks used as continuations, handlers, arith success,\r
5884runtime return, or case switch labels), then\r
5885<literal>List.push(varInfo a, NONE)</literal>.\r
5886</simpara>\r
5887</listitem>\r
5888</itemizedlist>\r
5889<simpara>Now, any block argument <literal>a</literal> such that <literal>varInfo a = xs</literal>, where all of\r
5890the elements of <literal>xs</literal> are equal to <literal>SOME x</literal>, can be optimized by\r
5891setting <literal>a = x</literal> at the beginning of the block and dropping the\r
5892argument from <literal>Goto</literal> transfers.</simpara>\r
5893<simpara>That takes care of the example above. We can clearly do slightly\r
5894better, by changing the transformation criteria to the following: any\r
5895block argument a such that <literal>varInfo a = xs</literal>, where all of the elements\r
5896of <literal>xs</literal> are equal to <literal>SOME x</literal> <emphasis>or</emphasis> are equal to <literal>SOME a</literal>, can be\r
5897optimized by setting <literal>a = x</literal> at the beginning of the block and\r
5898dropping the argument from <literal>Goto</literal> transfers. This optimizes a case\r
5899like:</simpara>\r
5900<screen>L_1 ()\r
5901 ... z1 = ? ...\r
5902 L_3 (x, y, z1)\r
5903L_2 ()\r
5904 ... z2 = ? ...\r
5905 L_3(x, y, z2)\r
5906L_3 (a, b, c)\r
5907 ... w = ? ...\r
5908 case w of\r
5909 true =&gt; L_4 | false =&gt; L_5\r
5910L_4 ()\r
5911 ...\r
5912 L_3 (a, b, w)\r
5913L_5 ()\r
5914 ...</screen>\r
5915<simpara>where a common argument is passed to a loop (and is invariant through\r
5916the loop). Of course, the <link linkend="LoopInvariant">LoopInvariant</link> optimization pass would\r
5917normally introduce a local loop and essentially reduce this to the\r
5918first example, but I have seen this in practice, which suggests that\r
5919some optimizations after <link linkend="LoopInvariant">LoopInvariant</link> do enough simplifications\r
5920to introduce (new) loop invariant arguments.</simpara>\r
5921</section>\r
5922<section id="_fixpoint_analysis">\r
5923<title>Fixpoint Analysis</title>\r
5924<simpara>However, the above analysis and transformation doesn&#8217;t cover the cases\r
5925where eliminating one common argument exposes the opportunity to\r
5926eliminate other common arguments. For example:</simpara>\r
5927<screen>L_1 ()\r
5928 ...\r
5929 L_3 (x)\r
5930L_2 ()\r
5931 ...\r
5932 L_3 (x)\r
5933L_3 (a)\r
5934 ...\r
5935 L_5 (a)\r
5936L_4 ()\r
5937 ...\r
5938 L_5 (x)\r
5939L_5 (b)\r
5940 ...</screen>\r
5941<simpara>One pass of analysis and transformation would eliminate the argument\r
5942to <literal>L_3</literal> and rewrite the <literal>L_5(a)</literal> transfer to <literal>L_5 (x)</literal>, thereby\r
5943exposing the opportunity to eliminate the common argument to <literal>L_5</literal>.</simpara>\r
5944<simpara>The interdependency the arguments to <literal>L_3</literal> and <literal>L_5</literal> suggest\r
5945performing some sort of fixed-point analysis. This analysis is\r
5946relatively simple; maintain</simpara>\r
5947<screen>varInfo: Var.t -&gt; VarLattice.t</screen>\r
5948<simpara>where</simpara>\r
5949<screen>VarLattice.t ~=~ Bot | Point of Var.t | Top</screen>\r
5950<simpara>(but is implemented by the <link linkend="FlatLattice">FlatLattice</link> functor with a <literal>lessThan</literal>\r
5951list and <literal>value ref</literal> under the hood), initialized to <literal>Bot</literal>.</simpara>\r
5952<itemizedlist>\r
5953<listitem>\r
5954<simpara>\r
5955For each variable <literal>v</literal> bound in a <literal>Statement.t</literal> or in the\r
5956<literal>Function.t</literal> args, then <literal>VarLattice.&lt;= (Point v, varInfo v)</literal>\r
5957</simpara>\r
5958</listitem>\r
5959<listitem>\r
5960<simpara>\r
5961For each <literal>L (x1, ..., xn)</literal> transfer where <literal>(a1, ..., an)</literal> are the\r
5962formals of <literal>L</literal>}, then <literal>VarLattice.&lt;= (varInfo xi, varInfo ai)</literal>.\r
5963</simpara>\r
5964</listitem>\r
5965<listitem>\r
5966<simpara>\r
5967For each block argument a used in an unknown context, then\r
5968<literal>VarLattice.&lt;= (Point a, varInfo a)</literal>.\r
5969</simpara>\r
5970</listitem>\r
5971</itemizedlist>\r
5972<simpara>Now, any block argument a such that <literal>varInfo a = Point x</literal> can be\r
5973optimized by setting <literal>a = x</literal> at the beginning of the block and\r
5974dropping the argument from <literal>Goto</literal> transfers.</simpara>\r
5975<simpara>Now, with the last example, we introduce the ordering constraints:</simpara>\r
5976<screen>varInfo x &lt;= varInfo a\r
5977varInfo a &lt;= varInfo b\r
5978varInfo x &lt;= varInfo b</screen>\r
5979<simpara>Assuming that <literal>varInfo x = Point x</literal>, then we get <literal>varInfo a = Point x</literal>\r
5980and <literal>varInfo b = Point x</literal>, and we optimize the example as desired.</simpara>\r
5981<simpara>But, that is a rather weak assumption. It&#8217;s quite possible for\r
5982<literal>varInfo x = Top</literal>. For example, consider:</simpara>\r
5983<screen>G_1 ()\r
5984 ... n = 1 ...\r
5985 L_0 (n)\r
5986G_2 ()\r
5987 ... m = 2 ...\r
5988 L_0 (m)\r
5989L_0 (x)\r
5990 ...\r
5991L_1 ()\r
5992 ...\r
5993 L_3 (x)\r
5994L_2 ()\r
5995 ...\r
5996 L_3 (x)\r
5997L_3 (a)\r
5998 ...\r
5999 L_5(a)\r
6000L_4 ()\r
6001 ...\r
6002 L_5(x)\r
6003L_5 (b)\r
6004 ...</screen>\r
6005<simpara>Now <literal>varInfo x = varInfo a = varInfo b = Top</literal>. What went wrong here?\r
6006When <literal>varInfo x</literal> went to <literal>Top</literal>, it got propagated all the way through\r
6007to <literal>a</literal> and <literal>b</literal>, and prevented the elimination of any common arguments.\r
6008What we&#8217;d like to do instead is when <literal>varInfo x</literal> goes to <literal>Top</literal>,\r
6009propagate on <literal>Point x</literal>&#8201;&#8212;&#8201;we have no hope of eliminating <literal>x</literal>, but if\r
6010we hold <literal>x</literal> constant, then we have a chance of eliminating arguments\r
6011for which <literal>x</literal> is passed as an actual.</simpara>\r
6012</section>\r
6013<section id="_dominator_analysis">\r
6014<title>Dominator Analysis</title>\r
6015<simpara>Does anyone see where this is going yet? Pausing for a little\r
6016thought, <link linkend="MatthewFluet">MatthewFluet</link> realized that he had once before tried\r
6017proposing this kind of "fix" to a fixed-point analysis&#8201;&#8212;&#8201;when we were\r
6018first investigating the <link linkend="Contify">Contify</link> optimization in light of John\r
6019Reppy&#8217;s CWS paper. Of course, that "fix" failed because it defined a\r
6020non-monotonic function and one couldn&#8217;t take the fixed point. But,\r
6021<link linkend="StephenWeeks">StephenWeeks</link> suggested a dominator based approach, and we were\r
6022able to show that, indeed, the dominator analysis subsumed both the\r
6023previous call based analysis and the cont based analysis. And, a\r
6024moment&#8217;s reflection reveals further parallels: when\r
6025<literal>varInfo: Var.t -&gt; Var.t option list ref</literal>, we have something analogous\r
6026to the call analysis, and when <literal>varInfo: Var.t -&gt; VarLattice.t</literal>, we\r
6027have something analogous to the cont analysis. Maybe there is\r
6028something analogous to the dominator approach (and therefore superior\r
6029to the previous analyses).</simpara>\r
6030<simpara>And this turns out to be the case. Construct the graph <literal>G</literal> as follows:</simpara>\r
6031<screen>nodes(G) = {Root} U Var.t\r
6032edges(G) = {Root -&gt; v | v bound in a Statement.t or\r
6033 in the Function.t args} U\r
6034 {xi -&gt; ai | L(x1, ..., xn) transfer where (a1, ..., an)\r
6035 are the formals of L} U\r
6036 {Root -&gt; a | a is a block argument used in an unknown context}</screen>\r
6037<simpara>Let <literal>idom(x)</literal> be the immediate dominator of <literal>x</literal> in <literal>G</literal> with root\r
6038<literal>Root</literal>. Now, any block argument a such that <literal>idom(a) = x &lt;&gt; Root</literal> can\r
6039be optimized by setting <literal>a = x</literal> at the beginning of the block and\r
6040dropping the argument from <literal>Goto</literal> transfers.</simpara>\r
6041<simpara>Furthermore, experimental evidence suggests (and we are confident that\r
6042a formal presentation could prove) that the dominator analysis\r
6043subsumes the "syntactic" and "fixpoint" based analyses in this context\r
6044as well and that the dominator analysis gets "everything" in one go.</simpara>\r
6045</section>\r
6046<section id="_final_thoughts">\r
6047<title>Final Thoughts</title>\r
6048<simpara>I must admit, I was rather surprised at this progression and final\r
6049result. At the outset, I never would have thought of a connection\r
6050between <link linkend="Contify">Contify</link> and <link linkend="CommonArg">CommonArg</link> optimizations. They would seem\r
6051to be two completely different optimizations. Although, this may not\r
6052really be the case. As one of the reviewers of the ICFP paper said:</simpara>\r
6053<blockquote>\r
6054<simpara>I understand that such a form of CPS might be convenient in some\r
6055cases, but when we&#8217;re talking about analyzing code to detect that some\r
6056continuation is constant, I think it makes a lot more sense to make\r
6057all the continuation arguments completely explicit.</simpara>\r
6058<simpara>I believe that making all the continuation arguments explicit will\r
6059show that the optimization can be generalized to eliminating constant\r
6060arguments, whether continuations or not.</simpara>\r
6061</blockquote>\r
6062<simpara>What I think the common argument optimization shows is that the\r
6063dominator analysis does slightly better than the reviewer puts it: we\r
6064find more than just constant continuations, we find common\r
6065continuations. And I think this is further justified by the fact that\r
6066I have observed common argument eliminate some <literal>env_X</literal> arguments which\r
6067would appear to correspond to determining that while the closure being\r
6068executed isn&#8217;t constant it is at least the same as the closure being\r
6069passed elsewhere.</simpara>\r
6070<simpara>At first, I was curious whether or not we had missed a bigger picture\r
6071with the dominator analysis. When we wrote the contification paper, I\r
6072assumed that the dominator analysis was a specialized solution to a\r
6073specialized problem; we never suggested that it was a technique suited\r
6074to a larger class of analyses. After initially finding a connection\r
6075between <link linkend="Contify">Contify</link> and <link linkend="CommonArg">CommonArg</link> (and thinking that the only\r
6076connection was the technique), I wondered if the dominator technique\r
6077really was applicable to a larger class of analyses. That is still a\r
6078question, but after writing up the above, I&#8217;m suspecting that the\r
6079"real story" is that the dominator analysis is a solution to the\r
6080common argument optimization, and that the <link linkend="Contify">Contify</link> optimization is\r
6081specializing <link linkend="CommonArg">CommonArg</link> to the case of continuation arguments (with\r
6082a different transformation at the end). (Note, a whole-program,\r
6083inter-procedural common argument analysis doesn&#8217;t really make sense\r
6084(in our <link linkend="SSA">SSA</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link>), because the only way of\r
6085passing values between functions is as arguments. (Unless of course\r
6086in the case that the common argument is also a constant argument, in\r
6087which case <link linkend="ConstantPropagation">ConstantPropagation</link> could lift it to a global.) The\r
6088inter-procedural <link linkend="Contify">Contify</link> optimization works out because there we\r
6089move the function to the argument.)</simpara>\r
6090<simpara>Anyways, it&#8217;s still unclear to me whether or not the dominator based\r
6091approach solves other kinds of problems.</simpara>\r
6092</section>\r
6093<section id="_phase_ordering">\r
6094<title>Phase Ordering</title>\r
6095<simpara>On the downside, the optimization doesn&#8217;t have a huge impact on\r
6096runtime, although it does predictably saved some code size. I stuck\r
6097it in the optimization sequence after <link linkend="Flatten">Flatten</link> and (the third round\r
6098of) <link linkend="LocalFlatten">LocalFlatten</link>, since it seems to me that we could have cases\r
6099where some components of a tuple used as an argument are common, but\r
6100the whole tuple isn&#8217;t. I think it makes sense to add it after\r
6101<link linkend="IntroduceLoops">IntroduceLoops</link> and <link linkend="LoopInvariant">LoopInvariant</link> (even though <link linkend="CommonArg">CommonArg</link>\r
6102get some things that <link linkend="LoopInvariant">LoopInvariant</link> gets, it doesn&#8217;t get all of\r
6103them). I also think that it makes sense to add it before\r
6104<link linkend="CommonSubexp">CommonSubexp</link>, since identifying variables could expose more common\r
6105subexpressions. I would think a similar thought applies to\r
6106<link linkend="RedundantTests">RedundantTests</link>.</simpara>\r
6107<simpara><?asciidoc-pagebreak?></simpara>\r
6108</section>\r
6109</section>\r
6110</section>\r
6111<section id="CommonBlock">\r
6112<title>CommonBlock</title>\r
6113<simpara><link linkend="CommonBlock">CommonBlock</link> is an optimization pass for the <link linkend="SSA">SSA</link>\r
6114<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="SSASimplify">SSASimplify</link>.</simpara>\r
6115<section id="_description_7">\r
6116<title>Description</title>\r
6117<simpara>It eliminates equivalent blocks in a <link linkend="SSA">SSA</link> function. The\r
6118equivalence criteria requires blocks to have no arguments or\r
6119statements and transfer via <literal>Raise</literal>, <literal>Return</literal>, or <literal>Goto</literal> of a single\r
6120global variable.</simpara>\r
6121</section>\r
6122<section id="_implementation_9">\r
6123<title>Implementation</title>\r
6124<itemizedlist>\r
6125<listitem>\r
6126<simpara>\r
6127<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/common-block.fun"><literal>common-block.fun</literal></ulink>\r
6128</simpara>\r
6129</listitem>\r
6130</itemizedlist>\r
6131</section>\r
6132<section id="_details_and_notes_9">\r
6133<title>Details and Notes</title>\r
6134<itemizedlist>\r
6135<listitem>\r
6136<simpara>\r
6137Rewrites\r
6138</simpara>\r
6139<screen>L_X ()\r
6140 raise (global_Y)</screen>\r
6141<simpara>to</simpara>\r
6142<screen>L_X ()\r
6143 L_Y' ()</screen>\r
6144<simpara>and adds</simpara>\r
6145<screen>L_Y' ()\r
6146 raise (global_Y)</screen>\r
6147<simpara>to the <link linkend="SSA">SSA</link> function.</simpara>\r
6148</listitem>\r
6149<listitem>\r
6150<simpara>\r
6151Rewrites\r
6152</simpara>\r
6153<screen>L_X ()\r
6154 return (global_Y)</screen>\r
6155<simpara>to</simpara>\r
6156<screen>L_X ()\r
6157 L_Y' ()</screen>\r
6158<simpara>and adds</simpara>\r
6159<screen>L_Y' ()\r
6160 return (global_Y)</screen>\r
6161<simpara>to the <link linkend="SSA">SSA</link> function.</simpara>\r
6162</listitem>\r
6163<listitem>\r
6164<simpara>\r
6165Rewrites\r
6166</simpara>\r
6167<screen>L_X ()\r
6168 L_Z (global_Y)</screen>\r
6169<simpara>to</simpara>\r
6170<screen>L_X ()\r
6171 L_Y' ()</screen>\r
6172<simpara>and adds</simpara>\r
6173<screen>L_Y' ()\r
6174 L_Z (global_Y)</screen>\r
6175<simpara>to the <link linkend="SSA">SSA</link> function.</simpara>\r
6176</listitem>\r
6177</itemizedlist>\r
6178<simpara>The <link linkend="Shrink">Shrink</link> pass rewrites all uses of <literal>L_X</literal> to <literal>L_Y'</literal> and drops <literal>L_X</literal>.</simpara>\r
6179<simpara>For example, all uncaught <literal>Overflow</literal> exceptions in a <link linkend="SSA">SSA</link> function\r
6180share the same raising block.</simpara>\r
6181<simpara><?asciidoc-pagebreak?></simpara>\r
6182</section>\r
6183</section>\r
6184<section id="CommonSubexp">\r
6185<title>CommonSubexp</title>\r
6186<simpara><link linkend="CommonSubexp">CommonSubexp</link> is an optimization pass for the <link linkend="SSA">SSA</link>\r
6187<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="SSASimplify">SSASimplify</link>.</simpara>\r
6188<section id="_description_8">\r
6189<title>Description</title>\r
6190<simpara>It eliminates instances of common subexpressions.</simpara>\r
6191</section>\r
6192<section id="_implementation_10">\r
6193<title>Implementation</title>\r
6194<itemizedlist>\r
6195<listitem>\r
6196<simpara>\r
6197<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/common-subexp.fun"><literal>common-subexp.fun</literal></ulink>\r
6198</simpara>\r
6199</listitem>\r
6200</itemizedlist>\r
6201</section>\r
6202<section id="_details_and_notes_10">\r
6203<title>Details and Notes</title>\r
6204<simpara>In addition to getting the usual sorts of things like</simpara>\r
6205<itemizedlist>\r
6206<listitem>\r
6207<simpara>\r
6208</simpara>\r
6209<screen>(w + 0wx1) + (w + 0wx1)</screen>\r
6210<simpara>rewritten to</simpara>\r
6211<screen>let val w' = w + 0wx1 in w' + w' end</screen>\r
6212</listitem>\r
6213</itemizedlist>\r
6214<simpara>it also gets things like</simpara>\r
6215<itemizedlist>\r
6216<listitem>\r
6217<simpara>\r
6218</simpara>\r
6219<screen>val a = Array_uninit n\r
6220val b = Array_length a</screen>\r
6221<simpara>rewritten to</simpara>\r
6222<screen>val a = Array_uninit n\r
6223val b = n</screen>\r
6224</listitem>\r
6225</itemizedlist>\r
6226<simpara><literal>Arith</literal> transfers are handled specially. The <emphasis>result</emphasis> of an <literal>Arith</literal>\r
6227transfer can be used in <emphasis>common</emphasis> <literal>Arith</literal> transfers that it dominates:</simpara>\r
6228<itemizedlist>\r
6229<listitem>\r
6230<simpara>\r
6231</simpara>\r
6232<screen>val l = (n + m) + (n + m)\r
6233\r
6234val k = (l + n) + ((l + m) handle Overflow =&gt; ((l + m)\r
6235 handle Overflow =&gt; l + n))</screen>\r
6236<simpara>is rewritten so that <literal>(n + m)</literal> is computed exactly once, as are\r
6237<literal>(l + n)</literal> and <literal>(l + m)</literal>.</simpara>\r
6238</listitem>\r
6239</itemizedlist>\r
6240<simpara><?asciidoc-pagebreak?></simpara>\r
6241</section>\r
6242</section>\r
6243<section id="CompilationManager">\r
6244<title>CompilationManager</title>\r
6245<simpara>The <ulink url="http://www.smlnj.org/doc/CM/index.html">Compilation Manager</ulink> (CM) is SML/NJ&#8217;s mechanism for supporting programming-in-the-very-large.</simpara>\r
6246<section id="_porting_sml_nj_cm_files_to_mlton">\r
6247<title>Porting SML/NJ CM files to MLton</title>\r
6248<simpara>To help in porting CM files to MLton, the MLton source distribution\r
6249includes the sources for a utility, <literal>cm2mlb</literal>, that will print an\r
6250<link linkend="MLBasis">ML Basis</link> file with essentially the same semantics as the\r
6251CM file&#8201;&#8212;&#8201;handling the full syntax of CM supported by your installed\r
6252SML/NJ version and correctly handling export filters. When <literal>cm2mlb</literal>\r
6253encounters a <literal>.cm</literal> import, it attempts to convert it to a\r
6254corresponding <literal>.mlb</literal> import. CM anchored paths are translated to\r
6255paths according to a default configuration file\r
6256(<ulink url="https://github.com/MLton/mlton/blob/master/util/cm2mlb/cm2mlb-map"><literal>cm2mlb-map</literal></ulink>). For example,\r
6257the default configuration includes</simpara>\r
6258<screen># Standard ML Basis Library\r
6259$SMLNJ-BASIS $(SML_LIB)/basis\r
6260$basis.cm $(SML_LIB)/basis\r
6261$basis.cm/basis.cm $(SML_LIB)/basis/basis.mlb</screen>\r
6262<simpara>to ensure that a <literal>$/basis.cm</literal> import is translated to a\r
6263<literal>$(SML_LIB)/basis/basis.mlb</literal> import. See <literal>util/cm2mlb</literal> for details.\r
6264Building <literal>cm2mlb</literal> requires that you have already installed a recent\r
6265version of SML/NJ.</simpara>\r
6266<simpara><?asciidoc-pagebreak?></simpara>\r
6267</section>\r
6268</section>\r
6269<section id="CompilerOverview">\r
6270<title>CompilerOverview</title>\r
6271<simpara>The following table shows the overall structure of the compiler.\r
6272<link linkend="IntermediateLanguage">IntermediateLanguage</link>s are shown in the center column. The names\r
6273of compiler passes are listed in the left and right columns.</simpara>\r
6274<informaltable\r
6275frame="all"\r
6276rowsep="1" colsep="1"\r
6277>\r
6278<tgroup cols="3">\r
6279<colspec colname="col_1" colwidth="33*"/>\r
6280<colspec colname="col_2" colwidth="33*"/>\r
6281<colspec colname="col_3" colwidth="33*"/>\r
6282<tbody>\r
6283<row>\r
6284<entry align="center" valign="top" namest="col_1" nameend="col_3"><simpara><emphasis role="strong">Compiler Overview</emphasis></simpara></entry>\r
6285</row>\r
6286<row>\r
6287<entry align="center" valign="top"><simpara><emphasis>Translation Passes</emphasis></simpara></entry>\r
6288<entry align="center" valign="top"><simpara><emphasis><link linkend="IntermediateLanguage">IntermediateLanguage</link></emphasis></simpara></entry>\r
6289<entry align="center" valign="top"><simpara><emphasis>Optimization Passes</emphasis></simpara></entry>\r
6290</row>\r
6291<row>\r
6292<entry align="center" valign="top"><simpara></simpara></entry>\r
6293<entry align="center" valign="top"><simpara>Source</simpara></entry>\r
6294<entry align="center" valign="top"><simpara></simpara></entry>\r
6295</row>\r
6296<row>\r
6297<entry align="center" valign="top"><simpara><link linkend="FrontEnd">FrontEnd</link></simpara></entry>\r
6298<entry align="center" valign="top"><simpara></simpara></entry>\r
6299<entry align="center" valign="top"><simpara></simpara></entry>\r
6300</row>\r
6301<row>\r
6302<entry align="center" valign="top"><simpara></simpara></entry>\r
6303<entry align="center" valign="top"><simpara><link linkend="AST">AST</link></simpara></entry>\r
6304<entry align="center" valign="top"><simpara></simpara></entry>\r
6305</row>\r
6306<row>\r
6307<entry align="center" valign="top"><simpara><link linkend="Elaborate">Elaborate</link></simpara></entry>\r
6308<entry align="center" valign="top"><simpara></simpara></entry>\r
6309<entry align="center" valign="top"><simpara></simpara></entry>\r
6310</row>\r
6311<row>\r
6312<entry align="center" valign="top"><simpara></simpara></entry>\r
6313<entry align="center" valign="top"><simpara><link linkend="CoreML">CoreML</link></simpara></entry>\r
6314<entry align="center" valign="top"><simpara><link linkend="CoreMLSimplify">CoreMLSimplify</link></simpara></entry>\r
6315</row>\r
6316<row>\r
6317<entry align="center" valign="top"><simpara><link linkend="Defunctorize">Defunctorize</link></simpara></entry>\r
6318<entry align="center" valign="top"><simpara></simpara></entry>\r
6319<entry align="center" valign="top"><simpara></simpara></entry>\r
6320</row>\r
6321<row>\r
6322<entry align="center" valign="top"><simpara></simpara></entry>\r
6323<entry align="center" valign="top"><simpara><link linkend="XML">XML</link></simpara></entry>\r
6324<entry align="center" valign="top"><simpara><link linkend="XMLSimplify">XMLSimplify</link></simpara></entry>\r
6325</row>\r
6326<row>\r
6327<entry align="center" valign="top"><simpara><link linkend="Monomorphise">Monomorphise</link></simpara></entry>\r
6328<entry align="center" valign="top"><simpara></simpara></entry>\r
6329<entry align="center" valign="top"><simpara></simpara></entry>\r
6330</row>\r
6331<row>\r
6332<entry align="center" valign="top"><simpara></simpara></entry>\r
6333<entry align="center" valign="top"><simpara><link linkend="SXML">SXML</link></simpara></entry>\r
6334<entry align="center" valign="top"><simpara><link linkend="SXMLSimplify">SXMLSimplify</link></simpara></entry>\r
6335</row>\r
6336<row>\r
6337<entry align="center" valign="top"><simpara><link linkend="ClosureConvert">ClosureConvert</link></simpara></entry>\r
6338<entry align="center" valign="top"><simpara></simpara></entry>\r
6339<entry align="center" valign="top"><simpara></simpara></entry>\r
6340</row>\r
6341<row>\r
6342<entry align="center" valign="top"><simpara></simpara></entry>\r
6343<entry align="center" valign="top"><simpara><link linkend="SSA">SSA</link></simpara></entry>\r
6344<entry align="center" valign="top"><simpara><link linkend="SSASimplify">SSASimplify</link></simpara></entry>\r
6345</row>\r
6346<row>\r
6347<entry align="center" valign="top"><simpara><link linkend="ToSSA2">ToSSA2</link></simpara></entry>\r
6348<entry align="center" valign="top"><simpara></simpara></entry>\r
6349<entry align="center" valign="top"><simpara></simpara></entry>\r
6350</row>\r
6351<row>\r
6352<entry align="center" valign="top"><simpara></simpara></entry>\r
6353<entry align="center" valign="top"><simpara><link linkend="SSA2">SSA2</link></simpara></entry>\r
6354<entry align="center" valign="top"><simpara><link linkend="SSA2Simplify">SSA2Simplify</link></simpara></entry>\r
6355</row>\r
6356<row>\r
6357<entry align="center" valign="top"><simpara><link linkend="ToRSSA">ToRSSA</link></simpara></entry>\r
6358<entry align="center" valign="top"><simpara></simpara></entry>\r
6359<entry align="center" valign="top"><simpara></simpara></entry>\r
6360</row>\r
6361<row>\r
6362<entry align="center" valign="top"><simpara></simpara></entry>\r
6363<entry align="center" valign="top"><simpara><link linkend="RSSA">RSSA</link></simpara></entry>\r
6364<entry align="center" valign="top"><simpara><link linkend="RSSASimplify">RSSASimplify</link></simpara></entry>\r
6365</row>\r
6366<row>\r
6367<entry align="center" valign="top"><simpara><link linkend="ToMachine">ToMachine</link></simpara></entry>\r
6368<entry align="center" valign="top"><simpara></simpara></entry>\r
6369<entry align="center" valign="top"><simpara></simpara></entry>\r
6370</row>\r
6371<row>\r
6372<entry align="center" valign="top"><simpara></simpara></entry>\r
6373<entry align="center" valign="top"><simpara><link linkend="Machine">Machine</link></simpara></entry>\r
6374<entry align="center" valign="top"><simpara></simpara></entry>\r
6375</row>\r
6376<row>\r
6377<entry align="center" valign="top"><simpara><link linkend="Codegen">Codegen</link></simpara></entry>\r
6378<entry align="center" valign="top"><simpara></simpara></entry>\r
6379<entry align="center" valign="top"><simpara></simpara></entry>\r
6380</row>\r
6381</tbody>\r
6382</tgroup>\r
6383</informaltable>\r
6384<simpara>The <literal>Compile</literal> functor (<ulink url="https://github.com/MLton/mlton/blob/master/mlton/main/compile.sig"><literal>compile.sig</literal></ulink>,\r
6385<ulink url="https://github.com/MLton/mlton/blob/master/mlton/main/compile.fun"><literal>compile.fun</literal></ulink>), controls the\r
6386high-level view of the compiler passes, from <link linkend="FrontEnd">FrontEnd</link> to code\r
6387generation.</simpara>\r
6388<simpara><?asciidoc-pagebreak?></simpara>\r
6389</section>\r
6390<section id="CompilerPassTemplate">\r
6391<title>CompilerPassTemplate</title>\r
6392<simpara>An analysis pass for the <link linkend="ZZZ">ZZZ</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="ZZZOtherPass">ZZZOtherPass</link>.\r
6393An implementation pass for the <link linkend="ZZZ">ZZZ</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="ZZZSimplify">ZZZSimplify</link>.\r
6394An optimization pass for the <link linkend="ZZZ">ZZZ</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="ZZZSimplify">ZZZSimplify</link>.\r
6395A rewrite pass for the <link linkend="ZZZ">ZZZ</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="ZZZOtherPass">ZZZOtherPass</link>.\r
6396A translation pass from the <link linkend="ZZA">ZZA</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link> to the <link linkend="ZZB">ZZB</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link>.</simpara>\r
6397<section id="_description_9">\r
6398<title>Description</title>\r
6399<simpara>A short description of the pass.</simpara>\r
6400</section>\r
6401<section id="_implementation_11">\r
6402<title>Implementation</title>\r
6403<itemizedlist>\r
6404<listitem>\r
6405<simpara>\r
6406<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ZZZ.fun"><literal>ZZZ.fun</literal></ulink>\r
6407</simpara>\r
6408</listitem>\r
6409</itemizedlist>\r
6410</section>\r
6411<section id="_details_and_notes_11">\r
6412<title>Details and Notes</title>\r
6413<simpara>Relevant details and notes.</simpara>\r
6414<simpara><?asciidoc-pagebreak?></simpara>\r
6415</section>\r
6416</section>\r
6417<section id="CompileTimeOptions">\r
6418<title>CompileTimeOptions</title>\r
6419<simpara>MLton&#8217;s compile-time options control the name of the output file, the\r
6420verbosity of compile-time messages, and whether or not certain\r
6421optimizations are performed. They also can specify which intermediate\r
6422files are saved and can stop the compilation process early, at some\r
6423intermediate pass, in which case compilation can be resumed by passing\r
6424the generated files to MLton. MLton uses the input file suffix to\r
6425determine the type of input program. The possibilities are <literal>.c</literal>,\r
6426<literal>.mlb</literal>, <literal>.o</literal>, <literal>.s</literal>, and <literal>.sml</literal>.</simpara>\r
6427<simpara>With no arguments, MLton prints the version number and exits. For a\r
6428usage message, run MLton with an invalid switch, e.g. <literal>mlton -z</literal>. In\r
6429the explanation below and in the usage message, for flags that take a\r
6430number of choices (e.g. <literal>{true|false}</literal>), the first value listed is the\r
6431default.</simpara>\r
6432<section id="_options">\r
6433<title>Options</title>\r
6434<itemizedlist>\r
6435<listitem>\r
6436<simpara>\r
6437<literal>-align <emphasis>n</emphasis></literal>\r
6438</simpara>\r
6439<simpara>Aligns object in memory by the specified alignment (<literal>4</literal> or <literal>8</literal>).\r
6440The default varies depending on architecture.</simpara>\r
6441</listitem>\r
6442<listitem>\r
6443<simpara>\r
6444<literal>-as-opt <emphasis>option</emphasis></literal>\r
6445</simpara>\r
6446<simpara>Pass <emphasis>option</emphasis> to <literal>gcc</literal> when compiling assembler code. If you wish to\r
6447pass an option to the assembler, you must use <literal>gcc</literal>'s <literal>-Wa,</literal> syntax.</simpara>\r
6448</listitem>\r
6449<listitem>\r
6450<simpara>\r
6451<literal>-cc-opt <emphasis>option</emphasis></literal>\r
6452</simpara>\r
6453<simpara>Pass <emphasis>option</emphasis> to <literal>gcc</literal> when compiling C code.</simpara>\r
6454</listitem>\r
6455<listitem>\r
6456<simpara>\r
6457<literal>-codegen {native|amd64|c|llvm|x86}</literal>\r
6458</simpara>\r
6459<simpara>Generate native object code via amd64 assembly, C code, LLVM code, or\r
6460x86 code or C code. With <literal>-codegen native</literal> (<literal>-codegen amd64</literal> or\r
6461<literal>-codegen x86</literal>), MLton typically compiles more quickly and generates\r
6462better code.</simpara>\r
6463</listitem>\r
6464<listitem>\r
6465<simpara>\r
6466<literal>-const <emphasis>name</emphasis> <emphasis>value</emphasis></literal>\r
6467</simpara>\r
6468<simpara>Set the value of a compile-time constant. Here is a list of\r
6469available constants, their default values, and what they control.</simpara>\r
6470<itemizedlist>\r
6471<listitem>\r
6472<simpara>\r
6473<literal>Exn.keepHistory {false|true}</literal>\r
6474</simpara>\r
6475<simpara>Enable <literal>MLton.Exn.history</literal>. See <link linkend="MLtonExn">MLtonExn</link> for details. There is a\r
6476performance cost to setting this to <literal>true</literal>, both in memory usage of\r
6477exceptions and in run time, because of additional work that must be\r
6478performed at each exception construction, raise, and handle.</simpara>\r
6479</listitem>\r
6480</itemizedlist>\r
6481</listitem>\r
6482<listitem>\r
6483<simpara>\r
6484<literal>-default-ann <emphasis>ann</emphasis></literal>\r
6485</simpara>\r
6486<simpara>Specify default <link linkend="MLBasisAnnotations">ML Basis annotations</link>. For\r
6487example, <literal>-default-ann 'warnUnused true'</literal> causes unused variable\r
6488warnings to be enabled by default. A default is overridden by the\r
6489corresponding annotation in an ML Basis file.</simpara>\r
6490</listitem>\r
6491<listitem>\r
6492<simpara>\r
6493<literal>-default-type <emphasis>type</emphasis></literal>\r
6494</simpara>\r
6495<simpara>Specify the default binding for a primitive type. For example,\r
6496<literal>-default-type word64</literal> causes the top-level type <literal>word</literal> and the\r
6497top-level structure <literal>Word</literal> in the <link linkend="BasisLibrary">Basis Library</link> to be\r
6498equal to <literal>Word64.word</literal> and <literal>Word64:WORD</literal>, respectively. Similarly,\r
6499<literal>-default-type intinf</literal> causes the top-level type <literal>int</literal> and the\r
6500top-level structure <literal>Int</literal> in the <link linkend="BasisLibrary">Basis Library</link> to be\r
6501equal to <literal>IntInf.int</literal> and <literal>IntInf:INTEGER</literal>, respectively.</simpara>\r
6502</listitem>\r
6503<listitem>\r
6504<simpara>\r
6505<literal>-disable-ann <emphasis>ann</emphasis></literal>\r
6506</simpara>\r
6507<simpara>Ignore the specified <link linkend="MLBasisAnnotations">ML Basis annotation</link> in\r
6508every ML Basis file. For example, to see <emphasis>all</emphasis> match and unused\r
6509warnings, compile with</simpara>\r
6510<screen>-default-ann 'warnUnused true'\r
6511-disable-ann forceUsed\r
6512-disable-ann nonexhaustiveMatch\r
6513-disable-ann redundantMatch\r
6514-disable-ann warnUnused</screen>\r
6515</listitem>\r
6516<listitem>\r
6517<simpara>\r
6518<literal>-export-header <emphasis>file</emphasis></literal>\r
6519</simpara>\r
6520<simpara>Write C prototypes to <emphasis>file</emphasis> for all of the functions in the program\r
6521<link linkend="CallingFromCToSML">exported from SML to C</link>.</simpara>\r
6522</listitem>\r
6523<listitem>\r
6524<simpara>\r
6525<literal>-ieee-fp {false|true}</literal>\r
6526</simpara>\r
6527<simpara>Cause the x86 native code generator to be pedantic about following the\r
6528IEEE floating point standard. By default, it is not, because of the\r
6529performance cost. This only has an effect with <literal>-codegen x86</literal>.</simpara>\r
6530</listitem>\r
6531<listitem>\r
6532<simpara>\r
6533<literal>-inline <emphasis>n</emphasis></literal>\r
6534</simpara>\r
6535<simpara>Set the inlining threshold used in the optimizer. The threshold is an\r
6536approximate measure of code size of a procedure. The default is\r
6537<literal>320</literal>.</simpara>\r
6538</listitem>\r
6539<listitem>\r
6540<simpara>\r
6541<literal>-keep {g|o}</literal>\r
6542</simpara>\r
6543<simpara>Save intermediate files. If no <literal>-keep</literal> argument is given, then only\r
6544the output file is saved.</simpara>\r
6545<informaltable\r
6546frame="all"\r
6547rowsep="1" colsep="1"\r
6548>\r
6549<tgroup cols="2">\r
6550<colspec colname="col_1" colwidth="25*"/>\r
6551<colspec colname="col_2" colwidth="75*"/>\r
6552<tbody>\r
6553<row>\r
6554<entry align="center" valign="top"><simpara><literal>g</literal></simpara></entry>\r
6555<entry align="left" valign="top"><simpara>generated <literal>.c</literal> and <literal>.s</literal> files passed to <literal>gcc</literal> and generated <literal>.ll</literal> files passed to <literal>llvm-as</literal></simpara></entry>\r
6556</row>\r
6557<row>\r
6558<entry align="center" valign="top"><simpara><literal>o</literal></simpara></entry>\r
6559<entry align="left" valign="top"><simpara>object (<literal>.o</literal>) files</simpara></entry>\r
6560</row>\r
6561</tbody>\r
6562</tgroup>\r
6563</informaltable>\r
6564</listitem>\r
6565<listitem>\r
6566<simpara>\r
6567<literal>-link-opt <emphasis>option</emphasis></literal>\r
6568</simpara>\r
6569<simpara>Pass <emphasis>option</emphasis> to <literal>gcc</literal> when linking. You can use this to specify\r
6570library search paths, e.g. <literal>-link-opt -Lpath</literal>, and libraries to link\r
6571with, e.g., <literal>-link-opt -lfoo</literal>, or even both at the same time,\r
6572e.g. <literal>-link-opt '-Lpath -lfoo'</literal>. If you wish to pass an option to the\r
6573linker, you must use <literal>gcc</literal>'s <literal>-Wl,</literal> syntax, e.g.,\r
6574<literal>-link-opt '-Wl,--export-dynamic'</literal>.</simpara>\r
6575</listitem>\r
6576<listitem>\r
6577<simpara>\r
6578<literal>-llvm-as-opt <emphasis>option</emphasis></literal>\r
6579</simpara>\r
6580<simpara>Pass <emphasis>option</emphasis> to <literal>llvm-as</literal> when assembling (<literal>.ll</literal> to <literal>.bc</literal>) LLVM code.</simpara>\r
6581</listitem>\r
6582<listitem>\r
6583<simpara>\r
6584<literal>-llvm-llc-opt <emphasis>option</emphasis></literal>\r
6585</simpara>\r
6586<simpara>Pass <emphasis>option</emphasis> to <literal>llc</literal> when compiling (<literal>.bc</literal> to <literal>.o</literal>) LLVM code.</simpara>\r
6587</listitem>\r
6588<listitem>\r
6589<simpara>\r
6590<literal>-llvm-opt-opt <emphasis>option</emphasis></literal>\r
6591</simpara>\r
6592<simpara>Pass <emphasis>option</emphasis> to <literal>opt</literal> when optimizing (<literal>.bc</literal> to <literal>.bc</literal>) LLVM code.</simpara>\r
6593</listitem>\r
6594<listitem>\r
6595<simpara>\r
6596<literal>-mlb-path-map <emphasis>file</emphasis></literal>\r
6597</simpara>\r
6598<simpara>Use <emphasis>file</emphasis> as an <link linkend="MLBasisPathMap">ML Basis path map</link> to define\r
6599additional MLB path variables. Multiple uses of <literal>-mlb-path-map</literal> and\r
6600<literal>-mlb-path-var</literal> are allowed, with variable definitions in later path\r
6601maps taking precedence over earlier ones.</simpara>\r
6602</listitem>\r
6603<listitem>\r
6604<simpara>\r
6605<literal>-mlb-path-var <emphasis>name</emphasis> <emphasis>value</emphasis></literal>\r
6606</simpara>\r
6607<simpara>Define an additional MLB path variable. Multiple uses of\r
6608<literal>-mlb-path-map</literal> and <literal>-mlb-path-var</literal> are allowed, with variable\r
6609definitions in later path maps taking precedence over earlier ones.</simpara>\r
6610</listitem>\r
6611<listitem>\r
6612<simpara>\r
6613<literal>-output <emphasis>file</emphasis></literal>\r
6614</simpara>\r
6615<simpara>Specify the name of the final output file. The default name is the\r
6616input file name with its suffix removed and an appropriate, possibly\r
6617empty, suffix added.</simpara>\r
6618</listitem>\r
6619<listitem>\r
6620<simpara>\r
6621<literal>-profile {no|alloc|count|time}</literal>\r
6622</simpara>\r
6623<simpara>Produce an executable that gathers <link linkend="Profiling">profiling</link> data. When\r
6624such an executable is run, it produces an <literal>mlmon.out</literal> file.</simpara>\r
6625</listitem>\r
6626<listitem>\r
6627<simpara>\r
6628<literal>-profile-branch {false|true}</literal>\r
6629</simpara>\r
6630<simpara>If true, the profiler will separately gather profiling data for each\r
6631branch of a function definition, <literal>case</literal> expression, and <literal>if</literal>\r
6632expression.</simpara>\r
6633</listitem>\r
6634<listitem>\r
6635<simpara>\r
6636<literal>-profile-stack {false|true}</literal>\r
6637</simpara>\r
6638<simpara>If <literal>true</literal>, the executable will gather profiling data for all functions\r
6639on the stack, not just the currently executing function. See\r
6640<link linkend="ProfilingTheStack">ProfilingTheStack</link>.</simpara>\r
6641</listitem>\r
6642<listitem>\r
6643<simpara>\r
6644<literal>-profile-val {false|true}</literal>\r
6645</simpara>\r
6646<simpara>If <literal>true</literal>, the profiler will separately gather profiling data for each\r
6647(expansive) <literal>val</literal> declaration.</simpara>\r
6648</listitem>\r
6649<listitem>\r
6650<simpara>\r
6651<literal>-runtime <emphasis>arg</emphasis></literal>\r
6652</simpara>\r
6653<simpara>Pass argument to the runtime system via <literal>@MLton</literal>. See\r
6654<link linkend="RunTimeOptions">RunTimeOptions</link>. The argument will be processed before other\r
6655<literal>@MLton</literal> command line switches. Multiple uses of <literal>-runtime</literal> are\r
6656allowed, and will pass all the arguments in order. If the same\r
6657runtime switch occurs more than once, then the last setting will take\r
6658effect. There is no need to supply the leading <literal>@MLton</literal> or the\r
6659trailing <literal>--</literal>; these will be supplied automatically.</simpara>\r
6660<simpara>An argument to <literal>-runtime</literal> may contain spaces, which will cause the\r
6661argument to be treated as a sequence of words by the runtime. For\r
6662example the command line:</simpara>\r
6663<screen>mlton -runtime 'ram-slop 0.4' foo.sml</screen>\r
6664<simpara>will cause <literal>foo</literal> to run as if it had been called like:</simpara>\r
6665<screen>foo @MLton ram-slop 0.4 --</screen>\r
6666<simpara>An executable created with <literal>-runtime stop</literal> doesn&#8217;t process any\r
6667<literal>@MLton</literal> arguments. This is useful to create an executable, e.g.,\r
6668<literal>echo</literal>, that must treat <literal>@MLton</literal> like any other command-line argument.</simpara>\r
6669<screen>% mlton -runtime stop echo.sml\r
6670% echo @MLton --\r
6671@MLton --</screen>\r
6672</listitem>\r
6673<listitem>\r
6674<simpara>\r
6675<literal>-show-basis <emphasis>file</emphasis></literal>\r
6676</simpara>\r
6677<simpara>Pretty print to <emphasis>file</emphasis> the basis defined by the input program. See\r
6678<link linkend="ShowBasis">ShowBasis</link>.</simpara>\r
6679</listitem>\r
6680<listitem>\r
6681<simpara>\r
6682<literal>-show-def-use <emphasis>file</emphasis></literal>\r
6683</simpara>\r
6684<simpara>Output def-use information to <emphasis>file</emphasis>. Each identifier that is defined\r
6685appears on a line, followed on subsequent lines by the position of\r
6686each use.</simpara>\r
6687</listitem>\r
6688<listitem>\r
6689<simpara>\r
6690<literal>-stop {f|g|o|tc}</literal>\r
6691</simpara>\r
6692<simpara>Specify when to stop.</simpara>\r
6693<informaltable\r
6694frame="all"\r
6695rowsep="1" colsep="1"\r
6696>\r
6697<tgroup cols="2">\r
6698<colspec colname="col_1" colwidth="25*"/>\r
6699<colspec colname="col_2" colwidth="75*"/>\r
6700<tbody>\r
6701<row>\r
6702<entry align="center" valign="top"><simpara><literal>f</literal></simpara></entry>\r
6703<entry align="left" valign="top"><simpara>list of files on stdout (only makes sense when input is <literal>foo.mlb</literal>)</simpara></entry>\r
6704</row>\r
6705<row>\r
6706<entry align="center" valign="top"><simpara><literal>g</literal></simpara></entry>\r
6707<entry align="left" valign="top"><simpara>generated <literal>.c</literal> and <literal>.s</literal> files</simpara></entry>\r
6708</row>\r
6709<row>\r
6710<entry align="center" valign="top"><simpara><literal>o</literal></simpara></entry>\r
6711<entry align="left" valign="top"><simpara>object (<literal>.o</literal>) files</simpara></entry>\r
6712</row>\r
6713<row>\r
6714<entry align="center" valign="top"><simpara><literal>tc</literal></simpara></entry>\r
6715<entry align="left" valign="top"><simpara>after type checking</simpara></entry>\r
6716</row>\r
6717</tbody>\r
6718</tgroup>\r
6719</informaltable>\r
6720<simpara>If you compile with <literal>-stop g</literal> or <literal>-stop o</literal>, you can resume compilation\r
6721by running MLton on the generated <literal>.c</literal> and <literal>.s</literal> or <literal>.o</literal> files.</simpara>\r
6722</listitem>\r
6723<listitem>\r
6724<simpara>\r
6725<literal>-target {self|<emphasis>&#8230;</emphasis>}</literal>\r
6726</simpara>\r
6727<simpara>Generate an executable that runs on the specified platform. The\r
6728default is <literal>self</literal>, which means to compile for the machine that MLton\r
6729is running on. To use any other target, you must first install a\r
6730<link linkend="CrossCompiling">cross compiler</link>.</simpara>\r
6731</listitem>\r
6732<listitem>\r
6733<simpara>\r
6734<literal>-target-as-opt <emphasis>target</emphasis> <emphasis>option</emphasis></literal>\r
6735</simpara>\r
6736<simpara>Like <literal>-as-opt</literal>, this passes <emphasis>option</emphasis> to <literal>gcc</literal> when compliling\r
6737assembler code, except it only passes <emphasis>option</emphasis> when the target\r
6738architecture, operating system, or arch-os pair is <emphasis>target</emphasis>.</simpara>\r
6739</listitem>\r
6740<listitem>\r
6741<simpara>\r
6742<literal>-target-cc-opt <emphasis>target</emphasis> <emphasis>option</emphasis></literal>\r
6743</simpara>\r
6744<simpara>Like <literal>-cc-opt</literal>, this passes <emphasis>option</emphasis> to <literal>gcc</literal> when compiling C code,\r
6745except it only passes <emphasis>option</emphasis> when the target architecture, operating\r
6746system, or arch-os pair is <emphasis>target</emphasis>.</simpara>\r
6747</listitem>\r
6748<listitem>\r
6749<simpara>\r
6750<literal>-target-link-opt <emphasis>target</emphasis> <emphasis>option</emphasis></literal>\r
6751</simpara>\r
6752<simpara>Like <literal>-link-opt</literal>, this passes <emphasis>option</emphasis> to <literal>gcc</literal> when linking, except\r
6753it only passes <emphasis>option</emphasis> when the target architecture, operating\r
6754system, or arch-os pair is <emphasis>target</emphasis>.</simpara>\r
6755</listitem>\r
6756<listitem>\r
6757<simpara>\r
6758<literal>-verbose {0|1|2|3}</literal>\r
6759</simpara>\r
6760<simpara>How verbose to be about what passes are running. The default is <literal>0</literal>.</simpara>\r
6761<informaltable\r
6762frame="all"\r
6763rowsep="1" colsep="1"\r
6764>\r
6765<tgroup cols="2">\r
6766<colspec colname="col_1" colwidth="25*"/>\r
6767<colspec colname="col_2" colwidth="75*"/>\r
6768<tbody>\r
6769<row>\r
6770<entry align="center" valign="top"><simpara><literal>0</literal></simpara></entry>\r
6771<entry align="left" valign="top"><simpara>silent</simpara></entry>\r
6772</row>\r
6773<row>\r
6774<entry align="center" valign="top"><simpara><literal>1</literal></simpara></entry>\r
6775<entry align="left" valign="top"><simpara>calls to compiler, assembler, and linker</simpara></entry>\r
6776</row>\r
6777<row>\r
6778<entry align="center" valign="top"><simpara><literal>2</literal></simpara></entry>\r
6779<entry align="left" valign="top"><simpara>1, plus intermediate compiler passes</simpara></entry>\r
6780</row>\r
6781<row>\r
6782<entry align="center" valign="top"><simpara><literal>3</literal></simpara></entry>\r
6783<entry align="left" valign="top"><simpara>2, plus some data structure sizes</simpara></entry>\r
6784</row>\r
6785</tbody>\r
6786</tgroup>\r
6787</informaltable>\r
6788</listitem>\r
6789</itemizedlist>\r
6790<simpara><?asciidoc-pagebreak?></simpara>\r
6791</section>\r
6792</section>\r
6793<section id="CompilingWithSMLNJ">\r
6794<title>CompilingWithSMLNJ</title>\r
6795<simpara>You can compile MLton with <link linkend="SMLNJ">SML/NJ</link>, however the resulting\r
6796compiler will run much more slowly than MLton compiled by itself. We\r
6797don&#8217;t recommend using SML/NJ as a means of\r
6798<link linkend="PortingMLton">porting MLton</link> to a new platform or bootstrapping on a\r
6799new platform.</simpara>\r
6800<simpara>If you do want to build MLton with SML/NJ, it is best to have a binary\r
6801MLton package installed. If you don&#8217;t, here are some issues you may\r
6802encounter when you run <literal>make smlnj-mlton</literal>.</simpara>\r
6803<simpara>You will get (many copies of) the error messages:</simpara>\r
6804<screen>/bin/sh: mlton: command not found</screen>\r
6805<simpara>and</simpara>\r
6806<screen>make[2]: mlton: Command not found</screen>\r
6807<simpara>The <literal>Makefile</literal> calls <literal>mlton</literal> to determine dependencies, and can\r
6808proceed in spite of this error.</simpara>\r
6809<simpara>If you don&#8217;t have an <literal>mllex</literal> executable, you will get the error\r
6810message:</simpara>\r
6811<screen>mllex: Command not found</screen>\r
6812<simpara>Building MLton requires <literal>mllex</literal> and <literal>mlyacc</literal> executables, which are\r
6813distributed with a binary package of MLton. The easiest solution is\r
6814to copy the front-end lexer/parser files from a different machine\r
6815(<literal>ml.grm.sml</literal>, <literal>ml.grm.sig</literal>, <literal>ml.lex.sml</literal>, <literal>mlb.grm.sig</literal>,\r
6816<literal>mlb.grm.sml</literal>).</simpara>\r
6817<simpara><?asciidoc-pagebreak?></simpara>\r
6818</section>\r
6819<section id="ConcurrentML">\r
6820<title>ConcurrentML</title>\r
6821<simpara><ulink url="http://cml.cs.uchicago.edu/">Concurrent ML</ulink> is an SML concurrency\r
6822library based on synchronous message passing. MLton has an initial\r
6823port of CML from SML/NJ, but is missing a thread-safe wrapper around\r
6824the Basis Library and event-based equivalents to <literal>IO</literal> and <literal>OS</literal>\r
6825functions.</simpara>\r
6826<simpara>All of the core CML functionality is present.</simpara>\r
6827<programlisting language="sml" linenumbering="unnumbered">structure CML: CML\r
6828structure SyncVar: SYNC_VAR\r
6829structure Mailbox: MAILBOX\r
6830structure Multicast: MULTICAST\r
6831structure SimpleRPC: SIMPLE_RPC\r
6832structure RunCML: RUN_CML</programlisting>\r
6833<simpara>The <literal>RUN_CML</literal> signature is minimal.</simpara>\r
6834<programlisting language="sml" linenumbering="unnumbered">signature RUN_CML =\r
6835 sig\r
6836 val isRunning: unit -&gt; bool\r
6837 val doit: (unit -&gt; unit) * Time.time option -&gt; OS.Process.status\r
6838 val shutdown: OS.Process.status -&gt; 'a\r
6839 end</programlisting>\r
6840<simpara>MLton&#8217;s <literal>RunCML</literal> structure does not include all of the cleanup and\r
6841logging operations of SML/NJ&#8217;s <literal>RunCML</literal> structure. However, the\r
6842implementation does include the <literal>CML.timeOutEvt</literal> and <literal>CML.atTimeEvt</literal>\r
6843functions, and a preemptive scheduler that knows to sleep when there\r
6844are no ready threads and some threads blocked on time events.</simpara>\r
6845<simpara>Because MLton does not wrap the Basis Library for CML, the "right" way\r
6846to call a Basis Library function that is stateful is to wrap the call\r
6847with <literal>MLton.Thread.atomically</literal>.</simpara>\r
6848<section id="_usage_2">\r
6849<title>Usage</title>\r
6850<itemizedlist>\r
6851<listitem>\r
6852<simpara>\r
6853You can import the CML Library into an MLB file with:\r
6854</simpara>\r
6855<informaltable\r
6856frame="all"\r
6857rowsep="1" colsep="1"\r
6858>\r
6859<tgroup cols="2">\r
6860<colspec colname="col_1" colwidth="50*"/>\r
6861<colspec colname="col_2" colwidth="50*"/>\r
6862<thead>\r
6863<row>\r
6864<entry align="left" valign="top">MLB file</entry>\r
6865<entry align="left" valign="top">Description</entry>\r
6866</row>\r
6867</thead>\r
6868<tbody>\r
6869<row>\r
6870<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/cml/cml.mlb</literal></simpara></entry>\r
6871<entry align="left" valign="top"><simpara></simpara></entry>\r
6872</row>\r
6873</tbody>\r
6874</tgroup>\r
6875</informaltable>\r
6876</listitem>\r
6877<listitem>\r
6878<simpara>\r
6879If you are porting a project from SML/NJ&#8217;s <link linkend="CompilationManager">CompilationManager</link> to\r
6880MLton&#8217;s <link linkend="MLBasis">ML Basis system</link> using <literal>cm2mlb</literal>, note that the\r
6881following map is included by default:\r
6882</simpara>\r
6883<screen># CML Library\r
6884$cml $(SML_LIB)/cml\r
6885$cml/cml.cm $(SML_LIB)/cml/cml.mlb</screen>\r
6886<simpara>This will automatically convert a <literal>$cml/cml.cm</literal> import in an input <literal>.cm</literal> file into a <literal>$(SML_LIB)/cml/cml.mlb</literal> import in the output <literal>.mlb</literal> file.</simpara>\r
6887</listitem>\r
6888</itemizedlist>\r
6889</section>\r
6890<section id="_also_see_2">\r
6891<title>Also see</title>\r
6892<itemizedlist>\r
6893<listitem>\r
6894<simpara>\r
6895<link linkend="ConcurrentMLImplementation">ConcurrentMLImplementation</link>\r
6896</simpara>\r
6897</listitem>\r
6898<listitem>\r
6899<simpara>\r
6900<link linkend="eXene">eXene</link>\r
6901</simpara>\r
6902</listitem>\r
6903</itemizedlist>\r
6904<simpara><?asciidoc-pagebreak?></simpara>\r
6905</section>\r
6906</section>\r
6907<section id="ConcurrentMLImplementation">\r
6908<title>ConcurrentMLImplementation</title>\r
6909<simpara>Here are some notes on MLton&#8217;s implementation of <link linkend="ConcurrentML">ConcurrentML</link>.</simpara>\r
6910<simpara>Concurrent ML was originally implemented for SML/NJ. It was ported to\r
6911MLton in the summer of 2004. The main difference between the\r
6912implementations is that SML/NJ uses continuations to implement CML\r
6913threads, while MLton uses its underlying <link linkend="MLtonThread">thread</link>\r
6914package. Presently, MLton&#8217;s threads are a little more heavyweight\r
6915than SML/NJ&#8217;s continuations, but it&#8217;s pretty clear that there is some\r
6916fat there that could be trimmed.</simpara>\r
6917<simpara>The implementation of CML in SML/NJ is built upon the first-class\r
6918continuations of the <literal>SMLofNJ.Cont</literal> module.</simpara>\r
6919<programlisting language="sml" linenumbering="unnumbered">type 'a cont\r
6920val callcc: ('a cont -&gt; 'a) -&gt; 'a\r
6921val isolate: ('a -&gt; unit) -&gt; 'a cont\r
6922val throw: 'a cont -&gt; 'a -&gt; 'b</programlisting>\r
6923<simpara>The implementation of CML in MLton is built upon the first-class\r
6924threads of the <link linkend="MLtonThread">MLtonThread</link> module.</simpara>\r
6925<programlisting language="sml" linenumbering="unnumbered">type 'a t\r
6926val new: ('a -&gt; unit) -&gt; 'a t\r
6927val prepare: 'a t * 'a -&gt; Runnable.t\r
6928val switch: ('a t -&gt; Runnable.t) -&gt; 'a</programlisting>\r
6929<simpara>The port is relatively straightforward, because CML always throws to a\r
6930continuation at most once. Hence, an "abstract" implementation of\r
6931CML could be built upon first-class one-shot continuations, which map\r
6932equally well to SML/NJ&#8217;s continuations and MLton&#8217;s threads.</simpara>\r
6933<simpara>The "essence" of the port is to transform:</simpara>\r
6934<screen>callcc (fn k =&gt; ... throw k' v')</screen>\r
6935<simpara>to</simpara>\r
6936<screen>switch (fn t =&gt; ... prepare (t', v'))</screen>\r
6937<simpara>which suffices for the vast majority of the CML implementation.</simpara>\r
6938<simpara>There was only one complicated transformation: blocking multiple base\r
6939events. In SML/NJ CML, the representation of base events is given by:</simpara>\r
6940<programlisting language="sml" linenumbering="unnumbered">datatype 'a event_status\r
6941 = ENABLED of {prio: int, doFn: unit -&gt; 'a}\r
6942 | BLOCKED of {\r
6943 transId: trans_id ref,\r
6944 cleanUp: unit -&gt; unit,\r
6945 next: unit -&gt; unit\r
6946 } -&gt; 'a\r
6947type 'a base_evt = unit -&gt; 'a event_status</programlisting>\r
6948<simpara>When synchronizing on a set of base events, which are all blocked, we\r
6949must invoke each <literal>BLOCKED</literal> function with the same <literal>transId</literal> and\r
6950<literal>cleanUp</literal> (the <literal>transId</literal> is (checked and) set to <literal>CANCEL</literal> by the\r
6951<literal>cleanUp</literal> function, which is invoked by the first enabled event; this\r
6952"fizzles" every other event in the synchronization group that later\r
6953becomes enabled). However, each <literal>BLOCKED</literal> function is implemented by\r
6954a callcc, so that when the event is enabled, it throws back to the\r
6955point of synchronization. Hence, the next function (which doesn&#8217;t\r
6956return) is invoked by the <literal>BLOCKED</literal> function to escape the callcc and\r
6957continue in the thread performing the synchronization. In SML/NJ this\r
6958is implemented as follows:</simpara>\r
6959<programlisting language="sml" linenumbering="unnumbered">fun ext ([], blockFns) = callcc (fn k =&gt; let\r
6960 val throw = throw k\r
6961 val (transId, setFlg) = mkFlg()\r
6962 fun log [] = S.atomicDispatch ()\r
6963 | log (blockFn:: r) =\r
6964 throw (blockFn {\r
6965 transId = transId,\r
6966 cleanUp = setFlg,\r
6967 next = fn () =&gt; log r\r
6968 })\r
6969 in\r
6970 log blockFns; error "[log]"\r
6971 end)</programlisting>\r
6972<simpara>(Note that <literal>S.atomicDispatch</literal> invokes the continuation of the next\r
6973continuation on the ready queue.) This doesn&#8217;t map well to the MLton\r
6974thread model. Although it follows the</simpara>\r
6975<screen>callcc (fn k =&gt; ... throw k v)</screen>\r
6976<simpara>model, the fact that <literal>blockFn</literal> will also attempt to do</simpara>\r
6977<screen>callcc (fn k' =&gt; ... next ())</screen>\r
6978<simpara>means that the naive transformation will result in nested <literal>switch</literal>-es.</simpara>\r
6979<simpara>We need to think a little more about what this code is trying to do.\r
6980Essentially, each <literal>blockFn</literal> wants to capture this continuation, hold\r
6981on to it until the event is enabled, and continue with next; when the\r
6982event is enabled, before invoking the continuation and returning to\r
6983the synchronization point, the <literal>cleanUp</literal> and other event specific\r
6984operations are performed.</simpara>\r
6985<simpara>To accomplish the same effect in the MLton thread implementation, we\r
6986have the following:</simpara>\r
6987<programlisting language="sml" linenumbering="unnumbered">datatype 'a status =\r
6988 ENABLED of {prio: int, doitFn: unit -&gt; 'a}\r
6989 | BLOCKED of {transId: trans_id,\r
6990 cleanUp: unit -&gt; unit,\r
6991 next: unit -&gt; rdy_thread} -&gt; 'a\r
6992\r
6993type 'a base = unit -&gt; 'a status\r
6994\r
6995fun ext ([], blockFns): 'a =\r
6996 S.atomicSwitch\r
6997 (fn (t: 'a S.thread) =&gt;\r
6998 let\r
6999 val (transId, cleanUp) = TransID.mkFlg ()\r
7000 fun log blockFns: S.rdy_thread =\r
7001 case blockFns of\r
7002 [] =&gt; S.next ()\r
7003 | blockFn::blockFns =&gt;\r
7004 (S.prep o S.new)\r
7005 (fn _ =&gt; fn () =&gt;\r
7006 let\r
7007 val () = S.atomicBegin ()\r
7008 val x = blockFn {transId = transId,\r
7009 cleanUp = cleanUp,\r
7010 next = fn () =&gt; log blockFns}\r
7011 in S.switch(fn _ =&gt; S.prepVal (t, x))\r
7012 end)\r
7013 in\r
7014 log blockFns\r
7015 end)</programlisting>\r
7016<simpara>To avoid the nested <literal>switch</literal>-es, I run the <literal>blockFn</literal> in it&#8217;s own\r
7017thread, whose only purpose is to return to the synchronization point.\r
7018This corresponds to the <literal>throw (blockFn {...})</literal> in the SML/NJ\r
7019implementation. I&#8217;m worried that this implementation might be a\r
7020little expensive, starting a new thread for each blocked event (when\r
7021there are only multiple blocked events in a synchronization group).\r
7022But, I don&#8217;t see another way of implementing this behavior in the\r
7023MLton thread model.</simpara>\r
7024<simpara>Note that another way of thinking about what is going on is to\r
7025consider each <literal>blockFn</literal> as prepending a different set of actions to\r
7026the thread <literal>t</literal>. It might be possible to give a\r
7027<literal>MLton.Thread.unsafePrepend</literal>.</simpara>\r
7028<programlisting language="sml" linenumbering="unnumbered">fun unsafePrepend (T r: 'a t, f: 'b -&gt; 'a): 'b t =\r
7029 let\r
7030 val t =\r
7031 case !r of\r
7032 Dead =&gt; raise Fail "prepend to a Dead thread"\r
7033 | New g =&gt; New (g o f)\r
7034 | Paused (g, t) =&gt; Paused (fn h =&gt; g (f o h), t)\r
7035 in (* r := Dead; *)\r
7036 T (ref t)\r
7037 end</programlisting>\r
7038<simpara>I have commented out the <literal>r := Dead</literal>, which would allow multiple\r
7039prepends to the same thread (i.e., not destroying the original thread\r
7040in the process). Of course, only one of the threads could be run: if\r
7041the original thread were in the <literal>Paused</literal> state, then multiple threads\r
7042would share the underlying runtime/primitive thread. Now, this\r
7043matches the "one-shot" nature of CML continuations/threads, but I&#8217;m\r
7044not comfortable with extending <literal>MLton.Thread</literal> with such an unsafe\r
7045operation.</simpara>\r
7046<simpara>Other than this complication with blocking multiple base events, the\r
7047port was quite routine. (As a very pleasant surprise, the CML\r
7048implementation in SML/NJ doesn&#8217;t use any SML/NJ-isms.) There is a\r
7049slight difference in the way in which critical sections are handled in\r
7050SML/NJ and MLton; since <literal>MLton.Thread.switch</literal> <emphasis>always</emphasis> leaves a\r
7051critical section, it is sometimes necessary to add additional\r
7052<literal>atomicBegin</literal>-s/<literal>atomicEnd</literal>-s to ensure that we remain in a critical\r
7053section after a thread switch.</simpara>\r
7054<simpara>While looking at virtually every file in the core CML implementation,\r
7055I took the liberty of simplifying things where it seemed possible; in\r
7056terms of style, the implementation is about half-way between Reppy&#8217;s\r
7057original and MLton&#8217;s.</simpara>\r
7058<simpara>Some changes of note:</simpara>\r
7059<itemizedlist>\r
7060<listitem>\r
7061<simpara>\r
7062<literal>util/</literal> contains all pertinent data-structures: (functional and\r
7063imperative) queues, (functional) priority queues. Hence, it should be\r
7064easier to switch in more efficient or real-time implementations.\r
7065</simpara>\r
7066</listitem>\r
7067<listitem>\r
7068<simpara>\r
7069<literal>core-cml/scheduler.sml</literal>: in both implementations, this is where\r
7070most of the interesting action takes place. I&#8217;ve made the connection\r
7071between <literal>MLton.Thread.t</literal>-s and <literal>ThreadId.thread_id</literal>-s more abstract\r
7072than it is in the SML/NJ implementation, and encapsulated all of the\r
7073<literal>MLton.Thread</literal> operations in this module.\r
7074</simpara>\r
7075</listitem>\r
7076<listitem>\r
7077<simpara>\r
7078eliminated all of the "by hand" inlining\r
7079</simpara>\r
7080</listitem>\r
7081</itemizedlist>\r
7082<section id="_future_extensions">\r
7083<title>Future Extensions</title>\r
7084<simpara>The CML documentation says the following:</simpara>\r
7085<blockquote>\r
7086<screen>CML.joinEvt: thread_id -&gt; unit event</screen>\r
7087<itemizedlist>\r
7088<listitem>\r
7089<simpara>\r
7090<literal>joinEvt tid</literal>\r
7091</simpara>\r
7092<simpara>creates an event value for synchronizing on the termination of the\r
7093thread with the ID tid. There are three ways that a thread may\r
7094terminate: the function that was passed to spawn (or spawnc) may\r
7095return; it may call the exit function, or it may have an uncaught\r
7096exception. Note that <literal>joinEvt</literal> does not distinguish between these\r
7097cases; it also does not become enabled if the named thread deadlocks\r
7098(even if it is garbage collected).</simpara>\r
7099</listitem>\r
7100</itemizedlist>\r
7101</blockquote>\r
7102<simpara>I believe that the <literal>MLton.Finalizable</literal> might be able to relax that\r
7103last restriction. Upon the creation of a <literal>'a Scheduler.thread</literal>, we\r
7104could attach a finalizer to the underlying <literal>'a MLton.Thread.t</literal> that\r
7105enables the <literal>joinEvt</literal> (in the associated <literal>ThreadID.thread_id</literal>) when\r
7106the <literal>'a MLton.Thread.t</literal> becomes unreachable.</simpara>\r
7107<simpara>I don&#8217;t know why CML doesn&#8217;t have</simpara>\r
7108<screen>CML.kill: thread_id -&gt; unit</screen>\r
7109<simpara>which has a fairly simple implementation&#8201;&#8212;&#8201;setting a kill flag in the\r
7110<literal>thread_id</literal> and adjusting the scheduler to discard any killed threads\r
7111that it takes off the ready queue. The fairness of the scheduler\r
7112ensures that a killed thread will eventually be discarded. The\r
7113semantics are little murky for blocked threads that are killed,\r
7114though. For example, consider a thread blocked on <literal>SyncVar.mTake mv</literal>\r
7115and a thread blocked on <literal>SyncVar.mGet mv</literal>. If the first thread is\r
7116killed while blocked, and a third thread does <literal>SyncVar.mPut (mv, x)</literal>,\r
7117then we might expect that we&#8217;ll enable the second thread, and never\r
7118the first. But, when only the ready queue is able to discard killed\r
7119threads, then the <literal>SyncVar.mPut</literal> could enable the first thread\r
7120(putting it on the ready queue, from which it will be discarded) and\r
7121leave the second thread blocked. We could solve this by adjusting the\r
7122<literal>TransID.trans_id types</literal> and the "cleaner" functions to look for both\r
7123canceled transactions and transactions on killed threads.</simpara>\r
7124<simpara>John Reppy says that <link linkend="References_MarlowEtAl01">MarlowEtAl01</link> and <link linkend="References_FlattFindler04">FlattFindler04</link>\r
7125explain why <literal>CML.kill</literal> would be a bad idea.</simpara>\r
7126<simpara>Between <literal>CML.timeOutEvt</literal> and <literal>CML.kill</literal>, one could give an efficient\r
7127solution to the recent <literal>comp.lang.ml</literal> post about terminating a\r
7128function that doesn&#8217;t complete in a given time.</simpara>\r
7129<programlisting language="sml" linenumbering="unnumbered"> fun timeOut (f: unit -&gt; 'a, t: Time.time): 'a option =\r
7130 let\r
7131 val iv = SyncVar.iVar ()\r
7132 val tid = CML.spawn (fn () =&gt; SyncVar.iPut (iv, f ()))\r
7133 in\r
7134 CML.select\r
7135 [CML.wrap (CML.timeOutEvt t, fn () =&gt; (CML.kill tid; NONE)),\r
7136 CML.wrap (SyncVar.iGetEvt iv, fn x =&gt; SOME x)]\r
7137 end</programlisting>\r
7138</section>\r
7139<section id="_space_safety">\r
7140<title>Space Safety</title>\r
7141<simpara>There are some CML related posts on the MLton mailing list:</simpara>\r
7142<itemizedlist>\r
7143<listitem>\r
7144<simpara>\r
7145<ulink url="http://www.mlton.org/pipermail/mlton/2004-May/">http://www.mlton.org/pipermail/mlton/2004-May/</ulink>\r
7146</simpara>\r
7147</listitem>\r
7148</itemizedlist>\r
7149<simpara>that discuss concerns that SML/NJ&#8217;s implementation is not space\r
7150efficient, because multi-shot continuations can be held indefinitely\r
7151on event queues. MLton is better off because of the one-shot nature&#8201;&#8212;&#8201;when an event enables a thread, all other copies of the thread\r
7152waiting in other event queues get turned into dead threads (of zero\r
7153size).</simpara>\r
7154<simpara><?asciidoc-pagebreak?></simpara>\r
7155</section>\r
7156</section>\r
7157<section id="ConstantPropagation">\r
7158<title>ConstantPropagation</title>\r
7159<simpara><link linkend="ConstantPropagation">ConstantPropagation</link> is an optimization pass for the <link linkend="SSA">SSA</link>\r
7160<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="SSASimplify">SSASimplify</link>.</simpara>\r
7161<section id="_description_10">\r
7162<title>Description</title>\r
7163<simpara>This is whole-program constant propagation, even through data\r
7164structures. It also performs globalization of (small) values computed\r
7165once.</simpara>\r
7166<simpara>Uses <link linkend="Multi">Multi</link>.</simpara>\r
7167</section>\r
7168<section id="_implementation_12">\r
7169<title>Implementation</title>\r
7170<itemizedlist>\r
7171<listitem>\r
7172<simpara>\r
7173<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/constant-propagation.fun"><literal>constant-propagation.fun</literal></ulink>\r
7174</simpara>\r
7175</listitem>\r
7176</itemizedlist>\r
7177</section>\r
7178<section id="_details_and_notes_12">\r
7179<title>Details and Notes</title>\r
7180<simpara></simpara>\r
7181<simpara><?asciidoc-pagebreak?></simpara>\r
7182</section>\r
7183</section>\r
7184<section id="Contact">\r
7185<title>Contact</title>\r
7186<section id="_mailing_lists">\r
7187<title>Mailing lists</title>\r
7188<simpara>There are three mailing lists available.</simpara>\r
7189<itemizedlist>\r
7190<listitem>\r
7191<simpara>\r
7192<ulink url="mailto:MLton-user@mlton.org"><literal>MLton-user@mlton.org</literal></ulink>\r
7193</simpara>\r
7194<simpara>MLton user community discussion</simpara>\r
7195<itemizedlist>\r
7196<listitem>\r
7197<simpara>\r
7198<ulink url="https://lists.sourceforge.net/lists/listinfo/mlton-user">subscribe</ulink>\r
7199<ulink url="https://sourceforge.net/mailarchive/forum.php?forum_name=mlton-user">archive (SourceForge; current)</ulink>,\r
7200<ulink url="http://www.mlton.org/pipermail/mlton-user/">archive (PiperMail; through 201110)</ulink>\r
7201</simpara>\r
7202</listitem>\r
7203</itemizedlist>\r
7204</listitem>\r
7205<listitem>\r
7206<simpara>\r
7207<ulink url="mailto:MLton-devel@mlton.org"><literal>MLton-devel@mlton.org</literal></ulink>\r
7208</simpara>\r
7209<simpara>MLton developer community discussion</simpara>\r
7210<itemizedlist>\r
7211<listitem>\r
7212<simpara>\r
7213<ulink url="https://lists.sourceforge.net/lists/listinfo/mlton-devel">subscribe</ulink>\r
7214<ulink url="https://sourceforge.net/mailarchive/forum.php?forum_name=mlton-devel">archive (SourceForge; current)</ulink>,\r
7215<ulink url="http://www.mlton.org/pipermail/mlton-devel/">archive (PiperMail; through 201110)</ulink>\r
7216</simpara>\r
7217</listitem>\r
7218</itemizedlist>\r
7219</listitem>\r
7220<listitem>\r
7221<simpara>\r
7222<ulink url="mailto:MLton-commit@mlton.org"><literal>MLton-commit@mlton.org</literal></ulink>\r
7223</simpara>\r
7224<simpara>MLton code commits</simpara>\r
7225<itemizedlist>\r
7226<listitem>\r
7227<simpara>\r
7228<ulink url="https://lists.sourceforge.net/lists/listinfo/mlton-commit">subscribe</ulink>\r
7229</simpara>\r
7230</listitem>\r
7231<listitem>\r
7232<simpara>\r
7233<ulink url="https://sourceforge.net/mailarchive/forum.php?forum_name=mlton-commit">archive (SourceForge; current)</ulink>,\r
7234<ulink url="http://www.mlton.org/pipermail/mlton-commit/">archive (PiperMail; through 201110)</ulink>\r
7235</simpara>\r
7236</listitem>\r
7237</itemizedlist>\r
7238</listitem>\r
7239</itemizedlist>\r
7240<section id="_mailing_list_policies">\r
7241<title>Mailing list policies</title>\r
7242<itemizedlist>\r
7243<listitem>\r
7244<simpara>\r
7245Both mailing lists are unmoderated. However, the mailing lists are\r
7246configured to discard all spam, to hold all non-subscriber posts\r
7247for moderation, to accept all subscriber posts, and to admin approve\r
7248subscription requests. Please contact\r
7249<ulink url="mailto:matthew.fluet@gmail.com">Matthew Fluet</ulink> if it appears that your\r
7250messages are being discarded as spam.\r
7251</simpara>\r
7252</listitem>\r
7253<listitem>\r
7254<simpara>\r
7255Large messages (over 256K) should not be sent. Rather, please send\r
7256an email containing the discussion text and a link to any large files.\r
7257</simpara>\r
7258</listitem>\r
7259</itemizedlist>\r
7260<itemizedlist>\r
7261<listitem>\r
7262<simpara>\r
7263Discussions started on the mailing lists should stay on the mailing\r
7264lists. Private replies may be bounced to the mailing list for the\r
7265benefit of those following the discussion.\r
7266</simpara>\r
7267</listitem>\r
7268<listitem>\r
7269<simpara>\r
7270Discussions started on\r
7271<ulink url="mailto:MLton-user@mlton.org"><literal>MLton-user@mlton.org</literal></ulink> may be migrated to\r
7272<ulink url="mailto:MLton-devel@mlton.org"><literal>MLton-devel@mlton.org</literal></ulink>, particularly\r
7273when the discussion shifts from how to use MLton to how to modify\r
7274MLton (e.g., to fix a bug identified by the initial discussion).\r
7275</simpara>\r
7276</listitem>\r
7277</itemizedlist>\r
7278</section>\r
7279</section>\r
7280<section id="_irc">\r
7281<title>IRC</title>\r
7282<itemizedlist>\r
7283<listitem>\r
7284<simpara>\r
7285Some MLton developers and users are in channel <literal>#sml</literal> on <ulink url="http://freenode.net">http://freenode.net</ulink>.\r
7286</simpara>\r
7287</listitem>\r
7288</itemizedlist>\r
7289<simpara><?asciidoc-pagebreak?></simpara>\r
7290</section>\r
7291</section>\r
7292<section id="Contify">\r
7293<title>Contify</title>\r
7294<simpara><link linkend="Contify">Contify</link> is an optimization pass for the <link linkend="SSA">SSA</link>\r
7295<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="SSASimplify">SSASimplify</link>.</simpara>\r
7296<section id="_description_11">\r
7297<title>Description</title>\r
7298<simpara>Contification is a compiler optimization that turns a function that\r
7299always returns to the same place into a continuation. This exposes\r
7300control-flow information that is required by many optimizations,\r
7301including traditional loop optimizations.</simpara>\r
7302</section>\r
7303<section id="_implementation_13">\r
7304<title>Implementation</title>\r
7305<itemizedlist>\r
7306<listitem>\r
7307<simpara>\r
7308<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/contify.fun"><literal>contify.fun</literal></ulink>\r
7309</simpara>\r
7310</listitem>\r
7311</itemizedlist>\r
7312</section>\r
7313<section id="_details_and_notes_13">\r
7314<title>Details and Notes</title>\r
7315<simpara>See <link linkend="References_FluetWeeks01">Contification Using Dominators</link>. The\r
7316intermediate language described in that paper has since evolved to the\r
7317<link linkend="SSA">SSA</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link>; hence, the complication described in\r
7318Section 6.1 is no longer relevant.</simpara>\r
7319<simpara><?asciidoc-pagebreak?></simpara>\r
7320</section>\r
7321</section>\r
7322<section id="CoreML">\r
7323<title>CoreML</title>\r
7324<simpara><link linkend="CoreML">Core ML</link> is an <link linkend="IntermediateLanguage">IntermediateLanguage</link>, translated from\r
7325<link linkend="AST">AST</link> by <link linkend="Elaborate">Elaborate</link>, optimized by <link linkend="CoreMLSimplify">CoreMLSimplify</link>, and\r
7326translated by <link linkend="Defunctorize">Defunctorize</link> to <link linkend="XML">XML</link>.</simpara>\r
7327<section id="_description_12">\r
7328<title>Description</title>\r
7329<simpara><link linkend="CoreML">CoreML</link> is polymorphic, higher-order, and has nested patterns.</simpara>\r
7330</section>\r
7331<section id="_implementation_14">\r
7332<title>Implementation</title>\r
7333<itemizedlist>\r
7334<listitem>\r
7335<simpara>\r
7336<ulink url="https://github.com/MLton/mlton/blob/master/mlton/core-ml/core-ml.sig"><literal>core-ml.sig</literal></ulink>\r
7337</simpara>\r
7338</listitem>\r
7339<listitem>\r
7340<simpara>\r
7341<ulink url="https://github.com/MLton/mlton/blob/master/mlton/core-ml/core-ml.fun"><literal>core-ml.fun</literal></ulink>\r
7342</simpara>\r
7343</listitem>\r
7344</itemizedlist>\r
7345</section>\r
7346<section id="_type_checking_2">\r
7347<title>Type Checking</title>\r
7348<simpara>The <link linkend="CoreML">CoreML</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link> has no independent type\r
7349checker.</simpara>\r
7350</section>\r
7351<section id="_details_and_notes_14">\r
7352<title>Details and Notes</title>\r
7353<simpara></simpara>\r
7354<simpara><?asciidoc-pagebreak?></simpara>\r
7355</section>\r
7356</section>\r
7357<section id="CoreMLSimplify">\r
7358<title>CoreMLSimplify</title>\r
7359<simpara>The single optimization pass for the <link linkend="CoreML">CoreML</link>\r
7360<link linkend="IntermediateLanguage">IntermediateLanguage</link> is controlled by the <literal>Compile</literal> functor\r
7361(<ulink url="https://github.com/MLton/mlton/blob/master/mlton/main/compile.fun"><literal>compile.fun</literal></ulink>).</simpara>\r
7362<simpara>The following optimization pass is implemented:</simpara>\r
7363<itemizedlist>\r
7364<listitem>\r
7365<simpara>\r
7366<link linkend="DeadCode">DeadCode</link>\r
7367</simpara>\r
7368</listitem>\r
7369</itemizedlist>\r
7370<simpara><?asciidoc-pagebreak?></simpara>\r
7371</section>\r
7372<section id="Credits">\r
7373<title>Credits</title>\r
7374<simpara>MLton was designed and implemented by HenryCejtin,\r
7375MatthewFluet, SureshJagannathan, and <link linkend="StephenWeeks">StephenWeeks</link>.</simpara>\r
7376<itemizedlist>\r
7377<listitem>\r
7378<simpara>\r
7379<link linkend="HenryCejtin">HenryCejtin</link> wrote the <literal>IntInf</literal> implementation, the original\r
7380 profiler, the original man pages, the <literal>.spec</literal> files for the RPMs,\r
7381 and lots of little hacks to speed stuff up.\r
7382</simpara>\r
7383</listitem>\r
7384<listitem>\r
7385<simpara>\r
7386<link linkend="MatthewFluet">MatthewFluet</link> implemented the X86 and AMD64 native code generators,\r
7387 ported <literal>mlprof</literal> to work with the native code generator, did a lot\r
7388 of work on the SSA optimizer, both adding new optimizations and\r
7389 improving or porting existing optimizations, updated the\r
7390 <link linkend="BasisLibrary">Basis Library</link> implementation, ported\r
7391 <link linkend="ConcurrentML">ConcurrentML</link> and <link linkend="MLNLFFI">ML-NLFFI</link> to MLton, implemented the\r
7392 <link linkend="MLBasis">ML Basis system</link>, ported MLton to 64-bit platforms,\r
7393 and currently leads the project.\r
7394</simpara>\r
7395</listitem>\r
7396<listitem>\r
7397<simpara>\r
7398<link linkend="SureshJagannathan">SureshJagannathan</link> implemented some early inlining and uncurrying\r
7399 optimizations.\r
7400</simpara>\r
7401</listitem>\r
7402<listitem>\r
7403<simpara>\r
7404<link linkend="StephenWeeks">StephenWeeks</link> implemented most of the original version of MLton, and\r
7405 continues to keep his fingers in most every part.\r
7406</simpara>\r
7407</listitem>\r
7408</itemizedlist>\r
7409<simpara>Many people have helped us over the years. Here is an alphabetical\r
7410list.</simpara>\r
7411<itemizedlist>\r
7412<listitem>\r
7413<simpara>\r
7414<link linkend="JesperLouisAndersen">JesperLouisAndersen</link> sent several patches to improve the runtime on\r
7415 FreeBSD and ported MLton to run on NetBSD and OpenBSD.\r
7416</simpara>\r
7417</listitem>\r
7418<listitem>\r
7419<simpara>\r
7420<link linkend="JohnnyAndersen">JohnnyAndersen</link> implemented <literal>BinIO</literal>, modified MLton so it could\r
7421 cross compile to MinGW, and provided useful discussion about\r
7422 cross-compilation.\r
7423</simpara>\r
7424</listitem>\r
7425<listitem>\r
7426<simpara>\r
7427Alexander Abushkevich extended support for OpenBSD.\r
7428</simpara>\r
7429</listitem>\r
7430<listitem>\r
7431<simpara>\r
7432Ross Bayer added the <literal>-keep ast</literal> compile-time option and experimented with\r
7433 porting the build system to CMake.\r
7434</simpara>\r
7435</listitem>\r
7436<listitem>\r
7437<simpara>\r
7438Kevin Bradley added initial support for <link linkend="SuccessorML">SuccessorML</link> features.\r
7439</simpara>\r
7440</listitem>\r
7441<listitem>\r
7442<simpara>\r
7443Bryan Camp added <literal>-disable-pass _regex_</literal> and <literal>enable-pass _regex_</literal> compile\r
7444 options to generalize <literal>-drop-pass _regex_</literal> and added <literal>Array_copyArray</literal> and\r
7445 <literal>Array_copyVector</literal> primitives.\r
7446</simpara>\r
7447</listitem>\r
7448<listitem>\r
7449<simpara>\r
7450Jason Carr added a parser combinator library and a parser for the <link linkend="SXML">SXML</link>\r
7451 IR, extended compilation to start with a <literal>.sxml</literal> file, and experimented with\r
7452 alternate control-flow analyses for <link linkend="ClosureConvert">closure conversion</link>.\r
7453</simpara>\r
7454</listitem>\r
7455<listitem>\r
7456<simpara>\r
7457Christopher Cramer contributed support for additional\r
7458 <literal>Posix.ProcEnv.sysconf</literal> variables, performance improvements for\r
7459 <literal>String.concatWith</literal>, and Debian packaging.\r
7460</simpara>\r
7461</listitem>\r
7462<listitem>\r
7463<simpara>\r
7464Alain Deutsch and\r
7465 <ulink url="http://www.polyspace.com/">PolySpace Technologies</ulink> provided many bug\r
7466 fixes and runtime system improvements, code to help the Sparc/Solaris\r
7467 port, and funded a number of improvements to MLton.\r
7468</simpara>\r
7469</listitem>\r
7470<listitem>\r
7471<simpara>\r
7472Armando Doval updated <literal>mlnlffigen</literal> to warn and skip functions with\r
7473 <literal>struct</literal>/<literal>union</literal> arguments.\r
7474</simpara>\r
7475</listitem>\r
7476<listitem>\r
7477<simpara>\r
7478Martin Elsman provided helpful discussions in the development of\r
7479 the <link linkend="MLBasis">ML Basis system</link>.\r
7480</simpara>\r
7481</listitem>\r
7482<listitem>\r
7483<simpara>\r
7484Brent Fulgham ported MLton most of the way to MinGW.\r
7485</simpara>\r
7486</listitem>\r
7487<listitem>\r
7488<simpara>\r
7489<link linkend="AdamGoode">AdamGoode</link> provided a script to build the PDF MLton Guide and\r
7490 maintains the\r
7491 <ulink url="https://admin.fedoraproject.org/pkgdb/acls/name/mlton">Fedora</ulink>\r
7492 packages.\r
7493</simpara>\r
7494</listitem>\r
7495<listitem>\r
7496<simpara>\r
7497Simon Helsen provided bug reports, suggestions, and helpful\r
7498 discussions.\r
7499</simpara>\r
7500</listitem>\r
7501<listitem>\r
7502<simpara>\r
7503Joe Hurd provided useful discussion and feedback on source-level\r
7504 profiling.\r
7505</simpara>\r
7506</listitem>\r
7507<listitem>\r
7508<simpara>\r
7509<link linkend="VesaKarvonen">VesaKarvonen</link> contributed <literal>esml-mode.el</literal> and <literal>esml-mlb-mode.el</literal> (see <link linkend="Emacs">Emacs</link>),\r
7510 contributed patches for improving match warnings,\r
7511 contributed <literal>esml-du-mlton.el</literal> and extended def-use output to include types of variable definitions (see <link linkend="EmacsDefUseMode">EmacsDefUseMode</link>), and\r
7512 improved constant folding of floating-point operations.\r
7513</simpara>\r
7514</listitem>\r
7515<listitem>\r
7516<simpara>\r
7517Richard Kelsey provided helpful discussions.\r
7518</simpara>\r
7519</listitem>\r
7520<listitem>\r
7521<simpara>\r
7522Ville Laurikari ported MLton to IA64/HPUX, HPPA/HPUX, PowerPC/AIX, PowerPC64/AIX.\r
7523</simpara>\r
7524</listitem>\r
7525<listitem>\r
7526<simpara>\r
7527Brian Leibig implemented the <link linkend="LLVMCodegen">LLVMCodegen</link>.\r
7528</simpara>\r
7529</listitem>\r
7530<listitem>\r
7531<simpara>\r
7532Geoffrey Mainland helped with FreeBSD packaging.\r
7533</simpara>\r
7534</listitem>\r
7535<listitem>\r
7536<simpara>\r
7537Eric McCorkle ported MLton to Intel Mac.\r
7538</simpara>\r
7539</listitem>\r
7540<listitem>\r
7541<simpara>\r
7542<link linkend="TomMurphy">TomMurphy</link> wrote the original version of <literal>MLton.Syslog</literal> as part\r
7543 of his <literal>mlftpd</literal> project, and has sent many useful bug reports and\r
7544 suggestions.\r
7545</simpara>\r
7546</listitem>\r
7547<listitem>\r
7548<simpara>\r
7549Michael Neumann helped to patch the runtime to compile under\r
7550 FreeBSD.\r
7551</simpara>\r
7552</listitem>\r
7553<listitem>\r
7554<simpara>\r
7555Barak Pearlmutter built the original\r
7556 <ulink url="http://packages.debian.org/mlton">Debian package</ulink> for MLton, and\r
7557 helped us to take over the process.\r
7558</simpara>\r
7559</listitem>\r
7560<listitem>\r
7561<simpara>\r
7562Filip Pizlo ported MLton to (PowerPC) Darwin.\r
7563</simpara>\r
7564</listitem>\r
7565<listitem>\r
7566<simpara>\r
7567Vedant Raiththa extended the <link linkend="ForeignFunctionInterface">ForeignFunctionInterface</link> with support for\r
7568 <literal>pure</literal> and <literal>impure</literal> attributes to <literal>_import</literal>.\r
7569</simpara>\r
7570</listitem>\r
7571<listitem>\r
7572<simpara>\r
7573Krishna Ravikumar added initial support for vector expressions and the\r
7574 <literal>Vector_vector</literal> primitive.\r
7575</simpara>\r
7576</listitem>\r
7577<listitem>\r
7578<simpara>\r
7579John Reppy assisted in porting MLton to Intel Mac.\r
7580</simpara>\r
7581</listitem>\r
7582<listitem>\r
7583<simpara>\r
7584Sam Rushing ported MLton to FreeBSD.\r
7585</simpara>\r
7586</listitem>\r
7587<listitem>\r
7588<simpara>\r
7589Rob Simmons refactored the array and vector implementation in the\r
7590 <link linkend="BasisLibrary">Basis Library:</link> into a primitive implementation (using\r
7591 <literal>SeqInt.int</literal> for indexing) and a wrapper implementation (using the default\r
7592 <literal>Int.int</literal> for indexing).\r
7593</simpara>\r
7594</listitem>\r
7595<listitem>\r
7596<simpara>\r
7597Jeffrey Mark Siskind provided helpful discussions and inspiration\r
7598 with his Stalin Scheme compiler.\r
7599</simpara>\r
7600</listitem>\r
7601<listitem>\r
7602<simpara>\r
7603Matthew Surawski added <link linkend="LoopUnroll">LoopUnroll</link> and <link linkend="LoopUnswitch">LoopUnswitch</link> SSA optimizations.\r
7604</simpara>\r
7605</listitem>\r
7606<listitem>\r
7607<simpara>\r
7608<link linkend="WesleyTerpstra">WesleyTerpstra</link> added support for <literal>MLton.Process.create</literal>, made\r
7609 a number of contributions to the <link linkend="ForeignFunctionInterface">ForeignFunctionInterface</link>,\r
7610 contributed a number of runtime system patches,\r
7611 added support for compiling to a <link linkend="LibrarySupport">C library</link>,\r
7612 ported MLton to <ulink url="http://mingw.org">MinGW</ulink> and all <ulink url="http://packages.debian.org/search?keywords=mlton&amp;searchon=names&amp;suite=all&amp;section=all">Debian</ulink> supported architectures with <link linkend="CrossCompiling">cross-compiling</link> support,\r
7613 and maintains the <ulink url="http://packages.debian.org/search?keywords=mlton&amp;searchon=names&amp;suite=all&amp;section=all">Debian</ulink> and <ulink url="http://mingw.org">MinGW</ulink> packages.\r
7614</simpara>\r
7615</listitem>\r
7616<listitem>\r
7617<simpara>\r
7618Maksim Yegorov added rudimentary support for <literal>./configure</literal> and other\r
7619 improvements to the build system and implemented the <link linkend="ShareZeroVec">ShareZeroVec</link> SSA\r
7620 optimization.\r
7621</simpara>\r
7622</listitem>\r
7623<listitem>\r
7624<simpara>\r
7625Luke Ziarek assisted in porting MLton to (PowerPC) Darwin.\r
7626</simpara>\r
7627</listitem>\r
7628</itemizedlist>\r
7629<simpara>We have also benefited from other software development tools and\r
7630used code from other sources.</simpara>\r
7631<itemizedlist>\r
7632<listitem>\r
7633<simpara>\r
7634MLton was developed using\r
7635 <link linkend="SMLNJ">Standard ML of New Jersey</link> and the\r
7636 <link linkend="CompilationManager">Compilation Manager (CM)</link>\r
7637</simpara>\r
7638</listitem>\r
7639<listitem>\r
7640<simpara>\r
7641MLton&#8217;s lexer (<literal>mlton/frontend/ml.lex</literal>), parser\r
7642 (<literal>mlton/frontend/ml.grm</literal>), and precedence-parser\r
7643 (<literal>mlton/elaborate/precedence-parse.fun</literal>) are modified versions of\r
7644 code from SML/NJ.\r
7645</simpara>\r
7646</listitem>\r
7647<listitem>\r
7648<simpara>\r
7649The MLton <link linkend="BasisLibrary">Basis Library</link> implementation of\r
7650 conversions between binary and decimal representations of reals uses\r
7651 David Gay&#8217;s <ulink url="http://www.netlib.org/fp/">gdtoa</ulink> library.\r
7652</simpara>\r
7653</listitem>\r
7654<listitem>\r
7655<simpara>\r
7656The MLton <link linkend="BasisLibrary">Basis Library</link> implementation uses\r
7657 modified versions of portions of the the SML/NJ Basis Library\r
7658 implementation modules <literal>OS.IO</literal>, <literal>Posix.IO</literal>, <literal>Process</literal>,\r
7659 and <literal>Unix</literal>.\r
7660</simpara>\r
7661</listitem>\r
7662<listitem>\r
7663<simpara>\r
7664The MLton <link linkend="BasisLibrary">Basis Library</link> implementation uses\r
7665 modified versions of portions of the <link linkend="MLKit">ML Kit</link> Version 4.1.4\r
7666 Basis Library implementation modules <literal>Path</literal>, <literal>Time</literal>, and\r
7667 <literal>Date</literal>.\r
7668</simpara>\r
7669</listitem>\r
7670<listitem>\r
7671<simpara>\r
7672Many of the benchmarks come from the SML/NJ benchmark suite.\r
7673</simpara>\r
7674</listitem>\r
7675<listitem>\r
7676<simpara>\r
7677Many of the regression tests come from the ML Kit Version 4.1.4\r
7678 distribution, which borrowed them from the\r
7679 <ulink url="http://www.dina.kvl.dk/%7Esestoft/mosml.html">Moscow ML</ulink> distribution.\r
7680</simpara>\r
7681</listitem>\r
7682<listitem>\r
7683<simpara>\r
7684MLton uses the <ulink url="http://www.gnu.org/software/gmp/gmp.html">GNU multiprecision library</ulink> for its implementation of <literal>IntInf</literal>.\r
7685</simpara>\r
7686</listitem>\r
7687<listitem>\r
7688<simpara>\r
7689MLton&#8217;s implementation of <link linkend="MLLex">mllex</link>, <link linkend="MLYacc">mlyacc</link>,\r
7690 the <link linkend="CKitLibrary">ckit Library</link>,\r
7691 the <link linkend="MLLPTLibrary">ML-LPT Library</link>,\r
7692 the <link linkend="MLRISCLibrary">MLRISC Library</link>,\r
7693 the <link linkend="SMLNJLibrary">SML/NJ Library</link>,\r
7694 <link linkend="ConcurrentML">Concurrent ML</link>,\r
7695 mlnlffigen and <link linkend="MLNLFFI">ML-NLFFI</link>\r
7696 are modified versions of code from SML/NJ.\r
7697</simpara>\r
7698</listitem>\r
7699</itemizedlist>\r
7700<simpara><?asciidoc-pagebreak?></simpara>\r
7701</section>\r
7702<section id="CrossCompiling">\r
7703<title>CrossCompiling</title>\r
7704<simpara>MLton&#8217;s <literal>-target</literal> flag directs MLton to cross compile an application\r
7705for another platform. By default, MLton is only able to compile for\r
7706the machine it is running on. In order to use MLton as a cross\r
7707compiler, you need to do two things.</simpara>\r
7708<orderedlist numeration="arabic">\r
7709<listitem>\r
7710<simpara>\r
7711Install the GCC cross-compiler tools on the host so that GCC can\r
7712compile to the target.\r
7713</simpara>\r
7714</listitem>\r
7715<listitem>\r
7716<simpara>\r
7717Cross compile the MLton runtime system to build the runtime\r
7718libraries for the target.\r
7719</simpara>\r
7720</listitem>\r
7721</orderedlist>\r
7722<simpara>To make the terminology clear, we refer to the <emphasis>host</emphasis> as the machine\r
7723MLton is running on and the <emphasis>target</emphasis> as the machine that MLton is\r
7724compiling for.</simpara>\r
7725<simpara>To build a GCC cross-compiler toolset on the host, you can use the\r
7726script <literal>bin/build-cross-gcc</literal>, available in the MLton sources, as a\r
7727template. The value of the <literal>target</literal> variable in that script is\r
7728important, since that is what you will pass to MLton&#8217;s <literal>-target</literal> flag.\r
7729Once you have the toolset built, you should be able to test it by\r
7730cross compiling a simple hello world program on your host machine.</simpara>\r
7731<screen>% gcc -b i386-pc-cygwin -o hello-world hello-world.c</screen>\r
7732<simpara>You should now be able to run <literal>hello-world</literal> on the target machine, in\r
7733this case, a Cygwin machine.</simpara>\r
7734<simpara>Next, you must cross compile the MLton runtime system and inform MLton\r
7735of the availability of the new target. The script <literal>bin/add-cross</literal>\r
7736from the MLton sources will help you do this. Please read the\r
7737comments at the top of the script. Here is a sample run adding a\r
7738Solaris cross compiler.</simpara>\r
7739<screen>% add-cross sparc-sun-solaris sun blade\r
7740Making runtime.\r
7741Building print-constants executable.\r
7742Running print-constants on blade.</screen>\r
7743<simpara>Running <literal>add-cross</literal> uses <literal>ssh</literal> to compile the runtime on the target\r
7744machine and to create <literal>print-constants</literal>, which prints out all of the\r
7745constants that MLton needs in order to implement the\r
7746<link linkend="BasisLibrary">Basis Library</link>. The script runs <literal>print-constants</literal> on\r
7747the target machine (<literal>blade</literal> in this case), and saves the output.</simpara>\r
7748<simpara>Once you have done all this, you should be able to cross compile SML\r
7749applications. For example,</simpara>\r
7750<screen>mlton -target i386-pc-cygwin hello-world.sml</screen>\r
7751<simpara>will create <literal>hello-world</literal>, which you should be able to run from a\r
7752Cygwin shell on your Windows machine.</simpara>\r
7753<section id="_cross_compiling_alternatives">\r
7754<title>Cross-compiling alternatives</title>\r
7755<simpara>Building and maintaining cross-compiling <literal>gcc</literal>'s is complex. You may\r
7756find it simpler to use <literal>mlton -keep g</literal> to generate the files on the\r
7757host, then copy the files to the target, and then use <literal>gcc</literal> or <literal>mlton</literal>\r
7758on the target to compile the files.</simpara>\r
7759<simpara><?asciidoc-pagebreak?></simpara>\r
7760</section>\r
7761</section>\r
7762<section id="CVS">\r
7763<title>CVS</title>\r
7764<simpara><ulink url="http://www.gnu.org/software/cvs/">CVS</ulink> (Concurrent Versions System) is\r
7765a version control system. The MLton project used CVS to maintain its\r
7766<link linkend="Sources">source code</link>, but switched to <link linkend="Subversion">Subversion</link> on 20050730.</simpara>\r
7767<simpara>Here are some online CVS resources.</simpara>\r
7768<itemizedlist>\r
7769<listitem>\r
7770<simpara>\r
7771<ulink url="http://cvsbook.red-bean.com/">Open Source Development with CVS</ulink>\r
7772</simpara>\r
7773</listitem>\r
7774</itemizedlist>\r
7775<simpara><?asciidoc-pagebreak?></simpara>\r
7776</section>\r
7777<section id="DeadCode">\r
7778<title>DeadCode</title>\r
7779<simpara><link linkend="DeadCode">DeadCode</link> is an optimization pass for the <link linkend="CoreML">CoreML</link>\r
7780<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="CoreMLSimplify">CoreMLSimplify</link>.</simpara>\r
7781<section id="_description_13">\r
7782<title>Description</title>\r
7783<simpara>This pass eliminates declarations from the\r
7784<link linkend="BasisLibrary">Basis Library</link> not needed by the user program.</simpara>\r
7785</section>\r
7786<section id="_implementation_15">\r
7787<title>Implementation</title>\r
7788<itemizedlist>\r
7789<listitem>\r
7790<simpara>\r
7791<ulink url="https://github.com/MLton/mlton/blob/master/mlton/core-ml/dead-code.sig"><literal>dead-code.sig</literal></ulink>\r
7792</simpara>\r
7793</listitem>\r
7794<listitem>\r
7795<simpara>\r
7796<ulink url="https://github.com/MLton/mlton/blob/master/mlton/core-ml/dead-code.fun"><literal>dead-code.fun</literal></ulink>\r
7797</simpara>\r
7798</listitem>\r
7799</itemizedlist>\r
7800</section>\r
7801<section id="_details_and_notes_15">\r
7802<title>Details and Notes</title>\r
7803<simpara>In order to compile small programs rapidly, a pass of dead code\r
7804elimination is run in order to eliminate as much of the Basis Library\r
7805as possible. The dead code elimination algorithm used is not safe in\r
7806general, and only works because the Basis Library implementation has\r
7807special properties:</simpara>\r
7808<itemizedlist>\r
7809<listitem>\r
7810<simpara>\r
7811it terminates\r
7812</simpara>\r
7813</listitem>\r
7814<listitem>\r
7815<simpara>\r
7816it performs no I/O\r
7817</simpara>\r
7818</listitem>\r
7819</itemizedlist>\r
7820<simpara>The dead code elimination includes the minimal set of\r
7821declarations from the Basis Library so that there are no free\r
7822variables in the user program (or remaining Basis Library\r
7823implementation). It has a special hack to include all\r
7824bindings of the form:</simpara>\r
7825<programlisting language="sml" linenumbering="unnumbered"> val _ = ...</programlisting>\r
7826<simpara>There is an <link linkend="MLBasisAnnotations">ML Basis annotation</link>,\r
7827<literal>deadCode true</literal>, that governs which code is subject to this unsafe\r
7828dead-code elimination.</simpara>\r
7829<simpara><?asciidoc-pagebreak?></simpara>\r
7830</section>\r
7831</section>\r
7832<section id="DeepFlatten">\r
7833<title>DeepFlatten</title>\r
7834<simpara><link linkend="DeepFlatten">DeepFlatten</link> is an optimization pass for the <link linkend="SSA2">SSA2</link>\r
7835<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="SSA2Simplify">SSA2Simplify</link>.</simpara>\r
7836<section id="_description_14">\r
7837<title>Description</title>\r
7838<simpara>This pass flattens into mutable fields of objects and into vectors.</simpara>\r
7839<simpara>For example, an <literal>(int * int) ref</literal> is represented by a 2 word\r
7840object, and an <literal>(int * int) array</literal> contains pairs of <literal>int</literal>-s,\r
7841rather than pointers to pairs of <literal>int</literal>-s.</simpara>\r
7842</section>\r
7843<section id="_implementation_16">\r
7844<title>Implementation</title>\r
7845<itemizedlist>\r
7846<listitem>\r
7847<simpara>\r
7848<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/deep-flatten.fun"><literal>deep-flatten.fun</literal></ulink>\r
7849</simpara>\r
7850</listitem>\r
7851</itemizedlist>\r
7852</section>\r
7853<section id="_details_and_notes_16">\r
7854<title>Details and Notes</title>\r
7855<simpara>There are some performance issues with the deep flatten pass, where it\r
7856consumes an excessive amount of memory.</simpara>\r
7857<itemizedlist>\r
7858<listitem>\r
7859<simpara>\r
7860<ulink url="http://www.mlton.org/pipermail/mlton/2005-April/026990.html">http://www.mlton.org/pipermail/mlton/2005-April/026990.html</ulink>\r
7861</simpara>\r
7862</listitem>\r
7863<listitem>\r
7864<simpara>\r
7865<ulink url="http://www.mlton.org/pipermail/mlton-user/2010-June/001626.html">http://www.mlton.org/pipermail/mlton-user/2010-June/001626.html</ulink>\r
7866</simpara>\r
7867</listitem>\r
7868<listitem>\r
7869<simpara>\r
7870<ulink url="http://www.mlton.org/pipermail/mlton/2010-December/030876.html">http://www.mlton.org/pipermail/mlton/2010-December/030876.html</ulink>\r
7871</simpara>\r
7872</listitem>\r
7873</itemizedlist>\r
7874<simpara>A number of applications require compilation with\r
7875<literal>-disable-pass deepFlatten</literal> to avoid exceeding available memory. It is\r
7876often asked whether the deep flatten pass usually has a significant\r
7877impact on performance. The standard benchmark suite was run with and\r
7878without the deep flatten pass enabled when the pass was first\r
7879introduced:</simpara>\r
7880<itemizedlist>\r
7881<listitem>\r
7882<simpara>\r
7883<ulink url="http://www.mlton.org/pipermail/mlton/2004-August/025760.html">http://www.mlton.org/pipermail/mlton/2004-August/025760.html</ulink>\r
7884</simpara>\r
7885</listitem>\r
7886</itemizedlist>\r
7887<simpara>The conclusion is that it does not have a significant impact.\r
7888However, these are micro benchmarks; other applications may derive\r
7889greater benefit from the pass.</simpara>\r
7890<simpara><?asciidoc-pagebreak?></simpara>\r
7891</section>\r
7892</section>\r
7893<section id="DefineTypeBeforeUse">\r
7894<title>DefineTypeBeforeUse</title>\r
7895<simpara><link linkend="StandardML">Standard ML</link> requires types to be defined before they are\r
7896used. Because of type inference, the use of a type can be implicit;\r
7897hence, this requirement is more subtle than it might appear. For\r
7898example, the following program is not type correct, because the type\r
7899of <literal>r</literal> is <literal>t option ref</literal>, but <literal>t</literal> is defined after <literal>r</literal>.</simpara>\r
7900<programlisting language="sml" linenumbering="unnumbered">val r = ref NONE\r
7901datatype t = A | B\r
7902val () = r := SOME A</programlisting>\r
7903<simpara>MLton reports the following error, indicating that the type defined on\r
7904line 2 is used on line 1.</simpara>\r
7905<screen>Error: z.sml 3.10-3.20.\r
7906 Function applied to incorrect argument.\r
7907 expects: _ * [???] option\r
7908 but got: _ * [t] option\r
7909 in: := (r, SOME A)\r
7910 note: type would escape its scope: t\r
7911 escape from: z.sml 2.10-2.10\r
7912 escape to: z.sml 1.1-1.16\r
7913Warning: z.sml 1.5-1.5.\r
7914 Type of variable was not inferred and could not be generalized: r.\r
7915 type: ??? option ref\r
7916 in: val r = ref NONE</screen>\r
7917<simpara>While the above example is benign, the following example shows how to\r
7918cast an integer to a function by (implicitly) using a type before it\r
7919is defined. In the example, the ref cell <literal>r</literal> is of type\r
7920<literal>t option ref</literal>, where <literal>t</literal> is defined <emphasis>after</emphasis> <literal>r</literal>, as a parameter to\r
7921functor <literal>F</literal>.</simpara>\r
7922<programlisting language="sml" linenumbering="unnumbered">val r = ref NONE\r
7923functor F (type t\r
7924 val x: t) =\r
7925 struct\r
7926 val () = r := SOME x\r
7927 fun get () = valOf (!r)\r
7928 end\r
7929structure S1 = F (type t = unit -&gt; unit\r
7930 val x = fn () =&gt; ())\r
7931structure S2 = F (type t = int\r
7932 val x = 13)\r
7933val () = S1.get () ()</programlisting>\r
7934<simpara>MLton reports the following error.</simpara>\r
7935<screen>Warning: z.sml 1.5-1.5.\r
7936 Type of variable was not inferred and could not be generalized: r.\r
7937 type: ??? option ref\r
7938 in: val r = ref NONE\r
7939Error: z.sml 5.16-5.26.\r
7940 Function applied to incorrect argument.\r
7941 expects: _ * [???] option\r
7942 but got: _ * [t] option\r
7943 in: := (r, SOME x)\r
7944 note: type would escape its scope: t\r
7945 escape from: z.sml 2.17-2.17\r
7946 escape to: z.sml 1.1-1.16\r
7947Warning: z.sml 6.11-6.13.\r
7948 Type of variable was not inferred and could not be generalized: get.\r
7949 type: unit -&gt; ???\r
7950 in: fun get () = (valOf (! r))\r
7951Error: z.sml 12.10-12.18.\r
7952 Function not of arrow type.\r
7953 function: [unit]\r
7954 in: (S1.get ()) ()</screen>\r
7955<simpara><?asciidoc-pagebreak?></simpara>\r
7956</section>\r
7957<section id="DefinitionOfStandardML">\r
7958<title>DefinitionOfStandardML</title>\r
7959<simpara><link linkend="References_MilnerEtAl97">The Definition of Standard ML (Revised)</link> is a\r
7960terse and formal specification of <link linkend="StandardML">Standard ML</link>'s syntax\r
7961and semantics. The language specified by this book is often referred\r
7962to as SML 97. You can check its syntax\r
7963<ulink url="http://www.mpi-sws.org/~rossberg/sml.html">grammar</ulink> online (thanks to\r
7964Andreas Rossberg).</simpara>\r
7965<simpara><link linkend="References_MilnerEtAl90">The Definition of Standard ML</link> is an older\r
7966version of the definition, published in 1990. The accompanying\r
7967<link linkend="References_MilnerTofte91">Commentary</link> introduces and explains the notation\r
7968and approach. The same notation is used in the SML 97 definition, so it\r
7969is worth keeping the older definition and its commentary at hand if you\r
7970intend a close study of the definition.</simpara>\r
7971<simpara><?asciidoc-pagebreak?></simpara>\r
7972</section>\r
7973<section id="Defunctorize">\r
7974<title>Defunctorize</title>\r
7975<simpara><link linkend="Defunctorize">Defunctorize</link> is a translation pass from the <link linkend="CoreML">CoreML</link>\r
7976<link linkend="IntermediateLanguage">IntermediateLanguage</link> to the <link linkend="XML">XML</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link>.</simpara>\r
7977<section id="_description_15">\r
7978<title>Description</title>\r
7979<simpara>This pass converts a <link linkend="CoreML">CoreML</link> program to an <link linkend="XML">XML</link> program by\r
7980performing:</simpara>\r
7981<itemizedlist>\r
7982<listitem>\r
7983<simpara>\r
7984linearization\r
7985</simpara>\r
7986</listitem>\r
7987<listitem>\r
7988<simpara>\r
7989<link linkend="MatchCompile">MatchCompile</link>\r
7990</simpara>\r
7991</listitem>\r
7992<listitem>\r
7993<simpara>\r
7994polymorphic <literal>val</literal> dec expansion\r
7995</simpara>\r
7996</listitem>\r
7997<listitem>\r
7998<simpara>\r
7999<literal>datatype</literal> lifting (to the top-level)\r
8000</simpara>\r
8001</listitem>\r
8002</itemizedlist>\r
8003</section>\r
8004<section id="_implementation_17">\r
8005<title>Implementation</title>\r
8006<itemizedlist>\r
8007<listitem>\r
8008<simpara>\r
8009<ulink url="https://github.com/MLton/mlton/blob/master/mlton/defunctorize/defunctorize.sig"><literal>defunctorize.sig</literal></ulink>\r
8010</simpara>\r
8011</listitem>\r
8012<listitem>\r
8013<simpara>\r
8014<ulink url="https://github.com/MLton/mlton/blob/master/mlton/defunctorize/defunctorize.fun"><literal>defunctorize.fun</literal></ulink>\r
8015</simpara>\r
8016</listitem>\r
8017</itemizedlist>\r
8018</section>\r
8019<section id="_details_and_notes_17">\r
8020<title>Details and Notes</title>\r
8021<simpara>This pass is grossly misnamed and does not perform defunctorization.</simpara>\r
8022<section id="_datatype_lifting">\r
8023<title>Datatype Lifting</title>\r
8024<simpara>This pass moves all <literal>datatype</literal> declarations to the top level.</simpara>\r
8025<simpara><link linkend="StandardML">Standard ML</link> <literal>datatype</literal> declarations can contain type\r
8026variables that are not bound in the declaration itself. For example,\r
8027the following program is valid.</simpara>\r
8028<programlisting language="sml" linenumbering="unnumbered">fun 'a f (x: 'a) =\r
8029 let\r
8030 datatype 'b t = T of 'a * 'b\r
8031 val y: int t = T (x, 1)\r
8032 in\r
8033 13\r
8034 end</programlisting>\r
8035<simpara>Unfortunately, the <literal>datatype</literal> declaration can not be immediately moved\r
8036to the top level, because that would leave <literal>'a</literal> free.</simpara>\r
8037<programlisting language="sml" linenumbering="unnumbered">datatype 'b t = T of 'a * 'b\r
8038fun 'a f (x: 'a) =\r
8039 let\r
8040 val y: int t = T (x, 1)\r
8041 in\r
8042 13\r
8043 end</programlisting>\r
8044<simpara>In order to safely move `datatype`s, this pass must close them, as\r
8045well as add any free type variables as extra arguments to the type\r
8046constructor. For example, the above program would be translated to\r
8047the following.</simpara>\r
8048<programlisting language="sml" linenumbering="unnumbered">datatype ('a, 'b) t = T of 'a * 'b\r
8049fun 'a f (x: 'a) =\r
8050 let\r
8051 val y: ('a * int) t = T (x, 1)\r
8052 in\r
8053 13\r
8054 end</programlisting>\r
8055</section>\r
8056</section>\r
8057<section id="_historical_notes">\r
8058<title>Historical Notes</title>\r
8059<simpara>The <link linkend="Defunctorize">Defunctorize</link> pass originally eliminated\r
8060<link linkend="StandardML">Standard ML</link> functors by duplicating their body at each\r
8061application. These duties have been adopted by the <link linkend="Elaborate">Elaborate</link>\r
8062pass.</simpara>\r
8063<simpara><?asciidoc-pagebreak?></simpara>\r
8064</section>\r
8065</section>\r
8066<section id="Developers">\r
8067<title>Developers</title>\r
8068<simpara>Here is a picture of the MLton team at a meeting in Chicago in August\r
80692003. From left to right we have:</simpara>\r
8070<informaltable\r
8071frame="none"\r
8072rowsep="1" colsep="1"\r
8073>\r
8074<tgroup cols="1">\r
8075<colspec colname="col_1" colwidth="100*"/>\r
8076<tbody>\r
8077<row>\r
8078<entry align="center" valign="top"><simpara><link linkend="StephenWeeks">StephenWeeks</link>&#8201;&#8212;&#8201;<link linkend="MatthewFluet">MatthewFluet</link>&#8201;&#8212;&#8201;<link linkend="HenryCejtin">HenryCejtin</link>&#8201;&#8212;&#8201;<link linkend="SureshJagannathan">SureshJagannathan</link></simpara></entry>\r
8079</row>\r
8080</tbody>\r
8081</tgroup>\r
8082</informaltable>\r
8083<informalfigure>\r
8084<mediaobject>\r
8085 <imageobject>\r
8086 <imagedata fileref="Developers.attachments/team.jpg" align="center"/>\r
8087 </imageobject>\r
8088 <textobject><phrase>Developers.attachments/team.jpg</phrase></textobject>\r
8089</mediaobject>\r
8090</informalfigure>\r
8091<simpara>Also see the <link linkend="Credits">Credits</link> for a list of specific contributions.</simpara>\r
8092<section id="_developers_list">\r
8093<title>Developers list</title>\r
8094<simpara>A number of people read the developers mailing list,\r
8095<ulink url="mailto:MLton-devel@mlton.org"><literal>MLton-devel@mlton.org</literal></ulink>, and make\r
8096contributions there. Here&#8217;s a list of those who have a page here.</simpara>\r
8097<itemizedlist>\r
8098<listitem>\r
8099<simpara>\r
8100<link linkend="AndreiFormiga">AndreiFormiga</link>\r
8101</simpara>\r
8102</listitem>\r
8103<listitem>\r
8104<simpara>\r
8105<link linkend="JesperLouisAndersen">JesperLouisAndersen</link>\r
8106</simpara>\r
8107</listitem>\r
8108<listitem>\r
8109<simpara>\r
8110<link linkend="JohnnyAndersen">JohnnyAndersen</link>\r
8111</simpara>\r
8112</listitem>\r
8113<listitem>\r
8114<simpara>\r
8115<link linkend="MichaelNorrish">MichaelNorrish</link>\r
8116</simpara>\r
8117</listitem>\r
8118<listitem>\r
8119<simpara>\r
8120<link linkend="MikeThomas">MikeThomas</link>\r
8121</simpara>\r
8122</listitem>\r
8123<listitem>\r
8124<simpara>\r
8125<link linkend="RayRacine">RayRacine</link>\r
8126</simpara>\r
8127</listitem>\r
8128<listitem>\r
8129<simpara>\r
8130<link linkend="WesleyTerpstra">WesleyTerpstra</link>\r
8131</simpara>\r
8132</listitem>\r
8133<listitem>\r
8134<simpara>\r
8135<link linkend="VesaKarvonen">VesaKarvonen</link>\r
8136</simpara>\r
8137</listitem>\r
8138</itemizedlist>\r
8139<simpara><?asciidoc-pagebreak?></simpara>\r
8140</section>\r
8141</section>\r
8142<section id="Development">\r
8143<title>Development</title>\r
8144<simpara>This page is the central point for MLton development.</simpara>\r
8145<itemizedlist>\r
8146<listitem>\r
8147<simpara>\r
8148Access the <link linkend="Sources">Sources</link>.\r
8149</simpara>\r
8150</listitem>\r
8151<listitem>\r
8152<simpara>\r
8153Check the current <ulink url="https://github.com/MLton/mlton/blob/master/CHANGELOG.adoc"><literal>CHANGELOG.adoc</literal></ulink> or recent <ulink url="https://github.com/MLton/mlton/commits/master">commits</ulink>.\r
8154</simpara>\r
8155</listitem>\r
8156<listitem>\r
8157<simpara>\r
8158Open <ulink url="https://github.com/MLton/mlton/issues">Issues</ulink>.\r
8159</simpara>\r
8160</listitem>\r
8161<listitem>\r
8162<simpara>\r
8163Ideas for <link linkend="Projects">Projects</link> to improve MLton.\r
8164</simpara>\r
8165</listitem>\r
8166<listitem>\r
8167<simpara>\r
8168<link linkend="Developers">Developers</link> that are or have been involved in the project.\r
8169</simpara>\r
8170</listitem>\r
8171</itemizedlist>\r
8172<section id="_notes">\r
8173<title>Notes</title>\r
8174<itemizedlist>\r
8175<listitem>\r
8176<simpara>\r
8177<link linkend="CompilerOverview">CompilerOverview</link>\r
8178</simpara>\r
8179</listitem>\r
8180<listitem>\r
8181<simpara>\r
8182<link linkend="CompilingWithSMLNJ">CompilingWithSMLNJ</link>\r
8183</simpara>\r
8184</listitem>\r
8185<listitem>\r
8186<simpara>\r
8187<link linkend="CrossCompiling">CrossCompiling</link>\r
8188</simpara>\r
8189</listitem>\r
8190<listitem>\r
8191<simpara>\r
8192<link linkend="License">License</link>\r
8193</simpara>\r
8194</listitem>\r
8195<listitem>\r
8196<simpara>\r
8197<link linkend="NeedsReview">NeedsReview</link>\r
8198</simpara>\r
8199</listitem>\r
8200<listitem>\r
8201<simpara>\r
8202<link linkend="PortingMLton">PortingMLton</link>\r
8203</simpara>\r
8204</listitem>\r
8205<listitem>\r
8206<simpara>\r
8207<link linkend="ReleaseChecklist">ReleaseChecklist</link>\r
8208</simpara>\r
8209</listitem>\r
8210<listitem>\r
8211<simpara>\r
8212<link linkend="SelfCompiling">SelfCompiling</link>\r
8213</simpara>\r
8214</listitem>\r
8215</itemizedlist>\r
8216<simpara><?asciidoc-pagebreak?></simpara>\r
8217</section>\r
8218</section>\r
8219<section id="Documentation">\r
8220<title>Documentation</title>\r
8221<simpara>Documentation is available on the following topics.</simpara>\r
8222<itemizedlist>\r
8223<listitem>\r
8224<simpara>\r
8225<link linkend="StandardML">Standard ML</link>\r
8226</simpara>\r
8227<itemizedlist>\r
8228<listitem>\r
8229<simpara>\r
8230<link linkend="BasisLibrary">Basis Library</link>\r
8231</simpara>\r
8232</listitem>\r
8233<listitem>\r
8234<simpara>\r
8235<link linkend="Libraries">Additional libraries</link>\r
8236</simpara>\r
8237</listitem>\r
8238</itemizedlist>\r
8239</listitem>\r
8240<listitem>\r
8241<simpara>\r
8242<link linkend="Installation">Installing MLton</link>\r
8243</simpara>\r
8244</listitem>\r
8245<listitem>\r
8246<simpara>\r
8247Using MLton\r
8248</simpara>\r
8249<itemizedlist>\r
8250<listitem>\r
8251<simpara>\r
8252<link linkend="ForeignFunctionInterface">Foreign function interface (FFI)</link>\r
8253</simpara>\r
8254</listitem>\r
8255<listitem>\r
8256<simpara>\r
8257<link linkend="ManualPage">Manual page</link> (<link linkend="CompileTimeOptions">compile-time options</link> <link linkend="RunTimeOptions">run-time options</link>)\r
8258</simpara>\r
8259</listitem>\r
8260<listitem>\r
8261<simpara>\r
8262<link linkend="MLBasis">ML Basis system</link>\r
8263</simpara>\r
8264</listitem>\r
8265<listitem>\r
8266<simpara>\r
8267<link linkend="MLtonStructure">MLton structure</link>\r
8268</simpara>\r
8269</listitem>\r
8270<listitem>\r
8271<simpara>\r
8272<link linkend="PlatformSpecificNotes">Platform-specific notes</link>\r
8273</simpara>\r
8274</listitem>\r
8275<listitem>\r
8276<simpara>\r
8277<link linkend="Profiling">Profiling</link>\r
8278</simpara>\r
8279</listitem>\r
8280<listitem>\r
8281<simpara>\r
8282<link linkend="TypeChecking">Type checking</link>\r
8283</simpara>\r
8284</listitem>\r
8285<listitem>\r
8286<simpara>\r
8287Help for porting from <link linkend="SMLNJ">SML/NJ</link> to MLton.\r
8288</simpara>\r
8289</listitem>\r
8290</itemizedlist>\r
8291</listitem>\r
8292<listitem>\r
8293<simpara>\r
8294About MLton\r
8295</simpara>\r
8296<itemizedlist>\r
8297<listitem>\r
8298<simpara>\r
8299<link linkend="Credits">Credits</link>\r
8300</simpara>\r
8301</listitem>\r
8302<listitem>\r
8303<simpara>\r
8304<link linkend="Drawbacks">Drawbacks</link>\r
8305</simpara>\r
8306</listitem>\r
8307<listitem>\r
8308<simpara>\r
8309<link linkend="Features">Features</link>\r
8310</simpara>\r
8311</listitem>\r
8312<listitem>\r
8313<simpara>\r
8314<link linkend="History">History</link>\r
8315</simpara>\r
8316</listitem>\r
8317<listitem>\r
8318<simpara>\r
8319<link linkend="License">License</link>\r
8320</simpara>\r
8321</listitem>\r
8322<listitem>\r
8323<simpara>\r
8324<link linkend="Talk">Talk</link>\r
8325</simpara>\r
8326</listitem>\r
8327<listitem>\r
8328<simpara>\r
8329<link linkend="WishList">WishList</link>\r
8330</simpara>\r
8331</listitem>\r
8332</itemizedlist>\r
8333</listitem>\r
8334<listitem>\r
8335<simpara>\r
8336Tools\r
8337</simpara>\r
8338<itemizedlist>\r
8339<listitem>\r
8340<simpara>\r
8341<link linkend="MLLex">MLLex</link> (<ulink url="guide/Documentation.attachments/mllex.pdf"><literal>mllex.pdf</literal></ulink>)\r
8342</simpara>\r
8343</listitem>\r
8344<listitem>\r
8345<simpara>\r
8346<link linkend="MLYacc">MLYacc</link> (<ulink url="guide/Documentation.attachments/mlyacc.pdf"><literal>mlyacc.pdf</literal></ulink>)\r
8347</simpara>\r
8348</listitem>\r
8349<listitem>\r
8350<simpara>\r
8351<link linkend="MLNLFFIGen">MLNLFFIGen</link> (<ulink url="guide/Documentation.attachments/mlyacc.pdf"><literal>mlyacc.pdf</literal></ulink>)\r
8352</simpara>\r
8353</listitem>\r
8354</itemizedlist>\r
8355</listitem>\r
8356<listitem>\r
8357<simpara>\r
8358<link linkend="References">References</link>\r
8359</simpara>\r
8360</listitem>\r
8361</itemizedlist>\r
8362<simpara><?asciidoc-pagebreak?></simpara>\r
8363</section>\r
8364<section id="Drawbacks">\r
8365<title>Drawbacks</title>\r
8366<simpara>MLton has several drawbacks due to its use of whole-program\r
8367compilation.</simpara>\r
8368<itemizedlist>\r
8369<listitem>\r
8370<simpara>\r
8371Large compile-time memory requirement.\r
8372</simpara>\r
8373<simpara>Because MLton performs whole-program analysis and optimization,\r
8374compilation requires a large amount of memory. For example, compiling\r
8375MLton (over 140K lines) requires at least 512M RAM.</simpara>\r
8376</listitem>\r
8377<listitem>\r
8378<simpara>\r
8379Long compile times.\r
8380</simpara>\r
8381<simpara>Whole-program compilation can take a long time. For example,\r
8382compiling MLton (over 140K lines) on a 1.6GHz machine takes five to\r
8383ten minutes.</simpara>\r
8384</listitem>\r
8385<listitem>\r
8386<simpara>\r
8387No interactive top level.\r
8388</simpara>\r
8389<simpara>Because of whole-program compilation, MLton does not provide an\r
8390interactive top level. In particular, it does not implement the\r
8391optional <link linkend="BasisLibrary">Basis Library</link> function <literal>use</literal>.</simpara>\r
8392</listitem>\r
8393</itemizedlist>\r
8394<simpara><?asciidoc-pagebreak?></simpara>\r
8395</section>\r
8396<section id="Eclipse">\r
8397<title>Eclipse</title>\r
8398<simpara><ulink url="http://eclipse.org/">Eclipse</ulink> is an open, extensible IDE.</simpara>\r
8399<simpara><ulink url="http://www.cse.iitd.ernet.in/%7Ecsu02132/mldev/">ML-Dev</ulink> is a plug-in\r
8400for Eclipse, based on <link linkend="SMLNJ">SML/NJ</link>.</simpara>\r
8401<simpara>There has been some talk on the MLton mailing list about adding\r
8402support to Eclipse for MLton/SML, and in particular, using\r
8403<ulink url="http://eclipsefp.sourceforge.net/">http://eclipsefp.sourceforge.net/</ulink>. We are unaware of any progress\r
8404along those lines.</simpara>\r
8405<simpara><?asciidoc-pagebreak?></simpara>\r
8406</section>\r
8407<section id="Elaborate">\r
8408<title>Elaborate</title>\r
8409<simpara><link linkend="Elaborate">Elaborate</link> is a translation pass from the <link linkend="AST">AST</link>\r
8410<link linkend="IntermediateLanguage">IntermediateLanguage</link> to the <link linkend="CoreML">CoreML</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link>.</simpara>\r
8411<section id="_description_16">\r
8412<title>Description</title>\r
8413<simpara>This pass performs type inference and type checking according to the\r
8414<link linkend="DefinitionOfStandardML">Definition</link>. It also defunctorizes the\r
8415program, eliminating all module-level constructs.</simpara>\r
8416</section>\r
8417<section id="_implementation_18">\r
8418<title>Implementation</title>\r
8419<itemizedlist>\r
8420<listitem>\r
8421<simpara>\r
8422<ulink url="https://github.com/MLton/mlton/blob/master/mlton/elaborate/elaborate.sig"><literal>elaborate.sig</literal></ulink>\r
8423</simpara>\r
8424</listitem>\r
8425<listitem>\r
8426<simpara>\r
8427<ulink url="https://github.com/MLton/mlton/blob/master/mlton/elaborate/elaborate.fun"><literal>elaborate.fun</literal></ulink>\r
8428</simpara>\r
8429</listitem>\r
8430<listitem>\r
8431<simpara>\r
8432<ulink url="https://github.com/MLton/mlton/blob/master/mlton/elaborate/elaborate-env.sig"><literal>elaborate-env.sig</literal></ulink>\r
8433</simpara>\r
8434</listitem>\r
8435<listitem>\r
8436<simpara>\r
8437<ulink url="https://github.com/MLton/mlton/blob/master/mlton/elaborate/elaborate-env.fun"><literal>elaborate-env.fun</literal></ulink>\r
8438</simpara>\r
8439</listitem>\r
8440<listitem>\r
8441<simpara>\r
8442<ulink url="https://github.com/MLton/mlton/blob/master/mlton/elaborate/elaborate-modules.sig"><literal>elaborate-modules.sig</literal></ulink>\r
8443</simpara>\r
8444</listitem>\r
8445<listitem>\r
8446<simpara>\r
8447<ulink url="https://github.com/MLton/mlton/blob/master/mlton/elaborate/elaborate-modules.fun"><literal>elaborate-modules.fun</literal></ulink>\r
8448</simpara>\r
8449</listitem>\r
8450<listitem>\r
8451<simpara>\r
8452<ulink url="https://github.com/MLton/mlton/blob/master/mlton/elaborate/elaborate-core.sig"><literal>elaborate-core.sig</literal></ulink>\r
8453</simpara>\r
8454</listitem>\r
8455<listitem>\r
8456<simpara>\r
8457<ulink url="https://github.com/MLton/mlton/blob/master/mlton/elaborate/elaborate-core.fun"><literal>elaborate-core.fun</literal></ulink>\r
8458</simpara>\r
8459</listitem>\r
8460<listitem>\r
8461<simpara>\r
8462<ulink url="https://github.com/MLton/mlton/tree/master/mlton/elaborate"><literal>elaborate</literal></ulink>\r
8463</simpara>\r
8464</listitem>\r
8465</itemizedlist>\r
8466</section>\r
8467<section id="_details_and_notes_18">\r
8468<title>Details and Notes</title>\r
8469<simpara>At the modules level, the <link linkend="Elaborate">Elaborate</link> pass:</simpara>\r
8470<itemizedlist>\r
8471<listitem>\r
8472<simpara>\r
8473elaborates signatures with interfaces (see\r
8474<ulink url="https://github.com/MLton/mlton/blob/master/mlton/elaborate/interface.sig"><literal>interface.sig</literal></ulink> and\r
8475<ulink url="https://github.com/MLton/mlton/blob/master/mlton/elaborate/interface.fun"><literal>interface.fun</literal></ulink>)\r
8476</simpara>\r
8477<simpara>The main trick is to use disjoint sets to efficiently handle sharing\r
8478of tycons and of structures and then to copy signatures as dags rather\r
8479than as trees.</simpara>\r
8480</listitem>\r
8481<listitem>\r
8482<simpara>\r
8483checks functors at the point of definition, using functor summaries\r
8484to speed up checking of functor applications.\r
8485</simpara>\r
8486<simpara>When a functor is first type checked, we keep track of the dummy\r
8487argument structure and the dummy result structure, as well as all the\r
8488tycons that were created while elaborating the body. Then, if we\r
8489later need to type check an application of the functor (as opposed to\r
8490defunctorize an application), we pair up tycons in the dummy argument\r
8491structure with the actual argument structure and then replace the\r
8492dummy tycons with the actual tycons in the dummy result structure,\r
8493yielding the actual result structure. We also generate new tycons for\r
8494all the tycons that we created while originally elaborating the body.</simpara>\r
8495</listitem>\r
8496<listitem>\r
8497<simpara>\r
8498handles opaque signature constraints.\r
8499</simpara>\r
8500<simpara>This is implemented by building a dummy structure realized from the\r
8501signature, just as we would for a functor argument when type checking\r
8502a functor. The dummy structure contains exactly the type information\r
8503that is in the signature, which is what opacity requires. We then\r
8504replace the variables (and constructors) in the dummy structure with\r
8505the corresponding variables (and constructors) from the actual\r
8506structure so that the translation to <link linkend="CoreML">CoreML</link> uses the right stuff.\r
8507For each tycon in the dummy structure, we keep track of the\r
8508corresponding type structure in the actual structure. This is used\r
8509when producing the <link linkend="CoreML">CoreML</link> types (see <literal>expandOpaque</literal> in\r
8510<ulink url="https://github.com/MLton/mlton/blob/master/mlton/elaborate/type-env.sig"><literal>type-env.sig</literal></ulink> and\r
8511<ulink url="https://github.com/MLton/mlton/blob/master/mlton/elaborate/type-env.fun"><literal>type-env.fun</literal></ulink>).</simpara>\r
8512<simpara>Then, within each <literal>structure</literal> or <literal>functor</literal> body, for each declaration\r
8513(<literal>&lt;dec&gt;</literal> in the <link linkend="StandardML">Standard ML</link> grammar), the <link linkend="Elaborate">Elaborate</link>\r
8514pass does three steps:</simpara>\r
8515<orderedlist numeration="arabic">\r
8516<listitem>\r
8517<simpara>\r
8518<link linkend="ScopeInference">ScopeInference</link>\r
8519</simpara>\r
8520</listitem>\r
8521<listitem>\r
8522<simpara>\r
8523</simpara>\r
8524<itemizedlist>\r
8525<listitem>\r
8526<simpara>\r
8527<link linkend="PrecedenceParse">PrecedenceParse</link>\r
8528</simpara>\r
8529</listitem>\r
8530<listitem>\r
8531<simpara>\r
8532<literal>_{ex,im}port</literal> expansion\r
8533</simpara>\r
8534</listitem>\r
8535<listitem>\r
8536<simpara>\r
8537profiling insertion\r
8538</simpara>\r
8539</listitem>\r
8540<listitem>\r
8541<simpara>\r
8542unification\r
8543</simpara>\r
8544</listitem>\r
8545</itemizedlist>\r
8546</listitem>\r
8547<listitem>\r
8548<simpara>\r
8549Overloaded {constant, function, record pattern} resolution\r
8550</simpara>\r
8551</listitem>\r
8552</orderedlist>\r
8553</listitem>\r
8554</itemizedlist>\r
8555<section id="_defunctorization">\r
8556<title>Defunctorization</title>\r
8557<simpara>The <link linkend="Elaborate">Elaborate</link> pass performs a number of duties historically\r
8558assigned to the <link linkend="Defunctorize">Defunctorize</link> pass.</simpara>\r
8559<simpara>As part of the <link linkend="Elaborate">Elaborate</link> pass, all module level constructs\r
8560(<literal>open</literal>, <literal>signature</literal>, <literal>structure</literal>, <literal>functor</literal>, long identifiers) are\r
8561removed. This works because the <link linkend="Elaborate">Elaborate</link> pass assigns a unique\r
8562name to every type and variable in the program. This also allows the\r
8563<link linkend="Elaborate">Elaborate</link> pass to eliminate <literal>local</literal> declarations, which are purely\r
8564for namespace management.</simpara>\r
8565</section>\r
8566</section>\r
8567<section id="_examples">\r
8568<title>Examples</title>\r
8569<simpara>Here are a number of examples of elaboration.</simpara>\r
8570<itemizedlist>\r
8571<listitem>\r
8572<simpara>\r
8573All variables bound in <literal>val</literal> declarations are renamed.\r
8574</simpara>\r
8575<programlisting language="sml" linenumbering="unnumbered">val x = 13\r
8576val y = x</programlisting>\r
8577<screen>val x_0 = 13\r
8578val y_0 = x_0</screen>\r
8579</listitem>\r
8580<listitem>\r
8581<simpara>\r
8582All variables in <literal>fun</literal> declarations are renamed.\r
8583</simpara>\r
8584<programlisting language="sml" linenumbering="unnumbered">fun f x = g x\r
8585and g y = f y</programlisting>\r
8586<screen>fun f_0 x_0 = g_0 x_0\r
8587and g_0 y_0 = f_0 y_0</screen>\r
8588</listitem>\r
8589<listitem>\r
8590<simpara>\r
8591Type abbreviations are removed, and the abbreviation is expanded\r
8592wherever it is used.\r
8593</simpara>\r
8594<programlisting language="sml" linenumbering="unnumbered">type 'a u = int * 'a\r
8595type 'b t = 'b u * real\r
8596fun f (x : bool t) = x</programlisting>\r
8597<screen>fun f_0 (x_0 : (int * bool) * real) = x_0</screen>\r
8598</listitem>\r
8599<listitem>\r
8600<simpara>\r
8601Exception declarations create a new constructor and rename the type.\r
8602</simpara>\r
8603<programlisting language="sml" linenumbering="unnumbered">type t = int\r
8604exception E of t * real</programlisting>\r
8605<screen>exception E_0 of int * real</screen>\r
8606</listitem>\r
8607<listitem>\r
8608<simpara>\r
8609The type and value constructors in datatype declarations are renamed.\r
8610</simpara>\r
8611<programlisting language="sml" linenumbering="unnumbered">datatype t = A of int | B of real * t</programlisting>\r
8612<screen>datatype t_0 = A_0 of int | B_0 of real * t_0</screen>\r
8613</listitem>\r
8614<listitem>\r
8615<simpara>\r
8616Local declarations are moved to the top-level. The environment\r
8617keeps track of the variables in scope.\r
8618</simpara>\r
8619<programlisting language="sml" linenumbering="unnumbered">val x = 13\r
8620local val x = 14\r
8621in val y = x\r
8622end\r
8623val z = x</programlisting>\r
8624<screen>val x_0 = 13\r
8625val x_1 = 14\r
8626val y_0 = x_1\r
8627val z_0 = x_0</screen>\r
8628</listitem>\r
8629<listitem>\r
8630<simpara>\r
8631Structure declarations are eliminated, with all declarations moved\r
8632to the top level. Long identifiers are renamed.\r
8633</simpara>\r
8634<programlisting language="sml" linenumbering="unnumbered">structure S =\r
8635 struct\r
8636 type t = int\r
8637 val x : t = 13\r
8638 end\r
8639val y : S.t = S.x</programlisting>\r
8640<screen>val x_0 : int = 13\r
8641val y_0 : int = x_0</screen>\r
8642</listitem>\r
8643<listitem>\r
8644<simpara>\r
8645Open declarations are eliminated.\r
8646</simpara>\r
8647<programlisting language="sml" linenumbering="unnumbered">val x = 13\r
8648val y = 14\r
8649structure S =\r
8650 struct\r
8651 val x = 15\r
8652 end\r
8653open S\r
8654val z = x + y</programlisting>\r
8655<screen>val x_0 = 13\r
8656val y_0 = 14\r
8657val x_1 = 15\r
8658val z_0 = x_1 + y_0</screen>\r
8659</listitem>\r
8660<listitem>\r
8661<simpara>\r
8662Functor declarations are eliminated, and the body of a functor is\r
8663duplicated wherever the functor is applied.\r
8664</simpara>\r
8665<programlisting language="sml" linenumbering="unnumbered">functor F(val x : int) =\r
8666 struct\r
8667 val y = x\r
8668 end\r
8669structure F1 = F(val x = 13)\r
8670structure F2 = F(val x = 14)\r
8671val z = F1.y + F2.y</programlisting>\r
8672<screen>val x_0 = 13\r
8673val y_0 = x_0\r
8674val x_1 = 14\r
8675val y_1 = x_1\r
8676val z_0 = y_0 + y_1</screen>\r
8677</listitem>\r
8678<listitem>\r
8679<simpara>\r
8680Signature constraints are eliminated. Note that signatures do\r
8681affect how subsequent variables are renamed.\r
8682</simpara>\r
8683<programlisting language="sml" linenumbering="unnumbered">val y = 13\r
8684structure S : sig\r
8685 val x : int\r
8686 end =\r
8687 struct\r
8688 val x = 14\r
8689 val y = x\r
8690 end\r
8691open S\r
8692val z = x + y</programlisting>\r
8693<screen>val y_0 = 13\r
8694val x_0 = 14\r
8695val y_1 = x_0\r
8696val z_0 = x_0 + y_0</screen>\r
8697</listitem>\r
8698</itemizedlist>\r
8699<simpara><?asciidoc-pagebreak?></simpara>\r
8700</section>\r
8701</section>\r
8702<section id="Emacs">\r
8703<title>Emacs</title>\r
8704<section id="_sml_modes">\r
8705<title>SML modes</title>\r
8706<simpara>There are a few Emacs modes for SML.</simpara>\r
8707<itemizedlist>\r
8708<listitem>\r
8709<simpara>\r
8710<literal>sml-mode</literal>\r
8711</simpara>\r
8712<itemizedlist>\r
8713<listitem>\r
8714<simpara>\r
8715<ulink url="http://www.xemacs.org/Documentation/packages/html/sml-mode_3.html">http://www.xemacs.org/Documentation/packages/html/sml-mode_3.html</ulink>\r
8716</simpara>\r
8717</listitem>\r
8718<listitem>\r
8719<simpara>\r
8720<ulink url="http://www.smlnj.org/doc/Emacs/sml-mode.html">http://www.smlnj.org/doc/Emacs/sml-mode.html</ulink>\r
8721</simpara>\r
8722</listitem>\r
8723<listitem>\r
8724<simpara>\r
8725<ulink url="http://www.iro.umontreal.ca/%7Emonnier/elisp/">http://www.iro.umontreal.ca/%7Emonnier/elisp/</ulink>\r
8726</simpara>\r
8727</listitem>\r
8728</itemizedlist>\r
8729</listitem>\r
8730<listitem>\r
8731<simpara>\r
8732<ulink url="https://github.com/MLton/mlton/blob/master/ide/emacs/mlton.el"><literal>mlton.el</literal></ulink> contains the Emacs lisp that <link linkend="StephenWeeks">StephenWeeks</link> uses to interact with MLton (in addition to using <literal>sml-mode</literal>).\r
8733</simpara>\r
8734</listitem>\r
8735<listitem>\r
8736<simpara>\r
8737<ulink url="http://primate.net/%7Eitz/mindent.tar">http://primate.net/%7Eitz/mindent.tar</ulink>, developed by Ian Zimmerman, who writes:\r
8738</simpara>\r
8739<blockquote>\r
8740<simpara>Unlike the widespread <literal>sml-mode.el</literal> it doesn&#8217;t try to indent code\r
8741based on ML syntax. I gradually got skeptical about this approach\r
8742after writing the initial indentation support for caml mode and\r
8743watching it bloat insanely as the language added new features. Also,\r
8744any such attempts that I know of impose a particular coding style, or\r
8745at best a choice among a limited set of styles, which I now oppose.\r
8746Instead my mode is based on a generic package which provides manual\r
8747bindable commands for common indentation operations (example: indent\r
8748the current line under the n-th occurrence of a particular character\r
8749in the previous non-blank line).</simpara>\r
8750</blockquote>\r
8751</listitem>\r
8752</itemizedlist>\r
8753</section>\r
8754<section id="_mlb_modes">\r
8755<title>MLB modes</title>\r
8756<simpara>There is a mode for editing <link linkend="MLBasis">ML Basis</link> files.</simpara>\r
8757<itemizedlist>\r
8758<listitem>\r
8759<simpara>\r
8760<ulink url="https://github.com/MLton/mlton/blob/master/ide/emacs/esml-mlb-mode.el"><literal>esml-mlb-mode.el</literal></ulink> (plus other files)\r
8761</simpara>\r
8762</listitem>\r
8763</itemizedlist>\r
8764</section>\r
8765<section id="_definitions_and_uses">\r
8766<title>Definitions and uses</title>\r
8767<simpara>There is a mode that supports the precise def-use information that\r
8768MLton can output. It highlights definitions and uses and provides\r
8769commands for navigation (e.g., <literal>jump-to-def</literal>, <literal>jump-to-next</literal>,\r
8770<literal>list-all-refs</literal>). It can be handy, for example, for navigating in the\r
8771MLton compiler source code. See <link linkend="EmacsDefUseMode">EmacsDefUseMode</link> for further\r
8772information.</simpara>\r
8773</section>\r
8774<section id="_building_on_the_background">\r
8775<title>Building on the background</title>\r
8776<simpara>Tired of manually starting/stopping/restarting builds after editing\r
8777files? Now you don&#8217;t have to. See <link linkend="EmacsBgBuildMode">EmacsBgBuildMode</link> for further\r
8778information.</simpara>\r
8779</section>\r
8780<section id="_error_messages">\r
8781<title>Error messages</title>\r
8782<simpara>MLton&#8217;s error messages are not among those that the Emacs <literal>next-error</literal>\r
8783parser natively understands. The easiest way to fix this is to add\r
8784the following to your <literal>.emacs</literal> to teach Emacs to recognize MLton&#8217;s\r
8785error messages.</simpara>\r
8786<programlisting language="cl" linenumbering="unnumbered">(require 'compile)\r
8787(add-to-list 'compilation-error-regexp-alist 'mlton)\r
8788(add-to-list 'compilation-error-regexp-alist-alist\r
8789 '(mlton\r
8790 "^[[:space:]]*\\(\\(?:\\(Error\\)\\|\\(Warning\\)\\|\\(\\(?:\\(?:defn\\|spec\\) at\\)\\|\\(?:escape \\(?:from\\|to\\)\\)\\|\\(?:scoped at\\)\\)\\): \\(.+\\) \\([0-9]+\\)\\.\\([0-9]+\\)\\(?:-\\([0-9]+\\)\\.\\([0-9]+\\)\\)?\\.?\\)$"\r
8791 5 (6 . 8) (7 . 9) (3 . 4) 1))</programlisting>\r
8792<simpara><?asciidoc-pagebreak?></simpara>\r
8793</section>\r
8794</section>\r
8795<section id="EmacsBgBuildMode">\r
8796<title>EmacsBgBuildMode</title>\r
8797<simpara>Do you really want to think about starting a build of you project?\r
8798What if you had a personal slave that would restart a build of your\r
8799project whenever you save any file belonging to that project? The\r
8800bg-build mode does just that. Just save the file, a compile is\r
8801started (silently!), you can continue working without even thinking\r
8802about starting a build, and if there are errors, you are notified\r
8803(with a message), and can then jump to errors.</simpara>\r
8804<simpara>This mode is not specific to MLton per se, but is particularly useful\r
8805for working with MLton due to the longer compile times. By the time\r
8806you start wondering about possible errors, the build is already on the\r
8807way.</simpara>\r
8808<section id="_functionality_and_features">\r
8809<title>Functionality and Features</title>\r
8810<itemizedlist>\r
8811<listitem>\r
8812<simpara>\r
8813Each time a file is saved, and after a user configurable delay\r
8814period has been exhausted, a build is started silently in the\r
8815background.\r
8816</simpara>\r
8817</listitem>\r
8818<listitem>\r
8819<simpara>\r
8820When the build is finished, a status indicator (message) is\r
8821displayed non-intrusively.\r
8822</simpara>\r
8823</listitem>\r
8824<listitem>\r
8825<simpara>\r
8826At any time, you can switch to a build process buffer where all the\r
8827messages from the build are shown.\r
8828</simpara>\r
8829</listitem>\r
8830<listitem>\r
8831<simpara>\r
8832Optionally highlights (error/warning) message locations in (source\r
8833code) buffers after a finished build.\r
8834</simpara>\r
8835</listitem>\r
8836<listitem>\r
8837<simpara>\r
8838After a build has finished, you can jump to locations of warnings\r
8839and errors from the build process buffer or by using the <literal>first-error</literal>\r
8840and <literal>next-error</literal> commands.\r
8841</simpara>\r
8842</listitem>\r
8843<listitem>\r
8844<simpara>\r
8845When a build fails, bg-build mode can optionally execute a user\r
8846specified command. By default, bg-build mode executes <literal>first-error</literal>.\r
8847</simpara>\r
8848</listitem>\r
8849<listitem>\r
8850<simpara>\r
8851When starting a build of a particular project, a possible previous\r
8852live build of the same project is interrupted first.\r
8853</simpara>\r
8854</listitem>\r
8855<listitem>\r
8856<simpara>\r
8857A project configuration file specifies the commands required to\r
8858build a project.\r
8859</simpara>\r
8860</listitem>\r
8861<listitem>\r
8862<simpara>\r
8863Multiple projects can be loaded into bg-build mode and bg-build mode\r
8864can build a given maximum number of projects concurrently.\r
8865</simpara>\r
8866</listitem>\r
8867<listitem>\r
8868<simpara>\r
8869Supports both <ulink url="http://www.gnu.org/software/emacs/">Gnu Emacs</ulink> and\r
8870<ulink url="http://www.xemacs.org">XEmacs</ulink>.\r
8871</simpara>\r
8872</listitem>\r
8873</itemizedlist>\r
8874</section>\r
8875<section id="_download_4">\r
8876<title>Download</title>\r
8877<simpara>There is no package for the mode at the moment. To install the mode you\r
8878need to fetch the Emacs Lisp, <literal>*.el</literal>, files from the MLton repository:\r
8879<ulink url="https://github.com/MLton/mlton/tree/master/ide/emacs"><literal>emacs</literal></ulink>.</simpara>\r
8880</section>\r
8881<section id="_setup">\r
8882<title>Setup</title>\r
8883<simpara>The easiest way to load the mode is to first tell Emacs where to find the\r
8884files. For example, add</simpara>\r
8885<programlisting language="cl" linenumbering="unnumbered">(add-to-list 'load-path (file-truename "path-to-the-el-files"))</programlisting>\r
8886<simpara>to your <literal>~/.emacs</literal> or <literal>~/.xemacs/init.el</literal>. You&#8217;ll probably also want\r
8887to start the mode automatically by adding</simpara>\r
8888<programlisting language="cl" linenumbering="unnumbered">(require 'bg-build-mode)\r
8889(bg-build-mode)</programlisting>\r
8890<simpara>to your Emacs init file. Once the mode is activated, you should see\r
8891the <literal>BGB</literal> indicator on the mode line.</simpara>\r
8892<section id="_mlton_and_compilation_mode">\r
8893<title>MLton and Compilation-Mode</title>\r
8894<simpara>At the time of writing, neither Gnu Emacs nor XEmacs contain an error\r
8895regexp that would match MLton&#8217;s messages.</simpara>\r
8896<simpara>If you use Gnu Emacs, insert the following code into your <literal>.emacs</literal> file:</simpara>\r
8897<programlisting language="cl" linenumbering="unnumbered">(require 'compile)\r
8898(add-to-list\r
8899 'compilation-error-regexp-alist\r
8900 '("^\\(Warning\\|Error\\): \\(.+\\) \\([0-9]+\\)\\.\\([0-9]+\\)\\.$"\r
8901 2 3 4))</programlisting>\r
8902<simpara>If you use XEmacs, insert the following code into your <literal>init.el</literal> file:</simpara>\r
8903<programlisting language="cl" linenumbering="unnumbered">(require 'compile)\r
8904(add-to-list\r
8905 'compilation-error-regexp-alist-alist\r
8906 '(mlton\r
8907 ("^\\(Warning\\|Error\\): \\(.+\\) \\([0-9]+\\)\\.\\([0-9]+\\)\\.$"\r
8908 2 3 4)))\r
8909(compilation-build-compilation-error-regexp-alist)</programlisting>\r
8910</section>\r
8911</section>\r
8912<section id="_usage_3">\r
8913<title>Usage</title>\r
8914<simpara>Typically projects are built (or compiled) using a tool like <ulink url="http://www.gnu.org/software/make/"><literal>make</literal></ulink>,\r
8915but the details vary. The bg-build mode needs a project configuration file to\r
8916know how to build your project. A project configuration file basically contains\r
8917an Emacs Lisp expression calling a function named <literal>bg-build</literal> that returns a\r
8918project object. A simple example of a project configuration file would be the\r
8919(<ulink url="https://github.com/MLton/mltonlib/blob/master/com/ssh/async/unstable/example/smlbot/Build.bgb"><literal>Build.bgb</literal></ulink>)\r
8920file used with smlbot:</simpara>\r
8921<programlisting language="cl" linenumbering="unnumbered">(bg-build\r
8922 :name "SML-Bot"\r
8923 :shell "nice -n5 make all")</programlisting>\r
8924<simpara>The <literal>bg-build</literal> function takes a number of keyword arguments:</simpara>\r
8925<itemizedlist>\r
8926<listitem>\r
8927<simpara>\r
8928<literal>:name</literal> specifies the name of the project. This can be any\r
8929expression that evaluates to a string or to a nullary function that\r
8930returns a string.\r
8931</simpara>\r
8932</listitem>\r
8933<listitem>\r
8934<simpara>\r
8935<literal>:shell</literal> specifies a shell command to execute. This can be any\r
8936expression that evaluates to a string, a list of strings, or to a\r
8937nullary function returning a list of strings.\r
8938</simpara>\r
8939</listitem>\r
8940<listitem>\r
8941<simpara>\r
8942<literal>:build?</literal> specifies a predicate to determine whether the project\r
8943should be built after some files have been modified. The predicate is\r
8944given a list of filenames and should return a non-nil value when the\r
8945project should be built and nil otherwise.\r
8946</simpara>\r
8947</listitem>\r
8948</itemizedlist>\r
8949<simpara>All of the keyword arguments, except <literal>:shell</literal>, are optional and can be left out.</simpara>\r
8950<simpara>Note the use of the <literal>nice</literal> command above. It means that background\r
8951build process is given a lower priority by the system process\r
8952scheduler. Assuming your machine has enough memory, using nice\r
8953ensures that your computer remains responsive. (You probably won&#8217;t\r
8954even notice when a build is started.)</simpara>\r
8955<simpara>Once you have written a project file for bg-build mode. Use the\r
8956<literal>bg-build-add-project</literal> command to load the project file for bg-build\r
8957mode. The bg-build mode can also optionally load recent project files\r
8958automatically at startup.</simpara>\r
8959<simpara>After the project file has been loaded and bg-build mode activated,\r
8960each time you save a file in Emacs, the bg-build mode tries to build\r
8961your project.</simpara>\r
8962<simpara>The <literal>bg-build-status</literal> command creates a buffer that displays some\r
8963status information on builds and allows you to manage projects (start\r
8964builds explicitly, remove a project from bg-build, &#8230;) as well as\r
8965visit buffers created by bg-build. Notice the count of started\r
8966builds. At the end of the day it can be in the hundreds or thousands.\r
8967Imagine the number of times you&#8217;ve been relieved of starting a build\r
8968explicitly!</simpara>\r
8969<simpara><?asciidoc-pagebreak?></simpara>\r
8970</section>\r
8971</section>\r
8972<section id="EmacsDefUseMode">\r
8973<title>EmacsDefUseMode</title>\r
8974<simpara>MLton provides an <link linkend="CompileTimeOptions">option</link>,\r
8975<literal>-show-def-use <emphasis>file</emphasis></literal>, to output precise (giving exact source\r
8976locations) and accurate (including all uses and no false data)\r
8977whole-program def-use information to a file. Unlike typical tags\r
8978facilities, the information includes local variables and distinguishes\r
8979between different definitions even when they have the same name. The\r
8980def-use Emacs mode uses the information to provide navigation support,\r
8981which can be particularly useful while reading SML programs compiled\r
8982with MLton (such as the MLton compiler itself).</simpara>\r
8983<section id="_screen_capture">\r
8984<title>Screen Capture</title>\r
8985<simpara>Note the highlighting and the type displayed in the minibuffer.</simpara>\r
8986<informalfigure>\r
8987<mediaobject>\r
8988 <imageobject>\r
8989 <imagedata fileref="EmacsDefUseMode.attachments/def-use-capture.png" align="center"/>\r
8990 </imageobject>\r
8991 <textobject><phrase>EmacsDefUseMode.attachments/def-use-capture.png</phrase></textobject>\r
8992</mediaobject>\r
8993</informalfigure>\r
8994</section>\r
8995<section id="_features">\r
8996<title>Features</title>\r
8997<itemizedlist>\r
8998<listitem>\r
8999<simpara>\r
9000Highlights definitions and uses. Different colors for definitions, unused definitions, and uses.\r
9001</simpara>\r
9002</listitem>\r
9003<listitem>\r
9004<simpara>\r
9005Shows types (with highlighting) of variable definitions in the minibuffer.\r
9006</simpara>\r
9007</listitem>\r
9008<listitem>\r
9009<simpara>\r
9010Navigation: <literal>jump-to-def</literal>, <literal>jump-to-next</literal>, and <literal>jump-to-prev</literal>. These work precisely (no searching involved).\r
9011</simpara>\r
9012</listitem>\r
9013<listitem>\r
9014<simpara>\r
9015Can list, visit and mark all references to a definition (within a program).\r
9016</simpara>\r
9017</listitem>\r
9018<listitem>\r
9019<simpara>\r
9020Automatically reloads updated def-use files.\r
9021</simpara>\r
9022</listitem>\r
9023<listitem>\r
9024<simpara>\r
9025Automatically loads previously used def-use files at startup.\r
9026</simpara>\r
9027</listitem>\r
9028<listitem>\r
9029<simpara>\r
9030Supports both <ulink url="http://www.gnu.org/software/emacs/">Gnu Emacs</ulink> and <ulink url="http://www.xemacs.org">XEmacs</ulink>.\r
9031</simpara>\r
9032</listitem>\r
9033</itemizedlist>\r
9034</section>\r
9035<section id="_download_5">\r
9036<title>Download</title>\r
9037<simpara>There is no separate package for the def-use mode although the mode\r
9038has been relatively stable for some time already. To install the mode\r
9039you need to get the Emacs Lisp, <literal>*.el</literal>, files from MLton&#8217;s repository:\r
9040<ulink url="https://github.com/MLton/mlton/tree/master/ide/emacs"><literal>emacs</literal></ulink>. The easiest way to get the files\r
9041is to use <link linkend="Git">Git</link> to access MLton&#8217;s <link linkend="Sources">sources</link>.</simpara>\r
9042</section>\r
9043<section id="_setup_2">\r
9044<title>Setup</title>\r
9045<simpara>The easiest way to load def-use mode is to first tell Emacs where to\r
9046find the files. For example, add</simpara>\r
9047<programlisting language="cl" linenumbering="unnumbered">(add-to-list 'load-path (file-truename "path-to-the-el-files"))</programlisting>\r
9048<simpara>to your <literal>~/.emacs</literal> or <literal>~/.xemacs/init.el</literal>. You&#8217;ll probably\r
9049also want to start <literal>def-use-mode</literal> automatically by adding</simpara>\r
9050<programlisting language="cl" linenumbering="unnumbered">(require 'esml-du-mlton)\r
9051(def-use-mode)</programlisting>\r
9052<simpara>to your Emacs init file. Once the def-use mode is activated, you\r
9053should see the <literal>DU</literal> indicator on the mode line.</simpara>\r
9054</section>\r
9055<section id="_usage_4">\r
9056<title>Usage</title>\r
9057<simpara>To use def-use mode one typically first sets up the program&#8217;s makefile\r
9058or build script so that the def-use information is saved each time the\r
9059program is compiled. In addition to the <literal>-show-def-use <emphasis>file</emphasis></literal>\r
9060option, the <literal>-prefer-abs-paths true</literal> expert option is required.\r
9061Note that the time it takes to save the information is small (compared\r
9062to type-checking), so it is recommended to simply add the options to\r
9063the MLton invocation that compiles the program. However, it is only\r
9064necessary to type check the program (or library), so one can specify\r
9065the <literal>-stop tc</literal> option. For example, suppose you have a program\r
9066defined by an MLB file named <literal>my-prg.mlb</literal>, you can save the def-use\r
9067information to the file <literal>my-prg.du</literal> by invoking MLton as:</simpara>\r
9068<screen>mlton -prefer-abs-paths true -show-def-use my-prg.du -stop tc my-prg.mlb</screen>\r
9069<simpara>Finally, one needs to tell the mode where to find the def-use\r
9070information. This is done with the <literal>esml-du-mlton</literal> command. For\r
9071example, to load the <literal>my-prg.du</literal> file, one would type:</simpara>\r
9072<screen>M-x esml-du-mlton my-prg.du</screen>\r
9073<simpara>After doing all of the above, find an SML file covered by the\r
9074previously saved and loaded def-use information, and place the cursor\r
9075at some variable (definition or use, it doesn&#8217;t matter). You should\r
9076see the variable being highlighted. (Note that specifications in\r
9077signatures do not define variables.)</simpara>\r
9078<simpara>You might also want to setup and use the\r
9079<link linkend="EmacsBgBuildMode">Bg-Build mode</link> to start builds automatically.</simpara>\r
9080</section>\r
9081<section id="_types">\r
9082<title>Types</title>\r
9083<simpara><literal>-show-def-use</literal> output was extended to include types of variable\r
9084definitions in revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r6333"><literal>r6333</literal></ulink>. To get good type names, the\r
9085types must be in scope at the end of the program. If you are using the\r
9086<link linkend="MLBasis">ML Basis</link> system, this means that the root MLB-file for your\r
9087application should not wrap the libraries used in the application inside\r
9088<literal>local ... in ... end</literal>, because that would remove them from the scope before\r
9089the end of the program.</simpara>\r
9090<simpara><?asciidoc-pagebreak?></simpara>\r
9091</section>\r
9092</section>\r
9093<section id="Enscript">\r
9094<title>Enscript</title>\r
9095<simpara><ulink url="http://www.gnu.org/s/enscript/">GNU Enscript</ulink> converts ASCII files to\r
9096PostScript, HTML, and other output languages, applying language\r
9097sensitive highlighting (similar to <link linkend="Emacs">Emacs</link>'s font lock mode). Here\r
9098are a few <emphasis>states</emphasis> files for highlighting <link linkend="StandardML">Standard ML</link>.</simpara>\r
9099<itemizedlist>\r
9100<listitem>\r
9101<simpara>\r
9102<ulink url="https://github.com/MLton/mlton/blob/master/ide/enscript/sml_simple.st"><literal>sml_simple.st</literal></ulink>&#8201;&#8212;&#8201;Provides highlighting of keywords, string and character constants, and (nested) comments.\r
9103</simpara>\r
9104</listitem>\r
9105</itemizedlist>\r
9106<itemizedlist>\r
9107<listitem>\r
9108<simpara>\r
9109<ulink url="https://github.com/MLton/mlton/blob/master/ide/enscript/sml_verbose.st"><literal>sml_verbose.st</literal></ulink>&#8201;&#8212;&#8201;Supersedes\r
9110the above, adding highlighting of numeric constants. Due to the\r
9111limited parsing available, numeric record labels are highlighted as\r
9112numeric constants, in all contexts. Likewise, a binding precedence\r
9113separated from <literal>infix</literal> or <literal>infixr</literal> by a newline is highlighted as a\r
9114numeric constant and a numeric record label selector separated from\r
9115<literal>#</literal> by a newline is highlighted as a numeric constant.\r
9116</simpara>\r
9117</listitem>\r
9118</itemizedlist>\r
9119<itemizedlist>\r
9120<listitem>\r
9121<simpara>\r
9122<ulink url="https://github.com/MLton/mlton/blob/master/ide/enscript/sml_fancy.st"><literal>sml_fancy.st</literal></ulink>&#8201;&#8212;&#8201;Supersedes the\r
9123above, adding highlighting of type and constructor bindings,\r
9124highlighting of explicit binding of type variables at <literal>val</literal> and <literal>fun</literal>\r
9125declarations, and separate highlighting of core and modules level\r
9126keywords. Due to the limited parsing available, it is assumed that\r
9127the input is a syntactically correct, top-level declaration.\r
9128</simpara>\r
9129</listitem>\r
9130</itemizedlist>\r
9131<itemizedlist>\r
9132<listitem>\r
9133<simpara>\r
9134<ulink url="https://github.com/MLton/mlton/blob/master/ide/enscript/sml_gaudy.st"><literal>sml_gaudy.st</literal></ulink>&#8201;&#8212;&#8201;Supersedes the\r
9135above, adding highlighting of type annotations, in both expressions\r
9136and signatures. Due to the limited parsing available, it is assumed\r
9137that the input is a syntactically correct, top-level declaration.\r
9138</simpara>\r
9139</listitem>\r
9140</itemizedlist>\r
9141<section id="_install_and_use">\r
9142<title>Install and use</title>\r
9143<itemizedlist>\r
9144<listitem>\r
9145<simpara>\r
9146Version 1.6.3 of <ulink url="http://people.ssh.com/mtr/genscript">GNU Enscript</ulink>\r
9147</simpara>\r
9148<itemizedlist>\r
9149<listitem>\r
9150<simpara>\r
9151Copy all files to <literal>/usr/share/enscript/hl/</literal> or <literal>.enscript/</literal> in your home directory.\r
9152</simpara>\r
9153</listitem>\r
9154<listitem>\r
9155<simpara>\r
9156Invoke <literal>enscript</literal> with <literal>--highlight=sml_simple</literal> (or <literal>--highlight=sml_verbose</literal> or <literal>--highlight=sml_fancy</literal> or <literal>--highlight=sml_gaudy</literal>).\r
9157</simpara>\r
9158</listitem>\r
9159</itemizedlist>\r
9160</listitem>\r
9161<listitem>\r
9162<simpara>\r
9163Version 1.6.1 of <ulink url="http://people.ssh.com/mtr/genscript">GNU Enscript</ulink>\r
9164</simpara>\r
9165<itemizedlist>\r
9166<listitem>\r
9167<simpara>\r
9168Append <ulink url="https://github.com/MLton/mlton/blob/master/ide/enscript/sml_all.st"><literal>sml_all.st</literal></ulink> to <literal>/usr/share/enscript/enscript.st</literal>\r
9169</simpara>\r
9170</listitem>\r
9171<listitem>\r
9172<simpara>\r
9173Invoke <literal>enscript</literal> with <literal>--pretty-print=sml_simple</literal> (or <literal>--pretty-print=sml_verbose</literal> or <literal>--pretty-print=sml_fancy</literal> or <literal>--pretty-print=sml_gaudy</literal>).\r
9174</simpara>\r
9175</listitem>\r
9176</itemizedlist>\r
9177</listitem>\r
9178</itemizedlist>\r
9179</section>\r
9180<section id="_feedback">\r
9181<title>Feedback</title>\r
9182<simpara>Comments and suggestions should be directed to <link linkend="MatthewFluet">MatthewFluet</link>.</simpara>\r
9183<simpara><?asciidoc-pagebreak?></simpara>\r
9184</section>\r
9185</section>\r
9186<section id="EqualityType">\r
9187<title>EqualityType</title>\r
9188<simpara>An equality type is a type to which <link linkend="PolymorphicEquality">PolymorphicEquality</link> can be\r
9189applied. The <link linkend="DefinitionOfStandardML">Definition</link> and the\r
9190<link linkend="BasisLibrary">Basis Library</link> precisely spell out which types are\r
9191equality types.</simpara>\r
9192<itemizedlist>\r
9193<listitem>\r
9194<simpara>\r
9195<literal>bool</literal>, <literal>char</literal>, <literal>IntInf.int</literal>, <literal>Int<emphasis>&lt;N&gt;</emphasis>.int</literal>, <literal>string</literal>, and <literal>Word<emphasis>&lt;N&gt;</emphasis>.word</literal> are equality types.\r
9196</simpara>\r
9197</listitem>\r
9198<listitem>\r
9199<simpara>\r
9200for any <literal>t</literal>, both <literal>t array</literal> and <literal>t ref</literal> are equality types.\r
9201</simpara>\r
9202</listitem>\r
9203<listitem>\r
9204<simpara>\r
9205if <literal>t</literal> is an equality type, then <literal>t list</literal>, and <literal>t vector</literal> are equality types.\r
9206</simpara>\r
9207</listitem>\r
9208<listitem>\r
9209<simpara>\r
9210if <literal>t1</literal>, &#8230;, <literal>tn</literal> are equality types, then <literal>t1 * ... * tn</literal> and <literal>{l1: t1, ..., ln: tn}</literal> are equality types.\r
9211</simpara>\r
9212</listitem>\r
9213<listitem>\r
9214<simpara>\r
9215if <literal>t1</literal>, &#8230;, <literal>tn</literal> are equality types and <literal>t</literal> <link linkend="AdmitsEquality">AdmitsEquality</link>, then <literal>(t1, ..., tn) t</literal> is an equality type.\r
9216</simpara>\r
9217</listitem>\r
9218</itemizedlist>\r
9219<simpara>To check that a type t is an equality type, use the following idiom.</simpara>\r
9220<programlisting language="sml" linenumbering="unnumbered">structure S: sig eqtype t end =\r
9221 struct\r
9222 type t = ...\r
9223 end</programlisting>\r
9224<simpara>Notably, <literal>exn</literal> and <literal>real</literal> are not equality types. Neither is <literal>t1 -&gt; t2</literal>, for any <literal>t1</literal> and <literal>t2</literal>.</simpara>\r
9225<simpara>Equality on arrays and ref cells is by identity, not structure.\r
9226For example, <literal>ref 13 = ref 13</literal> is <literal>false</literal>.\r
9227On the other hand, equality for lists, strings, and vectors is by\r
9228structure, not identity. For example, the following equalities hold.</simpara>\r
9229<programlisting language="sml" linenumbering="unnumbered">val _ = [1, 2, 3] = 1 :: [2, 3]\r
9230val _ = "foo" = concat ["f", "o", "o"]\r
9231val _ = Vector.fromList [1, 2, 3] = Vector.tabulate (3, fn i =&gt; i + 1)</programlisting>\r
9232<simpara><?asciidoc-pagebreak?></simpara>\r
9233</section>\r
9234<section id="EqualityTypeVariable">\r
9235<title>EqualityTypeVariable</title>\r
9236<simpara>An equality type variable is a type variable that starts with two or\r
9237more primes, as in <literal>''a</literal> or <literal>''b</literal>. The canonical use of equality type\r
9238variables is in specifying the type of the <link linkend="PolymorphicEquality">PolymorphicEquality</link>\r
9239function, which is <literal>''a * ''a -&gt; bool</literal>. Equality type variables\r
9240ensure that polymorphic equality is only used on\r
9241<link linkend="EqualityType">equality types</link>, by requiring that at every use of a\r
9242polymorphic value, equality type variables are instantiated by\r
9243equality types.</simpara>\r
9244<simpara>For example, the following program is type correct because polymorphic\r
9245equality is applied to variables of type <literal>''a</literal>.</simpara>\r
9246<programlisting language="sml" linenumbering="unnumbered">fun f (x: ''a, y: ''a): bool = x = y</programlisting>\r
9247<simpara>On the other hand, the following program is not type correct, because\r
9248polymorphic equality is applied to variables of type <literal>'a</literal>, which is\r
9249not an equality type.</simpara>\r
9250<programlisting language="sml" linenumbering="unnumbered">fun f (x: 'a, y: 'a): bool = x = y</programlisting>\r
9251<simpara>MLton reports the following error, indicating that polymorphic\r
9252equality expects equality types, but didn&#8217;t get them.</simpara>\r
9253<screen>Error: z.sml 1.30-1.34.\r
9254 Function applied to incorrect argument.\r
9255 expects: [&lt;equality&gt;] * [&lt;equality&gt;]\r
9256 but got: ['a] * ['a]\r
9257 in: = (x, y)</screen>\r
9258<simpara>As an example of using such a function that requires equality types,\r
9259suppose that <literal>f</literal> has polymorphic type <literal>''a -&gt; unit</literal>. Then, <literal>f 13</literal> is\r
9260type correct because <literal>int</literal> is an equality type. On the other hand,\r
9261<literal>f 13.0</literal> and <literal>f (fn x =&gt; x)</literal> are not type correct, because <literal>real</literal> and\r
9262arrow types are not equality types. We can test these facts with the\r
9263following short programs. First, we verify that such an <literal>f</literal> can be\r
9264applied to integers.</simpara>\r
9265<programlisting language="sml" linenumbering="unnumbered">functor Ok (val f: ''a -&gt; unit): sig end =\r
9266 struct\r
9267 val () = f 13\r
9268 val () = f 14\r
9269 end</programlisting>\r
9270<simpara>We can do better, and verify that such an <literal>f</literal> can be applied to\r
9271any integer.</simpara>\r
9272<programlisting language="sml" linenumbering="unnumbered">functor Ok (val f: ''a -&gt; unit): sig end =\r
9273 struct\r
9274 fun g (x: int) = f x\r
9275 end</programlisting>\r
9276<simpara>Even better, we don&#8217;t need to introduce a dummy function name; we can\r
9277use a type constraint.</simpara>\r
9278<programlisting language="sml" linenumbering="unnumbered">functor Ok (val f: ''a -&gt; unit): sig end =\r
9279 struct\r
9280 val _ = f: int -&gt; unit\r
9281 end</programlisting>\r
9282<simpara>Even better, we can use a signature constraint.</simpara>\r
9283<programlisting language="sml" linenumbering="unnumbered">functor Ok (S: sig val f: ''a -&gt; unit end):\r
9284 sig val f: int -&gt; unit end = S</programlisting>\r
9285<simpara>This functor concisely verifies that a function of polymorphic type\r
9286<literal>''a -&gt; unit</literal> can be safely used as a function of type <literal>int -&gt; unit</literal>.</simpara>\r
9287<simpara>As above, we can verify that such an <literal>f</literal> can not be used at\r
9288non-equality types.</simpara>\r
9289<programlisting language="sml" linenumbering="unnumbered">functor Bad (S: sig val f: ''a -&gt; unit end):\r
9290 sig val f: real -&gt; unit end = S\r
9291\r
9292functor Bad (S: sig val f: ''a -&gt; unit end):\r
9293 sig val f: ('a -&gt; 'a) -&gt; unit end = S</programlisting>\r
9294<simpara>MLton reports the following errors.</simpara>\r
9295<screen>Error: z.sml 2.4-2.30.\r
9296 Variable in structure disagrees with signature (type): f.\r
9297 structure: val f: [&lt;equality&gt;] -&gt; _\r
9298 defn at: z.sml 1.25-1.25\r
9299 signature: val f: [real] -&gt; _\r
9300 spec at: z.sml 2.12-2.12\r
9301Error: z.sml 5.4-5.36.\r
9302 Variable in structure disagrees with signature (type): f.\r
9303 structure: val f: [&lt;equality&gt;] -&gt; _\r
9304 defn at: z.sml 4.25-4.25\r
9305 signature: val f: [_ -&gt; _] -&gt; _\r
9306 spec at: z.sml 5.12-5.12</screen>\r
9307<section id="_equality_type_variables_in_type_and_datatype_declarations">\r
9308<title>Equality type variables in type and datatype declarations</title>\r
9309<simpara>Equality type variables can be used in type and datatype declarations;\r
9310however they play no special role. For example,</simpara>\r
9311<programlisting language="sml" linenumbering="unnumbered">type 'a t = 'a * int</programlisting>\r
9312<simpara>is completely identical to</simpara>\r
9313<programlisting language="sml" linenumbering="unnumbered">type ''a t = ''a * int</programlisting>\r
9314<simpara>In particular, such a definition does <emphasis>not</emphasis> require that <literal>t</literal> only be\r
9315applied to equality types.</simpara>\r
9316<simpara>Similarly,</simpara>\r
9317<programlisting language="sml" linenumbering="unnumbered">datatype 'a t = A | B of 'a</programlisting>\r
9318<simpara>is completely identical to</simpara>\r
9319<programlisting language="sml" linenumbering="unnumbered">datatype ''a t = A | B of ''a</programlisting>\r
9320<simpara><?asciidoc-pagebreak?></simpara>\r
9321</section>\r
9322</section>\r
9323<section id="EtaExpansion">\r
9324<title>EtaExpansion</title>\r
9325<simpara>Eta expansion is a simple syntactic change used to work around the\r
9326<link linkend="ValueRestriction">ValueRestriction</link> in <link linkend="StandardML">Standard ML</link>.</simpara>\r
9327<simpara>The eta expansion of an expression <literal>e</literal> is the expression\r
9328<literal>fn z =&gt; e z</literal>, where <literal>z</literal> does not occur in <literal>e</literal>. This only\r
9329makes sense if <literal>e</literal> denotes a function, i.e. is of arrow type. Eta\r
9330expansion delays the evaluation of <literal>e</literal> until the function is\r
9331applied, and will re-evaluate <literal>e</literal> each time the function is\r
9332applied.</simpara>\r
9333<simpara>The name "eta expansion" comes from the eta-conversion rule of the\r
9334<link linkend="LambdaCalculus">lambda calculus</link>. Expansion refers to the\r
9335directionality of the equivalence being used, namely taking <literal>e</literal> to\r
9336<literal>fn z =&gt; e z</literal> rather than <literal>fn z =&gt; e z</literal> to <literal>e</literal> (eta\r
9337contraction).</simpara>\r
9338<simpara><?asciidoc-pagebreak?></simpara>\r
9339</section>\r
9340<section id="eXene">\r
9341<title>eXene</title>\r
9342<simpara><ulink url="http://people.cs.uchicago.edu/%7Ejhr/eXene/index.html">eXene</ulink> is a\r
9343multi-threaded X Window System toolkit written in <link linkend="ConcurrentML">ConcurrentML</link>.</simpara>\r
9344<simpara>There is a group at K-State working toward\r
9345<ulink url="http://www.cis.ksu.edu/%7Estough/eXene/">eXene 2.0</ulink>.</simpara>\r
9346<simpara><?asciidoc-pagebreak?></simpara>\r
9347</section>\r
9348<section id="FAQ">\r
9349<title>FAQ</title>\r
9350<simpara>Feel free to ask questions and to update answers by editing this page.\r
9351Since we try to make as much information as possible available on the\r
9352web site and we like to avoid duplication, many of the answers are\r
9353simply links to a web page that answers the question.</simpara>\r
9354<section id="_how_do_you_pronounce_mlton">\r
9355<title>How do you pronounce MLton?</title>\r
9356<simpara><link linkend="Pronounce">Pronounce</link></simpara>\r
9357</section>\r
9358<section id="_what_sml_software_has_been_ported_to_mlton">\r
9359<title>What SML software has been ported to MLton?</title>\r
9360<simpara><link linkend="Libraries">Libraries</link></simpara>\r
9361</section>\r
9362<section id="_what_graphical_libraries_are_available_for_mlton">\r
9363<title>What graphical libraries are available for MLton?</title>\r
9364<simpara><link linkend="Libraries">Libraries</link></simpara>\r
9365</section>\r
9366<section id="_how_does_mlton_8217_s_performance_compare_to_other_sml_compilers_and_to_other_languages">\r
9367<title>How does MLton&#8217;s performance compare to other SML compilers and to other languages?</title>\r
9368<simpara>MLton has <link linkend="Performance">excellent performance</link>.</simpara>\r
9369</section>\r
9370<section id="_does_mlton_treat_monomorphic_arrays_and_vectors_specially">\r
9371<title>Does MLton treat monomorphic arrays and vectors specially?</title>\r
9372<simpara>MLton implements monomorphic arrays and vectors (e.g. <literal>BoolArray</literal>,\r
9373<literal>Word8Vector</literal>) exactly as instantiations of their polymorphic\r
9374counterpart (e.g. <literal>bool array</literal>, <literal>Word8.word vector</literal>). Thus, there is\r
9375no need to use the monomorphic versions except when required to\r
9376interface with the <link linkend="BasisLibrary">Basis Library</link> or for portability\r
9377with other SML implementations.</simpara>\r
9378</section>\r
9379<section id="_why_do_i_get_a_segfault_bus_error_in_a_program_that_uses_literal_intinf_literal_literal_largeint_literal_to_calculate_numbers_with_several_hundred_thousand_digits">\r
9380<title>Why do I get a Segfault/Bus error in a program that uses <literal>IntInf</literal>/<literal>LargeInt</literal> to calculate numbers with several hundred thousand digits?</title>\r
9381<simpara><link linkend="GnuMP">GnuMP</link></simpara>\r
9382</section>\r
9383<section id="_how_can_i_decrease_compile_time_memory_usage">\r
9384<title>How can I decrease compile-time memory usage?</title>\r
9385<itemizedlist>\r
9386<listitem>\r
9387<simpara>\r
9388Compile with <literal>-verbose 3</literal> to find out if the problem is due to an\r
9389SSA optimization pass. If so, compile with <literal>-disable-pass <emphasis>pass</emphasis></literal> to\r
9390skip that pass.\r
9391</simpara>\r
9392</listitem>\r
9393<listitem>\r
9394<simpara>\r
9395Compile with <literal>@MLton hash-cons 0.5 --</literal>, which will instruct the\r
9396runtime to hash cons the heap every other GC.\r
9397</simpara>\r
9398</listitem>\r
9399<listitem>\r
9400<simpara>\r
9401Compile with <literal>-polyvariance false</literal>, which is an undocumented option\r
9402that causes less code duplication.\r
9403</simpara>\r
9404</listitem>\r
9405</itemizedlist>\r
9406<simpara>Also, please <link linkend="Contact">Contact</link> us to let us know the problem to help us\r
9407better understand MLton&#8217;s limitations.</simpara>\r
9408</section>\r
9409<section id="_how_portable_is_sml_code_across_sml_compilers">\r
9410<title>How portable is SML code across SML compilers?</title>\r
9411<simpara><link linkend="StandardMLPortability">StandardMLPortability</link></simpara>\r
9412<simpara><?asciidoc-pagebreak?></simpara>\r
9413</section>\r
9414</section>\r
9415<section id="Features">\r
9416<title>Features</title>\r
9417<simpara>MLton has the following features.</simpara>\r
9418<section id="_portability">\r
9419<title>Portability</title>\r
9420<itemizedlist>\r
9421<listitem>\r
9422<simpara>\r
9423Runs on a variety of platforms.\r
9424</simpara>\r
9425<itemizedlist>\r
9426<listitem>\r
9427<simpara>\r
9428<link linkend="RunningOnARM">ARM</link>:\r
9429</simpara>\r
9430<itemizedlist>\r
9431<listitem>\r
9432<simpara>\r
9433<link linkend="RunningOnLinux">Linux</link> (Debian)\r
9434</simpara>\r
9435</listitem>\r
9436</itemizedlist>\r
9437</listitem>\r
9438<listitem>\r
9439<simpara>\r
9440<link linkend="RunningOnAlpha">Alpha</link>:\r
9441</simpara>\r
9442<itemizedlist>\r
9443<listitem>\r
9444<simpara>\r
9445<link linkend="RunningOnLinux">Linux</link> (Debian)\r
9446</simpara>\r
9447</listitem>\r
9448</itemizedlist>\r
9449</listitem>\r
9450<listitem>\r
9451<simpara>\r
9452<link linkend="RunningOnAMD64">AMD64</link>:\r
9453</simpara>\r
9454<itemizedlist>\r
9455<listitem>\r
9456<simpara>\r
9457<link linkend="RunningOnDarwin">Darwin</link> (Mac OS X)\r
9458</simpara>\r
9459</listitem>\r
9460<listitem>\r
9461<simpara>\r
9462<link linkend="RunningOnFreeBSD">FreeBSD</link>\r
9463</simpara>\r
9464</listitem>\r
9465<listitem>\r
9466<simpara>\r
9467<link linkend="RunningOnLinux">Linux</link> (Debian, Fedora, Ubuntu, &#8230;)\r
9468</simpara>\r
9469</listitem>\r
9470<listitem>\r
9471<simpara>\r
9472<link linkend="RunningOnOpenBSD">OpenBSD</link>\r
9473</simpara>\r
9474</listitem>\r
9475<listitem>\r
9476<simpara>\r
9477<link linkend="RunningOnSolaris">Solaris</link> (10 and above)\r
9478</simpara>\r
9479</listitem>\r
9480</itemizedlist>\r
9481</listitem>\r
9482<listitem>\r
9483<simpara>\r
9484<link linkend="RunningOnHPPA">HPPA</link>:\r
9485</simpara>\r
9486<itemizedlist>\r
9487<listitem>\r
9488<simpara>\r
9489<link linkend="RunningOnHPUX">HPUX</link> (11.11 and above)\r
9490</simpara>\r
9491</listitem>\r
9492<listitem>\r
9493<simpara>\r
9494<link linkend="RunningOnLinux">Linux</link> (Debian)\r
9495</simpara>\r
9496</listitem>\r
9497</itemizedlist>\r
9498</listitem>\r
9499<listitem>\r
9500<simpara>\r
9501<link linkend="RunningOnIA64">IA64</link>:\r
9502</simpara>\r
9503<itemizedlist>\r
9504<listitem>\r
9505<simpara>\r
9506<link linkend="RunningOnHPUX">HPUX</link> (11.11 and above)\r
9507</simpara>\r
9508</listitem>\r
9509<listitem>\r
9510<simpara>\r
9511<link linkend="RunningOnLinux">Linux</link> (Debian)\r
9512</simpara>\r
9513</listitem>\r
9514</itemizedlist>\r
9515</listitem>\r
9516<listitem>\r
9517<simpara>\r
9518<link linkend="RunningOnPowerPC">PowerPC</link>:\r
9519</simpara>\r
9520<itemizedlist>\r
9521<listitem>\r
9522<simpara>\r
9523<link linkend="RunningOnAIX">AIX</link> (5.2 and above)\r
9524</simpara>\r
9525</listitem>\r
9526<listitem>\r
9527<simpara>\r
9528<link linkend="RunningOnDarwin">Darwin</link> (Mac OS X)\r
9529</simpara>\r
9530</listitem>\r
9531<listitem>\r
9532<simpara>\r
9533<link linkend="RunningOnLinux">Linux</link> (Debian, Fedora, &#8230;)\r
9534</simpara>\r
9535</listitem>\r
9536</itemizedlist>\r
9537</listitem>\r
9538<listitem>\r
9539<simpara>\r
9540<link linkend="RunningOnPowerPC64">PowerPC64</link>:\r
9541</simpara>\r
9542<itemizedlist>\r
9543<listitem>\r
9544<simpara>\r
9545<link linkend="RunningOnAIX">AIX</link> (5.2 and above)\r
9546</simpara>\r
9547</listitem>\r
9548</itemizedlist>\r
9549</listitem>\r
9550<listitem>\r
9551<simpara>\r
9552<link linkend="RunningOnS390">S390</link>\r
9553</simpara>\r
9554<itemizedlist>\r
9555<listitem>\r
9556<simpara>\r
9557<link linkend="RunningOnLinux">Linux</link> (Debian)\r
9558</simpara>\r
9559</listitem>\r
9560</itemizedlist>\r
9561</listitem>\r
9562<listitem>\r
9563<simpara>\r
9564<link linkend="RunningOnSparc">Sparc</link>\r
9565</simpara>\r
9566<itemizedlist>\r
9567<listitem>\r
9568<simpara>\r
9569<link linkend="RunningOnLinux">Linux</link> (Debian)\r
9570</simpara>\r
9571</listitem>\r
9572<listitem>\r
9573<simpara>\r
9574<link linkend="RunningOnSolaris">Solaris</link> (8 and above)\r
9575</simpara>\r
9576</listitem>\r
9577</itemizedlist>\r
9578</listitem>\r
9579<listitem>\r
9580<simpara>\r
9581<link linkend="RunningOnX86">X86</link>:\r
9582</simpara>\r
9583<itemizedlist>\r
9584<listitem>\r
9585<simpara>\r
9586<link linkend="RunningOnCygwin">Cygwin</link>/Windows\r
9587</simpara>\r
9588</listitem>\r
9589<listitem>\r
9590<simpara>\r
9591<link linkend="RunningOnDarwin">Darwin</link> (Mac OS X)\r
9592</simpara>\r
9593</listitem>\r
9594<listitem>\r
9595<simpara>\r
9596<link linkend="RunningOnFreeBSD">FreeBSD</link>\r
9597</simpara>\r
9598</listitem>\r
9599<listitem>\r
9600<simpara>\r
9601<link linkend="RunningOnLinux">Linux</link> (Debian, Fedora, Ubuntu, &#8230;)\r
9602</simpara>\r
9603</listitem>\r
9604<listitem>\r
9605<simpara>\r
9606<link linkend="RunningOnMinGW">MinGW</link>/Windows\r
9607</simpara>\r
9608</listitem>\r
9609<listitem>\r
9610<simpara>\r
9611<link linkend="RunningOnNetBSD">NetBSD</link>\r
9612</simpara>\r
9613</listitem>\r
9614<listitem>\r
9615<simpara>\r
9616<link linkend="RunningOnOpenBSD">OpenBSD</link>\r
9617</simpara>\r
9618</listitem>\r
9619<listitem>\r
9620<simpara>\r
9621<link linkend="RunningOnSolaris">Solaris</link> (10 and above)\r
9622</simpara>\r
9623</listitem>\r
9624</itemizedlist>\r
9625</listitem>\r
9626</itemizedlist>\r
9627</listitem>\r
9628</itemizedlist>\r
9629</section>\r
9630<section id="_robustness">\r
9631<title>Robustness</title>\r
9632<itemizedlist>\r
9633<listitem>\r
9634<simpara>\r
9635Supports the full SML 97 language as given in <link linkend="DefinitionOfStandardML">The Definition of Standard ML (Revised)</link>.\r
9636</simpara>\r
9637<simpara>If there is a program that is valid according to the\r
9638<link linkend="DefinitionOfStandardML">Definition</link> that is rejected by MLton, or a\r
9639program that is invalid according to the\r
9640<link linkend="DefinitionOfStandardML">Definition</link> that is accepted by MLton, it is\r
9641a bug. For a list of known bugs, see <link linkend="UnresolvedBugs">UnresolvedBugs</link>.</simpara>\r
9642</listitem>\r
9643<listitem>\r
9644<simpara>\r
9645A complete implementation of the <link linkend="BasisLibrary">Basis Library</link>.\r
9646</simpara>\r
9647<simpara>MLton&#8217;s implementation matches latest <link linkend="BasisLibrary">Basis Library</link>\r
9648<ulink url="http://www.standardml.org/Basis">specification</ulink>, and includes a\r
9649complete implementation of all the required modules, as well as many\r
9650of the optional modules.</simpara>\r
9651</listitem>\r
9652<listitem>\r
9653<simpara>\r
9654Generates standalone executables.\r
9655</simpara>\r
9656<simpara>No additional code or libraries are necessary in order to run an\r
9657executable, except for the standard shared libraries. MLton can also\r
9658generate statically linked executables.</simpara>\r
9659</listitem>\r
9660<listitem>\r
9661<simpara>\r
9662Compiles large programs.\r
9663</simpara>\r
9664<simpara>MLton is sufficiently efficient and robust that it can compile large\r
9665programs, including itself (over 190K lines). The distributed version\r
9666of MLton was compiled by MLton.</simpara>\r
9667</listitem>\r
9668<listitem>\r
9669<simpara>\r
9670Support for large amounts of memory (up to 4G on 32-bit systems; more on 64-bit systems).\r
9671</simpara>\r
9672</listitem>\r
9673<listitem>\r
9674<simpara>\r
9675Support for large array lengths (up to 2<superscript>31</superscript>-1 on 32-bit systems; up to 2<superscript>63</superscript>-1 on 64-bit systems).\r
9676</simpara>\r
9677</listitem>\r
9678<listitem>\r
9679<simpara>\r
9680Support for large files, using 64-bit file positions.\r
9681</simpara>\r
9682</listitem>\r
9683</itemizedlist>\r
9684</section>\r
9685<section id="_performance">\r
9686<title>Performance</title>\r
9687<itemizedlist>\r
9688<listitem>\r
9689<simpara>\r
9690Executables have <link linkend="Performance">excellent running times</link>.\r
9691</simpara>\r
9692</listitem>\r
9693<listitem>\r
9694<simpara>\r
9695Generates small executables.\r
9696</simpara>\r
9697<simpara>MLton takes advantage of whole-program compilation to perform very\r
9698aggressive dead-code elimination, which often leads to smaller\r
9699executables than with other SML compilers.</simpara>\r
9700</listitem>\r
9701<listitem>\r
9702<simpara>\r
9703Untagged and unboxed native integers, reals, and words.\r
9704</simpara>\r
9705<simpara>In MLton, integers and words are 8 bits, 16 bits, 32 bits, and 64 bits\r
9706and arithmetic does not have any overhead due to tagging or boxing.\r
9707Also, reals (32-bit and 64-bit) are stored unboxed, avoiding any\r
9708overhead due to boxing.</simpara>\r
9709</listitem>\r
9710<listitem>\r
9711<simpara>\r
9712Unboxed native arrays.\r
9713</simpara>\r
9714<simpara>In MLton, an array (or vector) of integers, reals, or words uses the\r
9715natural C-like representation. This is fast and supports easy\r
9716exchange of data with C. Monomorphic arrays (and vectors) use the\r
9717same C-like representations as their polymorphic counterparts.</simpara>\r
9718</listitem>\r
9719<listitem>\r
9720<simpara>\r
9721Multiple <link linkend="GarbageCollection">garbage collection</link> strategies.\r
9722</simpara>\r
9723</listitem>\r
9724<listitem>\r
9725<simpara>\r
9726Fast arbitrary precision arithmetic (<literal>IntInf</literal>) based on <link linkend="GnuMP">GnuMP</link>.\r
9727</simpara>\r
9728<simpara>For <literal>IntInf</literal> intensive programs, MLton can be an order of magnitude or\r
9729more faster than Poly/ML or SML/NJ.</simpara>\r
9730</listitem>\r
9731</itemizedlist>\r
9732</section>\r
9733<section id="_tools">\r
9734<title>Tools</title>\r
9735<itemizedlist>\r
9736<listitem>\r
9737<simpara>\r
9738Source-level <link linkend="Profiling">Profiling</link> of both time and allocation.\r
9739</simpara>\r
9740</listitem>\r
9741<listitem>\r
9742<simpara>\r
9743<link linkend="MLLex">MLLex</link> lexer generator\r
9744</simpara>\r
9745</listitem>\r
9746<listitem>\r
9747<simpara>\r
9748<link linkend="MLYacc">MLYacc</link> parser generator\r
9749</simpara>\r
9750</listitem>\r
9751<listitem>\r
9752<simpara>\r
9753<link linkend="MLNLFFIGen">MLNLFFIGen</link> foreign-function-interface generator\r
9754</simpara>\r
9755</listitem>\r
9756</itemizedlist>\r
9757</section>\r
9758<section id="_extensions">\r
9759<title>Extensions</title>\r
9760<itemizedlist>\r
9761<listitem>\r
9762<simpara>\r
9763A simple and fast C <link linkend="ForeignFunctionInterface">ForeignFunctionInterface</link> that supports calling from SML to C and from C to SML.\r
9764</simpara>\r
9765</listitem>\r
9766<listitem>\r
9767<simpara>\r
9768The <link linkend="MLBasis">ML Basis system</link> for programming in the very large, separate delivery of library sources, and more.\r
9769</simpara>\r
9770</listitem>\r
9771<listitem>\r
9772<simpara>\r
9773A number of extension libraries that provide useful functionality\r
9774that cannot be implemented with the <link linkend="BasisLibrary">Basis Library</link>.\r
9775See below for an overview and <link linkend="MLtonStructure">MLtonStructure</link> for details.\r
9776</simpara>\r
9777<itemizedlist>\r
9778<listitem>\r
9779<simpara>\r
9780<link linkend="MLtonCont">continuations</link>\r
9781</simpara>\r
9782<simpara>MLton supports continuations via <literal>callcc</literal> and <literal>throw</literal>.</simpara>\r
9783</listitem>\r
9784<listitem>\r
9785<simpara>\r
9786<link linkend="MLtonFinalizable">finalization</link>\r
9787</simpara>\r
9788<simpara>MLton supports finalizable values of arbitrary type.</simpara>\r
9789</listitem>\r
9790<listitem>\r
9791<simpara>\r
9792<link linkend="MLtonItimer">interval timers</link>\r
9793</simpara>\r
9794<simpara>MLton supports the functionality of the C <literal>setitimer</literal> function.</simpara>\r
9795</listitem>\r
9796<listitem>\r
9797<simpara>\r
9798<link linkend="MLtonRandom">random numbers</link>\r
9799</simpara>\r
9800<simpara>MLton has functions similar to the C <literal>rand</literal> and <literal>srand</literal> functions, as well as support for access to <literal>/dev/random</literal> and <literal>/dev/urandom</literal>.</simpara>\r
9801</listitem>\r
9802<listitem>\r
9803<simpara>\r
9804<link linkend="MLtonRlimit">resource limits</link>\r
9805</simpara>\r
9806<simpara>MLton has functions similar to the C <literal>getrlimit</literal> and <literal>setrlimit</literal> functions.</simpara>\r
9807</listitem>\r
9808<listitem>\r
9809<simpara>\r
9810<link linkend="MLtonRusage">resource usage</link>\r
9811</simpara>\r
9812<simpara>MLton supports a subset of the functionality of the C <literal>getrusage</literal> function.</simpara>\r
9813</listitem>\r
9814<listitem>\r
9815<simpara>\r
9816<link linkend="MLtonSignal">signal handlers</link>\r
9817</simpara>\r
9818<simpara>MLton supports signal handlers written in SML. Signal handlers run in\r
9819a separate MLton thread, and have access to the thread that was\r
9820interrupted by the signal. Signal handlers can be used in conjunction\r
9821with threads to implement preemptive multitasking.</simpara>\r
9822</listitem>\r
9823<listitem>\r
9824<simpara>\r
9825<link linkend="MLtonStructure">size primitive</link>\r
9826</simpara>\r
9827<simpara>MLton includes a primitive that returns the size (in bytes) of any\r
9828object. This can be useful in understanding the space behavior of a\r
9829program.</simpara>\r
9830</listitem>\r
9831<listitem>\r
9832<simpara>\r
9833<link linkend="MLtonSyslog">system logging</link>\r
9834</simpara>\r
9835<simpara>MLton has a complete interface to the C <literal>syslog</literal> function.</simpara>\r
9836</listitem>\r
9837<listitem>\r
9838<simpara>\r
9839<link linkend="MLtonThread">threads</link>\r
9840</simpara>\r
9841<simpara>MLton has support for its own threads, upon which either preemptive or\r
9842non-preemptive multitasking can be implemented. MLton also has\r
9843support for <link linkend="ConcurrentML">Concurrent ML</link> (CML).</simpara>\r
9844</listitem>\r
9845<listitem>\r
9846<simpara>\r
9847<link linkend="MLtonWeak">weak pointers</link>\r
9848</simpara>\r
9849<simpara>MLton supports weak pointers, which allow the garbage collector to\r
9850reclaim objects that it would otherwise be forced to keep. Weak\r
9851pointers are also used to provide finalization.</simpara>\r
9852</listitem>\r
9853<listitem>\r
9854<simpara>\r
9855<link linkend="MLtonWorld">world save and restore</link>\r
9856</simpara>\r
9857<simpara>MLton has a facility for saving the entire state of a computation to a\r
9858file and restarting it later. This facility can be used for staging\r
9859and for checkpointing computations. It can even be used from within\r
9860signal handlers, allowing interrupt driven checkpointing.</simpara>\r
9861</listitem>\r
9862</itemizedlist>\r
9863</listitem>\r
9864</itemizedlist>\r
9865<simpara><?asciidoc-pagebreak?></simpara>\r
9866</section>\r
9867</section>\r
9868<section id="FirstClassPolymorphism">\r
9869<title>FirstClassPolymorphism</title>\r
9870<simpara>First-class polymorphism is the ability to treat polymorphic functions\r
9871just like other values: pass them as arguments, store them in data\r
9872structures, etc. Although <link linkend="StandardML">Standard ML</link> does have\r
9873polymorphic functions, it does not support first-class polymorphism.</simpara>\r
9874<simpara>For example, the following declares and uses the polymorphic function\r
9875<literal>id</literal>.</simpara>\r
9876<programlisting language="sml" linenumbering="unnumbered">val id = fn x =&gt; x\r
9877val _ = id 13\r
9878val _ = id "foo"</programlisting>\r
9879<simpara>If SML supported first-class polymorphism, we could write the\r
9880following.</simpara>\r
9881<programlisting language="sml" linenumbering="unnumbered">fun useId id = (id 13; id "foo")</programlisting>\r
9882<simpara>However, this does not type check. MLton reports the following error.</simpara>\r
9883<screen>Error: z.sml 1.24-1.31.\r
9884 Function applied to incorrect argument.\r
9885 expects: [int]\r
9886 but got: [string]\r
9887 in: id "foo"</screen>\r
9888<simpara>The error message arises because MLton infers from <literal>id 13</literal> that <literal>id</literal>\r
9889accepts an integer argument, but that <literal>id "foo"</literal> is passing a string.</simpara>\r
9890<simpara>Using explicit types sheds some light on the problem.</simpara>\r
9891<programlisting language="sml" linenumbering="unnumbered">fun useId (id: 'a -&gt; 'a) = (id 13; id "foo")</programlisting>\r
9892<simpara>On this, MLton reports the following errors.</simpara>\r
9893<screen>Error: z.sml 1.29-1.33.\r
9894 Function applied to incorrect argument.\r
9895 expects: ['a]\r
9896 but got: [int]\r
9897 in: id 13\r
9898Error: z.sml 1.36-1.43.\r
9899 Function applied to incorrect argument.\r
9900 expects: ['a]\r
9901 but got: [string]\r
9902 in: id "foo"</screen>\r
9903<simpara>The errors arise because the argument <literal>id</literal> is <emphasis>not</emphasis> polymorphic;\r
9904rather, it is monomorphic, with type <literal>'a -&gt; 'a</literal>. It is perfectly\r
9905valid to apply <literal>id</literal> to a value of type <literal>'a</literal>, as in the following</simpara>\r
9906<programlisting language="sml" linenumbering="unnumbered">fun useId (id: 'a -&gt; 'a, x: 'a) = id x (* type correct *)</programlisting>\r
9907<simpara>So, what is the difference between the type specification on <literal>id</literal> in\r
9908the following two declarations?</simpara>\r
9909<programlisting language="sml" linenumbering="unnumbered">val id: 'a -&gt; 'a = fn x =&gt; x\r
9910fun useId (id: 'a -&gt; 'a) = (id 13; id "foo")</programlisting>\r
9911<simpara>While the type specifications on <literal>id</literal> look identical, they mean\r
9912different things. The difference can be made clearer by explicitly\r
9913<link linkend="TypeVariableScope">scoping the type variables</link>.</simpara>\r
9914<programlisting language="sml" linenumbering="unnumbered">val 'a id: 'a -&gt; 'a = fn x =&gt; x\r
9915fun 'a useId (id: 'a -&gt; 'a) = (id 13; id "foo") (* type error *)</programlisting>\r
9916<simpara>In <literal>val 'a id</literal>, the type variable scoping means that for any <literal>'a</literal>,\r
9917<literal>id</literal> has type <literal>'a -&gt; 'a</literal>. Hence, <literal>id</literal> can be applied to arguments of\r
9918type <literal>int</literal>, <literal>real</literal>, etc. Similarly, in <literal>fun 'a useId</literal>, the scoping\r
9919means that <literal>useId</literal> is a polymorphic function that for any <literal>'a</literal> takes a\r
9920function of type <literal>'a -&gt; 'a</literal> and does something. Thus, <literal>useId</literal> could\r
9921be applied to a function of type <literal>int -&gt; int</literal>, <literal>real -&gt; real</literal>, etc.</simpara>\r
9922<simpara>One could imagine an extension of SML that allowed scoping of type\r
9923variables at places other than <literal>fun</literal> or <literal>val</literal> declarations, as in the\r
9924following.</simpara>\r
9925<screen>fun useId (id: ('a).'a -&gt; 'a) = (id 13; id "foo") (* not SML *)</screen>\r
9926<simpara>Such an extension would need to be thought through very carefully, as\r
9927it could cause significant complications with <link linkend="TypeInference">TypeInference</link>,\r
9928possible even undecidability.</simpara>\r
9929<simpara><?asciidoc-pagebreak?></simpara>\r
9930</section>\r
9931<section id="Fixpoints">\r
9932<title>Fixpoints</title>\r
9933<simpara>This page discusses a framework that makes it possible to compute\r
9934fixpoints over arbitrary products of abstract types. The code is from\r
9935an Extended Basis library\r
9936(<ulink url="https://github.com/MLton/mltonlib/blob/master/com/ssh/extended-basis/unstable/README"><literal>README</literal></ulink>).</simpara>\r
9937<simpara>First the signature of the framework\r
9938(<ulink url="https://github.com/MLton/mltonlib/blob/master/com/ssh/extended-basis/unstable/public/generic/tie.sig"><literal>tie.sig</literal></ulink>):</simpara>\r
9939<programlisting language="sml" linenumbering="unnumbered">(**\r
9940 * A framework for computing fixpoints.\r
9941 *\r
9942 * In a strict language you sometimes want to provide a fixpoint\r
9943 * combinator for an abstract type {t} to make it possible to write\r
9944 * recursive definitions. Unfortunately, a single combinator {fix} of the\r
9945 * type {(t -&gt; t) -&gt; t} does not support mutual recursion. To support\r
9946 * mutual recursion, you would need to provide a family of fixpoint\r
9947 * combinators having types of the form {(u -&gt; u) -&gt; u} where {u} is a\r
9948 * type of the form {t * ... * t}. Unfortunately, even such a family of\r
9949 * fixpoint combinators does not support mutual recursion over different\r
9950 * abstract types.\r
9951 *)\r
9952signature TIE = sig\r
9953 include ETAEXP'\r
9954 type 'a t = 'a etaexp\r
9955 (** The type of fixpoint witnesses. *)\r
9956\r
9957 val fix : 'a t -&gt; 'a Fix.t\r
9958 (**\r
9959 * Produces a fixpoint combinator from the given witness. For example,\r
9960 * one can make a mutually recursive definition of functions:\r
9961 *\r
9962 *&gt; val isEven &amp; isOdd =\r
9963 *&gt; let open Tie in fix (function *` function) end\r
9964 *&gt; (fn isEven &amp; isOdd =&gt;\r
9965 *&gt; (fn 0 =&gt; true\r
9966 *&gt; | 1 =&gt; false\r
9967 *&gt; | n =&gt; isOdd (n-1)) &amp;\r
9968 *&gt; (fn 0 =&gt; false\r
9969 *&gt; | 1 =&gt; true\r
9970 *&gt; | n =&gt; isEven (n-1)))\r
9971 *)\r
9972\r
9973 (** == Making New Witnesses == *)\r
9974\r
9975 val pure : ('a * 'a UnOp.t) Thunk.t -&gt; 'a t\r
9976 (**\r
9977 * {pure} is a more general version of {tier}. It is mostly useful for\r
9978 * computing fixpoints in a non-imperative manner.\r
9979 *)\r
9980\r
9981 val tier : ('a * 'a Effect.t) Thunk.t -&gt; 'a t\r
9982 (**\r
9983 * {tier} is used to define fixpoint witnesses for new abstract types\r
9984 * by providing a thunk whose instantiation allocates a mutable proxy\r
9985 * and a procedure for updating it with the result.\r
9986 *)\r
9987\r
9988 val id : 'a -&gt; 'a t\r
9989 (** {id x} is equivalent to {pure (const (x, id))}. *)\r
9990\r
9991 (** == Combining Existing Witnesses == *)\r
9992\r
9993 val iso : 'b t -&gt; ('a, 'b) Iso.t -&gt; 'a t\r
9994 (**\r
9995 * Given an isomorphism between {'a} and {'b} and a witness for {'b},\r
9996 * produces a witness for {'a}. This is useful when you have a new\r
9997 * type that is isomorphic to some old type for which you already have\r
9998 * a witness.\r
9999 *)\r
10000\r
10001 val product : 'a t * ('a -&gt; 'b t) -&gt; ('a, 'b) Product.t t\r
10002 (**\r
10003 * Dependent product combinator. Given a witness for {'a} and a\r
10004 * constructor from a {'a} to witness for {'b}, produces a witness for\r
10005 * the product {('a, 'b) Product.t}. The constructor for {'b} should\r
10006 * not access the (proxy) value {'a} before it has been fixed.\r
10007 *)\r
10008\r
10009 val *` : 'a t * 'b t -&gt; ('a, 'b) Product.t t\r
10010 (** {a *` b} is equivalent to {product (a, const b)}. *)\r
10011\r
10012 val tuple2 : 'a t * 'b t -&gt; ('a * 'b) t\r
10013 (**\r
10014 * Given witnesses for {'a} and {'b} produces a witness for the product\r
10015 * {'a * 'b}.\r
10016 *)\r
10017\r
10018 (** == Particular Witnesses == *)\r
10019\r
10020 val function : ('a -&gt; 'b) t\r
10021 (** Witness for functions. *)\r
10022end</programlisting>\r
10023<simpara><literal>fix</literal> is a <link linkend="TypeIndexedValues">type-indexed</link> function. The type-index\r
10024parameter to <literal>fix</literal> is called a "witness". To compute fixpoints over\r
10025products, one uses the <literal>*&grave;</literal> operator to combine witnesses. To provide\r
10026a fixpoint combinator for an abstract type, one implements a witness\r
10027providing a thunk whose instantiation allocates a fresh, mutable proxy\r
10028and a procedure for updating the proxy with the solution. Naturally\r
10029this means that not all possible ways of computing a fixpoint of a\r
10030particular type are possible under the framework. The <literal>pure</literal>\r
10031combinator is a generalization of <literal>tier</literal>. The <literal>iso</literal> combinator is\r
10032provided for reusing existing witnesses.</simpara>\r
10033<simpara>Note that instead of using an infix operator, we could alternatively\r
10034employ an interface using <link linkend="Fold">Fold</link>. Also, witnesses are eta-expanded\r
10035to work around the <link linkend="ValueRestriction">value restriction</link>, while\r
10036maintaining abstraction.</simpara>\r
10037<simpara>Here is the implementation\r
10038(<ulink url="https://github.com/MLton/mltonlib/blob/master/com/ssh/extended-basis/unstable/detail/generic/tie.sml"><literal>tie.sml</literal></ulink>):</simpara>\r
10039<programlisting language="sml" linenumbering="unnumbered">structure Tie :&gt; TIE = struct\r
10040 open Product\r
10041 infix &amp;\r
10042 type 'a etaexp_dom = Unit.t\r
10043 type 'a etaexp_cod = ('a * 'a UnOp.t) Thunk.t\r
10044 type 'a etaexp = 'a etaexp_dom -&gt; 'a etaexp_cod\r
10045 type 'a t = 'a etaexp\r
10046 fun fix aT f = let val (a, ta) = aT () () in ta (f a) end\r
10047 val pure = Thunk.mk\r
10048 fun iso bT (iso as (_, b2a)) () () = let\r
10049 val (b, fB) = bT () ()\r
10050 in\r
10051 (b2a b, Fn.map iso fB)\r
10052 end\r
10053 fun product (aT, a2bT) () () = let\r
10054 val (a, fA) = aT () ()\r
10055 val (b, fB) = a2bT a () ()\r
10056 in\r
10057 (a &amp; b, Product.map (fA, fB))\r
10058 end\r
10059 (* The rest are not primitive operations. *)\r
10060 fun op *` (aT, bT) = product (aT, Fn.const bT)\r
10061 fun tuple2 ab = iso (op *` ab) Product.isoTuple2\r
10062 fun tier th = pure ((fn (a, ua) =&gt; (a, Fn.const a o ua)) o th)\r
10063 fun id x = pure (Fn.const (x, Fn.id))\r
10064 fun function ? =\r
10065 pure (fn () =&gt; let\r
10066 val r = ref (Basic.raising Fix.Fix)\r
10067 in\r
10068 (fn x =&gt; !r x, fn f =&gt; (r := f ; f))\r
10069 end) ?\r
10070end</programlisting>\r
10071<simpara>Let&#8217;s then take a look at a couple of additional examples.</simpara>\r
10072<simpara>Here is a naive implementation of lazy promises:</simpara>\r
10073<programlisting language="sml" linenumbering="unnumbered">structure Promise :&gt; sig\r
10074 type 'a t\r
10075 val lazy : 'a Thunk.t -&gt; 'a t\r
10076 val force : 'a t -&gt; 'a\r
10077 val Y : 'a t Tie.t\r
10078end = struct\r
10079 datatype 'a t' =\r
10080 EXN of exn\r
10081 | THUNK of 'a Thunk.t\r
10082 | VALUE of 'a\r
10083 type 'a t = 'a t' Ref.t\r
10084 fun lazy f = ref (THUNK f)\r
10085 fun force t =\r
10086 case !t\r
10087 of EXN e =&gt; raise e\r
10088 | THUNK f =&gt; (t := VALUE (f ()) handle e =&gt; t := EXN e ; force t)\r
10089 | VALUE v =&gt; v\r
10090 fun Y ? = Tie.tier (fn () =&gt; let\r
10091 val r = lazy (raising Fix.Fix)\r
10092 in\r
10093 (r, r &lt;\ op := o !)\r
10094 end) ?\r
10095end</programlisting>\r
10096<simpara>An example use of our naive lazy promises is to implement equally naive\r
10097lazy streams:</simpara>\r
10098<programlisting language="sml" linenumbering="unnumbered">structure Stream :&gt; sig\r
10099 type 'a t\r
10100 val cons : 'a * 'a t -&gt; 'a t\r
10101 val get : 'a t -&gt; ('a * 'a t) Option.t\r
10102 val Y : 'a t Tie.t\r
10103end = struct\r
10104 datatype 'a t = IN of ('a * 'a t) Option.t Promise.t\r
10105 fun cons (x, xs) = IN (Promise.lazy (fn () =&gt; SOME (x, xs)))\r
10106 fun get (IN p) = Promise.force p\r
10107 fun Y ? = Tie.iso Promise.Y (fn IN p =&gt; p, IN) ?\r
10108end</programlisting>\r
10109<simpara>Note that above we make use of the <literal>iso</literal> combinator. Here is a finite\r
10110representation of an infinite stream of ones:</simpara>\r
10111<programlisting language="sml" linenumbering="unnumbered">val ones = let\r
10112 open Tie Stream\r
10113in\r
10114 fix Y (fn ones =&gt; cons (1, ones))\r
10115end</programlisting>\r
10116<simpara><?asciidoc-pagebreak?></simpara>\r
10117</section>\r
10118<section id="Flatten">\r
10119<title>Flatten</title>\r
10120<simpara><link linkend="Flatten">Flatten</link> is an optimization pass for the <link linkend="SSA">SSA</link>\r
10121<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="SSASimplify">SSASimplify</link>.</simpara>\r
10122<section id="_description_17">\r
10123<title>Description</title>\r
10124<simpara>This pass flattens arguments to <link linkend="SSA">SSA</link> constructors, blocks, and\r
10125functions.</simpara>\r
10126<simpara>If a tuple is explicitly available at all uses of a function\r
10127(resp. block), then:</simpara>\r
10128<itemizedlist>\r
10129<listitem>\r
10130<simpara>\r
10131The formals and call sites are changed so that the components of the\r
10132tuple are passed.\r
10133</simpara>\r
10134</listitem>\r
10135<listitem>\r
10136<simpara>\r
10137The tuple is reconstructed at the beginning of the body of the\r
10138function (resp. block).\r
10139</simpara>\r
10140</listitem>\r
10141</itemizedlist>\r
10142<simpara>Similarly, if a tuple is explicitly available at all uses of a\r
10143constructor, then:</simpara>\r
10144<itemizedlist>\r
10145<listitem>\r
10146<simpara>\r
10147The constructor argument datatype is changed to flatten the tuple\r
10148type.\r
10149</simpara>\r
10150</listitem>\r
10151<listitem>\r
10152<simpara>\r
10153The tuple is passed flat at each <literal>ConApp</literal>.\r
10154</simpara>\r
10155</listitem>\r
10156<listitem>\r
10157<simpara>\r
10158The tuple is reconstructed at each <literal>Case</literal> transfer target.\r
10159</simpara>\r
10160</listitem>\r
10161</itemizedlist>\r
10162</section>\r
10163<section id="_implementation_19">\r
10164<title>Implementation</title>\r
10165<itemizedlist>\r
10166<listitem>\r
10167<simpara>\r
10168<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/flatten.fun"><literal>flatten.fun</literal></ulink>\r
10169</simpara>\r
10170</listitem>\r
10171</itemizedlist>\r
10172</section>\r
10173<section id="_details_and_notes_19">\r
10174<title>Details and Notes</title>\r
10175<simpara></simpara>\r
10176<simpara><?asciidoc-pagebreak?></simpara>\r
10177</section>\r
10178</section>\r
10179<section id="Fold">\r
10180<title>Fold</title>\r
10181<simpara>This page describes a technique that enables convenient syntax for a\r
10182number of language features that are not explicitly supported by\r
10183<link linkend="StandardML">Standard ML</link>, including: variable number of arguments,\r
10184<link linkend="OptionalArguments">optional arguments and labeled arguments</link>,\r
10185<link linkend="ArrayLiteral">array and vector literals</link>,\r
10186<link linkend="FunctionalRecordUpdate">functional record update</link>,\r
10187and (seemingly) dependently typed functions like <link linkend="Printf">printf</link> and scanf.</simpara>\r
10188<simpara>The key idea to <emphasis>fold</emphasis> is to define functions <literal>fold</literal>, <literal>step0</literal>,\r
10189and <literal>$</literal> such that the following equation holds.</simpara>\r
10190<programlisting language="sml" linenumbering="unnumbered">fold (a, f) (step0 h1) (step0 h2) ... (step0 hn) $\r
10191= f (hn (... (h2 (h1 a))))</programlisting>\r
10192<simpara>The name <literal>fold</literal> comes because this is like a traditional list fold,\r
10193where <literal>a</literal> is the <emphasis>base element</emphasis>, and each <emphasis>step function</emphasis>,\r
10194<literal>step0 hi</literal>, corresponds to one element of the list and does one\r
10195step of the fold. The name <literal>$</literal> is chosen to mean "end of\r
10196arguments" from its common use in regular-expression syntax.</simpara>\r
10197<simpara>Unlike the usual list fold in which the same function is used to step\r
10198over each element in the list, this fold allows the step functions to\r
10199be different from each other, and even to be of different types. Also\r
10200unlike the usual list fold, this fold includes a "finishing\r
10201function", <literal>f</literal>, that is applied to the result of the fold. The\r
10202presence of the finishing function may seem odd because there is no\r
10203analogy in list fold. However, the finishing function is essential;\r
10204without it, there would be no way for the folder to perform an\r
10205arbitrary computation after processing all the arguments. The\r
10206examples below will make this clear.</simpara>\r
10207<simpara>The functions <literal>fold</literal>, <literal>step0</literal>, and <literal>$</literal> are easy to\r
10208define.</simpara>\r
10209<programlisting language="sml" linenumbering="unnumbered">fun $ (a, f) = f a\r
10210fun id x = x\r
10211structure Fold =\r
10212 struct\r
10213 fun fold (a, f) g = g (a, f)\r
10214 fun step0 h (a, f) = fold (h a, f)\r
10215 end</programlisting>\r
10216<simpara>We&#8217;ve placed <literal>fold</literal> and <literal>step0</literal> in the <literal>Fold</literal> structure\r
10217but left <literal>$</literal> at the toplevel because it is convenient in code to\r
10218always have <literal>$</literal> in scope. We&#8217;ve also defined the identity\r
10219function, <literal>id</literal>, at the toplevel since we use it so frequently.</simpara>\r
10220<simpara>Plugging in the definitions, it is easy to verify the equation from\r
10221above.</simpara>\r
10222<programlisting language="sml" linenumbering="unnumbered">fold (a, f) (step0 h1) (step0 h2) ... (step0 hn) $\r
10223= step0 h1 (a, f) (step0 h2) ... (step0 hn) $\r
10224= fold (h1 a, f) (step0 h2) ... (step0 hn) $\r
10225= step0 h2 (h1 a, f) ... (step0 hn) $\r
10226= fold (h2 (h1 a), f) ... (step0 hn) $\r
10227...\r
10228= fold (hn (... (h2 (h1 a))), f) $\r
10229= $ (hn (... (h2 (h1 a))), f)\r
10230= f (hn (... (h2 (h1 a))))</programlisting>\r
10231<section id="_example_variable_number_of_arguments">\r
10232<title>Example: variable number of arguments</title>\r
10233<simpara>The simplest example of fold is accepting a variable number of\r
10234(curried) arguments. We&#8217;ll define a function <literal>f</literal> and argument\r
10235<literal>a</literal> such that all of the following expressions are valid.</simpara>\r
10236<programlisting language="sml" linenumbering="unnumbered">f $\r
10237f a $\r
10238f a a $\r
10239f a a a $\r
10240f a a a ... a a a $ (* as many a's as we want *)</programlisting>\r
10241<simpara>Off-hand it may appear impossible that all of the above expressions\r
10242are type correct SML&#8201;&#8212;&#8201;how can a function <literal>f</literal> accept a variable\r
10243number of curried arguments? What could the type of <literal>f</literal> be?\r
10244We&#8217;ll have more to say later on how type checking works. For now,\r
10245once we have supplied the definitions below, you can check that the\r
10246expressions are type correct by feeding them to your favorite SML\r
10247implementation.</simpara>\r
10248<simpara>It is simple to define <literal>f</literal> and <literal>a</literal>. We define <literal>f</literal> as a\r
10249folder whose base element is <literal>()</literal> and whose finish function does\r
10250nothing. We define <literal>a</literal> as the step function that does nothing.\r
10251The only trickiness is that we must <link linkend="EtaExpansion">eta expand</link> the\r
10252definition of <literal>f</literal> and <literal>a</literal> to work around the ValueRestriction;\r
10253we frequently use eta expansion for this purpose without mention.</simpara>\r
10254<programlisting language="sml" linenumbering="unnumbered">val base = ()\r
10255fun finish () = ()\r
10256fun step () = ()\r
10257val f = fn z =&gt; Fold.fold (base, finish) z\r
10258val a = fn z =&gt; Fold.step0 step z</programlisting>\r
10259<simpara>One can easily apply the fold equation to verify by hand that <literal>f</literal>\r
10260applied to any number of <literal>a</literal>'s evaluates to <literal>()</literal>.</simpara>\r
10261<programlisting language="sml" linenumbering="unnumbered">f a ... a $\r
10262= finish (step (... (step base)))\r
10263= finish (step (... ()))\r
10264...\r
10265= finish ()\r
10266= ()</programlisting>\r
10267</section>\r
10268<section id="_example_variable_argument_sum">\r
10269<title>Example: variable-argument sum</title>\r
10270<simpara>Let&#8217;s look at an example that computes something: a variable-argument\r
10271function <literal>sum</literal> and a stepper <literal>a</literal> such that</simpara>\r
10272<programlisting language="sml" linenumbering="unnumbered">sum (a i1) (a i2) ... (a im) $ = i1 + i2 + ... + im</programlisting>\r
10273<simpara>The idea is simple&#8201;&#8212;&#8201;the folder starts with a base accumulator of\r
10274<literal>0</literal> and the stepper adds each element to the accumulator, <literal>s</literal>,\r
10275which the folder simply returns at the end.</simpara>\r
10276<programlisting language="sml" linenumbering="unnumbered">val sum = fn z =&gt; Fold.fold (0, fn s =&gt; s) z\r
10277fun a i = Fold.step0 (fn s =&gt; i + s)</programlisting>\r
10278<simpara>Using the fold equation, one can verify the following.</simpara>\r
10279<programlisting language="sml" linenumbering="unnumbered">sum (a 1) (a 2) (a 3) $ = 6</programlisting>\r
10280</section>\r
10281<section id="_step1">\r
10282<title>Step1</title>\r
10283<simpara>It is sometimes syntactically convenient to omit the parentheses\r
10284around the steps in a fold. This is easily done by defining a new\r
10285function, <literal>step1</literal>, as follows.</simpara>\r
10286<programlisting language="sml" linenumbering="unnumbered">structure Fold =\r
10287 struct\r
10288 open Fold\r
10289 fun step1 h (a, f) b = fold (h (b, a), f)\r
10290 end</programlisting>\r
10291<simpara>From the definition of <literal>step1</literal>, we have the following\r
10292equivalence.</simpara>\r
10293<programlisting language="sml" linenumbering="unnumbered">fold (a, f) (step1 h) b\r
10294= step1 h (a, f) b\r
10295= fold (h (b, a), f)</programlisting>\r
10296<simpara>Using the above equivalence, we can compute the following equation for\r
10297<literal>step1</literal>.</simpara>\r
10298<programlisting language="sml" linenumbering="unnumbered">fold (a, f) (step1 h1) b1 (step1 h2) b2 ... (step1 hn) bn $\r
10299= fold (h1 (b1, a), f) (step1 h2) b2 ... (step1 hn) bn $\r
10300= fold (h2 (b2, h1 (b1, a)), f) ... (step1 hn) bn $\r
10301= fold (hn (bn, ... (h2 (b2, h1 (b1, a)))), f) $\r
10302= f (hn (bn, ... (h2 (b2, h1 (b1, a)))))</programlisting>\r
10303<simpara>Here is an example using <literal>step1</literal> to define a variable-argument\r
10304product function, <literal>prod</literal>, with a convenient syntax.</simpara>\r
10305<programlisting language="sml" linenumbering="unnumbered">val prod = fn z =&gt; Fold.fold (1, fn p =&gt; p) z\r
10306val ` = fn z =&gt; Fold.step1 (fn (i, p) =&gt; i * p) z</programlisting>\r
10307<simpara>The functions <literal>prod</literal> and <literal>&grave;</literal> satisfy the following equation.</simpara>\r
10308<programlisting language="sml" linenumbering="unnumbered">prod `i1 `i2 ... `im $ = i1 * i2 * ... * im</programlisting>\r
10309<simpara>Note that in SML, <literal>&grave;i1</literal> is two different tokens, <literal>&grave;</literal> and\r
10310<literal>i1</literal>. We often use <literal>&grave;</literal> for an instance of a <literal>step1</literal> function\r
10311because of its syntactic unobtrusiveness and because no space is\r
10312required to separate it from an alphanumeric token.</simpara>\r
10313<simpara>Also note that there are no parenthesis around the steps. That is,\r
10314the following expression is not the same as the above one (in fact, it\r
10315is not type correct).</simpara>\r
10316<programlisting language="sml" linenumbering="unnumbered">prod (`i1) (`i2) ... (`im) $</programlisting>\r
10317</section>\r
10318<section id="_example_list_literals">\r
10319<title>Example: list literals</title>\r
10320<simpara>SML already has a syntax for list literals, e.g. <literal>[w, x, y, z]</literal>.\r
10321However, using fold, we can define our own syntax.</simpara>\r
10322<programlisting language="sml" linenumbering="unnumbered">val list = fn z =&gt; Fold.fold ([], rev) z\r
10323val ` = fn z =&gt; Fold.step1 (op ::) z</programlisting>\r
10324<simpara>The idea is that the folder starts out with the empty list, the steps\r
10325accumulate the elements into a list, and then the finishing function\r
10326reverses the list at the end.</simpara>\r
10327<simpara>With these definitions one can write a list like:</simpara>\r
10328<programlisting language="sml" linenumbering="unnumbered">list `w `x `y `z $</programlisting>\r
10329<simpara>While the example is not practically useful, it does demonstrate the\r
10330need for the finishing function to be incorporated in <literal>fold</literal>.\r
10331Without a finishing function, every use of <literal>list</literal> would need to be\r
10332wrapped in <literal>rev</literal>, as follows.</simpara>\r
10333<programlisting language="sml" linenumbering="unnumbered">rev (list `w `x `y `z $)</programlisting>\r
10334<simpara>The finishing function allows us to incorporate the reversal into the\r
10335definition of <literal>list</literal>, and to treat <literal>list</literal> as a truly variable\r
10336argument function, performing an arbitrary computation after receiving\r
10337all of its arguments.</simpara>\r
10338<simpara>See <link linkend="ArrayLiteral">ArrayLiteral</link> for a similar use of <literal>fold</literal> that provides a\r
10339syntax for array and vector literals, which are not built in to SML.</simpara>\r
10340</section>\r
10341<section id="_fold_right">\r
10342<title>Fold right</title>\r
10343<simpara>Just as <literal>fold</literal> is analogous to a fold left, in which the functions\r
10344are applied to the accumulator left-to-right, we can define a variant\r
10345of <literal>fold</literal> that is analogous to a fold right, in which the\r
10346functions are applied to the accumulator right-to-left. That is, we\r
10347can define functions <literal>foldr</literal> and <literal>step0</literal> such that the\r
10348following equation holds.</simpara>\r
10349<programlisting language="sml" linenumbering="unnumbered">foldr (a, f) (step0 h1) (step0 h2) ... (step0 hn) $\r
10350= f (h1 (h2 (... (hn a))))</programlisting>\r
10351<simpara>The implementation of fold right is easy, using fold. The idea is for\r
10352the fold to start with <literal>f</literal> and for each step to precompose the\r
10353next <literal>hi</literal>. Then, the finisher applies the composed function to\r
10354the base value, <literal>a</literal>. Here is the code.</simpara>\r
10355<programlisting language="sml" linenumbering="unnumbered">structure Foldr =\r
10356 struct\r
10357 fun foldr (a, f) = Fold.fold (f, fn g =&gt; g a)\r
10358 fun step0 h = Fold.step0 (fn g =&gt; g o h)\r
10359 end</programlisting>\r
10360<simpara>Verifying the fold-right equation is straightforward, using the\r
10361fold-left equation.</simpara>\r
10362<programlisting language="sml" linenumbering="unnumbered">foldr (a, f) (Foldr.step0 h1) (Foldr.step0 h2) ... (Foldr.step0 hn) $\r
10363= fold (f, fn g =&gt; g a)\r
10364 (Fold.step0 (fn g =&gt; g o h1))\r
10365 (Fold.step0 (fn g =&gt; g o h2))\r
10366 ...\r
10367 (Fold.step0 (fn g =&gt; g o hn)) $\r
10368= (fn g =&gt; g a)\r
10369 ((fn g =&gt; g o hn) (... ((fn g =&gt; g o h2) ((fn g =&gt; g o h1) f))))\r
10370= (fn g =&gt; g a)\r
10371 ((fn g =&gt; g o hn) (... ((fn g =&gt; g o h2) (f o h1))))\r
10372= (fn g =&gt; g a) ((fn g =&gt; g o hn) (... (f o h1 o h2)))\r
10373= (fn g =&gt; g a) (f o h1 o h2 o ... o hn)\r
10374= (f o h1 o h2 o ... o hn) a\r
10375= f (h1 (h2 (... (hn a))))</programlisting>\r
10376<simpara>One can also define the fold-right analogue of <literal>step1</literal>.</simpara>\r
10377<programlisting language="sml" linenumbering="unnumbered">structure Foldr =\r
10378 struct\r
10379 open Foldr\r
10380 fun step1 h = Fold.step1 (fn (b, g) =&gt; g o (fn a =&gt; h (b, a)))\r
10381 end</programlisting>\r
10382</section>\r
10383<section id="_example_list_literals_via_fold_right">\r
10384<title>Example: list literals via fold right</title>\r
10385<simpara>Revisiting the list literal example from earlier, we can use fold\r
10386right to define a syntax for list literals that doesn&#8217;t do a reversal.</simpara>\r
10387<programlisting language="sml" linenumbering="unnumbered">val list = fn z =&gt; Foldr.foldr ([], fn l =&gt; l) z\r
10388val ` = fn z =&gt; Foldr.step1 (op ::) z</programlisting>\r
10389<simpara>As before, with these definitions, one can write a list like:</simpara>\r
10390<programlisting language="sml" linenumbering="unnumbered">list `w `x `y `z $</programlisting>\r
10391<simpara>The difference between the fold-left and fold-right approaches is that\r
10392the fold-right approach does not have to reverse the list at the end,\r
10393since it accumulates the elements in the correct order. In practice,\r
10394MLton will simplify away all of the intermediate function composition,\r
10395so the the fold-right approach will be more efficient.</simpara>\r
10396</section>\r
10397<section id="_mixing_steppers">\r
10398<title>Mixing steppers</title>\r
10399<simpara>All of the examples so far have used the same step function throughout\r
10400a fold. This need not be the case. For example, consider the\r
10401following.</simpara>\r
10402<programlisting language="sml" linenumbering="unnumbered">val n = fn z =&gt; Fold.fold (0, fn i =&gt; i) z\r
10403val I = fn z =&gt; Fold.step0 (fn i =&gt; i * 2) z\r
10404val O = fn z =&gt; Fold.step0 (fn i =&gt; i * 2 + 1) z</programlisting>\r
10405<simpara>Here we have one folder, <literal>n</literal>, that can be used with two different\r
10406steppers, <literal>I</literal> and <literal>O</literal>. By using the fold equation, one can\r
10407verify the following equations.</simpara>\r
10408<programlisting language="sml" linenumbering="unnumbered">n O $ = 0\r
10409n I $ = 1\r
10410n I O $ = 2\r
10411n I O I $ = 5\r
10412n I I I O $ = 14</programlisting>\r
10413<simpara>That is, we&#8217;ve defined a syntax for writing binary integer constants.</simpara>\r
10414<simpara>Not only can one use different instances of <literal>step0</literal> in the same\r
10415fold, one can also intermix uses of <literal>step0</literal> and <literal>step1</literal>. For\r
10416example, consider the following.</simpara>\r
10417<programlisting language="sml" linenumbering="unnumbered">val n = fn z =&gt; Fold.fold (0, fn i =&gt; i) z\r
10418val O = fn z =&gt; Fold.step0 (fn i =&gt; n * 8) z\r
10419val ` = fn z =&gt; Fold.step1 (fn (i, n) =&gt; n * 8 + i) z</programlisting>\r
10420<simpara>Using the straightforward generalization of the fold equation to mixed\r
10421steppers, one can verify the following equations.</simpara>\r
10422<programlisting language="sml" linenumbering="unnumbered">n 0 $ = 0\r
10423n `3 O $ = 24\r
10424n `1 O `7 $ = 71</programlisting>\r
10425<simpara>That is, we&#8217;ve defined a syntax for writing octal integer constants,\r
10426with a special syntax, <literal>O</literal>, for the zero digit (admittedly\r
10427contrived, since one could just write <literal>&grave;0</literal> instead of <literal>O</literal>).</simpara>\r
10428<simpara>See <link linkend="NumericLiteral">NumericLiteral</link> for a practical extension of this approach that\r
10429supports numeric constants in any base and of any type.</simpara>\r
10430</section>\r
10431<section id="_seemingly_dependent_types">\r
10432<title>(Seemingly) dependent types</title>\r
10433<simpara>A normal list fold always returns the same type no matter what\r
10434elements are in the list or how long the list is. Variable-argument\r
10435fold is more powerful, because the result type can vary based both on\r
10436the arguments that are passed and on their number. This can provide\r
10437the illusion of dependent types.</simpara>\r
10438<simpara>For example, consider the following.</simpara>\r
10439<programlisting language="sml" linenumbering="unnumbered">val f = fn z =&gt; Fold.fold ((), id) z\r
10440val a = fn z =&gt; Fold.step0 (fn () =&gt; "hello") z\r
10441val b = fn z =&gt; Fold.step0 (fn () =&gt; 13) z\r
10442val c = fn z =&gt; Fold.step0 (fn () =&gt; (1, 2)) z</programlisting>\r
10443<simpara>Using the fold equation, one can verify the following equations.</simpara>\r
10444<programlisting language="sml" linenumbering="unnumbered">f a $ = "hello": string\r
10445f b $ = 13: int\r
10446f c $ = (1, 2): int * int</programlisting>\r
10447<simpara>That is, <literal>f</literal> returns a value of a different type depending on\r
10448whether it is applied to argument <literal>a</literal>, argument <literal>b</literal>, or\r
10449argument <literal>c</literal>.</simpara>\r
10450<simpara>The following example shows how the type of a fold can depend on the\r
10451number of arguments.</simpara>\r
10452<programlisting language="sml" linenumbering="unnumbered">val grow = fn z =&gt; Fold.fold ([], fn l =&gt; l) z\r
10453val a = fn z =&gt; Fold.step0 (fn x =&gt; [x]) z</programlisting>\r
10454<simpara>Using the fold equation, one can verify the following equations.</simpara>\r
10455<programlisting language="sml" linenumbering="unnumbered">grow $ = []: 'a list\r
10456grow a $ = [[]]: 'a list list\r
10457grow a a $ = [[[]]]: 'a list list list</programlisting>\r
10458<simpara>Clearly, the result type of a call to the variable argument <literal>grow</literal>\r
10459function depends on the number of arguments that are passed.</simpara>\r
10460<simpara>As a reminder, this is well-typed SML. You can check it out in any\r
10461implementation.</simpara>\r
10462</section>\r
10463<section id="_seemingly_dependently_typed_functional_results">\r
10464<title>(Seemingly) dependently-typed functional results</title>\r
10465<simpara>Fold is especially useful when it returns a curried function whose\r
10466arity depends on the number of arguments. For example, consider the\r
10467following.</simpara>\r
10468<programlisting language="sml" linenumbering="unnumbered">val makeSum = fn z =&gt; Fold.fold (id, fn f =&gt; f 0) z\r
10469val I = fn z =&gt; Fold.step0 (fn f =&gt; fn i =&gt; fn x =&gt; f (x + i)) z</programlisting>\r
10470<simpara>The <literal>makeSum</literal> folder constructs a function whose arity depends on\r
10471the number of <literal>I</literal> arguments and that adds together all of its\r
10472arguments. For example,\r
10473<literal>makeSum I $</literal> is of type <literal>int -&gt; int</literal> and\r
10474<literal>makeSum I I $</literal> is of type <literal>int -&gt; int -&gt; int</literal>.</simpara>\r
10475<simpara>One can use the fold equation to verify that the <literal>makeSum</literal> works\r
10476correctly. For example, one can easily check by hand the following\r
10477equations.</simpara>\r
10478<programlisting language="sml" linenumbering="unnumbered">makeSum I $ 1 = 1\r
10479makeSum I I $ 1 2 = 3\r
10480makeSum I I I $ 1 2 3 = 6</programlisting>\r
10481<simpara>Returning a function becomes especially interesting when there are\r
10482steppers of different types. For example, the following <literal>makeSum</literal>\r
10483folder constructs functions that sum integers and reals.</simpara>\r
10484<programlisting language="sml" linenumbering="unnumbered">val makeSum = fn z =&gt; Foldr.foldr (id, fn f =&gt; f 0.0) z\r
10485val I = fn z =&gt; Foldr.step0 (fn f =&gt; fn x =&gt; fn i =&gt; f (x + real i)) z\r
10486val R = fn z =&gt; Foldr.step0 (fn f =&gt; fn x: real =&gt; fn r =&gt; f (x + r)) z</programlisting>\r
10487<simpara>With these definitions, <literal>makeSum I R $</literal> is of type\r
10488<literal>int -&gt; real -&gt; real</literal> and <literal>makeSum R I I $</literal> is of type\r
10489<literal>real -&gt; int -&gt; int -&gt; real</literal>. One can use the foldr equation to\r
10490check the following equations.</simpara>\r
10491<programlisting language="sml" linenumbering="unnumbered">makeSum I $ 1 = 1.0\r
10492makeSum I R $ 1 2.5 = 3.5\r
10493makeSum R I I $ 1.5 2 3 = 6.5</programlisting>\r
10494<simpara>We used <literal>foldr</literal> instead of <literal>fold</literal> for this so that the order\r
10495in which the specifiers <literal>I</literal> and <literal>R</literal> appear is the same as the\r
10496order in which the arguments appear. Had we used <literal>fold</literal>, things\r
10497would have been reversed.</simpara>\r
10498<simpara>An extension of this idea is sufficient to define <link linkend="Printf">Printf</link>-like\r
10499functions in SML.</simpara>\r
10500</section>\r
10501<section id="_an_idiom_for_combining_steps">\r
10502<title>An idiom for combining steps</title>\r
10503<simpara>It is sometimes useful to combine a number of steps together and name\r
10504them as a single step. As a simple example, suppose that one often\r
10505sees an integer follower by a real in the <literal>makeSum</literal> example above.\r
10506One can define a new <emphasis>compound step</emphasis> <literal>IR</literal> as follows.</simpara>\r
10507<programlisting language="sml" linenumbering="unnumbered">val IR = fn u =&gt; Fold.fold u I R</programlisting>\r
10508<simpara>With this definition in place, one can verify the following.</simpara>\r
10509<programlisting language="sml" linenumbering="unnumbered">makeSum IR IR $ 1 2.2 3 4.4 = 10.6</programlisting>\r
10510<simpara>In general, one can combine steps <literal>s1</literal>, <literal>s2</literal>, &#8230; <literal>sn</literal> as</simpara>\r
10511<programlisting language="sml" linenumbering="unnumbered">fn u =&gt; Fold.fold u s1 s2 ... sn</programlisting>\r
10512<simpara>The following calculation shows why a compound step behaves as the\r
10513composition of its constituent steps.</simpara>\r
10514<programlisting language="sml" linenumbering="unnumbered">fold u (fn u =&gt; fold u s1 s2 ... sn)\r
10515= (fn u =&gt; fold u s1 s2 ... sn) u\r
10516= fold u s1 s2 ... sn</programlisting>\r
10517</section>\r
10518<section id="_post_composition">\r
10519<title>Post composition</title>\r
10520<simpara>Suppose we already have a function defined via fold,\r
10521<literal>w = fold (a, f)</literal>, and we would like to construct a new fold\r
10522function that is like <literal>w</literal>, but applies <literal>g</literal> to the result\r
10523produced by <literal>w</literal>. This is similar to function composition, but we\r
10524can&#8217;t just do <literal>g o w</literal>, because we don&#8217;t want to use <literal>g</literal> until\r
10525<literal>w</literal> has been applied to all of its arguments and received the\r
10526end-of-arguments terminator <literal>$</literal>.</simpara>\r
10527<simpara>More precisely, we want to define a post-composition function\r
10528<literal>post</literal> that satisfies the following equation.</simpara>\r
10529<programlisting language="sml" linenumbering="unnumbered">post (w, g) s1 ... sn $ = g (w s1 ... sn $)</programlisting>\r
10530<simpara>Here is the definition of <literal>post</literal>.</simpara>\r
10531<programlisting language="sml" linenumbering="unnumbered">structure Fold =\r
10532 struct\r
10533 open Fold\r
10534 fun post (w, g) s = w (fn (a, h) =&gt; s (a, g o h))\r
10535 end</programlisting>\r
10536<simpara>The following calculations show that <literal>post</literal> satisfies the desired\r
10537equation, where <literal>w = fold (a, f)</literal>.</simpara>\r
10538<programlisting language="sml" linenumbering="unnumbered">post (w, g) s\r
10539= w (fn (a, h) =&gt; s (a, g o h))\r
10540= fold (a, f) (fn (a, h) =&gt; s (a, g o h))\r
10541= (fn (a, h) =&gt; s (a, g o h)) (a, f)\r
10542= s (a, g o f)\r
10543= fold (a, g o f) s</programlisting>\r
10544<simpara>Now, suppose <literal>si = step0 hi</literal> for <literal>i</literal> from <literal>1</literal> to <literal>n</literal>.</simpara>\r
10545<programlisting language="sml" linenumbering="unnumbered">post (w, g) s1 s2 ... sn $\r
10546= fold (a, g o f) s1 s2 ... sn $\r
10547= (g o f) (hn (... (h1 a)))\r
10548= g (f (hn (... (h1 a))))\r
10549= g (fold (a, f) s1 ... sn $)\r
10550= g (w s1 ... sn $)</programlisting>\r
10551<simpara>For a practical example of post composition, see <link linkend="ArrayLiteral">ArrayLiteral</link>.</simpara>\r
10552</section>\r
10553<section id="_lift">\r
10554<title>Lift</title>\r
10555<simpara>We now define a peculiar-looking function, <literal>lift0</literal>, that is,\r
10556equationally speaking, equivalent to the identity function on a step\r
10557function.</simpara>\r
10558<programlisting language="sml" linenumbering="unnumbered">fun lift0 s (a, f) = fold (fold (a, id) s $, f)</programlisting>\r
10559<simpara>Using the definitions, we can prove the following equation.</simpara>\r
10560<programlisting language="sml" linenumbering="unnumbered">fold (a, f) (lift0 (step0 h)) = fold (a, f) (step0 h)</programlisting>\r
10561<simpara>Here is the proof.</simpara>\r
10562<programlisting language="sml" linenumbering="unnumbered">fold (a, f) (lift0 (step0 h))\r
10563= lift0 (step0 h) (a, f)\r
10564= fold (fold (a, id) (step0 h) $, f)\r
10565= fold (step0 h (a, id) $, f)\r
10566= fold (fold (h a, id) $, f)\r
10567= fold ($ (h a, id), f)\r
10568= fold (id (h a), f)\r
10569= fold (h a, f)\r
10570= step0 h (a, f)\r
10571= fold (a, f) (step0 h)</programlisting>\r
10572<simpara>If <literal>lift0</literal> is the identity, then why even define it? The answer\r
10573lies in the typing of fold expressions, which we have, until now, left\r
10574unexplained.</simpara>\r
10575</section>\r
10576<section id="_typing">\r
10577<title>Typing</title>\r
10578<simpara>Perhaps the most surprising aspect of fold is that it can be checked\r
10579by the SML type system. The types involved in fold expressions are\r
10580complex; fortunately type inference is able to deduce them.\r
10581Nevertheless, it is instructive to study the types of fold functions\r
10582and steppers. More importantly, it is essential to understand the\r
10583typing aspects of fold in order to write down signatures of functions\r
10584defined using fold and step.</simpara>\r
10585<simpara>Here is the <literal>FOLD</literal> signature, and a recapitulation of the entire\r
10586<literal>Fold</literal> structure, with additional type annotations.</simpara>\r
10587<programlisting language="sml" linenumbering="unnumbered">signature FOLD =\r
10588 sig\r
10589 type ('a, 'b, 'c, 'd) step = 'a * ('b -&gt; 'c) -&gt; 'd\r
10590 type ('a, 'b, 'c, 'd) t = ('a, 'b, 'c, 'd) step -&gt; 'd\r
10591 type ('a1, 'a2, 'b, 'c, 'd) step0 =\r
10592 ('a1, 'b, 'c, ('a2, 'b, 'c, 'd) t) step\r
10593 type ('a11, 'a12, 'a2, 'b, 'c, 'd) step1 =\r
10594 ('a12, 'b, 'c, 'a11 -&gt; ('a2, 'b, 'c, 'd) t) step\r
10595\r
10596 val fold: 'a * ('b -&gt; 'c) -&gt; ('a, 'b, 'c, 'd) t\r
10597 val lift0: ('a1, 'a2, 'a2, 'a2, 'a2) step0\r
10598 -&gt; ('a1, 'a2, 'b, 'c, 'd) step0\r
10599 val post: ('a, 'b, 'c1, 'd) t * ('c1 -&gt; 'c2)\r
10600 -&gt; ('a, 'b, 'c2, 'd) t\r
10601 val step0: ('a1 -&gt; 'a2) -&gt; ('a1, 'a2, 'b, 'c, 'd) step0\r
10602 val step1: ('a11 * 'a12 -&gt; 'a2)\r
10603 -&gt; ('a11, 'a12, 'a2, 'b, 'c, 'd) step1\r
10604 end\r
10605\r
10606structure Fold:&gt; FOLD =\r
10607 struct\r
10608 type ('a, 'b, 'c, 'd) step = 'a * ('b -&gt; 'c) -&gt; 'd\r
10609\r
10610 type ('a, 'b, 'c, 'd) t = ('a, 'b, 'c, 'd) step -&gt; 'd\r
10611\r
10612 type ('a1, 'a2, 'b, 'c, 'd) step0 =\r
10613 ('a1, 'b, 'c, ('a2, 'b, 'c, 'd) t) step\r
10614\r
10615 type ('a11, 'a12, 'a2, 'b, 'c, 'd) step1 =\r
10616 ('a12, 'b, 'c, 'a11 -&gt; ('a2, 'b, 'c, 'd) t) step\r
10617\r
10618 fun fold (a: 'a, f: 'b -&gt; 'c)\r
10619 (g: ('a, 'b, 'c, 'd) step): 'd =\r
10620 g (a, f)\r
10621\r
10622 fun step0 (h: 'a1 -&gt; 'a2)\r
10623 (a1: 'a1, f: 'b -&gt; 'c): ('a2, 'b, 'c, 'd) t =\r
10624 fold (h a1, f)\r
10625\r
10626 fun step1 (h: 'a11 * 'a12 -&gt; 'a2)\r
10627 (a12: 'a12, f: 'b -&gt; 'c)\r
10628 (a11: 'a11): ('a2, 'b, 'c, 'd) t =\r
10629 fold (h (a11, a12), f)\r
10630\r
10631 fun lift0 (s: ('a1, 'a2, 'a2, 'a2, 'a2) step0)\r
10632 (a: 'a1, f: 'b -&gt; 'c): ('a2, 'b, 'c, 'd) t =\r
10633 fold (fold (a, id) s $, f)\r
10634\r
10635 fun post (w: ('a, 'b, 'c1, 'd) t,\r
10636 g: 'c1 -&gt; 'c2)\r
10637 (s: ('a, 'b, 'c2, 'd) step): 'd =\r
10638 w (fn (a, h) =&gt; s (a, g o h))\r
10639 end</programlisting>\r
10640<simpara>That&#8217;s a lot to swallow, so let&#8217;s walk through it one step at a time.\r
10641First, we have the definition of type <literal>Fold.step</literal>.</simpara>\r
10642<programlisting language="sml" linenumbering="unnumbered">type ('a, 'b, 'c, 'd) step = 'a * ('b -&gt; 'c) -&gt; 'd</programlisting>\r
10643<simpara>As a fold proceeds over its arguments, it maintains two things: the\r
10644accumulator, of type <literal>'a</literal>, and the finishing function, of type\r
10645<literal>'b -&gt; 'c</literal>. Each step in the fold is a function that takes those\r
10646two pieces (i.e. <literal>'a * ('b -&gt; 'c)</literal> and does something to them\r
10647(i.e. produces <literal>'d</literal>). The result type of the step is completely\r
10648left open to be filled in by type inference, as it is an arrow type\r
10649that is capable of consuming the rest of the arguments to the fold.</simpara>\r
10650<simpara>A folder, of type <literal>Fold.t</literal>, is a function that consumes a single\r
10651step.</simpara>\r
10652<programlisting language="sml" linenumbering="unnumbered">type ('a, 'b, 'c, 'd) t = ('a, 'b, 'c, 'd) step -&gt; 'd</programlisting>\r
10653<simpara>Expanding out the type, we have:</simpara>\r
10654<programlisting language="sml" linenumbering="unnumbered">type ('a, 'b, 'c, 'd) t = ('a * ('b -&gt; 'c) -&gt; 'd) -&gt; 'd</programlisting>\r
10655<simpara>This shows that the only thing a folder does is to hand its\r
10656accumulator (<literal>'a</literal>) and finisher (<literal>'b -&gt; 'c</literal>) to the next step\r
10657(<literal>'a * ('b -&gt; 'c) -&gt; 'd</literal>). If SML had <link linkend="FirstClassPolymorphism">first-class polymorphism</link>,\r
10658we would write the fold type as follows.</simpara>\r
10659<programlisting language="sml" linenumbering="unnumbered">type ('a, 'b, 'c) t = Forall 'd . ('a, 'b, 'c, 'd) step -&gt; 'd</programlisting>\r
10660<simpara>This type definition shows that a folder had nothing to do with\r
10661the rest of the fold, it only deals with the next step.</simpara>\r
10662<simpara>We now can understand the type of <literal>fold</literal>, which takes the initial\r
10663value of the accumulator and the finishing function, and constructs a\r
10664folder, i.e. a function awaiting the next step.</simpara>\r
10665<programlisting language="sml" linenumbering="unnumbered">val fold: 'a * ('b -&gt; 'c) -&gt; ('a, 'b, 'c, 'd) t\r
10666fun fold (a: 'a, f: 'b -&gt; 'c)\r
10667 (g: ('a, 'b, 'c, 'd) step): 'd =\r
10668 g (a, f)</programlisting>\r
10669<simpara>Continuing on, we have the type of step functions.</simpara>\r
10670<programlisting language="sml" linenumbering="unnumbered">type ('a1, 'a2, 'b, 'c, 'd) step0 =\r
10671 ('a1, 'b, 'c, ('a2, 'b, 'c, 'd) t) step</programlisting>\r
10672<simpara>Expanding out the type a bit gives:</simpara>\r
10673<programlisting language="sml" linenumbering="unnumbered">type ('a1, 'a2, 'b, 'c, 'd) step0 =\r
10674 'a1 * ('b -&gt; 'c) -&gt; ('a2, 'b, 'c, 'd) t</programlisting>\r
10675<simpara>So, a step function takes the accumulator (<literal>'a1</literal>) and finishing\r
10676function (<literal>'b -&gt; 'c</literal>), which will be passed to it by the previous\r
10677folder, and transforms them to a new folder. This new folder has a\r
10678new accumulator (<literal>'a2</literal>) and the same finishing function.</simpara>\r
10679<simpara>Again, imagining that SML had <link linkend="FirstClassPolymorphism">first-class polymorphism</link> makes the type\r
10680clearer.</simpara>\r
10681<programlisting language="sml" linenumbering="unnumbered">type ('a1, 'a2) step0 =\r
10682 Forall ('b, 'c) . ('a1, 'b, 'c, ('a2, 'b, 'c) t) step</programlisting>\r
10683<simpara>Thus, in essence, a <literal>step0</literal> function is a wrapper around a\r
10684function of type <literal>'a1 -&gt; 'a2</literal>, which is exactly what the\r
10685definition of <literal>step0</literal> does.</simpara>\r
10686<programlisting language="sml" linenumbering="unnumbered">val step0: ('a1 -&gt; 'a2) -&gt; ('a1, 'a2, 'b, 'c, 'd) step0\r
10687fun step0 (h: 'a1 -&gt; 'a2)\r
10688 (a1: 'a1, f: 'b -&gt; 'c): ('a2, 'b, 'c, 'd) t =\r
10689 fold (h a1, f)</programlisting>\r
10690<simpara>It is not much beyond <literal>step0</literal> to understand <literal>step1</literal>.</simpara>\r
10691<programlisting language="sml" linenumbering="unnumbered">type ('a11, 'a12, 'a2, 'b, 'c, 'd) step1 =\r
10692 ('a12, 'b, 'c, 'a11 -&gt; ('a2, 'b, 'c, 'd) t) step</programlisting>\r
10693<simpara>A <literal>step1</literal> function takes the accumulator (<literal>'a12</literal>) and finisher\r
10694(<literal>'b -&gt; 'c</literal>) passed to it by the previous folder and transforms\r
10695them into a function that consumes the next argument (<literal>'a11</literal>) and\r
10696produces a folder that will continue the fold with a new accumulator\r
10697(<literal>'a2</literal>) and the same finisher.</simpara>\r
10698<programlisting language="sml" linenumbering="unnumbered">fun step1 (h: 'a11 * 'a12 -&gt; 'a2)\r
10699 (a12: 'a12, f: 'b -&gt; 'c)\r
10700 (a11: 'a11): ('a2, 'b, 'c, 'd) t =\r
10701 fold (h (a11, a12), f)</programlisting>\r
10702<simpara>With <link linkend="FirstClassPolymorphism">first-class polymorphism</link>, a <literal>step1</literal> function is more clearly\r
10703seen as a wrapper around a binary function of type\r
10704<literal>'a11 * 'a12 -&gt; 'a2</literal>.</simpara>\r
10705<programlisting language="sml" linenumbering="unnumbered">type ('a11, 'a12, 'a2) step1 =\r
10706 Forall ('b, 'c) . ('a12, 'b, 'c, 'a11 -&gt; ('a2, 'b, 'c) t) step</programlisting>\r
10707<simpara>The type of <literal>post</literal> is clear: it takes a folder with a finishing\r
10708function that produces type <literal>'c1</literal>, and a function of type\r
10709<literal>'c1 -&gt; 'c2</literal> to postcompose onto the folder. It returns a new\r
10710folder with a finishing function that produces type <literal>'c2</literal>.</simpara>\r
10711<programlisting language="sml" linenumbering="unnumbered">val post: ('a, 'b, 'c1, 'd) t * ('c1 -&gt; 'c2)\r
10712 -&gt; ('a, 'b, 'c2, 'd) t\r
10713fun post (w: ('a, 'b, 'c1, 'd) t,\r
10714 g: 'c1 -&gt; 'c2)\r
10715 (s: ('a, 'b, 'c2, 'd) step): 'd =\r
10716 w (fn (a, h) =&gt; s (a, g o h))</programlisting>\r
10717<simpara>We will return to <literal>lift0</literal> after an example.</simpara>\r
10718</section>\r
10719<section id="_an_example_typing">\r
10720<title>An example typing</title>\r
10721<simpara>Let&#8217;s type check our simplest example, a variable-argument fold.\r
10722Recall that we have a folder <literal>f</literal> and a stepper <literal>a</literal> defined as\r
10723follows.</simpara>\r
10724<programlisting language="sml" linenumbering="unnumbered">val f = fn z =&gt; Fold.fold ((), fn () =&gt; ()) z\r
10725val a = fn z =&gt; Fold.step0 (fn () =&gt; ()) z</programlisting>\r
10726<simpara>Since the accumulator and finisher are uninteresting, we&#8217;ll use some\r
10727abbreviations to simplify things.</simpara>\r
10728<programlisting language="sml" linenumbering="unnumbered">type 'd step = (unit, unit, unit, 'd) Fold.step\r
10729type 'd fold = 'd step -&gt; 'd</programlisting>\r
10730<simpara>With these abbreviations, <literal>f</literal> and <literal>a</literal> have the following polymorphic\r
10731types.</simpara>\r
10732<programlisting language="sml" linenumbering="unnumbered">f: 'd fold\r
10733a: 'd step</programlisting>\r
10734<simpara>Suppose we want to type check</simpara>\r
10735<programlisting language="sml" linenumbering="unnumbered">f a a a $: unit</programlisting>\r
10736<simpara>As a reminder, the fully parenthesized expression is</simpara>\r
10737<programlisting language="sml" linenumbering="unnumbered">((((f a) a) a) a) $</programlisting>\r
10738<simpara>The observation that we will use repeatedly is that for any type\r
10739<literal>z</literal>, if <literal>f: z fold</literal> and <literal>s: z step</literal>, then <literal>f s: z</literal>.\r
10740So, if we want</simpara>\r
10741<programlisting language="sml" linenumbering="unnumbered">(f a a a) $: unit</programlisting>\r
10742<simpara>then we must have</simpara>\r
10743<programlisting language="sml" linenumbering="unnumbered">f a a a: unit fold\r
10744$: unit step</programlisting>\r
10745<simpara>Applying the observation again, we must have</simpara>\r
10746<programlisting language="sml" linenumbering="unnumbered">f a a: unit fold fold\r
10747a: unit fold step</programlisting>\r
10748<simpara>Applying the observation two more times leads to the following type\r
10749derivation.</simpara>\r
10750<programlisting language="sml" linenumbering="unnumbered">f: unit fold fold fold fold a: unit fold fold fold step\r
10751f a: unit fold fold fold a: unit fold fold step\r
10752f a a: unit fold fold a: unit fold step\r
10753f a a a: unit fold $: unit step\r
10754f a a a $: unit</programlisting>\r
10755<simpara>So, each application is a fold that consumes the next step, producing\r
10756a fold of one smaller type.</simpara>\r
10757<simpara>One can expand some of the type definitions in <literal>f</literal> to see that it is\r
10758indeed a function that takes four curried arguments, each one a step\r
10759function.</simpara>\r
10760<programlisting language="sml" linenumbering="unnumbered">f: unit fold fold fold step\r
10761 -&gt; unit fold fold step\r
10762 -&gt; unit fold step\r
10763 -&gt; unit step\r
10764 -&gt; unit</programlisting>\r
10765<simpara>This example shows why we must eta expand uses of <literal>fold</literal> and <literal>step0</literal>\r
10766to work around the value restriction and make folders and steppers\r
10767polymorphic. The type of a fold function like <literal>f</literal> depends on the\r
10768number of arguments, and so will vary from use to use. Similarly,\r
10769each occurrence of an argument like <literal>a</literal> has a different type,\r
10770depending on the number of remaining arguments.</simpara>\r
10771<simpara>This example also shows that the type of a folder, when fully\r
10772expanded, is exponential in the number of arguments: there are as many\r
10773nested occurrences of the <literal>fold</literal> type constructor as there are\r
10774arguments, and each occurrence duplicates its type argument. One can\r
10775observe this exponential behavior in a type checker that doesn&#8217;t share\r
10776enough of the representation of types (e.g. one that represents types\r
10777as trees rather than directed acyclic graphs).</simpara>\r
10778<simpara>Generalizing this type derivation to uses of fold where the\r
10779accumulator and finisher are more interesting is straightforward. One\r
10780simply includes the type of the accumulator, which may change, for\r
10781each step, and the type of the finisher, which doesn&#8217;t change from\r
10782step to step.</simpara>\r
10783</section>\r
10784<section id="_typing_lift">\r
10785<title>Typing lift</title>\r
10786<simpara>The lack of <link linkend="FirstClassPolymorphism">first-class polymorphism</link> in SML\r
10787causes problems if one wants to use a step in a first-class way.\r
10788Consider the following <literal>double</literal> function, which takes a step, <literal>s</literal>, and\r
10789produces a composite step that does <literal>s</literal> twice.</simpara>\r
10790<programlisting language="sml" linenumbering="unnumbered">fun double s = fn u =&gt; Fold.fold u s s</programlisting>\r
10791<simpara>The definition of <literal>double</literal> is not type correct. The problem is that\r
10792the type of a step depends on the number of remaining arguments but\r
10793that the parameter <literal>s</literal> is not polymorphic, and so can not be used in\r
10794two different positions.</simpara>\r
10795<simpara>Fortunately, we can define a function, <literal>lift0</literal>, that takes a monotyped\r
10796step function and <emphasis>lifts</emphasis> it into a polymorphic step function. This\r
10797is apparent in the type of <literal>lift0</literal>.</simpara>\r
10798<programlisting language="sml" linenumbering="unnumbered">val lift0: ('a1, 'a2, 'a2, 'a2, 'a2) step0\r
10799 -&gt; ('a1, 'a2, 'b, 'c, 'd) step0\r
10800fun lift0 (s: ('a1, 'a2, 'a2, 'a2, 'a2) step0)\r
10801 (a: 'a1, f: 'b -&gt; 'c): ('a2, 'b, 'c, 'd) t =\r
10802 fold (fold (a, id) s $, f)</programlisting>\r
10803<simpara>The following definition of <literal>double</literal> uses <literal>lift0</literal>, appropriately eta\r
10804wrapped, to fix the problem.</simpara>\r
10805<programlisting language="sml" linenumbering="unnumbered">fun double s =\r
10806 let\r
10807 val s = fn z =&gt; Fold.lift0 s z\r
10808 in\r
10809 fn u =&gt; Fold.fold u s s\r
10810 end</programlisting>\r
10811<simpara>With that definition of <literal>double</literal> in place, we can use it as in the\r
10812following example.</simpara>\r
10813<programlisting language="sml" linenumbering="unnumbered">val f = fn z =&gt; Fold.fold ((), fn () =&gt; ()) z\r
10814val a = fn z =&gt; Fold.step0 (fn () =&gt; ()) z\r
10815val a2 = fn z =&gt; double a z\r
10816val () = f a a2 a a2 $</programlisting>\r
10817<simpara>Of course, we must eta wrap the call <literal>double</literal> in order to use its\r
10818result, which is a step function, polymorphically.</simpara>\r
10819</section>\r
10820<section id="_hiding_the_type_of_the_accumulator">\r
10821<title>Hiding the type of the accumulator</title>\r
10822<simpara>For clarity and to avoid mistakes, it can be useful to hide the type\r
10823of the accumulator in a fold. Reworking the simple variable-argument\r
10824example to do this leads to the following.</simpara>\r
10825<programlisting language="sml" linenumbering="unnumbered">structure S:&gt;\r
10826 sig\r
10827 type ac\r
10828 val f: (ac, ac, unit, 'd) Fold.t\r
10829 val s: (ac, ac, 'b, 'c, 'd) Fold.step0\r
10830 end =\r
10831 struct\r
10832 type ac = unit\r
10833 val f = fn z =&gt; Fold.fold ((), fn () =&gt; ()) z\r
10834 val s = fn z =&gt; Fold.step0 (fn () =&gt; ()) z\r
10835 end</programlisting>\r
10836<simpara>The idea is to name the accumulator type and use opaque signature\r
10837matching to make it abstract. This can prevent improper manipulation\r
10838of the accumulator by client code and ensure invariants that the\r
10839folder and stepper would like to maintain.</simpara>\r
10840<simpara>For a practical example of this technique, see <link linkend="ArrayLiteral">ArrayLiteral</link>.</simpara>\r
10841</section>\r
10842<section id="_also_see_3">\r
10843<title>Also see</title>\r
10844<simpara>Fold has a number of practical applications. Here are some of them.</simpara>\r
10845<itemizedlist>\r
10846<listitem>\r
10847<simpara>\r
10848<link linkend="ArrayLiteral">ArrayLiteral</link>\r
10849</simpara>\r
10850</listitem>\r
10851<listitem>\r
10852<simpara>\r
10853<link linkend="Fold01N">Fold01N</link>\r
10854</simpara>\r
10855</listitem>\r
10856<listitem>\r
10857<simpara>\r
10858<link linkend="FunctionalRecordUpdate">FunctionalRecordUpdate</link>\r
10859</simpara>\r
10860</listitem>\r
10861<listitem>\r
10862<simpara>\r
10863<link linkend="NumericLiteral">NumericLiteral</link>\r
10864</simpara>\r
10865</listitem>\r
10866<listitem>\r
10867<simpara>\r
10868<link linkend="OptionalArguments">OptionalArguments</link>\r
10869</simpara>\r
10870</listitem>\r
10871<listitem>\r
10872<simpara>\r
10873<link linkend="Printf">Printf</link>\r
10874</simpara>\r
10875</listitem>\r
10876<listitem>\r
10877<simpara>\r
10878<link linkend="VariableArityPolymorphism">VariableArityPolymorphism</link>\r
10879</simpara>\r
10880</listitem>\r
10881</itemizedlist>\r
10882<simpara>There are a number of related techniques. Here are some of them.</simpara>\r
10883<itemizedlist>\r
10884<listitem>\r
10885<simpara>\r
10886<link linkend="StaticSum">StaticSum</link>\r
10887</simpara>\r
10888</listitem>\r
10889<listitem>\r
10890<simpara>\r
10891<link linkend="TypeIndexedValues">TypeIndexedValues</link>\r
10892</simpara>\r
10893</listitem>\r
10894</itemizedlist>\r
10895<simpara><?asciidoc-pagebreak?></simpara>\r
10896</section>\r
10897</section>\r
10898<section id="Fold01N">\r
10899<title>Fold01N</title>\r
10900<simpara>A common use pattern of <link linkend="Fold">Fold</link> is to define a variable-arity\r
10901function that combines multiple arguments together using a binary\r
10902function. It is slightly tricky to do this directly using fold,\r
10903because of the special treatment required for the case of zero or one\r
10904argument. Here is a structure, <literal>Fold01N</literal>, that solves the problem\r
10905once and for all, and eases the definition of such functions.</simpara>\r
10906<programlisting language="sml" linenumbering="unnumbered">structure Fold01N =\r
10907 struct\r
10908 fun fold {finish, start, zero} =\r
10909 Fold.fold ((id, finish, fn () =&gt; zero, start),\r
10910 fn (finish, _, p, _) =&gt; finish (p ()))\r
10911\r
10912 fun step0 {combine, input} =\r
10913 Fold.step0 (fn (_, finish, _, f) =&gt;\r
10914 (finish,\r
10915 finish,\r
10916 fn () =&gt; f input,\r
10917 fn x' =&gt; combine (f input, x')))\r
10918\r
10919 fun step1 {combine} z input =\r
10920 step0 {combine = combine, input = input} z\r
10921 end</programlisting>\r
10922<simpara>If one has a value <literal>zero</literal>, and functions <literal>start</literal>, <literal>c</literal>, and <literal>finish</literal>,\r
10923then one can define a variable-arity function <literal>f</literal> and stepper\r
10924<literal>&grave;</literal> as follows.</simpara>\r
10925<programlisting language="sml" linenumbering="unnumbered">val f = fn z =&gt; Fold01N.fold {finish = finish, start = start, zero = zero} z\r
10926val ` = fn z =&gt; Fold01N.step1 {combine = c} z</programlisting>\r
10927<simpara>One can then use the fold equation to prove the following equations.</simpara>\r
10928<programlisting language="sml" linenumbering="unnumbered">f $ = zero\r
10929f `a1 $ = finish (start a1)\r
10930f `a1 `a2 $ = finish (c (start a1, a2))\r
10931f `a1 `a2 `a3 $ = finish (c (c (start a1, a2), a3))\r
10932...</programlisting>\r
10933<simpara>For an example of <literal>Fold01N</literal>, see <link linkend="VariableArityPolymorphism">VariableArityPolymorphism</link>.</simpara>\r
10934<section id="_typing_fold01n">\r
10935<title>Typing Fold01N</title>\r
10936<simpara>Here is the signature for <literal>Fold01N</literal>. We use a trick to avoid having\r
10937to duplicate the definition of some rather complex types in both the\r
10938signature and the structure. We first define the types in a\r
10939structure. Then, we define them via type re-definitions in the\r
10940signature, and via <literal>open</literal> in the full structure.</simpara>\r
10941<programlisting language="sml" linenumbering="unnumbered">structure Fold01N =\r
10942 struct\r
10943 type ('input, 'accum1, 'accum2, 'answer, 'zero,\r
10944 'a, 'b, 'c, 'd, 'e) t =\r
10945 (('zero -&gt; 'zero)\r
10946 * ('accum2 -&gt; 'answer)\r
10947 * (unit -&gt; 'zero)\r
10948 * ('input -&gt; 'accum1),\r
10949 ('a -&gt; 'b) * 'c * (unit -&gt; 'a) * 'd,\r
10950 'b,\r
10951 'e) Fold.t\r
10952\r
10953 type ('input1, 'accum1, 'input2, 'accum2,\r
10954 'a, 'b, 'c, 'd, 'e, 'f) step0 =\r
10955 ('a * 'b * 'c * ('input1 -&gt; 'accum1),\r
10956 'b * 'b * (unit -&gt; 'accum1) * ('input2 -&gt; 'accum2),\r
10957 'd, 'e, 'f) Fold.step0\r
10958\r
10959 type ('accum1, 'input, 'accum2,\r
10960 'a, 'b, 'c, 'd, 'e, 'f, 'g) step1 =\r
10961 ('a,\r
10962 'b * 'c * 'd * ('a -&gt; 'accum1),\r
10963 'c * 'c * (unit -&gt; 'accum1) * ('input -&gt; 'accum2),\r
10964 'e, 'f, 'g) Fold.step1\r
10965 end\r
10966\r
10967signature FOLD_01N =\r
10968 sig\r
10969 type ('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j) t =\r
10970 ('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j) Fold01N.t\r
10971 type ('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j) step0 =\r
10972 ('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j) Fold01N.step0\r
10973 type ('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j) step1 =\r
10974 ('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j) Fold01N.step1\r
10975\r
10976 val fold:\r
10977 {finish: 'accum2 -&gt; 'answer,\r
10978 start: 'input -&gt; 'accum1,\r
10979 zero: 'zero}\r
10980 -&gt; ('input, 'accum1, 'accum2, 'answer, 'zero,\r
10981 'a, 'b, 'c, 'd, 'e) t\r
10982\r
10983 val step0:\r
10984 {combine: 'accum1 * 'input2 -&gt; 'accum2,\r
10985 input: 'input1}\r
10986 -&gt; ('input1, 'accum1, 'input2, 'accum2,\r
10987 'a, 'b, 'c, 'd, 'e, 'f) step0\r
10988\r
10989 val step1:\r
10990 {combine: 'accum1 * 'input -&gt; 'accum2}\r
10991 -&gt; ('accum1, 'input, 'accum2,\r
10992 'a, 'b, 'c, 'd, 'e, 'f, 'g) step1\r
10993 end\r
10994\r
10995structure Fold01N: FOLD_01N =\r
10996 struct\r
10997 open Fold01N\r
10998\r
10999 fun fold {finish, start, zero} =\r
11000 Fold.fold ((id, finish, fn () =&gt; zero, start),\r
11001 fn (finish, _, p, _) =&gt; finish (p ()))\r
11002\r
11003 fun step0 {combine, input} =\r
11004 Fold.step0 (fn (_, finish, _, f) =&gt;\r
11005 (finish,\r
11006 finish,\r
11007 fn () =&gt; f input,\r
11008 fn x' =&gt; combine (f input, x')))\r
11009\r
11010 fun step1 {combine} z input =\r
11011 step0 {combine = combine, input = input} z\r
11012 end</programlisting>\r
11013<simpara><?asciidoc-pagebreak?></simpara>\r
11014</section>\r
11015</section>\r
11016<section id="ForeignFunctionInterface">\r
11017<title>ForeignFunctionInterface</title>\r
11018<simpara>MLton&#8217;s foreign function interface (FFI) extends Standard ML and makes\r
11019it easy to take the address of C global objects, access C global\r
11020variables, call from SML to C, and call from C to SML. MLton also\r
11021provides <link linkend="MLNLFFI">ML-NLFFI</link>, which is a higher-level FFI for calling\r
11022C functions and manipulating C data from SML.</simpara>\r
11023<section id="_overview">\r
11024<title>Overview</title>\r
11025<itemizedlist>\r
11026<listitem>\r
11027<simpara>\r
11028<link linkend="ForeignFunctionInterfaceTypes">Foreign Function Interface Types</link>\r
11029</simpara>\r
11030</listitem>\r
11031<listitem>\r
11032<simpara>\r
11033<link linkend="ForeignFunctionInterfaceSyntax">Foreign Function Interface Syntax</link>\r
11034</simpara>\r
11035</listitem>\r
11036</itemizedlist>\r
11037</section>\r
11038<section id="_importing_code_into_sml">\r
11039<title>Importing Code into SML</title>\r
11040<itemizedlist>\r
11041<listitem>\r
11042<simpara>\r
11043<link linkend="CallingFromSMLToC">Calling From SML To C</link>\r
11044</simpara>\r
11045</listitem>\r
11046<listitem>\r
11047<simpara>\r
11048<link linkend="CallingFromSMLToCFunctionPointer">Calling From SML To C Function Pointer</link>\r
11049</simpara>\r
11050</listitem>\r
11051</itemizedlist>\r
11052</section>\r
11053<section id="_exporting_code_from_sml">\r
11054<title>Exporting Code from SML</title>\r
11055<itemizedlist>\r
11056<listitem>\r
11057<simpara>\r
11058<link linkend="CallingFromCToSML">Calling From C To SML</link>\r
11059</simpara>\r
11060</listitem>\r
11061</itemizedlist>\r
11062</section>\r
11063<section id="_building_system_libraries">\r
11064<title>Building System Libraries</title>\r
11065<itemizedlist>\r
11066<listitem>\r
11067<simpara>\r
11068<link linkend="LibrarySupport">Library Support</link>\r
11069</simpara>\r
11070</listitem>\r
11071</itemizedlist>\r
11072<simpara><?asciidoc-pagebreak?></simpara>\r
11073</section>\r
11074</section>\r
11075<section id="ForeignFunctionInterfaceSyntax">\r
11076<title>ForeignFunctionInterfaceSyntax</title>\r
11077<simpara>MLton extends the syntax of SML with expressions that enable a\r
11078<link linkend="ForeignFunctionInterface">ForeignFunctionInterface</link> to C. The following description of the\r
11079syntax uses some abbreviations.</simpara>\r
11080<informaltable\r
11081frame="all"\r
11082rowsep="1" colsep="1"\r
11083>\r
11084<tgroup cols="3">\r
11085<colspec colname="col_1" colwidth="33*"/>\r
11086<colspec colname="col_2" colwidth="33*"/>\r
11087<colspec colname="col_3" colwidth="33*"/>\r
11088<thead>\r
11089<row>\r
11090<entry align="left" valign="top"> C base type </entry>\r
11091<entry align="left" valign="top"> <emphasis>cBaseTy</emphasis> </entry>\r
11092<entry align="left" valign="top"> <link linkend="ForeignFunctionInterfaceTypes">Foreign Function Interface types</link></entry>\r
11093</row>\r
11094</thead>\r
11095<tbody>\r
11096<row>\r
11097<entry align="left" valign="top"><simpara>C argument type</simpara></entry>\r
11098<entry align="left" valign="top"><simpara><emphasis>cArgTy</emphasis></simpara></entry>\r
11099<entry align="left" valign="top"><simpara><emphasis>cBaseTy</emphasis><subscript>1</subscript> <literal>*</literal> &#8230; <literal>*</literal> <emphasis>cBaseTy</emphasis><subscript>n</subscript> or <literal>unit</literal></simpara></entry>\r
11100</row>\r
11101<row>\r
11102<entry align="left" valign="top"><simpara>C return type</simpara></entry>\r
11103<entry align="left" valign="top"><simpara><emphasis>cRetTy</emphasis></simpara></entry>\r
11104<entry align="left" valign="top"><simpara><emphasis>cBaseTy</emphasis> or <literal>unit</literal></simpara></entry>\r
11105</row>\r
11106<row>\r
11107<entry align="left" valign="top"><simpara>C function type</simpara></entry>\r
11108<entry align="left" valign="top"><simpara><emphasis>cFuncTy</emphasis></simpara></entry>\r
11109<entry align="left" valign="top"><simpara><emphasis>cArgTy</emphasis> <literal>-&gt;</literal> <emphasis>cRetTy</emphasis></simpara></entry>\r
11110</row>\r
11111<row>\r
11112<entry align="left" valign="top"><simpara>C pointer type</simpara></entry>\r
11113<entry align="left" valign="top"><simpara><emphasis>cPtrTy</emphasis></simpara></entry>\r
11114<entry align="left" valign="top"><simpara><literal>MLton.Pointer.t</literal></simpara></entry>\r
11115</row>\r
11116</tbody>\r
11117</tgroup>\r
11118</informaltable>\r
11119<simpara>The type annotation and the semicolon are not optional in the syntax\r
11120of <link linkend="ForeignFunctionInterface">ForeignFunctionInterface</link> expressions. However, the type is\r
11121lexed, parsed, and elaborated as an SML type, so any type (including\r
11122type abbreviations) may be used, so long as it elaborates to a type of\r
11123the correct form.</simpara>\r
11124<section id="_address">\r
11125<title>Address</title>\r
11126<screen>_address "CFunctionOrVariableName" attr... : cPtrTy;</screen>\r
11127<simpara>Denotes the address of the C function or variable.</simpara>\r
11128<simpara><literal>attr...</literal> denotes a (possibly empty) sequence of attributes. The following attributes are recognized:</simpara>\r
11129<itemizedlist>\r
11130<listitem>\r
11131<simpara>\r
11132<literal>external</literal> : import with external symbol scope (see <link linkend="LibrarySupport">LibrarySupport</link>) (default).\r
11133</simpara>\r
11134</listitem>\r
11135<listitem>\r
11136<simpara>\r
11137<literal>private</literal> : import with private symbol scope (see <link linkend="LibrarySupport">LibrarySupport</link>).\r
11138</simpara>\r
11139</listitem>\r
11140<listitem>\r
11141<simpara>\r
11142<literal>public</literal> : import with public symbol scope (see <link linkend="LibrarySupport">LibrarySupport</link>).\r
11143</simpara>\r
11144</listitem>\r
11145</itemizedlist>\r
11146<simpara>See <link linkend="MLtonPointer">MLtonPointer</link> for functions that manipulate C pointers.</simpara>\r
11147</section>\r
11148<section id="_symbol">\r
11149<title>Symbol</title>\r
11150<screen>_symbol "CVariableName" attr... : (unit -&gt; cBaseTy) * (cBaseTy -&gt; unit);</screen>\r
11151<simpara>Denotes the <emphasis>getter</emphasis> and <emphasis>setter</emphasis> for a C variable. The <emphasis>cBaseTy</emphasis>s\r
11152must be identical.</simpara>\r
11153<simpara><literal>attr...</literal> denotes a (possibly empty) sequence of attributes. The following attributes are recognized:</simpara>\r
11154<itemizedlist>\r
11155<listitem>\r
11156<simpara>\r
11157<literal>alloc</literal> : allocate storage (and export a symbol) for the C variable.\r
11158</simpara>\r
11159</listitem>\r
11160<listitem>\r
11161<simpara>\r
11162<literal>external</literal> : import or export with external symbol scope (see <link linkend="LibrarySupport">LibrarySupport</link>) (default if not <literal>alloc</literal>).\r
11163</simpara>\r
11164</listitem>\r
11165<listitem>\r
11166<simpara>\r
11167<literal>private</literal> : import or export with private symbol scope (see <link linkend="LibrarySupport">LibrarySupport</link>).\r
11168</simpara>\r
11169</listitem>\r
11170<listitem>\r
11171<simpara>\r
11172<literal>public</literal> : import or export with public symbol scope (see <link linkend="LibrarySupport">LibrarySupport</link>) (default if <literal>alloc</literal>).\r
11173</simpara>\r
11174</listitem>\r
11175</itemizedlist>\r
11176<screen>_symbol * : cPtrTy -&gt; (unit -&gt; cBaseTy) * (cBaseTy -&gt; unit);</screen>\r
11177<simpara>Denotes the <emphasis>getter</emphasis> and <emphasis>setter</emphasis> for a C pointer to a variable.\r
11178The <emphasis>cBaseTy</emphasis>s must be identical.</simpara>\r
11179</section>\r
11180<section id="_import">\r
11181<title>Import</title>\r
11182<screen>_import "CFunctionName" attr... : cFuncTy;</screen>\r
11183<simpara>Denotes an SML function whose behavior is implemented by calling the C\r
11184function. See <link linkend="CallingFromSMLToC">Calling from SML to C</link> for more\r
11185details.</simpara>\r
11186<simpara><literal>attr...</literal> denotes a (possibly empty) sequence of attributes. The following attributes are recognized:</simpara>\r
11187<itemizedlist>\r
11188<listitem>\r
11189<simpara>\r
11190<literal>cdecl</literal> : call with the <literal>cdecl</literal> calling convention (default).\r
11191</simpara>\r
11192</listitem>\r
11193<listitem>\r
11194<simpara>\r
11195<literal>external</literal> : import with external symbol scope (see <link linkend="LibrarySupport">LibrarySupport</link>) (default).\r
11196</simpara>\r
11197</listitem>\r
11198<listitem>\r
11199<simpara>\r
11200<literal>impure</literal>: assert that the function depends upon state and/or performs side effects (default).\r
11201</simpara>\r
11202</listitem>\r
11203<listitem>\r
11204<simpara>\r
11205<literal>private</literal> : import with private symbol scope (see <link linkend="LibrarySupport">LibrarySupport</link>).\r
11206</simpara>\r
11207</listitem>\r
11208<listitem>\r
11209<simpara>\r
11210<literal>public</literal> : import with public symbol scope (see <link linkend="LibrarySupport">LibrarySupport</link>).\r
11211</simpara>\r
11212</listitem>\r
11213<listitem>\r
11214<simpara>\r
11215<literal>pure</literal>: assert that the function does not depend upon state or perform any side effects; such functions are subject to various optimizations (e.g., <link linkend="CommonSubexp">CommonSubexp</link>, <link linkend="RemoveUnused">RemoveUnused</link>)\r
11216</simpara>\r
11217</listitem>\r
11218<listitem>\r
11219<simpara>\r
11220<literal>reentrant</literal>: assert that the function (directly or indirectly) calls an <literal>_export</literal>-ed SML function.\r
11221</simpara>\r
11222</listitem>\r
11223<listitem>\r
11224<simpara>\r
11225<literal>stdcall</literal> : call with the <literal>stdcall</literal> calling convention (ignored except on Cygwin and MinGW).\r
11226</simpara>\r
11227</listitem>\r
11228</itemizedlist>\r
11229<screen>_import * attr... : cPtrTy -&gt; cFuncTy;</screen>\r
11230<simpara>Denotes an SML function whose behavior is implemented by calling a C\r
11231function through a C function pointer.</simpara>\r
11232<simpara><literal>attr...</literal> denotes a (possibly empty) sequence of attributes. The following attributes are recognized:</simpara>\r
11233<itemizedlist>\r
11234<listitem>\r
11235<simpara>\r
11236<literal>cdecl</literal> : call with the <literal>cdecl</literal> calling convention (default).\r
11237</simpara>\r
11238</listitem>\r
11239<listitem>\r
11240<simpara>\r
11241<literal>impure</literal>: assert that the function depends upon state and/or performs side effects (default).\r
11242</simpara>\r
11243</listitem>\r
11244<listitem>\r
11245<simpara>\r
11246<literal>pure</literal>: assert that the function does not depend upon state or perform any side effects; such functions are subject to various optimizations (e.g., <link linkend="CommonSubexp">CommonSubexp</link>, <link linkend="RemoveUnused">RemoveUnused</link>)\r
11247</simpara>\r
11248</listitem>\r
11249<listitem>\r
11250<simpara>\r
11251<literal>reentrant</literal>: assert that the function (directly or indirectly) calls an <literal>_export</literal>-ed SML function.\r
11252</simpara>\r
11253</listitem>\r
11254<listitem>\r
11255<simpara>\r
11256<literal>stdcall</literal> : call with the <literal>stdcall</literal> calling convention (ignored except on Cygwin and MinGW).\r
11257</simpara>\r
11258</listitem>\r
11259</itemizedlist>\r
11260<simpara>See\r
11261<link linkend="CallingFromSMLToCFunctionPointer">Calling from SML to C function pointer</link>\r
11262for more details.</simpara>\r
11263</section>\r
11264<section id="_export">\r
11265<title>Export</title>\r
11266<screen>_export "CFunctionName" attr... : cFuncTy -&gt; unit;</screen>\r
11267<simpara>Exports a C function with the name <literal>CFunctionName</literal> that can be used to\r
11268call an SML function of the type <emphasis>cFuncTy</emphasis>. When the function denoted\r
11269by the export expression is applied to an SML function <literal>f</literal>, subsequent\r
11270C calls to <literal>CFunctionName</literal> will call <literal>f</literal>. It is an error to call\r
11271<literal>CFunctionName</literal> before the export has been applied. The export may be\r
11272applied more than once, with each application replacing any previous\r
11273definition of <literal>CFunctionName</literal>.</simpara>\r
11274<simpara><literal>attr...</literal> denotes a (possibly empty) sequence of attributes. The following attributes are recognized:</simpara>\r
11275<itemizedlist>\r
11276<listitem>\r
11277<simpara>\r
11278<literal>cdecl</literal> : call with the <literal>cdecl</literal> calling convention (default).\r
11279</simpara>\r
11280</listitem>\r
11281<listitem>\r
11282<simpara>\r
11283<literal>private</literal> : export with private symbol scope (see <link linkend="LibrarySupport">LibrarySupport</link>).\r
11284</simpara>\r
11285</listitem>\r
11286<listitem>\r
11287<simpara>\r
11288<literal>public</literal> : export with public symbol scope (see <link linkend="LibrarySupport">LibrarySupport</link>) (default).\r
11289</simpara>\r
11290</listitem>\r
11291<listitem>\r
11292<simpara>\r
11293<literal>stdcall</literal> : call with the <literal>stdcall</literal> calling convention (ignored except on Cygwin and MinGW).\r
11294</simpara>\r
11295</listitem>\r
11296</itemizedlist>\r
11297<simpara>See <link linkend="CallingFromCToSML">Calling from C to SML</link> for more details.</simpara>\r
11298<simpara><?asciidoc-pagebreak?></simpara>\r
11299</section>\r
11300</section>\r
11301<section id="ForeignFunctionInterfaceTypes">\r
11302<title>ForeignFunctionInterfaceTypes</title>\r
11303<simpara>MLton&#8217;s <link linkend="ForeignFunctionInterface">ForeignFunctionInterface</link> only allows values of certain SML\r
11304types to be passed between SML and C. The following types are\r
11305allowed: <literal>bool</literal>, <literal>char</literal>, <literal>int</literal>, <literal>real</literal>, <literal>word</literal>. All of the different\r
11306sizes of (fixed-sized) integers, reals, and words are supported as\r
11307well: <literal>Int8.int</literal>, <literal>Int16.int</literal>, <literal>Int32.int</literal>, <literal>Int64.int</literal>,\r
11308<literal>Real32.real</literal>, <literal>Real64.real</literal>, <literal>Word8.word</literal>, <literal>Word16.word</literal>,\r
11309<literal>Word32.word</literal>, <literal>Word64.word</literal>. There is a special type,\r
11310<literal>MLton.Pointer.t</literal>, for passing C pointers&#8201;&#8212;&#8201;see <link linkend="MLtonPointer">MLtonPointer</link> for\r
11311details.</simpara>\r
11312<simpara>Arrays, refs, and vectors of the above types are also allowed.\r
11313Because in MLton monomorphic arrays and vectors are exactly the same\r
11314as their polymorphic counterpart, these are also allowed. Hence,\r
11315<literal>string</literal>, <literal>char vector</literal>, and <literal>CharVector.vector</literal> are also allowed.\r
11316Strings are not null terminated, unless you manually do so from the\r
11317SML side.</simpara>\r
11318<simpara>Unfortunately, passing tuples or datatypes is not allowed because that\r
11319would interfere with representation optimizations.</simpara>\r
11320<simpara>The C header file that <literal>-export-header</literal> generates includes\r
11321<literal>typedef</literal>s for the C types corresponding to the SML types. Here is\r
11322the mapping between SML types and C types.</simpara>\r
11323<informaltable\r
11324frame="all"\r
11325rowsep="1" colsep="1"\r
11326>\r
11327<tgroup cols="4">\r
11328<colspec colname="col_1" colwidth="25*"/>\r
11329<colspec colname="col_2" colwidth="25*"/>\r
11330<colspec colname="col_3" colwidth="25*"/>\r
11331<colspec colname="col_4" colwidth="25*"/>\r
11332<thead>\r
11333<row>\r
11334<entry align="left" valign="top"> SML type </entry>\r
11335<entry align="left" valign="top"> C typedef </entry>\r
11336<entry align="left" valign="top"> C type </entry>\r
11337<entry align="left" valign="top"> Note</entry>\r
11338</row>\r
11339</thead>\r
11340<tbody>\r
11341<row>\r
11342<entry align="left" valign="top"><simpara><literal>array</literal></simpara></entry>\r
11343<entry align="left" valign="top"><simpara><literal>Pointer</literal></simpara></entry>\r
11344<entry align="left" valign="top"><simpara><literal>unsigned char *</literal></simpara></entry>\r
11345<entry align="left" valign="top"><simpara></simpara></entry>\r
11346</row>\r
11347<row>\r
11348<entry align="left" valign="top"><simpara><literal>bool</literal></simpara></entry>\r
11349<entry align="left" valign="top"><simpara><literal>Bool</literal></simpara></entry>\r
11350<entry align="left" valign="top"><simpara><literal>int32_t</literal></simpara></entry>\r
11351<entry align="left" valign="top"><simpara></simpara></entry>\r
11352</row>\r
11353<row>\r
11354<entry align="left" valign="top"><simpara><literal>char</literal></simpara></entry>\r
11355<entry align="left" valign="top"><simpara><literal>Char8</literal></simpara></entry>\r
11356<entry align="left" valign="top"><simpara><literal>uint8_t</literal></simpara></entry>\r
11357<entry align="left" valign="top"><simpara></simpara></entry>\r
11358</row>\r
11359<row>\r
11360<entry align="left" valign="top"><simpara><literal>Int8.int</literal></simpara></entry>\r
11361<entry align="left" valign="top"><simpara><literal>Int8</literal></simpara></entry>\r
11362<entry align="left" valign="top"><simpara><literal>int8_t</literal></simpara></entry>\r
11363<entry align="left" valign="top"><simpara></simpara></entry>\r
11364</row>\r
11365<row>\r
11366<entry align="left" valign="top"><simpara><literal>Int16.int</literal></simpara></entry>\r
11367<entry align="left" valign="top"><simpara><literal>Int16</literal></simpara></entry>\r
11368<entry align="left" valign="top"><simpara><literal>int16_t</literal></simpara></entry>\r
11369<entry align="left" valign="top"><simpara></simpara></entry>\r
11370</row>\r
11371<row>\r
11372<entry align="left" valign="top"><simpara><literal>Int32.int</literal></simpara></entry>\r
11373<entry align="left" valign="top"><simpara><literal>Int32</literal></simpara></entry>\r
11374<entry align="left" valign="top"><simpara><literal>int32_t</literal></simpara></entry>\r
11375<entry align="left" valign="top"><simpara></simpara></entry>\r
11376</row>\r
11377<row>\r
11378<entry align="left" valign="top"><simpara><literal>Int64.int</literal></simpara></entry>\r
11379<entry align="left" valign="top"><simpara><literal>Int64</literal></simpara></entry>\r
11380<entry align="left" valign="top"><simpara><literal>int64_t</literal></simpara></entry>\r
11381<entry align="left" valign="top"><simpara></simpara></entry>\r
11382</row>\r
11383<row>\r
11384<entry align="left" valign="top"><simpara><literal>int</literal></simpara></entry>\r
11385<entry align="left" valign="top"><simpara><literal>Int32</literal></simpara></entry>\r
11386<entry align="left" valign="top"><simpara><literal>int32_t</literal></simpara></entry>\r
11387<entry align="left" valign="top"><simpara><link linkend="ForeignFunctionInterfaceTypes_Default">(default)</link></simpara></entry>\r
11388</row>\r
11389<row>\r
11390<entry align="left" valign="top"><simpara><literal>MLton.Pointer.t</literal></simpara></entry>\r
11391<entry align="left" valign="top"><simpara><literal>Pointer</literal></simpara></entry>\r
11392<entry align="left" valign="top"><simpara><literal>unsigned char *</literal></simpara></entry>\r
11393<entry align="left" valign="top"><simpara></simpara></entry>\r
11394</row>\r
11395<row>\r
11396<entry align="left" valign="top"><simpara><literal>Real32.real</literal></simpara></entry>\r
11397<entry align="left" valign="top"><simpara><literal>Real32</literal></simpara></entry>\r
11398<entry align="left" valign="top"><simpara><literal>float</literal></simpara></entry>\r
11399<entry align="left" valign="top"><simpara></simpara></entry>\r
11400</row>\r
11401<row>\r
11402<entry align="left" valign="top"><simpara><literal>Real64.real</literal></simpara></entry>\r
11403<entry align="left" valign="top"><simpara><literal>Real64</literal></simpara></entry>\r
11404<entry align="left" valign="top"><simpara><literal>double</literal></simpara></entry>\r
11405<entry align="left" valign="top"><simpara></simpara></entry>\r
11406</row>\r
11407<row>\r
11408<entry align="left" valign="top"><simpara><literal>real</literal></simpara></entry>\r
11409<entry align="left" valign="top"><simpara><literal>Real64</literal></simpara></entry>\r
11410<entry align="left" valign="top"><simpara><literal>double</literal></simpara></entry>\r
11411<entry align="left" valign="top"><simpara><link linkend="ForeignFunctionInterfaceTypes_Default">(default)</link></simpara></entry>\r
11412</row>\r
11413<row>\r
11414<entry align="left" valign="top"><simpara><literal>ref</literal></simpara></entry>\r
11415<entry align="left" valign="top"><simpara><literal>Pointer</literal></simpara></entry>\r
11416<entry align="left" valign="top"><simpara><literal>unsigned char *</literal></simpara></entry>\r
11417<entry align="left" valign="top"><simpara></simpara></entry>\r
11418</row>\r
11419<row>\r
11420<entry align="left" valign="top"><simpara><literal>string</literal></simpara></entry>\r
11421<entry align="left" valign="top"><simpara><literal>Pointer</literal></simpara></entry>\r
11422<entry align="left" valign="top"><simpara><literal>unsigned char *</literal></simpara></entry>\r
11423<entry align="left" valign="top"><simpara><link linkend="ForeignFunctionInterfaceTypes_ReadOnly">(read only)</link></simpara></entry>\r
11424</row>\r
11425<row>\r
11426<entry align="left" valign="top"><simpara><literal>vector</literal></simpara></entry>\r
11427<entry align="left" valign="top"><simpara><literal>Pointer</literal></simpara></entry>\r
11428<entry align="left" valign="top"><simpara><literal>unsigned char *</literal></simpara></entry>\r
11429<entry align="left" valign="top"><simpara><link linkend="ForeignFunctionInterfaceTypes_ReadOnly">(read only)</link></simpara></entry>\r
11430</row>\r
11431<row>\r
11432<entry align="left" valign="top"><simpara><literal>Word8.word</literal></simpara></entry>\r
11433<entry align="left" valign="top"><simpara><literal>Word8</literal></simpara></entry>\r
11434<entry align="left" valign="top"><simpara><literal>uint8_t</literal></simpara></entry>\r
11435<entry align="left" valign="top"><simpara></simpara></entry>\r
11436</row>\r
11437<row>\r
11438<entry align="left" valign="top"><simpara><literal>Word16.word</literal></simpara></entry>\r
11439<entry align="left" valign="top"><simpara><literal>Word16</literal></simpara></entry>\r
11440<entry align="left" valign="top"><simpara><literal>uint16_t</literal></simpara></entry>\r
11441<entry align="left" valign="top"><simpara></simpara></entry>\r
11442</row>\r
11443<row>\r
11444<entry align="left" valign="top"><simpara><literal>Word32.word</literal></simpara></entry>\r
11445<entry align="left" valign="top"><simpara><literal>Word32</literal></simpara></entry>\r
11446<entry align="left" valign="top"><simpara><literal>uint32_t</literal></simpara></entry>\r
11447<entry align="left" valign="top"><simpara></simpara></entry>\r
11448</row>\r
11449<row>\r
11450<entry align="left" valign="top"><simpara><literal>Word64.word</literal></simpara></entry>\r
11451<entry align="left" valign="top"><simpara><literal>Word64</literal></simpara></entry>\r
11452<entry align="left" valign="top"><simpara><literal>uint64_t</literal></simpara></entry>\r
11453<entry align="left" valign="top"><simpara></simpara></entry>\r
11454</row>\r
11455<row>\r
11456<entry align="left" valign="top"><simpara><literal>word</literal></simpara></entry>\r
11457<entry align="left" valign="top"><simpara><literal>Word32</literal></simpara></entry>\r
11458<entry align="left" valign="top"><simpara><literal>uint32_t</literal></simpara></entry>\r
11459<entry align="left" valign="top"><simpara><link linkend="ForeignFunctionInterfaceTypes_Default">(default)</link></simpara></entry>\r
11460</row>\r
11461</tbody>\r
11462</tgroup>\r
11463</informaltable>\r
11464<simpara><anchor id="ForeignFunctionInterfaceTypes_Default" xreflabel="[ForeignFunctionInterfaceTypes_Default]"/>Note (default): The default <literal>int</literal>, <literal>real</literal>, and\r
11465<literal>word</literal> types may be set by the <literal>-default-type <emphasis>type</emphasis></literal>\r
11466<link linkend="CompileTimeOptions">compiler option</link>. The given C typedef and C\r
11467types correspond to the default behavior.</simpara>\r
11468<simpara><anchor id="ForeignFunctionInterfaceTypes_ReadOnly" xreflabel="[ForeignFunctionInterfaceTypes_ReadOnly]"/>Note (read only): Because MLton assumes that\r
11469vectors and strings are read-only (and will perform optimizations\r
11470that, for instance, cause them to share space), you must not modify\r
11471the data pointed to by the <literal>unsigned char *</literal> in C code.</simpara>\r
11472<simpara>Although the C type of an array, ref, or vector is always <literal>Pointer</literal>,\r
11473in reality, the object has the natural C representation. Your C code\r
11474should cast to the appropriate C type if you want to keep the C\r
11475compiler from complaining.</simpara>\r
11476<simpara>When calling an <link linkend="CallingFromSMLToC">imported C function from SML</link>\r
11477that returns an array, ref, or vector result or when calling an\r
11478<link linkend="CallingFromCToSML">exported SML function from C</link> that takes an\r
11479array, ref, or string argument, then the object must be an ML object\r
11480allocated on the ML heap. (Although an array, ref, or vector object\r
11481has the natural C representation, the object also has an additional\r
11482header used by the SML runtime system.)</simpara>\r
11483<simpara>In addition, there is an <link linkend="MLBasis">MLBasis</link> file, <literal>$(SML_LIB)/basis/c-types.mlb</literal>,\r
11484which provides structure aliases for various C types:</simpara>\r
11485<informaltable\r
11486frame="all"\r
11487rowsep="1" colsep="1"\r
11488>\r
11489<tgroup cols="3">\r
11490<colspec colname="col_1" colwidth="33*"/>\r
11491<colspec colname="col_2" colwidth="33*"/>\r
11492<colspec colname="col_3" colwidth="33*"/>\r
11493<tbody>\r
11494<row>\r
11495<entry align="left" valign="top"><simpara>C type</simpara></entry>\r
11496<entry align="left" valign="top"><simpara>Structure</simpara></entry>\r
11497<entry align="left" valign="top"><simpara>Signature</simpara></entry>\r
11498</row>\r
11499<row>\r
11500<entry align="left" valign="top"><simpara><literal>char</literal></simpara></entry>\r
11501<entry align="left" valign="top"><simpara><literal>C_Char</literal></simpara></entry>\r
11502<entry align="left" valign="top"><simpara><literal>INTEGER</literal></simpara></entry>\r
11503</row>\r
11504<row>\r
11505<entry align="left" valign="top"><simpara><literal>signed char</literal></simpara></entry>\r
11506<entry align="left" valign="top"><simpara><literal>C_SChar</literal></simpara></entry>\r
11507<entry align="left" valign="top"><simpara><literal>INTEGER</literal></simpara></entry>\r
11508</row>\r
11509<row>\r
11510<entry align="left" valign="top"><simpara><literal>unsigned char</literal></simpara></entry>\r
11511<entry align="left" valign="top"><simpara><literal>C_UChar</literal></simpara></entry>\r
11512<entry align="left" valign="top"><simpara><literal>WORD</literal></simpara></entry>\r
11513</row>\r
11514<row>\r
11515<entry align="left" valign="top"><simpara><literal>short</literal></simpara></entry>\r
11516<entry align="left" valign="top"><simpara><literal>C_Short</literal></simpara></entry>\r
11517<entry align="left" valign="top"><simpara><literal>INTEGER</literal></simpara></entry>\r
11518</row>\r
11519<row>\r
11520<entry align="left" valign="top"><simpara><literal>signed short</literal></simpara></entry>\r
11521<entry align="left" valign="top"><simpara><literal>C_SShort</literal></simpara></entry>\r
11522<entry align="left" valign="top"><simpara><literal>INTEGER</literal></simpara></entry>\r
11523</row>\r
11524<row>\r
11525<entry align="left" valign="top"><simpara><literal>unsigned short</literal></simpara></entry>\r
11526<entry align="left" valign="top"><simpara><literal>C_UShort</literal></simpara></entry>\r
11527<entry align="left" valign="top"><simpara><literal>WORD</literal></simpara></entry>\r
11528</row>\r
11529<row>\r
11530<entry align="left" valign="top"><simpara><literal>int</literal></simpara></entry>\r
11531<entry align="left" valign="top"><simpara><literal>C_Int</literal></simpara></entry>\r
11532<entry align="left" valign="top"><simpara><literal>INTEGER</literal></simpara></entry>\r
11533</row>\r
11534<row>\r
11535<entry align="left" valign="top"><simpara><literal>signed int</literal></simpara></entry>\r
11536<entry align="left" valign="top"><simpara><literal>C_SInt</literal></simpara></entry>\r
11537<entry align="left" valign="top"><simpara><literal>INTEGER</literal></simpara></entry>\r
11538</row>\r
11539<row>\r
11540<entry align="left" valign="top"><simpara><literal>unsigned int</literal></simpara></entry>\r
11541<entry align="left" valign="top"><simpara><literal>C_UInt</literal></simpara></entry>\r
11542<entry align="left" valign="top"><simpara><literal>WORD</literal></simpara></entry>\r
11543</row>\r
11544<row>\r
11545<entry align="left" valign="top"><simpara><literal>long</literal></simpara></entry>\r
11546<entry align="left" valign="top"><simpara><literal>C_Long</literal></simpara></entry>\r
11547<entry align="left" valign="top"><simpara><literal>INTEGER</literal></simpara></entry>\r
11548</row>\r
11549<row>\r
11550<entry align="left" valign="top"><simpara><literal>signed long</literal></simpara></entry>\r
11551<entry align="left" valign="top"><simpara><literal>C_SLong</literal></simpara></entry>\r
11552<entry align="left" valign="top"><simpara><literal>INTEGER</literal></simpara></entry>\r
11553</row>\r
11554<row>\r
11555<entry align="left" valign="top"><simpara><literal>unsigned long</literal></simpara></entry>\r
11556<entry align="left" valign="top"><simpara><literal>C_ULong</literal></simpara></entry>\r
11557<entry align="left" valign="top"><simpara><literal>WORD</literal></simpara></entry>\r
11558</row>\r
11559<row>\r
11560<entry align="left" valign="top"><simpara><literal>long long</literal></simpara></entry>\r
11561<entry align="left" valign="top"><simpara><literal>C_LongLong</literal></simpara></entry>\r
11562<entry align="left" valign="top"><simpara><literal>INTEGER</literal></simpara></entry>\r
11563</row>\r
11564<row>\r
11565<entry align="left" valign="top"><simpara><literal>signed long long</literal></simpara></entry>\r
11566<entry align="left" valign="top"><simpara><literal>C_SLongLong</literal></simpara></entry>\r
11567<entry align="left" valign="top"><simpara><literal>INTEGER</literal></simpara></entry>\r
11568</row>\r
11569<row>\r
11570<entry align="left" valign="top"><simpara><literal>unsigned long long</literal></simpara></entry>\r
11571<entry align="left" valign="top"><simpara><literal>C_ULongLong</literal></simpara></entry>\r
11572<entry align="left" valign="top"><simpara><literal>WORD</literal></simpara></entry>\r
11573</row>\r
11574<row>\r
11575<entry align="left" valign="top"><simpara><literal>float</literal></simpara></entry>\r
11576<entry align="left" valign="top"><simpara><literal>C_Float</literal></simpara></entry>\r
11577<entry align="left" valign="top"><simpara><literal>REAL</literal></simpara></entry>\r
11578</row>\r
11579<row>\r
11580<entry align="left" valign="top"><simpara><literal>double</literal></simpara></entry>\r
11581<entry align="left" valign="top"><simpara><literal>C_Double</literal></simpara></entry>\r
11582<entry align="left" valign="top"><simpara><literal>REAL</literal></simpara></entry>\r
11583</row>\r
11584<row>\r
11585<entry align="left" valign="top"><simpara><literal>size_t</literal></simpara></entry>\r
11586<entry align="left" valign="top"><simpara><literal>C_Size</literal></simpara></entry>\r
11587<entry align="left" valign="top"><simpara><literal>WORD</literal></simpara></entry>\r
11588</row>\r
11589<row>\r
11590<entry align="left" valign="top"><simpara><literal>ptrdiff_t</literal></simpara></entry>\r
11591<entry align="left" valign="top"><simpara><literal>C_Ptrdiff</literal></simpara></entry>\r
11592<entry align="left" valign="top"><simpara><literal>INTEGER</literal></simpara></entry>\r
11593</row>\r
11594<row>\r
11595<entry align="left" valign="top"><simpara><literal>intmax_t</literal></simpara></entry>\r
11596<entry align="left" valign="top"><simpara><literal>C_Intmax</literal></simpara></entry>\r
11597<entry align="left" valign="top"><simpara><literal>INTEGER</literal></simpara></entry>\r
11598</row>\r
11599<row>\r
11600<entry align="left" valign="top"><simpara><literal>uintmax_t</literal></simpara></entry>\r
11601<entry align="left" valign="top"><simpara><literal>C_UIntmax</literal></simpara></entry>\r
11602<entry align="left" valign="top"><simpara><literal>WORD</literal></simpara></entry>\r
11603</row>\r
11604<row>\r
11605<entry align="left" valign="top"><simpara><literal>intptr_t</literal></simpara></entry>\r
11606<entry align="left" valign="top"><simpara><literal>C_Intptr</literal></simpara></entry>\r
11607<entry align="left" valign="top"><simpara><literal>INTEGER</literal></simpara></entry>\r
11608</row>\r
11609<row>\r
11610<entry align="left" valign="top"><simpara><literal>uintptr_t</literal></simpara></entry>\r
11611<entry align="left" valign="top"><simpara><literal>C_UIntptr</literal></simpara></entry>\r
11612<entry align="left" valign="top"><simpara><literal>WORD</literal></simpara></entry>\r
11613</row>\r
11614<row>\r
11615<entry align="left" valign="top"><simpara><literal>void *</literal></simpara></entry>\r
11616<entry align="left" valign="top"><simpara><literal>C_Pointer</literal></simpara></entry>\r
11617<entry align="left" valign="top"><simpara><literal>WORD</literal></simpara></entry>\r
11618</row>\r
11619</tbody>\r
11620</tgroup>\r
11621</informaltable>\r
11622<simpara>These aliases depend on the configuration of the C compiler for the\r
11623target architecture, and are independent of the configuration of MLton\r
11624(including the <literal>-default-type <emphasis>type</emphasis></literal>\r
11625<link linkend="CompileTimeOptions">compiler option</link>).</simpara>\r
11626<simpara><?asciidoc-pagebreak?></simpara>\r
11627</section>\r
11628<section id="ForLoops">\r
11629<title>ForLoops</title>\r
11630<simpara>A <literal>for</literal>-loop is typically used to iterate over a range of consecutive\r
11631integers that denote indices of some sort. For example, in <link linkend="OCaml">OCaml</link>\r
11632a <literal>for</literal>-loop takes either the form</simpara>\r
11633<screen>for &lt;name&gt; = &lt;lower&gt; to &lt;upper&gt; do &lt;body&gt; done</screen>\r
11634<simpara>or the form</simpara>\r
11635<screen>for &lt;name&gt; = &lt;upper&gt; downto &lt;lower&gt; do &lt;body&gt; done</screen>\r
11636<simpara>Some languages provide considerably more flexible <literal>for</literal>-loop or\r
11637<literal>foreach</literal>-constructs.</simpara>\r
11638<simpara>A bit surprisingly, <link linkend="StandardML">Standard ML</link> provides special syntax\r
11639for <literal>while</literal>-loops, but not for <literal>for</literal>-loops. Indeed, in SML, many uses\r
11640of <literal>for</literal>-loops are better expressed using <literal>app</literal>, <literal>foldl</literal>/<literal>foldr</literal>,\r
11641<literal>map</literal> and many other higher-order functions provided by the\r
11642<link linkend="BasisLibrary">Basis Library</link> for manipulating lists, vectors and\r
11643arrays. However, the Basis Library does not provide a function for\r
11644iterating over a range of integer values. Fortunately, it is very\r
11645easy to write one.</simpara>\r
11646<section id="_a_fairly_simple_design">\r
11647<title>A fairly simple design</title>\r
11648<simpara>The following implementation imitates both the syntax and semantics of\r
11649the OCaml <literal>for</literal>-loop.</simpara>\r
11650<programlisting language="sml" linenumbering="unnumbered">datatype for = to of int * int\r
11651 | downto of int * int\r
11652\r
11653infix to downto\r
11654\r
11655val for =\r
11656 fn lo to up =&gt;\r
11657 (fn f =&gt; let fun loop lo = if lo &gt; up then ()\r
11658 else (f lo; loop (lo+1))\r
11659 in loop lo end)\r
11660 | up downto lo =&gt;\r
11661 (fn f =&gt; let fun loop up = if up &lt; lo then ()\r
11662 else (f up; loop (up-1))\r
11663 in loop up end)</programlisting>\r
11664<simpara>For example,</simpara>\r
11665<programlisting language="sml" linenumbering="unnumbered">for (1 to 9)\r
11666 (fn i =&gt; print (Int.toString i))</programlisting>\r
11667<simpara>would print <literal>123456789</literal> and</simpara>\r
11668<programlisting language="sml" linenumbering="unnumbered">for (9 downto 1)\r
11669 (fn i =&gt; print (Int.toString i))</programlisting>\r
11670<simpara>would print <literal>987654321</literal>.</simpara>\r
11671<simpara>Straightforward formatting of nested loops</simpara>\r
11672<programlisting language="sml" linenumbering="unnumbered">for (a to b)\r
11673 (fn i =&gt;\r
11674 for (c to d)\r
11675 (fn j =&gt;\r
11676 ...))</programlisting>\r
11677<simpara>is fairly readable, but tends to cause the body of the loop to be\r
11678indented quite deeply.</simpara>\r
11679</section>\r
11680<section id="_off_by_one">\r
11681<title>Off-by-one</title>\r
11682<simpara>The above design has an annoying feature. In practice, the upper\r
11683bound of the iterated range is almost always excluded and most loops\r
11684would subtract one from the upper bound:</simpara>\r
11685<programlisting language="sml" linenumbering="unnumbered">for (0 to n-1) ...\r
11686for (n-1 downto 0) ...</programlisting>\r
11687<simpara>It is probably better to break convention and exclude the upper bound\r
11688by default, because it leads to more concise code and becomes\r
11689idiomatic with very little practice. The iterator combinators\r
11690described below exclude the upper bound by default.</simpara>\r
11691</section>\r
11692<section id="_iterator_combinators">\r
11693<title>Iterator combinators</title>\r
11694<simpara>While the simple <literal>for</literal>-function described in the previous section is\r
11695probably good enough for many uses, it is a bit cumbersome when one\r
11696needs to iterate over a Cartesian product. One might also want to\r
11697iterate over more than just consecutive integers. It turns out that\r
11698one can provide a library of iterator combinators that allow one to\r
11699implement iterators more flexibly.</simpara>\r
11700<simpara>Since the types of the combinators may be a bit difficult to infer\r
11701from their implementations, let&#8217;s first take a look at a signature of\r
11702the iterator combinator library:</simpara>\r
11703<programlisting language="sml" linenumbering="unnumbered">signature ITER =\r
11704 sig\r
11705 type 'a t = ('a -&gt; unit) -&gt; unit\r
11706\r
11707 val return : 'a -&gt; 'a t\r
11708 val &gt;&gt;= : 'a t * ('a -&gt; 'b t) -&gt; 'b t\r
11709\r
11710 val none : 'a t\r
11711\r
11712 val to : int * int -&gt; int t\r
11713 val downto : int * int -&gt; int t\r
11714\r
11715 val inList : 'a list -&gt; 'a t\r
11716 val inVector : 'a vector -&gt; 'a t\r
11717 val inArray : 'a array -&gt; 'a t\r
11718\r
11719 val using : ('a, 'b) StringCvt.reader -&gt; 'b -&gt; 'a t\r
11720\r
11721 val when : 'a t * ('a -&gt; bool) -&gt; 'a t\r
11722 val by : 'a t * ('a -&gt; 'b) -&gt; 'b t\r
11723 val @@ : 'a t * 'a t -&gt; 'a t\r
11724 val ** : 'a t * 'b t -&gt; ('a, 'b) product t\r
11725\r
11726 val for : 'a -&gt; 'a\r
11727 end</programlisting>\r
11728<simpara>Several of the above combinators are meant to be used as infix\r
11729operators. Here is a set of suitable infix declarations:</simpara>\r
11730<programlisting language="sml" linenumbering="unnumbered">infix 2 to downto\r
11731infix 1 @@ when by\r
11732infix 0 &gt;&gt;= **</programlisting>\r
11733<simpara>A few notes are in order:</simpara>\r
11734<itemizedlist>\r
11735<listitem>\r
11736<simpara>\r
11737The <literal>'a t</literal> type constructor with the <literal>return</literal> and <literal>&gt;&gt;=</literal> operators forms a monad.\r
11738</simpara>\r
11739</listitem>\r
11740<listitem>\r
11741<simpara>\r
11742The <literal>to</literal> and <literal>downto</literal> combinators will omit the upper bound of the range.\r
11743</simpara>\r
11744</listitem>\r
11745<listitem>\r
11746<simpara>\r
11747<literal>for</literal> is the identity function. It is purely for syntactic sugar and is not strictly required.\r
11748</simpara>\r
11749</listitem>\r
11750<listitem>\r
11751<simpara>\r
11752The <literal>@@</literal> combinator produces an iterator for the concatenation of the given iterators.\r
11753</simpara>\r
11754</listitem>\r
11755<listitem>\r
11756<simpara>\r
11757The <literal>**</literal> combinator produces an iterator for the Cartesian product of the given iterators.\r
11758</simpara>\r
11759<itemizedlist>\r
11760<listitem>\r
11761<simpara>\r
11762See <link linkend="ProductType">ProductType</link> for the type constructor <literal>('a, 'b) product</literal> used in the type of the iterator produced by <literal>**</literal>.\r
11763</simpara>\r
11764</listitem>\r
11765</itemizedlist>\r
11766</listitem>\r
11767<listitem>\r
11768<simpara>\r
11769The <literal>using</literal> combinator allows one to iterate over slices, streams and many other kinds of sequences.\r
11770</simpara>\r
11771</listitem>\r
11772<listitem>\r
11773<simpara>\r
11774<literal>when</literal> is the filtering combinator. The name <literal>when</literal> is inspired by <link linkend="OCaml">OCaml</link>'s guard clauses.\r
11775</simpara>\r
11776</listitem>\r
11777<listitem>\r
11778<simpara>\r
11779<literal>by</literal> is the mapping combinator.\r
11780</simpara>\r
11781</listitem>\r
11782</itemizedlist>\r
11783<simpara>The below implementation of the <literal>ITER</literal>-signature makes use of the\r
11784following basic combinators:</simpara>\r
11785<programlisting language="sml" linenumbering="unnumbered">fun const x _ = x\r
11786fun flip f x y = f y x\r
11787fun id x = x\r
11788fun opt fno fso = fn NONE =&gt; fno () | SOME ? =&gt; fso ?\r
11789fun pass x f = f x</programlisting>\r
11790<simpara>Here is an implementation the <literal>ITER</literal>-signature:</simpara>\r
11791<programlisting language="sml" linenumbering="unnumbered">structure Iter :&gt; ITER =\r
11792 struct\r
11793 type 'a t = ('a -&gt; unit) -&gt; unit\r
11794\r
11795 val return = pass\r
11796 fun (iA &gt;&gt;= a2iB) f = iA (flip a2iB f)\r
11797\r
11798 val none = ignore\r
11799\r
11800 fun (l to u) f = let fun `l = if l&lt;u then (f l; `(l+1)) else () in `l end\r
11801 fun (u downto l) f = let fun `u = if u&gt;l then (f (u-1); `(u-1)) else () in `u end\r
11802\r
11803 fun inList ? = flip List.app ?\r
11804 fun inVector ? = flip Vector.app ?\r
11805 fun inArray ? = flip Array.app ?\r
11806\r
11807 fun using get s f = let fun `s = opt (const ()) (fn (x, s) =&gt; (f x; `s)) (get s) in `s end\r
11808\r
11809 fun (iA when p) f = iA (fn a =&gt; if p a then f a else ())\r
11810 fun (iA by g) f = iA (f o g)\r
11811 fun (iA @@ iB) f = (iA f : unit; iB f)\r
11812 fun (iA ** iB) f = iA (fn a =&gt; iB (fn b =&gt; f (a &amp; b)))\r
11813\r
11814 val for = id\r
11815 end</programlisting>\r
11816<simpara>Note that some of the above combinators (e.g. <literal>**</literal>) could be expressed\r
11817in terms of the other combinators, most notably <literal>return</literal> and <literal>&gt;&gt;=</literal>.\r
11818Another implementation issue worth mentioning is that <literal>downto</literal> is\r
11819written specifically to avoid computing <literal>l-1</literal>, which could cause an\r
11820<literal>Overflow</literal>.</simpara>\r
11821<simpara>To use the above combinators the <literal>Iter</literal>-structure needs to be opened</simpara>\r
11822<programlisting language="sml" linenumbering="unnumbered">open Iter</programlisting>\r
11823<simpara>and one usually also wants to declare the infix status of the\r
11824operators as shown earlier.</simpara>\r
11825<simpara>Here is an example that illustrates some of the features:</simpara>\r
11826<programlisting language="sml" linenumbering="unnumbered">for (0 to 10 when (fn x =&gt; x mod 3 &lt;&gt; 0) ** inList ["a", "b"] ** 2 downto 1 by real)\r
11827 (fn x &amp; y &amp; z =&gt;\r
11828 print ("("^Int.toString x^", \""^y^"\", "^Real.toString z^")\n"))</programlisting>\r
11829<simpara>Using the <literal>Iter</literal> combinators one can easily produce more complicated\r
11830iterators. For example, here is an iterator over a "triangle":</simpara>\r
11831<programlisting language="sml" linenumbering="unnumbered">fun triangle (l, u) = l to u &gt;&gt;= (fn i =&gt; i to u &gt;&gt;= (fn j =&gt; return (i, j)))</programlisting>\r
11832<simpara><?asciidoc-pagebreak?></simpara>\r
11833</section>\r
11834</section>\r
11835<section id="FrontEnd">\r
11836<title>FrontEnd</title>\r
11837<simpara><link linkend="FrontEnd">FrontEnd</link> is a translation pass from source to the <link linkend="AST">AST</link>\r
11838<link linkend="IntermediateLanguage">IntermediateLanguage</link>.</simpara>\r
11839<section id="_description_18">\r
11840<title>Description</title>\r
11841<simpara>This pass performs lexing and parsing to produce an abstract syntax\r
11842tree.</simpara>\r
11843</section>\r
11844<section id="_implementation_20">\r
11845<title>Implementation</title>\r
11846<itemizedlist>\r
11847<listitem>\r
11848<simpara>\r
11849<ulink url="https://github.com/MLton/mlton/blob/master/mlton/front-end/front-end.sig"><literal>front-end.sig</literal></ulink>\r
11850</simpara>\r
11851</listitem>\r
11852<listitem>\r
11853<simpara>\r
11854<ulink url="https://github.com/MLton/mlton/blob/master/mlton/front-end/front-end.fun"><literal>front-end.fun</literal></ulink>\r
11855</simpara>\r
11856</listitem>\r
11857</itemizedlist>\r
11858</section>\r
11859<section id="_details_and_notes_20">\r
11860<title>Details and Notes</title>\r
11861<simpara>The lexer is produced by <link linkend="MLLex">MLLex</link> from\r
11862<ulink url="https://github.com/MLton/mlton/blob/master/mlton/front-end/ml.lex"><literal>ml.lex</literal></ulink>.</simpara>\r
11863<simpara>The parser is produced by <link linkend="MLYacc">MLYacc</link> from\r
11864<ulink url="https://github.com/MLton/mlton/blob/master/mlton/front-end/ml.grm"><literal>ml.grm</literal></ulink>.</simpara>\r
11865<simpara>The specifications for the lexer and parser were originally taken from\r
11866<link linkend="SMLNJ">SML/NJ</link> (version 109.32), but have been heavily modified\r
11867since then.</simpara>\r
11868<simpara><?asciidoc-pagebreak?></simpara>\r
11869</section>\r
11870</section>\r
11871<section id="FSharp">\r
11872<title>FSharp</title>\r
11873<simpara><ulink url="http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/">F#</ulink>\r
11874is a functional programming language developed at Microsoft Research.\r
11875F# was partly inspired by the <link linkend="OCaml">OCaml</link> language and shares some\r
11876common core constructs with it. F# is integrated with Visual Studio\r
118772010 as a first-class language.</simpara>\r
11878<simpara><?asciidoc-pagebreak?></simpara>\r
11879</section>\r
11880<section id="FunctionalRecordUpdate">\r
11881<title>FunctionalRecordUpdate</title>\r
11882<simpara>Functional record update is the copying of a record while replacing\r
11883the values of some of the fields. <link linkend="StandardML">Standard ML</link> does not\r
11884have explicit syntax for functional record update. We will show below\r
11885how to implement functional record update in SML, with a little\r
11886boilerplate code.</simpara>\r
11887<simpara>As an example, the functional update of the record</simpara>\r
11888<programlisting language="sml" linenumbering="unnumbered">{a = 13, b = 14, c = 15}</programlisting>\r
11889<simpara>with <literal>c = 16</literal> yields a new record</simpara>\r
11890<programlisting language="sml" linenumbering="unnumbered">{a = 13, b = 14, c = 16}</programlisting>\r
11891<simpara>Functional record update also makes sense with multiple simultaneous\r
11892updates. For example, the functional update of the record above with\r
11893<literal>a = 18, c = 19</literal> yields a new record</simpara>\r
11894<programlisting language="sml" linenumbering="unnumbered">{a = 18, b = 14, c = 19}</programlisting>\r
11895<simpara>One could easily imagine an extension of the SML that supports\r
11896functional record update. For example</simpara>\r
11897<programlisting language="sml" linenumbering="unnumbered">e with {a = 16, b = 17}</programlisting>\r
11898<simpara>would create a copy of the record denoted by <literal>e</literal> with field <literal>a</literal>\r
11899replaced with <literal>16</literal> and <literal>b</literal> replaced with <literal>17</literal>.</simpara>\r
11900<simpara>Since there is no such syntax in SML, we now show how to implement\r
11901functional record update directly. We first give a simple\r
11902implementation that has a number of problems. We then give an\r
11903advanced implementation, that, while complex underneath, is a reusable\r
11904library that admits simple use.</simpara>\r
11905<section id="_simple_implementation">\r
11906<title>Simple implementation</title>\r
11907<simpara>To support functional record update on the record type</simpara>\r
11908<programlisting language="sml" linenumbering="unnumbered">{a: 'a, b: 'b, c: 'c}</programlisting>\r
11909<simpara>first, define an update function for each component.</simpara>\r
11910<programlisting language="sml" linenumbering="unnumbered">fun withA ({a = _, b, c}, a) = {a = a, b = b, c = c}\r
11911fun withB ({a, b = _, c}, b) = {a = a, b = b, c = c}\r
11912fun withC ({a, b, c = _}, c) = {a = a, b = b, c = c}</programlisting>\r
11913<simpara>Then, one can express <literal>e with {a = 16, b = 17}</literal> as</simpara>\r
11914<programlisting language="sml" linenumbering="unnumbered">withB (withA (e, 16), 17)</programlisting>\r
11915<simpara>With infix notation</simpara>\r
11916<programlisting language="sml" linenumbering="unnumbered">infix withA withB withC</programlisting>\r
11917<simpara>the syntax is almost as concise as a language extension.</simpara>\r
11918<programlisting language="sml" linenumbering="unnumbered">e withA 16 withB 17</programlisting>\r
11919<simpara>This approach suffers from the fact that the amount of boilerplate\r
11920code is quadratic in the number of record fields. Furthermore,\r
11921changing, adding, or deleting a field requires time proportional to\r
11922the number of fields (because each <literal>with<emphasis>&lt;L&gt;</emphasis></literal> function must be\r
11923changed). It is also annoying to have to define a <literal>with<emphasis>&lt;L&gt;</emphasis></literal>\r
11924function, possibly with a fixity declaration, for each field.</simpara>\r
11925<simpara>Fortunately, there is a solution to these problems.</simpara>\r
11926</section>\r
11927<section id="_advanced_implementation">\r
11928<title>Advanced implementation</title>\r
11929<simpara>Using <link linkend="Fold">Fold</link> one can define a family of <literal>makeUpdate<emphasis>&lt;N&gt;</emphasis></literal>\r
11930functions and single <emphasis>update</emphasis> operator <literal>U</literal> so that one can define a\r
11931functional record update function for any record type simply by\r
11932specifying a (trivial) isomorphism between that type and function\r
11933argument list. For example, suppose that we would like to do\r
11934functional record update on records with fields <literal>a</literal> and <literal>b</literal>. Then one\r
11935defines a function <literal>updateAB</literal> as follows.</simpara>\r
11936<programlisting language="sml" linenumbering="unnumbered">val updateAB =\r
11937 fn z =&gt;\r
11938 let\r
11939 fun from v1 v2 = {a = v1, b = v2}\r
11940 fun to f {a = v1, b = v2} = f v1 v2\r
11941 in\r
11942 makeUpdate2 (from, from, to)\r
11943 end\r
11944 z</programlisting>\r
11945<simpara>The functions <literal>from</literal> (think <emphasis>from function arguments</emphasis>) and <literal>to</literal> (think\r
11946<emphasis>to function arguements</emphasis>) specify an isomorphism between <literal>a</literal>,<literal>b</literal>\r
11947records and function arguments. There is a second use of <literal>from</literal> to\r
11948work around the lack of\r
11949<link linkend="FirstClassPolymorphism">first-class polymorphism</link> in SML.</simpara>\r
11950<simpara>With the definition of <literal>updateAB</literal> in place, the following expressions\r
11951are valid.</simpara>\r
11952<programlisting language="sml" linenumbering="unnumbered">updateAB {a = 13, b = "hello"} (set#b "goodbye") $\r
11953updateAB {a = 13.5, b = true} (set#b false) (set#a 12.5) $</programlisting>\r
11954<simpara>As another example, suppose that we would like to do functional record\r
11955update on records with fields <literal>b</literal>, <literal>c</literal>, and <literal>d</literal>. Then one defines a\r
11956function <literal>updateBCD</literal> as follows.</simpara>\r
11957<programlisting language="sml" linenumbering="unnumbered">val updateBCD =\r
11958 fn z =&gt;\r
11959 let\r
11960 fun from v1 v2 v3 = {b = v1, c = v2, d = v3}\r
11961 fun to f {b = v1, c = v2, d = v3} = f v1 v2 v3\r
11962 in\r
11963 makeUpdate3 (from, from, to)\r
11964 end\r
11965 z</programlisting>\r
11966<simpara>With the definition of <literal>updateBCD</literal> in place, the following expression\r
11967is valid.</simpara>\r
11968<programlisting language="sml" linenumbering="unnumbered">updateBCD {b = 1, c = 2, d = 3} (set#c 4) (set#c 5) $</programlisting>\r
11969<simpara>Note that not all fields need be updated and that the same field may\r
11970be updated multiple times. Further note that the same <literal>set</literal> operator\r
11971is used for all update functions (in the above, for both <literal>updateAB</literal>\r
11972and <literal>updateBCD</literal>).</simpara>\r
11973<simpara>In general, to define a functional-record-update function on records\r
11974with fields <literal>f1</literal>, <literal>f2</literal>, &#8230;, <literal>fN</literal>, use the following template.</simpara>\r
11975<programlisting language="sml" linenumbering="unnumbered">val update =\r
11976 fn z =&gt;\r
11977 let\r
11978 fun from v1 v2 ... vn = {f1 = v1, f2 = v2, ..., fn = vn}\r
11979 fun to f {f1 = v1, f2 = v2, ..., fn = vn} = v1 v2 ... vn\r
11980 in\r
11981 makeUpdateN (from, from, to)\r
11982 end\r
11983 z</programlisting>\r
11984<simpara>With this, one can update a record as follows.</simpara>\r
11985<programlisting language="sml" linenumbering="unnumbered">update {f1 = v1, ..., fn = vn} (set#fi1 vi1) ... (set#fim vim) $</programlisting>\r
11986</section>\r
11987<section id="_the_literal_functionalrecordupdate_literal_structure">\r
11988<title>The <literal>FunctionalRecordUpdate</literal> structure</title>\r
11989<simpara>Here is the implementation of functional record update.</simpara>\r
11990<programlisting language="sml" linenumbering="unnumbered">structure FunctionalRecordUpdate =\r
11991 struct\r
11992 local\r
11993 fun next g (f, z) x = g (f x, z)\r
11994 fun f1 (f, z) x = f (z x)\r
11995 fun f2 z = next f1 z\r
11996 fun f3 z = next f2 z\r
11997\r
11998 fun c0 from = from\r
11999 fun c1 from = c0 from f1\r
12000 fun c2 from = c1 from f2\r
12001 fun c3 from = c2 from f3\r
12002\r
12003 fun makeUpdate cX (from, from', to) record =\r
12004 let\r
12005 fun ops () = cX from'\r
12006 fun vars f = to f record\r
12007 in\r
12008 Fold.fold ((vars, ops), fn (vars, _) =&gt; vars from)\r
12009 end\r
12010 in\r
12011 fun makeUpdate0 z = makeUpdate c0 z\r
12012 fun makeUpdate1 z = makeUpdate c1 z\r
12013 fun makeUpdate2 z = makeUpdate c2 z\r
12014 fun makeUpdate3 z = makeUpdate c3 z\r
12015\r
12016 fun upd z = Fold.step2 (fn (s, f, (vars, ops)) =&gt; (fn out =&gt; vars (s (ops ()) (out, f)), ops)) z\r
12017 fun set z = Fold.step2 (fn (s, v, (vars, ops)) =&gt; (fn out =&gt; vars (s (ops ()) (out, fn _ =&gt; v)), ops)) z\r
12018 end\r
12019 end</programlisting>\r
12020<simpara>The idea of <literal>makeUpdate</literal> is to build a record of functions which can\r
12021replace the contents of one argument out of a list of arguments. The\r
12022functions <literal>f<emphasis>&lt;X&gt;</emphasis></literal> replace the 0th, 1st, &#8230; argument with their\r
12023argument <literal>z</literal>. The <literal>c<emphasis>&lt;X&gt;</emphasis></literal> functions pass the first <emphasis>X</emphasis> <literal>f</literal>\r
12024functions to the record constructor.</simpara>\r
12025<simpara>The <literal>#field</literal> notation of Standard ML allows us to select the map\r
12026function which replaces the corresponding argument. By converting the\r
12027record to an argument list, feeding that list through the selected map\r
12028function and piping the list into the record constructor, functional\r
12029record update is achieved.</simpara>\r
12030</section>\r
12031<section id="_efficiency">\r
12032<title>Efficiency</title>\r
12033<simpara>With MLton, the efficiency of this approach is as good as one would\r
12034expect with the special syntax. Namely a sequence of updates will be\r
12035optimized into a single record construction that copies the unchanged\r
12036fields and fills in the changed fields with their new values.</simpara>\r
12037<simpara>Before Sep 14, 2009, this page advocated an alternative implementation\r
12038of <link linkend="FunctionalRecordUpdate">FunctionalRecordUpdate</link>. However, the old structure caused\r
12039exponentially increasing compile times. We advise you to switch to\r
12040the newer version.</simpara>\r
12041</section>\r
12042<section id="_applications">\r
12043<title>Applications</title>\r
12044<simpara>Functional record update can be used to implement labelled\r
12045<link linkend="OptionalArguments">optional arguments</link>.</simpara>\r
12046<simpara><?asciidoc-pagebreak?></simpara>\r
12047</section>\r
12048</section>\r
12049<section id="fxp">\r
12050<title>fxp</title>\r
12051<simpara><ulink url="http://atseidl2.informatik.tu-muenchen.de/%7Eberlea/Fxp/">fxp</ulink> is an XML\r
12052parser written in Standard ML.</simpara>\r
12053<simpara>It has a\r
12054<ulink url="http://atseidl2.informatik.tu-muenchen.de/%7Eberlea/Fxp/mlton.html">patch</ulink>\r
12055to compile with MLton.</simpara>\r
12056<simpara><?asciidoc-pagebreak?></simpara>\r
12057</section>\r
12058<section id="GarbageCollection">\r
12059<title>GarbageCollection</title>\r
12060<simpara>For a good introduction and overview to garbage collection, see\r
12061<link linkend="References_Jones99">Jones99</link>.</simpara>\r
12062<simpara>MLton&#8217;s garbage collector uses copying, mark-compact, and generational\r
12063collection, automatically switching between them at run time based on\r
12064the amount of live data relative to the amount of RAM. The runtime\r
12065system tries to keep the heap within RAM if at all possible.</simpara>\r
12066<simpara>MLton&#8217;s copying collector is a simple, two-space, breadth-first,\r
12067Cheney-style collector. The design for the generational and\r
12068mark-compact GC is based on <link linkend="References_Sansom91">Sansom91</link>.</simpara>\r
12069<section id="_design_notes">\r
12070<title>Design notes</title>\r
12071<itemizedlist>\r
12072<listitem>\r
12073<simpara>\r
12074<ulink url="http://www.mlton.org/pipermail/mlton/2002-May/012420.html">http://www.mlton.org/pipermail/mlton/2002-May/012420.html</ulink>\r
12075</simpara>\r
12076<simpara>object layout and header word design</simpara>\r
12077</listitem>\r
12078</itemizedlist>\r
12079</section>\r
12080<section id="_also_see_4">\r
12081<title>Also see</title>\r
12082<itemizedlist>\r
12083<listitem>\r
12084<simpara>\r
12085<link linkend="Regions">Regions</link>\r
12086</simpara>\r
12087</listitem>\r
12088</itemizedlist>\r
12089<simpara><?asciidoc-pagebreak?></simpara>\r
12090</section>\r
12091</section>\r
12092<section id="GenerativeDatatype">\r
12093<title>GenerativeDatatype</title>\r
12094<simpara>In <link linkend="StandardML">Standard ML</link>, datatype declarations are said to be\r
12095<emphasis>generative</emphasis>, because each time a datatype declaration is evaluated,\r
12096it yields a new type. Thus, any attempt to mix the types will lead to\r
12097a type error at compile-time. The following program, which does not\r
12098type check, demonstrates this.</simpara>\r
12099<programlisting language="sml" linenumbering="unnumbered">functor F () =\r
12100 struct\r
12101 datatype t = T\r
12102 end\r
12103structure S1 = F ()\r
12104structure S2 = F ()\r
12105val _: S1.t -&gt; S2.t = fn x =&gt; x</programlisting>\r
12106<simpara>Generativity also means that two different datatype declarations\r
12107define different types, even if they define identical constructors.\r
12108The following program does not type check due to this.</simpara>\r
12109<programlisting language="sml" linenumbering="unnumbered">datatype t = A | B\r
12110val a1 = A\r
12111datatype t = A | B\r
12112val a2 = A\r
12113val _ = if true then a1 else a2</programlisting>\r
12114<section id="_also_see_5">\r
12115<title>Also see</title>\r
12116<itemizedlist>\r
12117<listitem>\r
12118<simpara>\r
12119<link linkend="GenerativeException">GenerativeException</link>\r
12120</simpara>\r
12121</listitem>\r
12122</itemizedlist>\r
12123<simpara><?asciidoc-pagebreak?></simpara>\r
12124</section>\r
12125</section>\r
12126<section id="GenerativeException">\r
12127<title>GenerativeException</title>\r
12128<simpara>In <link linkend="StandardML">Standard ML</link>, exception declarations are said to be\r
12129<emphasis>generative</emphasis>, because each time an exception declaration is evaluated,\r
12130it yields a new exception.</simpara>\r
12131<simpara>The following program demonstrates the generativity of exceptions.</simpara>\r
12132<programlisting language="sml" linenumbering="unnumbered">exception E\r
12133val e1 = E\r
12134fun isE1 (e: exn): bool =\r
12135 case e of\r
12136 E =&gt; true\r
12137 | _ =&gt; false\r
12138exception E\r
12139val e2 = E\r
12140fun isE2 (e: exn): bool =\r
12141 case e of\r
12142 E =&gt; true\r
12143 | _ =&gt; false\r
12144fun pb (b: bool): unit =\r
12145 print (concat [Bool.toString b, "\n"])\r
12146val () = (pb (isE1 e1)\r
12147 ;pb (isE1 e2)\r
12148 ; pb (isE2 e1)\r
12149 ; pb (isE2 e2))</programlisting>\r
12150<simpara>In the above program, two different exception declarations declare an\r
12151exception <literal>E</literal> and a corresponding function that returns <literal>true</literal> only on\r
12152that exception. Although declared by syntactically identical\r
12153exception declarations, <literal>e1</literal> and <literal>e2</literal> are different exceptions. The\r
12154program, when run, prints <literal>true</literal>, <literal>false</literal>, <literal>false</literal>, <literal>true</literal>.</simpara>\r
12155<simpara>A slight modification of the above program shows that even a single\r
12156exception declaration yields a new exception each time it is\r
12157evaluated.</simpara>\r
12158<programlisting language="sml" linenumbering="unnumbered">fun f (): exn * (exn -&gt; bool) =\r
12159 let\r
12160 exception E\r
12161 in\r
12162 (E, fn E =&gt; true | _ =&gt; false)\r
12163 end\r
12164val (e1, isE1) = f ()\r
12165val (e2, isE2) = f ()\r
12166fun pb (b: bool): unit =\r
12167 print (concat [Bool.toString b, "\n"])\r
12168val () = (pb (isE1 e1)\r
12169 ; pb (isE1 e2)\r
12170 ; pb (isE2 e1)\r
12171 ; pb (isE2 e2))</programlisting>\r
12172<simpara>Each call to <literal>f</literal> yields a new exception and a function that returns\r
12173<literal>true</literal> only on that exception. The program, when run, prints <literal>true</literal>,\r
12174<literal>false</literal>, <literal>false</literal>, <literal>true</literal>.</simpara>\r
12175<section id="_type_safety">\r
12176<title>Type Safety</title>\r
12177<simpara>Exception generativity is required for type safety. Consider the\r
12178following valid SML program.</simpara>\r
12179<programlisting language="sml" linenumbering="unnumbered">fun f (): ('a -&gt; exn) * (exn -&gt; 'a) =\r
12180 let\r
12181 exception E of 'a\r
12182 in\r
12183 (E, fn E x =&gt; x | _ =&gt; raise Fail "f")\r
12184 end\r
12185fun cast (a: 'a): 'b =\r
12186 let\r
12187 val (make: 'a -&gt; exn, _) = f ()\r
12188 val (_, get: exn -&gt; 'b) = f ()\r
12189 in\r
12190 get (make a)\r
12191 end\r
12192val _ = ((cast 13): int -&gt; int) 14</programlisting>\r
12193<simpara>If exceptions weren&#8217;t generative, then each call <literal>f ()</literal> would yield\r
12194the same exception constructor <literal>E</literal>. Then, our <literal>cast</literal> function could\r
12195use <literal>make: 'a -&gt; exn</literal> to convert any value into an exception and then\r
12196<literal>get: exn -&gt; 'b</literal> to convert that exception to a value of arbitrary\r
12197type. If <literal>cast</literal> worked, then we could cast an integer as a function\r
12198and apply. Of course, because of generative exceptions, this program\r
12199raises <literal>Fail "f"</literal>.</simpara>\r
12200</section>\r
12201<section id="_applications_2">\r
12202<title>Applications</title>\r
12203<simpara>The <literal>exn</literal> type is effectively a <link linkend="UniversalType">universal type</link>.</simpara>\r
12204</section>\r
12205<section id="_also_see_6">\r
12206<title>Also see</title>\r
12207<itemizedlist>\r
12208<listitem>\r
12209<simpara>\r
12210<link linkend="GenerativeDatatype">GenerativeDatatype</link>\r
12211</simpara>\r
12212</listitem>\r
12213</itemizedlist>\r
12214<simpara><?asciidoc-pagebreak?></simpara>\r
12215</section>\r
12216</section>\r
12217<section id="Git">\r
12218<title>Git</title>\r
12219<simpara><ulink url="http://git-scm.com/">Git</ulink> is a distributed version control system. The\r
12220MLton project currently uses Git to maintain its\r
12221<link linkend="Sources">source code</link>.</simpara>\r
12222<simpara>Here are some online Git resources.</simpara>\r
12223<itemizedlist>\r
12224<listitem>\r
12225<simpara>\r
12226<ulink url="http://git-scm.com/docs">Reference Manual</ulink>\r
12227</simpara>\r
12228</listitem>\r
12229<listitem>\r
12230<simpara>\r
12231<ulink url="http://git-scm.com/book">ProGit, by Scott Chacon</ulink>\r
12232</simpara>\r
12233</listitem>\r
12234</itemizedlist>\r
12235<simpara><?asciidoc-pagebreak?></simpara>\r
12236</section>\r
12237<section id="Glade">\r
12238<title>Glade</title>\r
12239<simpara><ulink url="http://glade.gnome.org/features.html">Glade</ulink> is a tool for generating\r
12240Gtk user interfaces.</simpara>\r
12241<simpara><link linkend="WesleyTerpstra">WesleyTerpstra</link> is working on a Glade&#8594;mGTK converter.</simpara>\r
12242<itemizedlist>\r
12243<listitem>\r
12244<simpara>\r
12245<ulink url="http://www.mlton.org/pipermail/mlton/2004-December/016865.html">http://www.mlton.org/pipermail/mlton/2004-December/016865.html</ulink>\r
12246</simpara>\r
12247</listitem>\r
12248</itemizedlist>\r
12249<simpara><?asciidoc-pagebreak?></simpara>\r
12250</section>\r
12251<section id="Globalize">\r
12252<title>Globalize</title>\r
12253<simpara><link linkend="Globalize">Globalize</link> is an analysis pass for the <link linkend="SXML">SXML</link>\r
12254<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="ClosureConvert">ClosureConvert</link>.</simpara>\r
12255<section id="_description_19">\r
12256<title>Description</title>\r
12257<simpara>This pass marks values that are constant, allowing <link linkend="ClosureConvert">ClosureConvert</link>\r
12258to move them out to the top level so they are only evaluated once and\r
12259do not appear in closures.</simpara>\r
12260</section>\r
12261<section id="_implementation_21">\r
12262<title>Implementation</title>\r
12263<itemizedlist>\r
12264<listitem>\r
12265<simpara>\r
12266<ulink url="https://github.com/MLton/mlton/blob/master/mlton/closure-convert/globalize.sig"><literal>globalize.sig</literal></ulink>\r
12267</simpara>\r
12268</listitem>\r
12269<listitem>\r
12270<simpara>\r
12271<ulink url="https://github.com/MLton/mlton/blob/master/mlton/closure-convert/globalize.fun"><literal>globalize.fun</literal></ulink>\r
12272</simpara>\r
12273</listitem>\r
12274</itemizedlist>\r
12275</section>\r
12276<section id="_details_and_notes_21">\r
12277<title>Details and Notes</title>\r
12278<simpara></simpara>\r
12279<simpara><?asciidoc-pagebreak?></simpara>\r
12280</section>\r
12281</section>\r
12282<section id="GnuMP">\r
12283<title>GnuMP</title>\r
12284<simpara>The <ulink url="http://gmplib.org">GnuMP</ulink> library (GNU Multiple Precision\r
12285arithmetic library) is a library for arbitrary precision integer\r
12286arithmetic. MLton uses the GnuMP library to implement the\r
12287<link linkend="BasisLibrary">Basis Library</link> <literal>IntInf</literal> module.</simpara>\r
12288<section id="_known_issues">\r
12289<title>Known issues</title>\r
12290<itemizedlist>\r
12291<listitem>\r
12292<simpara>\r
12293There is a known problem with the GnuMP library (prior to version\r
122944.2.x), where it requires a lot of stack space for some computations,\r
12295e.g. <literal>IntInf.toString</literal> of a million digit number. If you run with\r
12296stack size limited, you may see a segfault in such programs. This\r
12297problem is mentioned in the <ulink url="http://gmplib.org/#FAQ">GnuMP FAQ</ulink>, where\r
12298they describe two solutions.\r
12299</simpara>\r
12300<itemizedlist>\r
12301<listitem>\r
12302<simpara>\r
12303Increase (or unlimit) your stack space. From your program, use\r
12304<literal>setrlimit</literal>, or from the shell, use <literal>ulimit</literal>.\r
12305</simpara>\r
12306</listitem>\r
12307<listitem>\r
12308<simpara>\r
12309Configure and rebuild <literal>libgmp</literal> with <literal>--disable-alloca</literal>, which will\r
12310cause it to allocate temporaries using <literal>malloc</literal> instead of on the\r
12311stack.\r
12312</simpara>\r
12313</listitem>\r
12314</itemizedlist>\r
12315</listitem>\r
12316<listitem>\r
12317<simpara>\r
12318On some platforms, the GnuMP library may be configured to use one of\r
12319multiple ABIs (Application Binary Interfaces). For example, on some\r
1232032-bit architectures, GnuMP may be configured to represent a limb as\r
12321either a 32-bit <literal>long</literal> or as a 64-bit <literal>long long</literal>. Similarly, GnuMP\r
12322may be configured to use specific CPU features.\r
12323</simpara>\r
12324<simpara>In order to efficiently use the GnuMP library, MLton represents an\r
12325<literal>IntInf.int</literal> value in a manner compatible with the GnuMP library&#8217;s\r
12326representation of a limb. Hence, it is important that MLton and the\r
12327GnuMP library agree upon the representation of a limb.</simpara>\r
12328<itemizedlist>\r
12329<listitem>\r
12330<simpara>\r
12331When using a source package of MLton, building will detect the\r
12332GnuMP library&#8217;s representation of a limb.\r
12333</simpara>\r
12334</listitem>\r
12335<listitem>\r
12336<simpara>\r
12337When using a binary package of MLton that is dynamically linked\r
12338against the GnuMP library, the build machine and the install machine\r
12339must have the GnuMP library configured with the same representation of\r
12340a limb. (On the other hand, the build machine need not have the GnuMP\r
12341library configured with CPU features compatible with the install\r
12342machine.)\r
12343</simpara>\r
12344</listitem>\r
12345<listitem>\r
12346<simpara>\r
12347When using a binary package of MLton that is statically linked\r
12348against the GnuMP library, the build machine and the install machine\r
12349need not have the GnuMP library configured with the same\r
12350representation of a limb. (On the other hand, the build machine must\r
12351have the GnuMP library configured with CPU features compatible with\r
12352the install machine.)\r
12353</simpara>\r
12354<simpara>However, MLton will be configured with the representation of a limb\r
12355from the GnuMP library of the build machine. Executables produced by\r
12356MLton will be incompatible with the GnuMP library of the install\r
12357machine. To <emphasis>reconfigure</emphasis> MLton with the representation of a limb\r
12358from the GnuMP library of the install machine, one must edit:</simpara>\r
12359<screen>/usr/lib/mlton/self/sizes</screen>\r
12360<simpara>changing the</simpara>\r
12361<screen>mplimb = ??</screen>\r
12362<simpara>entry so that <literal>??</literal> corresponds to the bytes in a limb; and, one must edit:</simpara>\r
12363<screen>/usr/lib/mlton/sml/basis/config/c/arch-os/c-types.sml</screen>\r
12364<simpara>changing the</simpara>\r
12365<screen>(* from "gmp.h" *)\r
12366structure C_MPLimb = struct open Word?? type t = word end\r
12367functor C_MPLimb_ChooseWordN (A: CHOOSE_WORDN_ARG) = ChooseWordN_Word?? (A)</screen>\r
12368<simpara>entries so that <literal>??</literal> corresponds to the bits in a limb.</simpara>\r
12369</listitem>\r
12370</itemizedlist>\r
12371</listitem>\r
12372</itemizedlist>\r
12373<simpara><?asciidoc-pagebreak?></simpara>\r
12374</section>\r
12375</section>\r
12376<section id="GoogleSummerOfCode2013">\r
12377<title>Google Summer of Code (2013)</title>\r
12378<section id="_mentors">\r
12379<title>Mentors</title>\r
12380<simpara>The following developers have agreed to serve as mentors for the 2013 Google Summer of Code:</simpara>\r
12381<itemizedlist>\r
12382<listitem>\r
12383<simpara>\r
12384<ulink url="http://www.cs.rit.edu/%7Emtf">Matthew Fluet</ulink>\r
12385</simpara>\r
12386</listitem>\r
12387<listitem>\r
12388<simpara>\r
12389<ulink url="http://www.cse.buffalo.edu/%7Elziarek/">Lukasz (Luke) Ziarek</ulink>\r
12390</simpara>\r
12391</listitem>\r
12392<listitem>\r
12393<simpara>\r
12394<ulink url="http://www.cs.purdue.edu/homes/suresh/">Suresh Jagannathan</ulink>\r
12395</simpara>\r
12396</listitem>\r
12397</itemizedlist>\r
12398</section>\r
12399<section id="_ideas_list">\r
12400<title>Ideas List</title>\r
12401<section id="_implement_a_partial_redundancy_elimination_pre_optimization">\r
12402<title>Implement a Partial Redundancy Elimination (PRE) Optimization</title>\r
12403<simpara>Partial redundancy elimination (PRE) is a program transformation that\r
12404removes operations that are redundant on some, but not necessarily all\r
12405paths, through the program. PRE can subsume both common subexpression\r
12406elimination and loop-invariant code motion, and is therefore a\r
12407potentially powerful optimization. However, a na&iuml;ve\r
12408implementation of PRE on a program in static single assignment (SSA)\r
12409form is unlikely to be effective. This project aims to adapt and\r
12410implement the SSAPRE algorithm(s) of Thomas VanDrunen in MLton&#8217;s SSA\r
12411intermediate language.</simpara>\r
12412<simpara>Background:</simpara>\r
12413<itemizedlist>\r
12414<listitem>\r
12415<simpara>\r
12416<ulink url="http://onlinelibrary.wiley.com/doi/10.1002/spe.618/abstract">Anticipation-based partial redundancy elimination for static single assignment form</ulink>; Thomas VanDrunen and Antony L. Hosking\r
12417</simpara>\r
12418</listitem>\r
12419<listitem>\r
12420<simpara>\r
12421<ulink url="http://cs.wheaton.edu/%7Etvandrun/writings/thesis.pdf">Partial Redundancy Elimination for Global Value Numbering</ulink>; Thomas VanDrunen\r
12422</simpara>\r
12423</listitem>\r
12424<listitem>\r
12425<simpara>\r
12426<ulink url="http://www.springerlink.com/content/w06m3cw453nphm1u/">Value-Based Partial Redundancy Elimination</ulink>; Thomas VanDrunen and Antony L. Hosking\r
12427</simpara>\r
12428</listitem>\r
12429<listitem>\r
12430<simpara>\r
12431<ulink url="http://portal.acm.org/citation.cfm?doid=319301.319348">Partial redundancy elimination in SSA form</ulink>; Robert Kennedy, Sun Chan, Shin-Ming Liu, Raymond Lo, Peng Tu, and Fred Chow\r
12432</simpara>\r
12433</listitem>\r
12434</itemizedlist>\r
12435<simpara>Recommended Skills: SML programming experience; some middle-end compiler experience</simpara>\r
12436</section>\r
12437<section id="_design_and_implement_a_heap_profiler">\r
12438<title>Design and Implement a Heap Profiler</title>\r
12439<simpara>A heap profile is a description of the space usage of a program. A\r
12440heap profile is concerned with the allocation, retention, and\r
12441deallocation (via garbage collection) of heap data during the\r
12442execution of a program. A heap profile can be used to diagnose\r
12443performance problems in a functional program that arise from space\r
12444leaks. This project aims to design and implement a heap profiler for\r
12445MLton compiled programs.</simpara>\r
12446<simpara>Background:</simpara>\r
12447<itemizedlist>\r
12448<listitem>\r
12449<simpara>\r
12450<ulink url="http://portal.acm.org/citation.cfm?doid=583854.582451">GCspy: an adaptable heap visualisation framework</ulink>; Tony Printezis and Richard Jones\r
12451</simpara>\r
12452</listitem>\r
12453<listitem>\r
12454<simpara>\r
12455<ulink url="http://journals.cambridge.org/action/displayAbstract?aid=1349892">New dimensions in heap profiling</ulink>; Colin Runciman and Niklas R&ouml;jemo\r
12456</simpara>\r
12457</listitem>\r
12458<listitem>\r
12459<simpara>\r
12460<ulink url="http://www.springerlink.com/content/710501660722gw37/">Heap profiling for space efficiency</ulink>; Colin Runciman and Niklas R&ouml;jemo\r
12461</simpara>\r
12462</listitem>\r
12463<listitem>\r
12464<simpara>\r
12465<ulink url="http://journals.cambridge.org/action/displayAbstract?aid=1323096">Heap profiling of lazy functional programs</ulink>; Colin Runciman and David Wakeling\r
12466</simpara>\r
12467</listitem>\r
12468</itemizedlist>\r
12469<simpara>Recommended Skills: C and SML programming experience; some experience with UI and visualization</simpara>\r
12470</section>\r
12471<section id="_garbage_collector_improvements">\r
12472<title>Garbage Collector Improvements</title>\r
12473<simpara>The garbage collector plays a significant role in the performance of\r
12474functional languages. Garbage collect too often, and program\r
12475performance suffers due to the excessive time spent in the garbage\r
12476collector. Garbage collect not often enough, and program performance\r
12477suffers due to the excessive space used by the uncollected garbage.\r
12478One particular issue is ensuring that a program utilizing a garbage\r
12479collector "plays nice" with other processes on the system, by not\r
12480using too much or too little physical memory. While there are some\r
12481reasonable theoretical results about garbage collections with heaps of\r
12482fixed size, there seems to be insufficient work that really looks\r
12483carefully at the question of dynamically resizing the heap in response\r
12484to the live data demands of the application and, similarly, in\r
12485response to the behavior of the operating system and other processes.\r
12486This project aims to investigate improvements to the memory behavior of\r
12487MLton compiled programs through better tuning of the garbage\r
12488collector.</simpara>\r
12489<simpara>Background:</simpara>\r
12490<itemizedlist>\r
12491<listitem>\r
12492<simpara>\r
12493<ulink url="http://www.dcs.gla.ac.uk/%7Ewhited/papers/automated_heap_sizing.pdf">Automated Heap Sizing in the Poly/ML Runtime (Position Paper)</ulink>; David White, Jeremy Singer, Jonathan Aitken, and David Matthews\r
12494</simpara>\r
12495</listitem>\r
12496<listitem>\r
12497<simpara>\r
12498<ulink url="http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=4145125">Isla Vista Heap Sizing: Using Feedback to Avoid Paging</ulink>; Chris Grzegorczyk, Sunil Soman, Chandra Krintz, and Rich Wolski\r
12499</simpara>\r
12500</listitem>\r
12501<listitem>\r
12502<simpara>\r
12503<ulink url="http://portal.acm.org/citation.cfm?doid=1152649.1152652">Controlling garbage collection and heap growth to reduce the execution time of Java applications</ulink>; Tim Brecht, Eshrat Arjomandi, Chang Li, and Hang Pham\r
12504</simpara>\r
12505</listitem>\r
12506<listitem>\r
12507<simpara>\r
12508<ulink url="http://portal.acm.org/citation.cfm?doid=1065010.1065028">Garbage collection without paging</ulink>; Matthew Hertz, Yi Feng, and Emery D. Berger\r
12509</simpara>\r
12510</listitem>\r
12511<listitem>\r
12512<simpara>\r
12513<ulink url="http://portal.acm.org/citation.cfm?doid=1029873.1029881">Automatic heap sizing: taking real memory into account</ulink>; Ting Yang, Matthew Hertz, Emery D. Berger, Scott F. Kaplan, and J. Eliot B. Moss\r
12514</simpara>\r
12515</listitem>\r
12516</itemizedlist>\r
12517<simpara>Recommended Skills: C programming experience; some operating systems and/or systems programming experience; some compiler and garbage collector experience</simpara>\r
12518</section>\r
12519<section id="_implement_successor_160_ml_language_features">\r
12520<title>Implement Successor&#160;ML Language Features</title>\r
12521<simpara>Any programming language, including Standard&#160;ML, can be improved.\r
12522The community has identified a number of modest extensions and\r
12523revisions to the Standard&#160;ML programming language that would\r
12524likely prove useful in practice. This project aims to implement these\r
12525language features in the MLton compiler.</simpara>\r
12526<simpara>Background:</simpara>\r
12527<itemizedlist>\r
12528<listitem>\r
12529<simpara>\r
12530<ulink url="http://successor-ml.org/index.php?title=Main_Page">Successor&#160;ML</ulink>\r
12531</simpara>\r
12532</listitem>\r
12533<listitem>\r
12534<simpara>\r
12535<ulink url="http://www.mpi-sws.org/%7Erossberg/hamlet/index.html#successor-ml">HaMLet (Successor&#160;ML)</ulink>\r
12536</simpara>\r
12537</listitem>\r
12538<listitem>\r
12539<simpara>\r
12540<ulink url="http://journals.cambridge.org/action/displayAbstract?aid=1322628">A critique of Standard&#160;ML</ulink>; Andrew W. Appel\r
12541</simpara>\r
12542</listitem>\r
12543</itemizedlist>\r
12544<simpara>Recommended Skills: SML programming experience; some front-end compiler experience (i.e., scanners and parsers)</simpara>\r
12545</section>\r
12546<section id="_implement_source_level_debugging">\r
12547<title>Implement Source-level Debugging</title>\r
12548<simpara>Debugging is a fact of programming life. Unfortunately, most SML\r
12549implementations (including MLton) provide little to no source-level\r
12550debugging support. This project aims to add basic to intermediate\r
12551source-level debugging support to the MLton compiler. MLton already\r
12552supports source-level profiling, which can be used to attribute bytes\r
12553allocated or time spent in source functions. It should be relatively\r
12554straightforward to leverage this source-level information into basic\r
12555source-level debugging support, with the ability to set/unset\r
12556breakpoints and step through declarations and functions. It may be\r
12557possible to also provide intermediate source-level debugging support,\r
12558with the ability to inspect in-scope variables of basic types (e.g.,\r
12559types compatible with MLton&#8217;s foreign function interface).</simpara>\r
12560<simpara>Background:</simpara>\r
12561<itemizedlist>\r
12562<listitem>\r
12563<simpara>\r
12564<ulink url="http://mlton.org/HowProfilingWorks">MLton&#8201;&#8212;&#8201;How Profiling Works</ulink>\r
12565</simpara>\r
12566</listitem>\r
12567<listitem>\r
12568<simpara>\r
12569<ulink url="http://mlton.org/ForeignFunctionInterfaceTypes">MLton&#8201;&#8212;&#8201;Foreign Function Interface Types</ulink>\r
12570</simpara>\r
12571</listitem>\r
12572<listitem>\r
12573<simpara>\r
12574<ulink url="http://dwarfstd.org/">DWARF Debugging Standard</ulink>\r
12575</simpara>\r
12576</listitem>\r
12577<listitem>\r
12578<simpara>\r
12579<ulink url="http://sourceware.org/gdb/current/onlinedocs/stabs/index.html">STABS Debugging Format</ulink>\r
12580</simpara>\r
12581</listitem>\r
12582</itemizedlist>\r
12583<simpara>Recommended Skills: SML programming experience; some compiler experience</simpara>\r
12584</section>\r
12585<section id="_simd_primitives">\r
12586<title>SIMD Primitives</title>\r
12587<simpara>Most modern processors offer some direct support for SIMD (Single\r
12588Instruction, Multiple Data) operations, such as Intel&#8217;s MMX/SSE\r
12589instructions, AMD&#8217;s 3DNow! instructions, and IBM&#8217;s AltiVec. Such\r
12590instructions are particularly useful for multimedia, scientific, and\r
12591cryptographic applications. This project aims to add preliminary\r
12592support for vector data and vector operations to the MLton compiler.\r
12593Ideally, after surveying SIMD instruction sets and SIMD support in\r
12594other compilers, a core set of SIMD primitives with broad architecture\r
12595and compiler support can be identified. After adding SIMD primitives\r
12596to the core compiler and carrying them through to the various\r
12597backends, there will be opportunities to design and implement an SML\r
12598library that exposes the primitives to the SML programmer as well as\r
12599opportunities to design and implement auto-vectorization\r
12600optimizations.</simpara>\r
12601<simpara>Background:</simpara>\r
12602<itemizedlist>\r
12603<listitem>\r
12604<simpara>\r
12605<ulink url="http://en.wikipedia.org/wiki/SIMD">SIMD</ulink>\r
12606</simpara>\r
12607</listitem>\r
12608<listitem>\r
12609<simpara>\r
12610<ulink url="http://gcc.gnu.org/projects/tree-ssa/vectorization.html">Auto-vectorization in GCC</ulink>\r
12611</simpara>\r
12612</listitem>\r
12613<listitem>\r
12614<simpara>\r
12615<ulink url="http://llvm.org/docs/Vectorizers.html">Auto-vectorization in LLVM</ulink>\r
12616</simpara>\r
12617</listitem>\r
12618</itemizedlist>\r
12619<simpara>Recommended Skills: SML programming experience; some compiler experience; some computer architecture experience</simpara>\r
12620</section>\r
12621<section id="_rtos_support">\r
12622<title>RTOS Support</title>\r
12623<simpara>This project entails porting the MLton compiler to RTOSs such as:\r
12624RTEMS, RT Linux, and FreeRTOS. The project will include modifications\r
12625to the MLton build and configuration process. Students will need to\r
12626extend the MLton configuration process for each of the RTOSs. The\r
12627MLton compilation process will need to be extended to invoke the C\r
12628cross compilers the RTOSs provide for embedded support. Test scripts\r
12629for validation will be necessary and these will need to be run in\r
12630emulators for supported architectures.</simpara>\r
12631<simpara>Recommended Skills: C programming experience; some scripting experience</simpara>\r
12632</section>\r
12633<section id="_region_based_memory_management">\r
12634<title>Region Based Memory Management</title>\r
12635<simpara>Region based memory management is an alternative automatic memory\r
12636management scheme to garbage collection. Regions can be inferred by\r
12637the compiler (e.g., Cyclone and MLKit) or provided to the programmer\r
12638through a library. Since many students do not have extensive\r
12639experience with compilers we plan on adopting the later approach.\r
12640Creating a viable region based memory solution requires the removal of\r
12641the GC and changes to the allocator. Additionally, write barriers\r
12642will be necessary to ensure references between two ML objects is never\r
12643established if the left hand side of the assignment has a longer\r
12644lifetime than the right hand side. Students will need to come up with\r
12645an appropriate interface for creating, entering, and exiting regions\r
12646(examples include RTSJ scoped memory and SCJ scoped memory).</simpara>\r
12647<simpara>Background:</simpara>\r
12648<itemizedlist>\r
12649<listitem>\r
12650<simpara>\r
12651Cyclone\r
12652</simpara>\r
12653</listitem>\r
12654<listitem>\r
12655<simpara>\r
12656MLKit\r
12657</simpara>\r
12658</listitem>\r
12659<listitem>\r
12660<simpara>\r
12661RTSJ + SCJ scopes\r
12662</simpara>\r
12663</listitem>\r
12664</itemizedlist>\r
12665<simpara>Recommended Skills: SML programming experience; C programming experience; some compiler and garbage collector experience</simpara>\r
12666</section>\r
12667<section id="_integration_of_multi_mlton">\r
12668<title>Integration of Multi-MLton</title>\r
12669<simpara><ulink url="http://multimlton.cs.purdue.edu">MultiMLton</ulink> is a compiler and runtime\r
12670environment that targets scalable multicore platforms. It is an\r
12671extension of MLton. It combines new language abstractions and\r
12672associated compiler analyses for expressing and implementing various\r
12673kinds of fine-grained parallelism (safe futures, speculation,\r
12674transactions, etc.), along with a sophisticated runtime system tuned\r
12675to efficiently handle large numbers of lightweight threads. The core\r
12676stable features of MultiMLton will need to be integrated with the\r
12677latest MLton public release. Certain experimental features, such as\r
12678support for the Intel SCC and distributed runtime will be omitted.\r
12679This project requires students to understand the delta between the\r
12680MultiMLton code base and the MLton code base. Students will need to\r
12681create build and configuration scripts for MLton to enable MultiMLton\r
12682features.</simpara>\r
12683<simpara>Background</simpara>\r
12684<itemizedlist>\r
12685<listitem>\r
12686<simpara>\r
12687<ulink url="http://multimlton.cs.purdue.edu/mML/Publications.html">MultiMLton&#8201;&#8212;&#8201;Publications</ulink>\r
12688</simpara>\r
12689</listitem>\r
12690</itemizedlist>\r
12691<simpara>Recommended Skills: SML programming experience; C programming experience; some compiler experience</simpara>\r
12692<simpara><?asciidoc-pagebreak?></simpara>\r
12693</section>\r
12694</section>\r
12695</section>\r
12696<section id="GoogleSummerOfCode2014">\r
12697<title>Google Summer of Code (2014)</title>\r
12698<section id="_mentors_2">\r
12699<title>Mentors</title>\r
12700<simpara>The following developers have agreed to serve as mentors for the 2014 Google Summer of Code:</simpara>\r
12701<itemizedlist>\r
12702<listitem>\r
12703<simpara>\r
12704<ulink url="http://www.cs.rit.edu/%7Emtf">Matthew Fluet</ulink>\r
12705</simpara>\r
12706</listitem>\r
12707<listitem>\r
12708<simpara>\r
12709<ulink url="http://www.cse.buffalo.edu/%7Elziarek/">Lukasz (Luke) Ziarek</ulink>\r
12710</simpara>\r
12711</listitem>\r
12712<listitem>\r
12713<simpara>\r
12714<ulink url="http://people.cs.uchicago.edu/~jhr/">John Reppy</ulink>\r
12715</simpara>\r
12716</listitem>\r
12717<listitem>\r
12718<simpara>\r
12719<ulink url="http://www.cs.purdue.edu/homes/chandras">KC Sivaramakrishnan</ulink>\r
12720</simpara>\r
12721</listitem>\r
12722</itemizedlist>\r
12723</section>\r
12724<section id="_ideas_list_2">\r
12725<title>Ideas List</title>\r
12726<section id="_implement_a_partial_redundancy_elimination_pre_optimization_2">\r
12727<title>Implement a Partial Redundancy Elimination (PRE) Optimization</title>\r
12728<simpara>Partial redundancy elimination (PRE) is a program transformation that\r
12729removes operations that are redundant on some, but not necessarily all\r
12730paths, through the program. PRE can subsume both common subexpression\r
12731elimination and loop-invariant code motion, and is therefore a\r
12732potentially powerful optimization. However, a na&iuml;ve\r
12733implementation of PRE on a program in static single assignment (SSA)\r
12734form is unlikely to be effective. This project aims to adapt and\r
12735implement the SSAPRE algorithm(s) of Thomas VanDrunen in MLton&#8217;s SSA\r
12736intermediate language.</simpara>\r
12737<simpara>Background:</simpara>\r
12738<itemizedlist>\r
12739<listitem>\r
12740<simpara>\r
12741<ulink url="http://onlinelibrary.wiley.com/doi/10.1002/spe.618/abstract">Anticipation-based partial redundancy elimination for static single assignment form</ulink>; Thomas VanDrunen and Antony L. Hosking\r
12742</simpara>\r
12743</listitem>\r
12744<listitem>\r
12745<simpara>\r
12746<ulink url="http://cs.wheaton.edu/%7Etvandrun/writings/thesis.pdf">Partial Redundancy Elimination for Global Value Numbering</ulink>; Thomas VanDrunen\r
12747</simpara>\r
12748</listitem>\r
12749<listitem>\r
12750<simpara>\r
12751<ulink url="http://www.springerlink.com/content/w06m3cw453nphm1u/">Value-Based Partial Redundancy Elimination</ulink>; Thomas VanDrunen and Antony L. Hosking\r
12752</simpara>\r
12753</listitem>\r
12754<listitem>\r
12755<simpara>\r
12756<ulink url="http://portal.acm.org/citation.cfm?doid=319301.319348">Partial redundancy elimination in SSA form</ulink>; Robert Kennedy, Sun Chan, Shin-Ming Liu, Raymond Lo, Peng Tu, and Fred Chow\r
12757</simpara>\r
12758</listitem>\r
12759</itemizedlist>\r
12760<simpara>Recommended Skills: SML programming experience; some middle-end compiler experience</simpara>\r
12761</section>\r
12762<section id="_design_and_implement_a_heap_profiler_2">\r
12763<title>Design and Implement a Heap Profiler</title>\r
12764<simpara>A heap profile is a description of the space usage of a program. A\r
12765heap profile is concerned with the allocation, retention, and\r
12766deallocation (via garbage collection) of heap data during the\r
12767execution of a program. A heap profile can be used to diagnose\r
12768performance problems in a functional program that arise from space\r
12769leaks. This project aims to design and implement a heap profiler for\r
12770MLton compiled programs.</simpara>\r
12771<simpara>Background:</simpara>\r
12772<itemizedlist>\r
12773<listitem>\r
12774<simpara>\r
12775<ulink url="http://portal.acm.org/citation.cfm?doid=583854.582451">GCspy: an adaptable heap visualisation framework</ulink>; Tony Printezis and Richard Jones\r
12776</simpara>\r
12777</listitem>\r
12778<listitem>\r
12779<simpara>\r
12780<ulink url="http://journals.cambridge.org/action/displayAbstract?aid=1349892">New dimensions in heap profiling</ulink>; Colin Runciman and Niklas R&ouml;jemo\r
12781</simpara>\r
12782</listitem>\r
12783<listitem>\r
12784<simpara>\r
12785<ulink url="http://www.springerlink.com/content/710501660722gw37/">Heap profiling for space efficiency</ulink>; Colin Runciman and Niklas R&ouml;jemo\r
12786</simpara>\r
12787</listitem>\r
12788<listitem>\r
12789<simpara>\r
12790<ulink url="http://journals.cambridge.org/action/displayAbstract?aid=1323096">Heap profiling of lazy functional programs</ulink>; Colin Runciman and David Wakeling\r
12791</simpara>\r
12792</listitem>\r
12793</itemizedlist>\r
12794<simpara>Recommended Skills: C and SML programming experience; some experience with UI and visualization</simpara>\r
12795</section>\r
12796<section id="_garbage_collector_improvements_2">\r
12797<title>Garbage Collector Improvements</title>\r
12798<simpara>The garbage collector plays a significant role in the performance of\r
12799functional languages. Garbage collect too often, and program\r
12800performance suffers due to the excessive time spent in the garbage\r
12801collector. Garbage collect not often enough, and program performance\r
12802suffers due to the excessive space used by the uncollected garbage.\r
12803One particular issue is ensuring that a program utilizing a garbage\r
12804collector "plays nice" with other processes on the system, by not\r
12805using too much or too little physical memory. While there are some\r
12806reasonable theoretical results about garbage collections with heaps of\r
12807fixed size, there seems to be insufficient work that really looks\r
12808carefully at the question of dynamically resizing the heap in response\r
12809to the live data demands of the application and, similarly, in\r
12810response to the behavior of the operating system and other processes.\r
12811This project aims to investigate improvements to the memory behavior of\r
12812MLton compiled programs through better tuning of the garbage\r
12813collector.</simpara>\r
12814<simpara>Background:</simpara>\r
12815<itemizedlist>\r
12816<listitem>\r
12817<simpara>\r
12818<ulink url="http://www.dcs.gla.ac.uk/%7Ewhited/papers/automated_heap_sizing.pdf">Automated Heap Sizing in the Poly/ML Runtime (Position Paper)</ulink>; David White, Jeremy Singer, Jonathan Aitken, and David Matthews\r
12819</simpara>\r
12820</listitem>\r
12821<listitem>\r
12822<simpara>\r
12823<ulink url="http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=4145125">Isla Vista Heap Sizing: Using Feedback to Avoid Paging</ulink>; Chris Grzegorczyk, Sunil Soman, Chandra Krintz, and Rich Wolski\r
12824</simpara>\r
12825</listitem>\r
12826<listitem>\r
12827<simpara>\r
12828<ulink url="http://portal.acm.org/citation.cfm?doid=1152649.1152652">Controlling garbage collection and heap growth to reduce the execution time of Java applications</ulink>; Tim Brecht, Eshrat Arjomandi, Chang Li, and Hang Pham\r
12829</simpara>\r
12830</listitem>\r
12831<listitem>\r
12832<simpara>\r
12833<ulink url="http://portal.acm.org/citation.cfm?doid=1065010.1065028">Garbage collection without paging</ulink>; Matthew Hertz, Yi Feng, and Emery D. Berger\r
12834</simpara>\r
12835</listitem>\r
12836<listitem>\r
12837<simpara>\r
12838<ulink url="http://portal.acm.org/citation.cfm?doid=1029873.1029881">Automatic heap sizing: taking real memory into account</ulink>; Ting Yang, Matthew Hertz, Emery D. Berger, Scott F. Kaplan, and J. Eliot B. Moss\r
12839</simpara>\r
12840</listitem>\r
12841</itemizedlist>\r
12842<simpara>Recommended Skills: C programming experience; some operating systems and/or systems programming experience; some compiler and garbage collector experience</simpara>\r
12843</section>\r
12844<section id="_implement_successor_160_ml_language_features_2">\r
12845<title>Implement Successor&#160;ML Language Features</title>\r
12846<simpara>Any programming language, including Standard&#160;ML, can be improved.\r
12847The community has identified a number of modest extensions and\r
12848revisions to the Standard&#160;ML programming language that would\r
12849likely prove useful in practice. This project aims to implement these\r
12850language features in the MLton compiler.</simpara>\r
12851<simpara>Background:</simpara>\r
12852<itemizedlist>\r
12853<listitem>\r
12854<simpara>\r
12855<ulink url="http://successor-ml.org/index.php?title=Main_Page">Successor&#160;ML</ulink>\r
12856</simpara>\r
12857</listitem>\r
12858<listitem>\r
12859<simpara>\r
12860<ulink url="http://www.mpi-sws.org/%7Erossberg/hamlet/index.html#successor-ml">HaMLet (Successor&#160;ML)</ulink>\r
12861</simpara>\r
12862</listitem>\r
12863<listitem>\r
12864<simpara>\r
12865<ulink url="http://journals.cambridge.org/action/displayAbstract?aid=1322628">A critique of Standard&#160;ML</ulink>; Andrew W. Appel\r
12866</simpara>\r
12867</listitem>\r
12868</itemizedlist>\r
12869<simpara>Recommended Skills: SML programming experience; some front-end compiler experience (i.e., scanners and parsers)</simpara>\r
12870</section>\r
12871<section id="_implement_source_level_debugging_2">\r
12872<title>Implement Source-level Debugging</title>\r
12873<simpara>Debugging is a fact of programming life. Unfortunately, most SML\r
12874implementations (including MLton) provide little to no source-level\r
12875debugging support. This project aims to add basic to intermediate\r
12876source-level debugging support to the MLton compiler. MLton already\r
12877supports source-level profiling, which can be used to attribute bytes\r
12878allocated or time spent in source functions. It should be relatively\r
12879straightforward to leverage this source-level information into basic\r
12880source-level debugging support, with the ability to set/unset\r
12881breakpoints and step through declarations and functions. It may be\r
12882possible to also provide intermediate source-level debugging support,\r
12883with the ability to inspect in-scope variables of basic types (e.g.,\r
12884types compatible with MLton&#8217;s foreign function interface).</simpara>\r
12885<simpara>Background:</simpara>\r
12886<itemizedlist>\r
12887<listitem>\r
12888<simpara>\r
12889<ulink url="http://mlton.org/HowProfilingWorks">MLton&#8201;&#8212;&#8201;How Profiling Works</ulink>\r
12890</simpara>\r
12891</listitem>\r
12892<listitem>\r
12893<simpara>\r
12894<ulink url="http://mlton.org/ForeignFunctionInterfaceTypes">MLton&#8201;&#8212;&#8201;Foreign Function Interface Types</ulink>\r
12895</simpara>\r
12896</listitem>\r
12897<listitem>\r
12898<simpara>\r
12899<ulink url="http://dwarfstd.org/">DWARF Debugging Standard</ulink>\r
12900</simpara>\r
12901</listitem>\r
12902<listitem>\r
12903<simpara>\r
12904<ulink url="http://sourceware.org/gdb/current/onlinedocs/stabs/index.html">STABS Debugging Format</ulink>\r
12905</simpara>\r
12906</listitem>\r
12907</itemizedlist>\r
12908<simpara>Recommended Skills: SML programming experience; some compiler experience</simpara>\r
12909</section>\r
12910<section id="_region_based_memory_management_2">\r
12911<title>Region Based Memory Management</title>\r
12912<simpara>Region based memory management is an alternative automatic memory\r
12913management scheme to garbage collection. Regions can be inferred by\r
12914the compiler (e.g., Cyclone and MLKit) or provided to the programmer\r
12915through a library. Since many students do not have extensive\r
12916experience with compilers we plan on adopting the later approach.\r
12917Creating a viable region based memory solution requires the removal of\r
12918the GC and changes to the allocator. Additionally, write barriers\r
12919will be necessary to ensure references between two ML objects is never\r
12920established if the left hand side of the assignment has a longer\r
12921lifetime than the right hand side. Students will need to come up with\r
12922an appropriate interface for creating, entering, and exiting regions\r
12923(examples include RTSJ scoped memory and SCJ scoped memory).</simpara>\r
12924<simpara>Background:</simpara>\r
12925<itemizedlist>\r
12926<listitem>\r
12927<simpara>\r
12928Cyclone\r
12929</simpara>\r
12930</listitem>\r
12931<listitem>\r
12932<simpara>\r
12933MLKit\r
12934</simpara>\r
12935</listitem>\r
12936<listitem>\r
12937<simpara>\r
12938RTSJ + SCJ scopes\r
12939</simpara>\r
12940</listitem>\r
12941</itemizedlist>\r
12942<simpara>Recommended Skills: SML programming experience; C programming experience; some compiler and garbage collector experience</simpara>\r
12943</section>\r
12944<section id="_integration_of_multi_mlton_2">\r
12945<title>Integration of Multi-MLton</title>\r
12946<simpara><ulink url="http://multimlton.cs.purdue.edu">MultiMLton</ulink> is a compiler and runtime\r
12947environment that targets scalable multicore platforms. It is an\r
12948extension of MLton. It combines new language abstractions and\r
12949associated compiler analyses for expressing and implementing various\r
12950kinds of fine-grained parallelism (safe futures, speculation,\r
12951transactions, etc.), along with a sophisticated runtime system tuned\r
12952to efficiently handle large numbers of lightweight threads. The core\r
12953stable features of MultiMLton will need to be integrated with the\r
12954latest MLton public release. Certain experimental features, such as\r
12955support for the Intel SCC and distributed runtime will be omitted.\r
12956This project requires students to understand the delta between the\r
12957MultiMLton code base and the MLton code base. Students will need to\r
12958create build and configuration scripts for MLton to enable MultiMLton\r
12959features.</simpara>\r
12960<simpara>Background</simpara>\r
12961<itemizedlist>\r
12962<listitem>\r
12963<simpara>\r
12964<ulink url="http://multimlton.cs.purdue.edu/mML/Publications.html">MultiMLton&#8201;&#8212;&#8201;Publications</ulink>\r
12965</simpara>\r
12966</listitem>\r
12967</itemizedlist>\r
12968<simpara>Recommended Skills: SML programming experience; C programming experience; some compiler experience</simpara>\r
12969</section>\r
12970<section id="_concurrent_160_ml_improvements">\r
12971<title>Concurrent&#160;ML Improvements</title>\r
12972<simpara><ulink url="http://cml.cs.uchicago.edu/">Concurrent ML</ulink> is an SML concurrency\r
12973library based on synchronous message passing. MLton has a partial\r
12974implementation of the CML message-passing primitives, but its use in\r
12975real-world applications has been stymied by the lack of completeness\r
12976and thread-safe I/O libraries. This project would aim to flesh out\r
12977the CML implementation in MLton to be fully compatible with the\r
12978"official" version distributed as part of SML/NJ. Furthermore, time\r
12979permitting, runtime system support could be added to allow use of\r
12980modern OS features, such as asynchronous I/O, in the implementation of\r
12981CML&#8217;s system interfaces.</simpara>\r
12982<simpara>Background</simpara>\r
12983<itemizedlist>\r
12984<listitem>\r
12985<simpara>\r
12986<ulink url="http://cml.cs.uchicago.edu/">http://cml.cs.uchicago.edu/</ulink>\r
12987</simpara>\r
12988</listitem>\r
12989<listitem>\r
12990<simpara>\r
12991<ulink url="http://mlton.org/ConcurrentML">http://mlton.org/ConcurrentML</ulink>\r
12992</simpara>\r
12993</listitem>\r
12994<listitem>\r
12995<simpara>\r
12996<ulink url="http://mlton.org/ConcurrentMLImplementation">http://mlton.org/ConcurrentMLImplementation</ulink>\r
12997</simpara>\r
12998</listitem>\r
12999</itemizedlist>\r
13000<simpara>Recommended Skills: SML programming experience; knowledge of concurrent programming; some operating systems and/or systems programming experience</simpara>\r
13001<simpara><?asciidoc-pagebreak?></simpara>\r
13002</section>\r
13003</section>\r
13004</section>\r
13005<section id="GoogleSummerOfCode2015">\r
13006<title>Google Summer of Code (2015)</title>\r
13007<section id="_mentors_3">\r
13008<title>Mentors</title>\r
13009<simpara>The following developers have agreed to serve as mentors for the 2015 Google Summer of Code:</simpara>\r
13010<itemizedlist>\r
13011<listitem>\r
13012<simpara>\r
13013<ulink url="http://www.cs.rit.edu/%7Emtf">Matthew Fluet</ulink>\r
13014</simpara>\r
13015</listitem>\r
13016<listitem>\r
13017<simpara>\r
13018<ulink url="http://www.cse.buffalo.edu/%7Elziarek/">Lukasz (Luke) Ziarek</ulink>\r
13019</simpara>\r
13020</listitem>\r
13021</itemizedlist>\r
13022</section>\r
13023<section id="_ideas_list_3">\r
13024<title>Ideas List</title>\r
13025<section id="_design_and_implement_a_heap_profiler_3">\r
13026<title>Design and Implement a Heap Profiler</title>\r
13027<simpara>A heap profile is a description of the space usage of a program. A\r
13028heap profile is concerned with the allocation, retention, and\r
13029deallocation (via garbage collection) of heap data during the\r
13030execution of a program. A heap profile can be used to diagnose\r
13031performance problems in a functional program that arise from space\r
13032leaks. This project aims to design and implement a heap profiler for\r
13033MLton compiled programs.</simpara>\r
13034<simpara>Background:</simpara>\r
13035<itemizedlist>\r
13036<listitem>\r
13037<simpara>\r
13038<ulink url="http://portal.acm.org/citation.cfm?doid=583854.582451">GCspy: an adaptable heap visualisation framework</ulink>; Tony Printezis and Richard Jones\r
13039</simpara>\r
13040</listitem>\r
13041<listitem>\r
13042<simpara>\r
13043<ulink url="http://journals.cambridge.org/action/displayAbstract?aid=1349892">New dimensions in heap profiling</ulink>; Colin Runciman and Niklas R&ouml;jemo\r
13044</simpara>\r
13045</listitem>\r
13046<listitem>\r
13047<simpara>\r
13048<ulink url="http://www.springerlink.com/content/710501660722gw37/">Heap profiling for space efficiency</ulink>; Colin Runciman and Niklas R&ouml;jemo\r
13049</simpara>\r
13050</listitem>\r
13051<listitem>\r
13052<simpara>\r
13053<ulink url="http://journals.cambridge.org/action/displayAbstract?aid=1323096">Heap profiling of lazy functional programs</ulink>; Colin Runciman and David Wakeling\r
13054</simpara>\r
13055</listitem>\r
13056</itemizedlist>\r
13057<simpara>Recommended Skills: C and SML programming experience; some experience with UI and visualization</simpara>\r
13058</section>\r
13059<section id="_garbage_collector_improvements_3">\r
13060<title>Garbage Collector Improvements</title>\r
13061<simpara>The garbage collector plays a significant role in the performance of\r
13062functional languages. Garbage collect too often, and program\r
13063performance suffers due to the excessive time spent in the garbage\r
13064collector. Garbage collect not often enough, and program performance\r
13065suffers due to the excessive space used by the uncollected\r
13066garbage. One particular issue is ensuring that a program utilizing a\r
13067garbage collector "plays nice" with other processes on the system, by\r
13068not using too much or too little physical memory. While there are some\r
13069reasonable theoretical results about garbage collections with heaps of\r
13070fixed size, there seems to be insufficient work that really looks\r
13071carefully at the question of dynamically resizing the heap in response\r
13072to the live data demands of the application and, similarly, in\r
13073response to the behavior of the operating system and other\r
13074processes. This project aims to investigate improvements to the memory\r
13075behavior of MLton compiled programs through better tuning of the\r
13076garbage collector.</simpara>\r
13077<simpara>Background:</simpara>\r
13078<itemizedlist>\r
13079<listitem>\r
13080<simpara>\r
13081<ulink url="http://gchandbook.org/">The Garbage Collection Handbook: The Art of Automatic Memory Management</ulink>; Richard Jones, Antony Hosking, Eliot Moss\r
13082</simpara>\r
13083</listitem>\r
13084<listitem>\r
13085<simpara>\r
13086<ulink url="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.24.1020">Dual-Mode Garbage Collection</ulink>; Patrick Sansom\r
13087</simpara>\r
13088</listitem>\r
13089<listitem>\r
13090<simpara>\r
13091<ulink url="http://portal.acm.org/citation.cfm?doid=1029873.1029881">Automatic Heap Sizing: Taking Real Memory into Account</ulink>; Ting Yang, Matthew Hertz, Emery D. Berger, Scott F. Kaplan, and J. Eliot B. Moss\r
13092</simpara>\r
13093</listitem>\r
13094<listitem>\r
13095<simpara>\r
13096<ulink url="http://portal.acm.org/citation.cfm?doid=1152649.1152652">Controlling Garbage Collection and Heap Growth to Reduce the Execution Time of Java Applications</ulink>; Tim Brecht, Eshrat Arjomandi, Chang Li, and Hang Pham\r
13097</simpara>\r
13098</listitem>\r
13099<listitem>\r
13100<simpara>\r
13101<ulink url="http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=4145125">Isla Vista Heap Sizing: Using Feedback to Avoid Paging</ulink>; Chris Grzegorczyk, Sunil Soman, Chandra Krintz, and Rich Wolski\r
13102</simpara>\r
13103</listitem>\r
13104<listitem>\r
13105<simpara>\r
13106<ulink url="http://portal.acm.org/citation.cfm?doid=1806651.1806669">The Economics of Garbage Collection</ulink>; Jeremy Singer, Richard E. Jones, Gavin Brown, and Mikel Luján\r
13107</simpara>\r
13108</listitem>\r
13109<listitem>\r
13110<simpara>\r
13111<ulink url="http://www.dcs.gla.ac.uk/%7Ejsinger/pdfs/tfp12.pdf">Automated Heap Sizing in the Poly/ML Runtime (Position Paper)</ulink>; David White, Jeremy Singer, Jonathan Aitken, and David Matthews\r
13112</simpara>\r
13113</listitem>\r
13114<listitem>\r
13115<simpara>\r
13116<ulink url="http://portal.acm.org/citation.cfm?doid=2555670.2466481">Control Theory for Principled Heap Sizing</ulink>; David R. White, Jeremy Singer, Jonathan M. Aitken, and Richard E. Jones\r
13117</simpara>\r
13118</listitem>\r
13119</itemizedlist>\r
13120<simpara>Recommended Skills: C programming experience; some operating systems and/or systems programming experience; some compiler and garbage collector experience</simpara>\r
13121</section>\r
13122<section id="_heap_allocated_activation_records">\r
13123<title>Heap-allocated Activation Records</title>\r
13124<simpara>Activation records (a.k.a., stack frames) are traditionally allocated\r
13125on a stack. This naturally corresponds to the call-return pattern of\r
13126function invocation. However, there are some disadvantages to\r
13127stack-allocated activation records. In a functional programming\r
13128language, functions may be deeply recursive, resulting in call stacks\r
13129that are much larger than typically supported by the operating system;\r
13130hence, a functional programming language implementation will typically\r
13131store its stack in its heap. Furthermore, a functional programming\r
13132language implementation must handle and recover from stack overflow,\r
13133by allocating a larger stack (again, in its heap) and copying\r
13134activation records from the old stack to the new stack. In the\r
13135presence of threads, stacks must be allocated in a heap and, in the\r
13136presence of a garbage collector, should be garbage collected when\r
13137unreachable. While heap-allocated activation records avoid many of\r
13138these disadvantages, they have not been widely implemented. This\r
13139project aims to implement and evaluate heap-allocated activation\r
13140records in the MLton compiler.</simpara>\r
13141<simpara>Background:</simpara>\r
13142<itemizedlist>\r
13143<listitem>\r
13144<simpara>\r
13145<ulink url="http://journals.cambridge.org/action/displayAbstract?aid=1295104">Empirical and Analytic Study of Stack Versus Heap Cost for Languages with Closures</ulink>; Andrew W. Appel and Zhong Shao\r
13146</simpara>\r
13147</listitem>\r
13148<listitem>\r
13149<simpara>\r
13150<ulink url="http://portal.acm.org/citation.cfm?doid=182590.156783">Space-efficient closure representations</ulink>; Zhong Shao and Andrew W. Appel\r
13151</simpara>\r
13152</listitem>\r
13153<listitem>\r
13154<simpara>\r
13155<ulink url="http://portal.acm.org/citation.cfm?doid=93548.93554">Representing control in the presence of first-class continuations</ulink>; R. Hieb, R. Kent Dybvig, and Carl Bruggeman\r
13156</simpara>\r
13157</listitem>\r
13158</itemizedlist>\r
13159<simpara>Recommended Skills: SML programming experience; some middle- and back-end compiler experience</simpara>\r
13160</section>\r
13161<section id="_correctly_rounded_floating_point_binary_to_decimal_and_decimal_to_binary_conversion_routines_in_standard_ml">\r
13162<title>Correctly Rounded Floating-point Binary-to-Decimal and Decimal-to-Binary Conversion Routines in Standard ML</title>\r
13163<simpara>The\r
13164<ulink url="http://en.wikipedia.org/wiki/IEEE_754-2008">IEEE Standard for Floating-Point Arithmetic (IEEE 754)</ulink>\r
13165is the de facto representation for floating-point computation.\r
13166However, it is a <emphasis>binary</emphasis> (base 2) representation of floating-point\r
13167values, while many applications call for input and output of\r
13168floating-point values in <emphasis>decimal</emphasis> (base 10) representation. The\r
13169<emphasis>decimal-to-binary</emphasis> conversion problem takes a decimal floating-point\r
13170representation (e.g., a string like <literal>"0.1"</literal>) and returns the best\r
13171binary floating-point representation of that number. The\r
13172<emphasis>binary-to-decimal</emphasis> conversion problem takes a binary floating-point\r
13173representation and returns a decimal floating-point representation\r
13174using the smallest number of digits that allow the decimal\r
13175floating-point representation to be converted to the original binary\r
13176floating-point representation. For both conversion routines, "best"\r
13177is dependent upon the current floating-point rounding mode.</simpara>\r
13178<simpara>MLton uses David Gay&#8217;s\r
13179<ulink url="http://www.netlib.org/fp/gdtoa.tgz">gdtoa library</ulink> for floating-point\r
13180conversions. While this is an exellent library, it generalizes the\r
13181decimal-to-binary and binary-to-decimal conversion routines beyond\r
13182what is required by the\r
13183<ulink url="http://standardml.org/Basis/">Standard ML Basis Library</ulink> and induces an\r
13184external dependency on the compiler. Native implementations of these\r
13185conversion routines in Standard ML would obviate the dependency on the\r
13186<literal>gdtoa</literal> library, while also being able to take advantage of Standard\r
13187ML features in the implementation (e.g., the published algorithms\r
13188often require use of infinite precision arithmetic, which is provided\r
13189by the <literal>IntInf</literal> structure in Standard ML, but is provided in an ad hoc\r
13190fasion in the <literal>gdtoa</literal> library).</simpara>\r
13191<simpara>This project aims to develop a native implementation of the conversion\r
13192routines in Standard ML.</simpara>\r
13193<simpara>Background:</simpara>\r
13194<itemizedlist>\r
13195<listitem>\r
13196<simpara>\r
13197<ulink url="http://dl.acm.org/citation.cfm?doid=103162.103163">What every computer scientist should know about floating-point arithmetic</ulink>; David Goldberg\r
13198</simpara>\r
13199</listitem>\r
13200<listitem>\r
13201<simpara>\r
13202<ulink url="http://dl.acm.org/citation.cfm?doid=93542.93559">How to print floating-point numbers accurately</ulink>; Guy L. Steele, Jr. and Jon L. White\r
13203</simpara>\r
13204</listitem>\r
13205<listitem>\r
13206<simpara>\r
13207<ulink url="http://dl.acm.org/citation.cfm?doid=93542.93557">How to read floating point numbers accurately</ulink>; William D. Clinger\r
13208</simpara>\r
13209</listitem>\r
13210<listitem>\r
13211<simpara>\r
13212<ulink url="http://cm.bell-labs.com/cm/cs/doc/90/4-10.ps.gz">Correctly Rounded Binary-Decimal and Decimal-Binary Conversions</ulink>; David Gay\r
13213</simpara>\r
13214</listitem>\r
13215<listitem>\r
13216<simpara>\r
13217<ulink url="http://dl.acm.org/citation.cfm?doid=249069.231397">Printing floating-point numbers quickly and accurately</ulink>; Robert G. Burger and R. Kent Dybvig\r
13218</simpara>\r
13219</listitem>\r
13220<listitem>\r
13221<simpara>\r
13222<ulink url="http://dl.acm.org/citation.cfm?doid=1806596.1806623">Printing floating-point numbers quickly and accurately with integers</ulink>; Florian Loitsch\r
13223</simpara>\r
13224</listitem>\r
13225</itemizedlist>\r
13226<simpara>Recommended Skills: SML programming experience; algorithm design and implementation</simpara>\r
13227</section>\r
13228<section id="_implement_source_level_debugging_3">\r
13229<title>Implement Source-level Debugging</title>\r
13230<simpara>Debugging is a fact of programming life. Unfortunately, most SML\r
13231implementations (including MLton) provide little to no source-level\r
13232debugging support. This project aims to add basic to intermediate\r
13233source-level debugging support to the MLton compiler. MLton already\r
13234supports source-level profiling, which can be used to attribute bytes\r
13235allocated or time spent in source functions. It should be relatively\r
13236straightforward to leverage this source-level information into basic\r
13237source-level debugging support, with the ability to set/unset\r
13238breakpoints and step through declarations and functions. It may be\r
13239possible to also provide intermediate source-level debugging support,\r
13240with the ability to inspect in-scope variables of basic types (e.g.,\r
13241types compatible with MLton&#8217;s foreign function interface).</simpara>\r
13242<simpara>Background:</simpara>\r
13243<itemizedlist>\r
13244<listitem>\r
13245<simpara>\r
13246<ulink url="http://mlton.org/HowProfilingWorks">MLton&#8201;&#8212;&#8201;How Profiling Works</ulink>\r
13247</simpara>\r
13248</listitem>\r
13249<listitem>\r
13250<simpara>\r
13251<ulink url="http://mlton.org/ForeignFunctionInterfaceTypes">MLton&#8201;&#8212;&#8201;Foreign Function Interface Types</ulink>\r
13252</simpara>\r
13253</listitem>\r
13254<listitem>\r
13255<simpara>\r
13256<ulink url="http://dwarfstd.org/">DWARF Debugging Standard</ulink>\r
13257</simpara>\r
13258</listitem>\r
13259<listitem>\r
13260<simpara>\r
13261<ulink url="http://sourceware.org/gdb/current/onlinedocs/stabs/index.html">STABS Debugging Format</ulink>\r
13262</simpara>\r
13263</listitem>\r
13264</itemizedlist>\r
13265<simpara>Recommended Skills: SML programming experience; some compiler experience</simpara>\r
13266</section>\r
13267<section id="_region_based_memory_management_3">\r
13268<title>Region Based Memory Management</title>\r
13269<simpara>Region based memory management is an alternative automatic memory\r
13270management scheme to garbage collection. Regions can be inferred by\r
13271the compiler (e.g., Cyclone and MLKit) or provided to the programmer\r
13272through a library. Since many students do not have extensive\r
13273experience with compilers we plan on adopting the later approach.\r
13274Creating a viable region based memory solution requires the removal of\r
13275the GC and changes to the allocator. Additionally, write barriers\r
13276will be necessary to ensure references between two ML objects is never\r
13277established if the left hand side of the assignment has a longer\r
13278lifetime than the right hand side. Students will need to come up with\r
13279an appropriate interface for creating, entering, and exiting regions\r
13280(examples include RTSJ scoped memory and SCJ scoped memory).</simpara>\r
13281<simpara>Background:</simpara>\r
13282<itemizedlist>\r
13283<listitem>\r
13284<simpara>\r
13285Cyclone\r
13286</simpara>\r
13287</listitem>\r
13288<listitem>\r
13289<simpara>\r
13290MLKit\r
13291</simpara>\r
13292</listitem>\r
13293<listitem>\r
13294<simpara>\r
13295RTSJ + SCJ scopes\r
13296</simpara>\r
13297</listitem>\r
13298</itemizedlist>\r
13299<simpara>Recommended Skills: SML programming experience; C programming experience; some compiler and garbage collector experience</simpara>\r
13300</section>\r
13301<section id="_adding_real_time_capabilities">\r
13302<title>Adding Real-Time Capabilities</title>\r
13303<simpara>This project focuses on exposing real-time APIs from a real-time OS\r
13304kernel at the SML level. This will require mapping the current MLton\r
13305(or <ulink url="http://multimlton.cs.purdue.edu">MultiMLton</ulink>) threading framework\r
13306to real-time threads that the RTOS provides. This will include\r
13307associating priorities with MLton threads and building priority based\r
13308scheduling algorithms. Additionally, support for perdioc, aperiodic,\r
13309and sporadic tasks should be supported. A real-time SML library will\r
13310need to be created to provide a forward facing interface for\r
13311programmers. Stretch goals include reworking the MLton <literal>atomic</literal>\r
13312statement and associated synchronization primitives built on top of\r
13313the MLton <literal>atomic</literal> statement.</simpara>\r
13314<simpara>Recommended Skills: SML programming experience; C programming experience; real-time experience a plus but not required</simpara>\r
13315</section>\r
13316<section id="_real_time_garbage_collection">\r
13317<title>Real-Time Garbage Collection</title>\r
13318<simpara>This project focuses on modifications to the MLton GC to support\r
13319real-time garbage collection. We will model the real-time GC on the\r
13320Schism RTGC. The first task will be to create a fixed size runtime\r
13321object representation. Large structures will need to be represented\r
13322as a linked lists of fixed sized objects. Arrays and vectors will be\r
13323transferred into dense trees. Compaction and copying can therefore be\r
13324removed from the GC algorithms that MLton currently supports. Lastly,\r
13325the GC will be made concurrent, allowing for the execution of the GC\r
13326threads as the lowest priority task in the system. Stretch goals\r
13327include a priority aware mechanism for the GC to signal to real-time\r
13328ML threads that it needs to scan their stack and identification of\r
13329places where the stack is shallow to bound priority inversion during\r
13330this procedure.</simpara>\r
13331<simpara>Recommended Skills: C programming experience; garbage collector experience a plus but not required</simpara>\r
13332<simpara><?asciidoc-pagebreak?></simpara>\r
13333</section>\r
13334</section>\r
13335</section>\r
13336<section id="HaMLet">\r
13337<title>HaMLet</title>\r
13338<simpara><ulink url="http://www.mpi-sws.org/~rossberg/hamlet/">HaMLet</ulink> is a\r
13339<link linkend="StandardMLImplementations">Standard ML implementation</link>. It is\r
13340intended as reference implementation of\r
13341<link linkend="DefinitionOfStandardML">The Definition of Standard ML (Revised)</link> and\r
13342not for serious practical work.</simpara>\r
13343<simpara><?asciidoc-pagebreak?></simpara>\r
13344</section>\r
13345<section id="HenryCejtin">\r
13346<title>HenryCejtin</title>\r
13347<simpara>I was one of the original developers of Mathematica (actually employee #1).\r
13348My background is a combination of mathematics and computer science.\r
13349Currently I am doing various things in Chicago.</simpara>\r
13350<simpara><?asciidoc-pagebreak?></simpara>\r
13351</section>\r
13352<section id="History">\r
13353<title>History</title>\r
13354<simpara>In April 1997, Stephen Weeks wrote a defunctorizer for Standard ML and\r
13355integrated it with SML/NJ. The defunctorizer used SML/NJ&#8217;s visible\r
13356compiler and operated on the <literal>Ast</literal> intermediate representation\r
13357produced by the SML/NJ front end. Experiments showed that\r
13358defunctorization gave a speedup of up to six times over separate\r
13359compilation and up to two times over batch compilation without functor\r
13360expansion.</simpara>\r
13361<simpara>In August 1997, we began development of an independent compiler for\r
13362SML. At the time the compiler was called <literal>smlc</literal>. By October, we had\r
13363a working monomorphiser. By November, we added a polyvariant\r
13364higher-order control-flow analysis. At that point, MLton was about\r
1336510,000 lines of code.</simpara>\r
13366<simpara>Over the next year and half, <literal>smlc</literal> morphed into a full-fledged\r
13367compiler for SML. It was renamed MLton, and first released in March\r
133681999.</simpara>\r
13369<simpara>From the start, MLton has been driven by whole-program optimization\r
13370and an emphasis on performance. Also from the start, MLton has had a\r
13371fast C FFI and <literal>IntInf</literal> based on the GNU multiprecision library. At\r
13372its first release, MLton was 48,006 lines.</simpara>\r
13373<simpara>Between the March 1999 and January 2002, MLton grew to 102,541 lines,\r
13374as we added a native code generator, mllex, mlyacc, a profiler, many\r
13375optimizations, and many libraries including threads and signal\r
13376handling.</simpara>\r
13377<simpara>During 2002, MLton grew to 112,204 lines and we had releases in April\r
13378and September. We added support for cross compilation and used this\r
13379to enable MLton to run on Cygwin/Windows and FreeBSD. We also made\r
13380improvements to the garbage collector, so that it now works with large\r
13381arrays and up to 4G of memory and so that it automatically uses\r
13382copying, mark-compact, or generational collection depending on heap\r
13383usage and RAM size. We also continued improvements to the optimizer\r
13384and libraries.</simpara>\r
13385<simpara>During 2003, MLton grew to 122,299 lines and we had releases in March\r
13386and July. We extended the profiler to support source-level profiling\r
13387of time and allocation and to display call graphs. We completed the\r
13388Basis Library implementation, and added new MLton-specific libraries\r
13389for weak pointers and finalization. We extended the FFI to allow\r
13390callbacks from C to SML. We added support for the Sparc/Solaris\r
13391platform, and made many improvements to the C code generator.</simpara>\r
13392<simpara><?asciidoc-pagebreak?></simpara>\r
13393</section>\r
13394<section id="HowProfilingWorks">\r
13395<title>HowProfilingWorks</title>\r
13396<simpara>Here&#8217;s how <link linkend="Profiling">Profiling</link> works. If profiling is on, the front end\r
13397(elaborator) inserts <literal>Enter</literal> and <literal>Leave</literal> statements into the source\r
13398program for function entry and exit. For example,</simpara>\r
13399<programlisting language="sml" linenumbering="unnumbered">fun f n = if n = 0 then 0 else 1 + f (n - 1)</programlisting>\r
13400<simpara>becomes</simpara>\r
13401<programlisting language="sml" linenumbering="unnumbered">fun f n =\r
13402 let\r
13403 val () = Enter "f"\r
13404 val res = (if n = 0 then 0 else 1 + f (n - 1))\r
13405 handle e =&gt; (Leave "f"; raise e)\r
13406 val () = Leave "f"\r
13407 in\r
13408 res\r
13409 end</programlisting>\r
13410<simpara>Actually there is a bit more information than just the source function\r
13411name; there is also lexical nesting and file position.</simpara>\r
13412<simpara>Most of the middle of the compiler ignores, but preserves, <literal>Enter</literal> and\r
13413<literal>Leave</literal>. However, so that profiling preserves tail calls, the\r
13414<link linkend="Shrink">SSA shrinker</link> has an optimization that notices when the only\r
13415operations that cause a call to be a nontail call are profiling\r
13416operations, and if so, moves them before the call, turning it into a\r
13417tail call. If you observe a program that has a tail call that appears\r
13418to be turned into a nontail when compiled with profiling, please\r
13419<link linkend="Bug">report a bug</link>.</simpara>\r
13420<simpara>There is the <literal>checkProf</literal> function in\r
13421<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/type-check.fun"><literal>type-check.fun</literal></ulink>, which checks that\r
13422the <literal>Enter</literal>/<literal>Leave</literal> statements match up.</simpara>\r
13423<simpara>In the backend, just before translating to the <link linkend="Machine">Machine IL</link>,\r
13424the profiler uses the <literal>Enter</literal>/<literal>Leave</literal> statements to infer the "local"\r
13425portion of the control stack at each program point. The profiler then\r
13426removes the <literal>Enter</literal>s/<literal>Leave</literal>s and inserts different information\r
13427depending on which kind of profiling is happening. For time profiling\r
13428(with the <link linkend="AMD64Codegen">AMD64Codegen</link> and <link linkend="X86Codegen">X86Codegen</link>), the profiler inserts labels that cover the\r
13429code (i.e. each statement has a unique label in its basic block that\r
13430prefixes it) and associates each label with the local control stack.\r
13431For time profiling (with the <link linkend="CCodegen">CCodegen</link> and <link linkend="LLVMCodegen">LLVMCodegen</link>), the profiler\r
13432inserts code that sets a global field that records the local control\r
13433stack. For allocation profiling, the profiler inserts calls to a C\r
13434function that will maintain byte counts. With stack profiling, the\r
13435profiler also inserts a call to a C function at each nontail call in\r
13436order to maintain information at runtime about what SML functions are\r
13437on the stack.</simpara>\r
13438<simpara>At run time, the profiler associates counters (either clock ticks or\r
13439byte counts) with source functions. When the program finishes, the\r
13440profiler writes the counts out to the <literal>mlmon.out</literal> file. Then,\r
13441<literal>mlprof</literal> uses source information stored in the executable to\r
13442associate the counts in the <literal>mlmon.out</literal> file with source\r
13443functions.</simpara>\r
13444<simpara>For time profiling, the profiler catches the <literal>SIGPROF</literal> signal 100\r
13445times per second and increments the appropriate counter, determined by\r
13446looking at the label prefixing the current program counter and mapping\r
13447that to the current source function.</simpara>\r
13448<section id="_caveats_2">\r
13449<title>Caveats</title>\r
13450<simpara>There may be a few missed clock ticks or bytes allocated at the very\r
13451end of the program after the data is written.</simpara>\r
13452<simpara>Profiling has not been tested with signals or threads. In particular,\r
13453stack profiling may behave strangely.</simpara>\r
13454<simpara><?asciidoc-pagebreak?></simpara>\r
13455</section>\r
13456</section>\r
13457<section id="Identifier">\r
13458<title>Identifier</title>\r
13459<simpara>In <link linkend="StandardML">Standard ML</link>, there are syntactically two kinds of\r
13460identifiers.</simpara>\r
13461<itemizedlist>\r
13462<listitem>\r
13463<simpara>\r
13464Alphanumeric: starts with a letter or prime (<literal>'</literal>) and is followed by letters, digits, primes and underbars (<literal>_</literal>).\r
13465</simpara>\r
13466<simpara>Examples: <literal>abc</literal>, <literal>ABC123</literal>, <literal>Abc_123</literal>, <literal>'a</literal>.</simpara>\r
13467</listitem>\r
13468<listitem>\r
13469<simpara>\r
13470Symbolic: a sequence of the following\r
13471</simpara>\r
13472<screen> ! % &amp; $ # + - / : &lt; = &gt; ? @ | ~ ` ^ | *</screen>\r
13473<simpara>Examples: <literal>+=</literal>, <literal>&lt;=</literal>, <literal>&gt;&gt;</literal>, <literal>$</literal>.</simpara>\r
13474</listitem>\r
13475</itemizedlist>\r
13476<simpara>With the exception of <literal>=</literal>, reserved words can not be identifiers.</simpara>\r
13477<simpara>There are a number of different classes of identifiers, some of which\r
13478have additional syntactic rules.</simpara>\r
13479<itemizedlist>\r
13480<listitem>\r
13481<simpara>\r
13482Identifiers not starting with a prime.\r
13483</simpara>\r
13484<itemizedlist>\r
13485<listitem>\r
13486<simpara>\r
13487value identifier (includes variables and constructors)\r
13488</simpara>\r
13489</listitem>\r
13490<listitem>\r
13491<simpara>\r
13492type constructor\r
13493</simpara>\r
13494</listitem>\r
13495<listitem>\r
13496<simpara>\r
13497structure identifier\r
13498</simpara>\r
13499</listitem>\r
13500<listitem>\r
13501<simpara>\r
13502signature identifier\r
13503</simpara>\r
13504</listitem>\r
13505<listitem>\r
13506<simpara>\r
13507functor identifier\r
13508</simpara>\r
13509</listitem>\r
13510</itemizedlist>\r
13511</listitem>\r
13512<listitem>\r
13513<simpara>\r
13514Identifiers starting with a prime.\r
13515</simpara>\r
13516<itemizedlist>\r
13517<listitem>\r
13518<simpara>\r
13519type variable\r
13520</simpara>\r
13521</listitem>\r
13522</itemizedlist>\r
13523</listitem>\r
13524<listitem>\r
13525<simpara>\r
13526Identifiers not starting with a prime and numeric labels (<literal>1</literal>, <literal>2</literal>, &#8230;).\r
13527</simpara>\r
13528<itemizedlist>\r
13529<listitem>\r
13530<simpara>\r
13531record label\r
13532</simpara>\r
13533</listitem>\r
13534</itemizedlist>\r
13535</listitem>\r
13536</itemizedlist>\r
13537<simpara><?asciidoc-pagebreak?></simpara>\r
13538</section>\r
13539<section id="Immutable">\r
13540<title>Immutable</title>\r
13541<simpara>Immutable means not <link linkend="Mutable">mutable</link> and is an adjective meaning\r
13542"can not be modified". Most values in <link linkend="StandardML">Standard ML</link> are\r
13543immutable. For example, constants, tuples, records, lists, and\r
13544vectors are all immutable.</simpara>\r
13545<simpara><?asciidoc-pagebreak?></simpara>\r
13546</section>\r
13547<section id="ImperativeTypeVariable">\r
13548<title>ImperativeTypeVariable</title>\r
13549<simpara>In <link linkend="StandardML">Standard ML</link>, an imperative type variable is a type\r
13550variable whose second character is a digit, as in <literal>'1a</literal> or\r
13551<literal>'2b</literal>. Imperative type variables were used as an alternative to\r
13552the <link linkend="ValueRestriction">ValueRestriction</link> in an earlier version of SML, but no longer play\r
13553a role. They are treated exactly as other type variables.</simpara>\r
13554<simpara><?asciidoc-pagebreak?></simpara>\r
13555</section>\r
13556<section id="ImplementExceptions">\r
13557<title>ImplementExceptions</title>\r
13558<simpara><link linkend="ImplementExceptions">ImplementExceptions</link> is a pass for the <link linkend="SXML">SXML</link>\r
13559<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="SXMLSimplify">SXMLSimplify</link>.</simpara>\r
13560<section id="_description_20">\r
13561<title>Description</title>\r
13562<simpara>This pass implements exceptions.</simpara>\r
13563</section>\r
13564<section id="_implementation_22">\r
13565<title>Implementation</title>\r
13566<itemizedlist>\r
13567<listitem>\r
13568<simpara>\r
13569<ulink url="https://github.com/MLton/mlton/blob/master/mlton/xml/implement-exceptions.fun"><literal>implement-exceptions.fun</literal></ulink>\r
13570</simpara>\r
13571</listitem>\r
13572</itemizedlist>\r
13573</section>\r
13574<section id="_details_and_notes_22">\r
13575<title>Details and Notes</title>\r
13576<simpara></simpara>\r
13577<simpara><?asciidoc-pagebreak?></simpara>\r
13578</section>\r
13579</section>\r
13580<section id="ImplementHandlers">\r
13581<title>ImplementHandlers</title>\r
13582<simpara><link linkend="ImplementHandlers">ImplementHandlers</link> is a pass for the <link linkend="RSSA">RSSA</link>\r
13583<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="RSSASimplify">RSSASimplify</link>.</simpara>\r
13584<section id="_description_21">\r
13585<title>Description</title>\r
13586<simpara>This pass implements the (threaded) exception handler stack.</simpara>\r
13587</section>\r
13588<section id="_implementation_23">\r
13589<title>Implementation</title>\r
13590<itemizedlist>\r
13591<listitem>\r
13592<simpara>\r
13593<ulink url="https://github.com/MLton/mlton/blob/master/mlton/backend/implement-handlers.fun"><literal>implement-handlers.fun</literal></ulink>\r
13594</simpara>\r
13595</listitem>\r
13596</itemizedlist>\r
13597</section>\r
13598<section id="_details_and_notes_23">\r
13599<title>Details and Notes</title>\r
13600<simpara></simpara>\r
13601<simpara><?asciidoc-pagebreak?></simpara>\r
13602</section>\r
13603</section>\r
13604<section id="ImplementProfiling">\r
13605<title>ImplementProfiling</title>\r
13606<simpara><link linkend="ImplementProfiling">ImplementProfiling</link> is a pass for the <link linkend="RSSA">RSSA</link>\r
13607<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="RSSASimplify">RSSASimplify</link>.</simpara>\r
13608<section id="_description_22">\r
13609<title>Description</title>\r
13610<simpara>This pass implements profiling.</simpara>\r
13611</section>\r
13612<section id="_implementation_24">\r
13613<title>Implementation</title>\r
13614<itemizedlist>\r
13615<listitem>\r
13616<simpara>\r
13617<ulink url="https://github.com/MLton/mlton/blob/master/mlton/backend/implement-profiling.fun"><literal>implement-profiling.fun</literal></ulink>\r
13618</simpara>\r
13619</listitem>\r
13620</itemizedlist>\r
13621</section>\r
13622<section id="_details_and_notes_24">\r
13623<title>Details and Notes</title>\r
13624<simpara>See <link linkend="HowProfilingWorks">HowProfilingWorks</link>.</simpara>\r
13625<simpara><?asciidoc-pagebreak?></simpara>\r
13626</section>\r
13627</section>\r
13628<section id="ImplementSuffix">\r
13629<title>ImplementSuffix</title>\r
13630<simpara><link linkend="ImplementSuffix">ImplementSuffix</link> is a pass for the <link linkend="SXML">SXML</link>\r
13631<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="SXMLSimplify">SXMLSimplify</link>.</simpara>\r
13632<section id="_description_23">\r
13633<title>Description</title>\r
13634<simpara>This pass implements the <literal>TopLevel_setSuffix</literal> primitive, which\r
13635installs a function to exit the program.</simpara>\r
13636</section>\r
13637<section id="_implementation_25">\r
13638<title>Implementation</title>\r
13639<itemizedlist>\r
13640<listitem>\r
13641<simpara>\r
13642<ulink url="https://github.com/MLton/mlton/blob/master/mlton/xml/implement-suffix.fun"><literal>implement-suffix.fun</literal></ulink>\r
13643</simpara>\r
13644</listitem>\r
13645</itemizedlist>\r
13646</section>\r
13647<section id="_details_and_notes_25">\r
13648<title>Details and Notes</title>\r
13649<simpara><link linkend="ImplementSuffix">ImplementSuffix</link> works by introducing a new <literal>ref</literal> cell to contain\r
13650the function of type <literal>unit -&gt; unit</literal> that should be called on program\r
13651exit.</simpara>\r
13652<itemizedlist>\r
13653<listitem>\r
13654<simpara>\r
13655The following code (appropriately alpha-converted) is appended to the beginning of the <link linkend="SXML">SXML</link> program:\r
13656</simpara>\r
13657<programlisting language="sml" linenumbering="unnumbered">val z_0 =\r
13658 fn a_0 =&gt;\r
13659 let\r
13660 val x_0 =\r
13661 "toplevel suffix not installed"\r
13662 val x_1 =\r
13663 MLton_bug (x_0)\r
13664 in\r
13665 x_1\r
13666 end\r
13667val topLevelSuffixCell =\r
13668 Ref_ref (z_0)</programlisting>\r
13669</listitem>\r
13670<listitem>\r
13671<simpara>\r
13672Any occurrence of\r
13673</simpara>\r
13674<programlisting language="sml" linenumbering="unnumbered">val x_0 =\r
13675 TopLevel_setSuffix (f_0)</programlisting>\r
13676<simpara>is rewritten to</simpara>\r
13677<programlisting language="sml" linenumbering="unnumbered">val x_0 =\r
13678 Ref_assign (topLevelSuffixCell, f_0)</programlisting>\r
13679</listitem>\r
13680<listitem>\r
13681<simpara>\r
13682The following code (appropriately alpha-converted) is appended to the end of the <link linkend="SXML">SXML</link> program:\r
13683</simpara>\r
13684<programlisting language="sml" linenumbering="unnumbered">val f_0 =\r
13685 Ref_deref (topLevelSuffixCell)\r
13686val z_0 =\r
13687 ()\r
13688val x_0 =\r
13689 f_0 z_0</programlisting>\r
13690</listitem>\r
13691</itemizedlist>\r
13692<simpara><?asciidoc-pagebreak?></simpara>\r
13693</section>\r
13694</section>\r
13695<section id="InfixingOperators">\r
13696<title>InfixingOperators</title>\r
13697<simpara>Fixity specifications are not part of signatures in\r
13698<link linkend="StandardML">Standard ML</link>. When one wants to use a module that\r
13699provides functions designed to be used as infix operators there are\r
13700several obvious alternatives:</simpara>\r
13701<itemizedlist>\r
13702<listitem>\r
13703<simpara>\r
13704Use only prefix applications. Unfortunately there are situations\r
13705where infix applications lead to considerably more readable code.\r
13706</simpara>\r
13707</listitem>\r
13708<listitem>\r
13709<simpara>\r
13710Make the fixity declarations at the top-level. This may lead to\r
13711collisions and may be unsustainable in a large project. Pollution of\r
13712the top-level should be avoided.\r
13713</simpara>\r
13714</listitem>\r
13715<listitem>\r
13716<simpara>\r
13717Make the fixity declarations at each scope where you want to use\r
13718infix applications. The duplication becomes inconvenient if the\r
13719operators are widely used. Duplication of code should be avoided.\r
13720</simpara>\r
13721</listitem>\r
13722<listitem>\r
13723<simpara>\r
13724Use non-standard extensions, such as the <link linkend="MLBasis">ML Basis system</link>\r
13725to control the scope of fixity declarations. This has the obvious\r
13726drawback of reduced portability.\r
13727</simpara>\r
13728</listitem>\r
13729<listitem>\r
13730<simpara>\r
13731Reuse existing infix operator symbols (<literal>^</literal>, <literal>+</literal>, <literal>-</literal>, &#8230;). This\r
13732can be convenient when the standard operators aren&#8217;t needed in the\r
13733same scope with the new operators. On the other hand, one is limited\r
13734to the standard operator symbols and the code may appear confusing.\r
13735</simpara>\r
13736</listitem>\r
13737</itemizedlist>\r
13738<simpara>None of the obvious alternatives is best in every case. The following\r
13739describes a slightly less obvious alternative that can sometimes be\r
13740useful. The idea is to approximate Haskell&#8217;s special syntax for\r
13741treating any identifier enclosed in grave accents (backquotes) as an\r
13742infix operator. In Haskell, instead of writing the prefix application\r
13743<literal>f x y</literal> one can write the infix application <literal>x &grave;f&grave; y</literal>.</simpara>\r
13744<section id="_infixing_operators">\r
13745<title>Infixing operators</title>\r
13746<simpara>Let&#8217;s first take a look at the definitions of the operators:</simpara>\r
13747<programlisting language="sml" linenumbering="unnumbered">infix 3 &lt;\ fun x &lt;\ f = fn y =&gt; f (x, y) (* Left section *)\r
13748infix 3 \&gt; fun f \&gt; y = f y (* Left application *)\r
13749infixr 3 /&gt; fun f /&gt; y = fn x =&gt; f (x, y) (* Right section *)\r
13750infixr 3 &lt;/ fun x &lt;/ f = f x (* Right application *)\r
13751\r
13752infix 2 o (* See motivation below *)\r
13753infix 0 :=</programlisting>\r
13754<simpara>The left and right sectioning operators, <literal>&lt;\</literal> and <literal>/&gt;</literal>, are useful in\r
13755SML for partial application of infix operators.\r
13756<link linkend="References_Paulson96">ML For the Working Programmer</link> describes curried\r
13757functions <literal>secl</literal> and <literal>secr</literal> for the same purpose on pages 179-181.\r
13758For example,</simpara>\r
13759<programlisting language="sml" linenumbering="unnumbered">List.map (op- /&gt; y)</programlisting>\r
13760<simpara>is a function for subtracting <literal>y</literal> from a list of integers and</simpara>\r
13761<programlisting language="sml" linenumbering="unnumbered">List.exists (x &lt;\ op=)</programlisting>\r
13762<simpara>is a function for testing whether a list contains an <literal>x</literal>.</simpara>\r
13763<simpara>Together with the left and right application operators, <literal>\&gt;</literal> and <literal>&lt;/</literal>,\r
13764the sectioning operators provide a way to treat any binary function\r
13765(i.e. a function whose domain is a pair) as an infix operator. In\r
13766general,</simpara>\r
13767<screen>x0 &lt;\f1\&gt; x1 &lt;\f2\&gt; x2 ... &lt;\fN\&gt; xN = fN (... f2 (f1 (x0, x1), x2) ..., xN)</screen>\r
13768<simpara>and</simpara>\r
13769<screen>xN &lt;/fN/&gt; ... x2 &lt;/f2/&gt; x1 &lt;/f1/&gt; x0 = fN (xN, ... f2 (x2, f1 (x1, x0)) ...)</screen>\r
13770<section id="_examples_2">\r
13771<title>Examples</title>\r
13772<simpara>As a fairly realistic example, consider providing a function for sequencing\r
13773comparisons:</simpara>\r
13774<programlisting language="sml" linenumbering="unnumbered">structure Order (* ... *) =\r
13775 struct\r
13776 (* ... *)\r
13777 val orWhenEq = fn (EQUAL, th) =&gt; th ()\r
13778 | (other, _) =&gt; other\r
13779 (* ... *)\r
13780 end</programlisting>\r
13781<simpara>Using <literal>orWhenEq</literal> and the infixing operators, one can write a\r
13782<literal>compare</literal> function for triples as</simpara>\r
13783<programlisting language="sml" linenumbering="unnumbered">fun compare (fad, fbe, fcf) ((a, b, c), (d, e, f)) =\r
13784 fad (a, d) &lt;\Order.orWhenEq\&gt; `fbe (b, e) &lt;\Order.orWhenEq\&gt; `fcf (c, f)</programlisting>\r
13785<simpara>where <literal>&grave;</literal> is defined as</simpara>\r
13786<programlisting language="sml" linenumbering="unnumbered">fun `f x = fn () =&gt; f x</programlisting>\r
13787<simpara>Although <literal>orWhenEq</literal> can be convenient (try rewriting the above without\r
13788it), it is probably not useful enough to be defined at the top level\r
13789as an infix operator. Fortunately we can use the infixing operators\r
13790and don&#8217;t have to.</simpara>\r
13791<simpara>Another fairly realistic example would be to use the infixing operators with\r
13792the technique described on the <link linkend="Printf">Printf</link> page. Assuming that you would have\r
13793a <literal>Printf</literal> module binding <literal>printf</literal>, <literal>&grave;</literal>, and formatting combinators\r
13794named <literal>int</literal> and <literal>string</literal>, you could write</simpara>\r
13795<programlisting language="sml" linenumbering="unnumbered">let open Printf in\r
13796 printf (`"Here's an int "&lt;\int\&gt;" and a string "&lt;\string\&gt;".") 13 "foo" end</programlisting>\r
13797<simpara>without having to duplicate the fixity declarations. Alternatively, you could\r
13798write</simpara>\r
13799<programlisting language="sml" linenumbering="unnumbered">P.printf (P.`"Here's an int "&lt;\P.int\&gt;" and a string "&lt;\P.string\&gt;".") 13 "foo"</programlisting>\r
13800<simpara>assuming you have the made the binding</simpara>\r
13801<programlisting language="sml" linenumbering="unnumbered">structure P = Printf</programlisting>\r
13802</section>\r
13803</section>\r
13804<section id="_application_and_piping_operators">\r
13805<title>Application and piping operators</title>\r
13806<simpara>The left and right application operators may also provide some notational\r
13807convenience on their own. In general,</simpara>\r
13808<screen>f \&gt; x1 \&gt; ... \&gt; xN = f x1 ... xN</screen>\r
13809<simpara>and</simpara>\r
13810<screen>xN &lt;/ ... &lt;/ x1 &lt;/ f = f x1 ... xN</screen>\r
13811<simpara>If nothing else, both of them can eliminate parentheses. For example,</simpara>\r
13812<programlisting language="sml" linenumbering="unnumbered">foo (1 + 2) = foo \&gt; 1 + 2</programlisting>\r
13813<simpara>The left and right application operators are related to operators\r
13814that could be described as the right and left piping operators:</simpara>\r
13815<programlisting language="sml" linenumbering="unnumbered">infix 1 &gt;| val op&gt;| = op&lt;/ (* Left pipe *)\r
13816infixr 1 |&lt; val op|&lt; = op\&gt; (* Right pipe *)</programlisting>\r
13817<simpara>As you can see, the left and right piping operators, <literal>&gt;|</literal> and <literal>|&lt;</literal>,\r
13818are the same as the right and left application operators,\r
13819respectively, except the associativities are reversed and the binding\r
13820strength is lower. They are useful for piping data through a sequence\r
13821of operations. In general,</simpara>\r
13822<screen>x &gt;| f1 &gt;| ... &gt;| fN = fN (... (f1 x) ...) = (fN o ... o f1) x</screen>\r
13823<simpara>and</simpara>\r
13824<screen>fN |&lt; ... |&lt; f1 |&lt; x = fN (... (f1 x) ...) = (fN o ... o f1) x</screen>\r
13825<simpara>The right piping operator, <literal>|&lt;</literal>, is provided by the Haskell prelude as\r
13826<literal>$</literal>. It can be convenient in CPS or continuation passing style.</simpara>\r
13827<simpara>A use for the left piping operator is with parsing combinators. In a\r
13828strict language, like SML, eta-reduction is generally unsafe. Using\r
13829the left piping operator, parsing functions can be formatted\r
13830conveniently as</simpara>\r
13831<programlisting language="sml" linenumbering="unnumbered">fun parsingFunc input =\r
13832 input &gt;| (* ... *)\r
13833 || (* ... *)\r
13834 || (* ... *)</programlisting>\r
13835<simpara>where <literal>||</literal> is supposed to be a combinator provided by the parsing combinator\r
13836library.</simpara>\r
13837</section>\r
13838<section id="_about_precedences">\r
13839<title>About precedences</title>\r
13840<simpara>You probably noticed that we redefined the\r
13841<link linkend="OperatorPrecedence">precedences</link> of the function composition operator\r
13842<literal>o</literal> and the assignment operator <literal>:=</literal>. Doing so is not strictly\r
13843necessary, but can be convenient and should be relatively\r
13844safe. Consider the following motivating examples from\r
13845<link linkend="WesleyTerpstra">Wesley W. Terpstra</link> relying on the redefined\r
13846precedences:</simpara>\r
13847<programlisting language="sml" linenumbering="unnumbered">Word8.fromInt o Char.ord o s &lt;\String.sub\r
13848(* Combining sectioning and composition *)\r
13849\r
13850x := s &lt;\String.sub\&gt; i\r
13851(* Assigning the result of an infixed application *)</programlisting>\r
13852<simpara>In imperative languages, assignment usually has the lowest precedence\r
13853(ignoring statement separators). The precedence of <literal>:=</literal> in the\r
13854<link linkend="BasisLibrary">Basis Library</link> is perhaps unnecessarily high, because\r
13855an expression of the form <literal>r := x</literal> always returns a unit, which makes\r
13856little sense to combine with anything. Dropping <literal>:=</literal> to the lowest\r
13857precedence level makes it behave more like in other imperative\r
13858languages.</simpara>\r
13859<simpara>The case for <literal>o</literal> is different. With the exception of <literal>before</literal> and\r
13860<literal>:=</literal>, it doesn&#8217;t seem to make much sense to use <literal>o</literal> with any of the\r
13861operators defined by the <link linkend="BasisLibrary">Basis Library</link> in an\r
13862unparenthesized expression. This is simply because none of the other\r
13863operators deal with functions. It would seem that the precedence of\r
13864<literal>o</literal> could be chosen completely arbitrarily from the set <literal>{1, ..., 9}</literal>\r
13865without having any adverse effects with respect to other infix\r
13866operators defined by the <link linkend="BasisLibrary">Basis Library</link>.</simpara>\r
13867</section>\r
13868<section id="_design_of_the_symbols">\r
13869<title>Design of the symbols</title>\r
13870<simpara>The closest approximation of Haskell&#8217;s <literal>x &grave;f&grave; y</literal> syntax\r
13871achievable in Standard ML would probably be something like\r
13872<literal>x &grave;f^ y</literal>, but <literal>^</literal> is already used for string\r
13873concatenation by the <link linkend="BasisLibrary">Basis Library</link>. Other\r
13874combinations of the characters <literal>&grave;</literal> and <literal>^</literal> would be\r
13875possible, but none seems clearly the best visually. The symbols <literal>&lt;\</literal>,\r
13876<literal>\&gt;</literal>, <literal>&lt;/</literal>, and <literal>/&gt;</literal> are reasonably concise and have a certain\r
13877self-documenting appearance and symmetry, which can help to remember\r
13878them. As the names suggest, the symbols of the piping operators <literal>&gt;|</literal>\r
13879and <literal>|&lt;</literal> are inspired by Unix shell pipelines.</simpara>\r
13880</section>\r
13881<section id="_also_see_7">\r
13882<title>Also see</title>\r
13883<itemizedlist>\r
13884<listitem>\r
13885<simpara>\r
13886<link linkend="Utilities">Utilities</link>\r
13887</simpara>\r
13888</listitem>\r
13889</itemizedlist>\r
13890<simpara><?asciidoc-pagebreak?></simpara>\r
13891</section>\r
13892</section>\r
13893<section id="Inline">\r
13894<title>Inline</title>\r
13895<simpara><link linkend="Inline">Inline</link> is an optimization pass for the <link linkend="SSA">SSA</link>\r
13896<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="SSASimplify">SSASimplify</link>.</simpara>\r
13897<section id="_description_24">\r
13898<title>Description</title>\r
13899<simpara>This pass inlines <link linkend="SSA">SSA</link> functions using a size-based metric.</simpara>\r
13900</section>\r
13901<section id="_implementation_26">\r
13902<title>Implementation</title>\r
13903<itemizedlist>\r
13904<listitem>\r
13905<simpara>\r
13906<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/inline.sig"><literal>inline.sig</literal></ulink>\r
13907</simpara>\r
13908</listitem>\r
13909<listitem>\r
13910<simpara>\r
13911<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/inline.fun"><literal>inline.fun</literal></ulink>\r
13912</simpara>\r
13913</listitem>\r
13914</itemizedlist>\r
13915</section>\r
13916<section id="_details_and_notes_26">\r
13917<title>Details and Notes</title>\r
13918<simpara>The <link linkend="Inline">Inline</link> pass can be invoked to use one of three metrics:</simpara>\r
13919<itemizedlist>\r
13920<listitem>\r
13921<simpara>\r
13922<literal>NonRecursive(product, small)</literal>&#8201;&#8212;&#8201;inline any function satisfying <literal>(numCalls - 1) * (size - small) &lt;= product</literal>, where <literal>numCalls</literal> is the static number of calls to the function and <literal>size</literal> is the size of the function.\r
13923</simpara>\r
13924</listitem>\r
13925<listitem>\r
13926<simpara>\r
13927<literal>Leaf(size)</literal>&#8201;&#8212;&#8201;inline any leaf function smaller than <literal>size</literal>\r
13928</simpara>\r
13929</listitem>\r
13930<listitem>\r
13931<simpara>\r
13932<literal>LeafNoLoop(size)</literal>&#8201;&#8212;&#8201;inline any leaf function without loops smaller than <literal>size</literal>\r
13933</simpara>\r
13934</listitem>\r
13935</itemizedlist>\r
13936<simpara><?asciidoc-pagebreak?></simpara>\r
13937</section>\r
13938</section>\r
13939<section id="InsertLimitChecks">\r
13940<title>InsertLimitChecks</title>\r
13941<simpara><link linkend="InsertLimitChecks">InsertLimitChecks</link> is a pass for the <link linkend="RSSA">RSSA</link>\r
13942<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="RSSASimplify">RSSASimplify</link>.</simpara>\r
13943<section id="_description_25">\r
13944<title>Description</title>\r
13945<simpara>This pass inserts limit checks.</simpara>\r
13946</section>\r
13947<section id="_implementation_27">\r
13948<title>Implementation</title>\r
13949<itemizedlist>\r
13950<listitem>\r
13951<simpara>\r
13952<ulink url="https://github.com/MLton/mlton/blob/master/mlton/backend/limit-check.fun"><literal>limit-check.fun</literal></ulink>\r
13953</simpara>\r
13954</listitem>\r
13955</itemizedlist>\r
13956</section>\r
13957<section id="_details_and_notes_27">\r
13958<title>Details and Notes</title>\r
13959<simpara></simpara>\r
13960<simpara><?asciidoc-pagebreak?></simpara>\r
13961</section>\r
13962</section>\r
13963<section id="InsertSignalChecks">\r
13964<title>InsertSignalChecks</title>\r
13965<simpara><link linkend="InsertSignalChecks">InsertSignalChecks</link> is a pass for the <link linkend="RSSA">RSSA</link>\r
13966<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="RSSASimplify">RSSASimplify</link>.</simpara>\r
13967<section id="_description_26">\r
13968<title>Description</title>\r
13969<simpara>This pass inserts signal checks.</simpara>\r
13970</section>\r
13971<section id="_implementation_28">\r
13972<title>Implementation</title>\r
13973<itemizedlist>\r
13974<listitem>\r
13975<simpara>\r
13976<ulink url="https://github.com/MLton/mlton/blob/master/mlton/backend/limit-check.fun"><literal>limit-check.fun</literal></ulink>\r
13977</simpara>\r
13978</listitem>\r
13979</itemizedlist>\r
13980</section>\r
13981<section id="_details_and_notes_28">\r
13982<title>Details and Notes</title>\r
13983<simpara></simpara>\r
13984<simpara><?asciidoc-pagebreak?></simpara>\r
13985</section>\r
13986</section>\r
13987<section id="Installation">\r
13988<title>Installation</title>\r
13989<simpara>MLton runs on a variety of platforms and is distributed in both source and\r
13990binary form.</simpara>\r
13991<simpara>A <literal>.tgz</literal> or <literal>.tbz</literal> binary package can be extracted at any location, yielding\r
13992<literal>README.adoc</literal> (this file), <literal>CHANGELOG.adoc</literal>, <literal>LICENSE</literal>, <literal>Makefile</literal>, <literal>bin/</literal>,\r
13993<literal>lib/</literal>, and <literal>share/</literal>. The compiler and tools can be executed in-place (e.g.,\r
13994<literal>./bin/mlton</literal>).</simpara>\r
13995<simpara>A small set of <literal>Makefile</literal> variables can be used to customize the binary package\r
13996via <literal>make update</literal>:</simpara>\r
13997<itemizedlist>\r
13998<listitem>\r
13999<simpara>\r
14000<literal>CC</literal>: Specify C compiler. Can be used for alternative tools (e.g.,\r
14001 <literal>CC=clang</literal> or <literal>CC=gcc-7</literal>).\r
14002</simpara>\r
14003</listitem>\r
14004<listitem>\r
14005<simpara>\r
14006<literal>WITH_GMP_DIR</literal>, <literal>WITH_GMP_INC_DIR</literal>, <literal>WITH_GMP_LIB_DIR</literal>: Specify GMP include\r
14007 and library paths, if not on default search paths. (If <literal>WITH_GMP_DIR</literal> is\r
14008 set, then <literal>WITH_GMP_INC_DIR</literal> defaults to <literal>$(WITH_GMP_DIR)/include</literal> and\r
14009 <literal>WITH_GMP_LIB_DIR</literal> defaults to <literal>$(WITH_GMP_DIR)/lib</literal>.)\r
14010</simpara>\r
14011</listitem>\r
14012</itemizedlist>\r
14013<simpara>For example:</simpara>\r
14014<programlisting language="sml" linenumbering="unnumbered">$ make CC=clang WITH_GMP_DIR=/opt/gmp update</programlisting>\r
14015<simpara>On typical platforms, installing MLton (after optionally performing\r
14016<literal>make update</literal>) to <literal>/usr/local</literal> can be accomplished via:</simpara>\r
14017<programlisting language="sml" linenumbering="unnumbered">$ make install</programlisting>\r
14018<simpara>A small set of <literal>Makefile</literal> variables can be used to customize the installation:</simpara>\r
14019<itemizedlist>\r
14020<listitem>\r
14021<simpara>\r
14022<literal>PREFIX</literal>: Specify the installation prefix.\r
14023</simpara>\r
14024</listitem>\r
14025<listitem>\r
14026<simpara>\r
14027<literal>CC</literal>: Specify C compiler. Can be used for alternative tools (e.g.,\r
14028 <literal>CC=clang</literal> or <literal>CC=gcc-7</literal>).\r
14029</simpara>\r
14030</listitem>\r
14031<listitem>\r
14032<simpara>\r
14033<literal>WITH_GMP_DIR</literal>, <literal>WITH_GMP_INC_DIR</literal>, <literal>WITH_GMP_LIB_DIR</literal>: Specify GMP include\r
14034 and library paths, if not on default search paths. (If <literal>WITH_GMP_DIR</literal> is\r
14035 set, then <literal>WITH_GMP_INC_DIR</literal> defaults to <literal>$(WITH_GMP_DIR)/include</literal> and\r
14036 <literal>WITH_GMP_LIB_DIR</literal> defaults to <literal>$(WITH_GMP_DIR)/lib</literal>.)\r
14037</simpara>\r
14038</listitem>\r
14039</itemizedlist>\r
14040<simpara>For example:</simpara>\r
14041<programlisting language="sml" linenumbering="unnumbered">$ make PREFIX=/opt/mlton install</programlisting>\r
14042<simpara>Installation of MLton creates the following files and directories.</simpara>\r
14043<itemizedlist>\r
14044<listitem>\r
14045<simpara>\r
14046<literal><emphasis>prefix</emphasis>/bin/mllex</literal>\r
14047</simpara>\r
14048<simpara>The <link linkend="MLLex">MLLex</link> lexer generator.</simpara>\r
14049</listitem>\r
14050<listitem>\r
14051<simpara>\r
14052<literal><emphasis>prefix</emphasis>/bin/mlnlffigen</literal>\r
14053</simpara>\r
14054<simpara>The <link linkend="MLNLFFI">ML-NLFFI</link> tool.</simpara>\r
14055</listitem>\r
14056<listitem>\r
14057<simpara>\r
14058<literal><emphasis>prefix</emphasis>/bin/mlprof</literal>\r
14059</simpara>\r
14060<simpara>A <link linkend="Profiling">Profiling</link> tool.</simpara>\r
14061</listitem>\r
14062<listitem>\r
14063<simpara>\r
14064<literal><emphasis>prefix</emphasis>/bin/mlton</literal>\r
14065</simpara>\r
14066<simpara>A script to call the compiler. This script may be moved anywhere,\r
14067however, it makes use of files in <literal><emphasis>prefix</emphasis>/lib/mlton</literal>.</simpara>\r
14068</listitem>\r
14069<listitem>\r
14070<simpara>\r
14071<literal><emphasis>prefix</emphasis>/bin/mlyacc</literal>\r
14072</simpara>\r
14073<simpara>The <link linkend="MLYacc">MLYacc</link> parser generator.</simpara>\r
14074</listitem>\r
14075<listitem>\r
14076<simpara>\r
14077<literal><emphasis>prefix</emphasis>/lib/mlton</literal>\r
14078</simpara>\r
14079<simpara>Directory containing libraries and include files needed during compilation.</simpara>\r
14080</listitem>\r
14081<listitem>\r
14082<simpara>\r
14083<literal><emphasis>prefix</emphasis>/share/man/man1/{mllex,mlnlffigen,mlprof,mlton,mlyacc}.1</literal>\r
14084</simpara>\r
14085<simpara>Man pages.</simpara>\r
14086</listitem>\r
14087<listitem>\r
14088<simpara>\r
14089<literal><emphasis>prefix</emphasis>/share/doc/mlton</literal>\r
14090</simpara>\r
14091<simpara>Directory containing the user guide for MLton, mllex, and mlyacc, as\r
14092well as example SML programs (in the <literal>examples</literal> directory), and license\r
14093information.</simpara>\r
14094</listitem>\r
14095</itemizedlist>\r
14096<section id="_hello_world">\r
14097<title>Hello, World!</title>\r
14098<simpara>Once you have installed MLton, create a file called <literal>hello-world.sml</literal>\r
14099with the following contents.</simpara>\r
14100<screen>print "Hello, world!\n";</screen>\r
14101<simpara>Now create an executable, <literal>hello-world</literal>, with the following command.</simpara>\r
14102<screen>mlton hello-world.sml</screen>\r
14103<simpara>You can now run <literal>hello-world</literal> to verify that it works. There are more\r
14104small examples in <literal><emphasis>prefix</emphasis>/share/doc/mlton/examples</literal>.</simpara>\r
14105</section>\r
14106<section id="_installation_on_cygwin">\r
14107<title>Installation on Cygwin</title>\r
14108<simpara>When installing the Cygwin <literal>tgz</literal>, you should use Cygwin&#8217;s <literal>bash</literal> and\r
14109<literal>tar</literal>. The use of an archiving tool that is not aware of Cygwin&#8217;s\r
14110mounts will put the files in the wrong place.</simpara>\r
14111<simpara><?asciidoc-pagebreak?></simpara>\r
14112</section>\r
14113</section>\r
14114<section id="IntermediateLanguage">\r
14115<title>IntermediateLanguage</title>\r
14116<simpara>MLton uses a number of intermediate languages in translating from the input source program to low-level code. Here is a list in the order which they are translated to.</simpara>\r
14117<itemizedlist>\r
14118<listitem>\r
14119<simpara>\r
14120<link linkend="AST">AST</link>. Pretty close to the source.\r
14121</simpara>\r
14122</listitem>\r
14123<listitem>\r
14124<simpara>\r
14125<link linkend="CoreML">CoreML</link>. Explicitly typed, no module constructs.\r
14126</simpara>\r
14127</listitem>\r
14128<listitem>\r
14129<simpara>\r
14130<link linkend="XML">XML</link>. Polymorphic, <link linkend="HigherOrder">HigherOrder</link>.\r
14131</simpara>\r
14132</listitem>\r
14133<listitem>\r
14134<simpara>\r
14135<link linkend="SXML">SXML</link>. SimplyTyped, <link linkend="HigherOrder">HigherOrder</link>.\r
14136</simpara>\r
14137</listitem>\r
14138<listitem>\r
14139<simpara>\r
14140<link linkend="SSA">SSA</link>. SimplyTyped, <link linkend="FirstOrder">FirstOrder</link>.\r
14141</simpara>\r
14142</listitem>\r
14143<listitem>\r
14144<simpara>\r
14145<link linkend="SSA2">SSA2</link>. SimplyTyped, <link linkend="FirstOrder">FirstOrder</link>.\r
14146</simpara>\r
14147</listitem>\r
14148<listitem>\r
14149<simpara>\r
14150<link linkend="RSSA">RSSA</link>. Explicit data representations.\r
14151</simpara>\r
14152</listitem>\r
14153<listitem>\r
14154<simpara>\r
14155<link linkend="Machine">Machine</link>. Untyped register transfer language.\r
14156</simpara>\r
14157</listitem>\r
14158</itemizedlist>\r
14159<simpara><?asciidoc-pagebreak?></simpara>\r
14160</section>\r
14161<section id="IntroduceLoops">\r
14162<title>IntroduceLoops</title>\r
14163<simpara><link linkend="IntroduceLoops">IntroduceLoops</link> is an optimization pass for the <link linkend="SSA">SSA</link>\r
14164<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="SSASimplify">SSASimplify</link>.</simpara>\r
14165<section id="_description_27">\r
14166<title>Description</title>\r
14167<simpara>This pass rewrites any <link linkend="SSA">SSA</link> function that calls itself in tail\r
14168position into one with a local loop and no self tail calls.</simpara>\r
14169<simpara>A <link linkend="SSA">SSA</link> function like</simpara>\r
14170<screen>fun F (arg_0, arg_1) = L_0 ()\r
14171 ...\r
14172 L_16 (x_0)\r
14173 ...\r
14174 F (z_0, z_1) Tail\r
14175 ...</screen>\r
14176<simpara>becomes</simpara>\r
14177<screen>fun F (arg_0', arg_1') = loopS_0 ()\r
14178 loopS_0 ()\r
14179 loop_0 (arg_0', arg_1')\r
14180 loop_0 (arg_0, arg_1)\r
14181 L_0 ()\r
14182 ...\r
14183 L_16 (x_0)\r
14184 ...\r
14185 loop_0 (z_0, z_1)\r
14186 ...</screen>\r
14187</section>\r
14188<section id="_implementation_29">\r
14189<title>Implementation</title>\r
14190<itemizedlist>\r
14191<listitem>\r
14192<simpara>\r
14193<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/introduce-loops.fun"><literal>introduce-loops.fun</literal></ulink>\r
14194</simpara>\r
14195</listitem>\r
14196</itemizedlist>\r
14197</section>\r
14198<section id="_details_and_notes_29">\r
14199<title>Details and Notes</title>\r
14200<simpara></simpara>\r
14201<simpara><?asciidoc-pagebreak?></simpara>\r
14202</section>\r
14203</section>\r
14204<section id="JesperLouisAndersen">\r
14205<title>JesperLouisAndersen</title>\r
14206<simpara>Jesper Louis Andersen is an undergraduate student at DIKU, the department of computer science, Copenhagen university. His contributions to MLton are few, though he has made the port of MLton to the NetBSD and OpenBSD platforms.</simpara>\r
14207<simpara>His general interests in computer science are compiler theory, language theory, algorithms and datastructures and programming. His assets are his general knowledge of UNIX systems, knowledge of system administration, knowledge of operating system kernels; NetBSD in particular.</simpara>\r
14208<simpara>He was employed by the university as a system administrator for 2 years, which has set him back somewhat in his studies. Currently he is trying to learn mathematics (real analysis, general topology, complex functional analysis and algebra).</simpara>\r
14209<section id="_projects_using_mlton">\r
14210<title>Projects using MLton</title>\r
14211<section id="_a_register_allocator">\r
14212<title>A register allocator</title>\r
14213<simpara>For internal use at a compiler course at DIKU. It is written in the literate programming style and implements the <emphasis>Iterated Register Coalescing</emphasis> algorithm by Lal George and Andrew Appel <ulink url="http://citeseer.ist.psu.edu/george96iterated.html">http://citeseer.ist.psu.edu/george96iterated.html</ulink>. The status of the project is that it is unfinished. Most of the basic parts of the algorithm is done, but the interface to the students (simple) datatype takes some conversion.</simpara>\r
14214</section>\r
14215<section id="_a_configuration_management_system_in_sml">\r
14216<title>A configuration management system in SML</title>\r
14217<simpara>At this time, only loose plans exists for this. The plan is to build a Configuration Management system on the principles of the OpenCM system, see <ulink url="http://www.opencm.org/docs.html">http://www.opencm.org/docs.html</ulink>. The basic idea is to unify "naming" and "identity" into one by uniquely identifying all objects managed in the repository by the use of cryptographic checksums. This mantra guides the rest of the system, providing integrity, accessibility and confidentiality.</simpara>\r
14218<simpara><?asciidoc-pagebreak?></simpara>\r
14219</section>\r
14220</section>\r
14221</section>\r
14222<section id="JohnnyAndersen">\r
14223<title>JohnnyAndersen</title>\r
14224<simpara>Johnny Andersen (aka Anoq of the Sun)</simpara>\r
14225<simpara>Here is a picture in front of the academy building\r
14226at the University of Athens, Greece, taken in September 2003.</simpara>\r
14227<informalfigure>\r
14228<mediaobject>\r
14229 <imageobject>\r
14230 <imagedata fileref="JohnnyAndersen.attachments/anoq.jpg" align="center"/>\r
14231 </imageobject>\r
14232 <textobject><phrase>JohnnyAndersen.attachments/anoq.jpg</phrase></textobject>\r
14233</mediaobject>\r
14234</informalfigure>\r
14235<simpara><?asciidoc-pagebreak?></simpara>\r
14236</section>\r
14237<section id="KnownCase">\r
14238<title>KnownCase</title>\r
14239<simpara><link linkend="KnownCase">KnownCase</link> is an optimization pass for the <link linkend="SSA">SSA</link>\r
14240<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="SSASimplify">SSASimplify</link>.</simpara>\r
14241<section id="_description_28">\r
14242<title>Description</title>\r
14243<simpara>This pass duplicates and simplifies <literal>Case</literal> transfers when the\r
14244constructor of the scrutinee is known.</simpara>\r
14245<simpara>Uses <link linkend="Restore">Restore</link>.</simpara>\r
14246<simpara>For example, the program</simpara>\r
14247<programlisting language="sml" linenumbering="unnumbered">val rec last =\r
14248 fn [] =&gt; 0\r
14249 | [x] =&gt; x\r
14250 | _ :: l =&gt; last l\r
14251\r
14252val _ = 1 + last [2, 3, 4, 5, 6, 7]</programlisting>\r
14253<simpara>gives rise to the <link linkend="SSA">SSA</link> function</simpara>\r
14254<screen>fun last_0 (x_142) = loopS_1 ()\r
14255 loopS_1 ()\r
14256 loop_11 (x_142)\r
14257 loop_11 (x_143)\r
14258 case x_143 of\r
14259 nil_1 =&gt; L_73 | ::_0 =&gt; L_74\r
14260 L_73 ()\r
14261 return global_5\r
14262 L_74 (x_145, x_144)\r
14263 case x_145 of\r
14264 nil_1 =&gt; L_75 | _ =&gt; L_76\r
14265 L_75 ()\r
14266 return x_144\r
14267 L_76 ()\r
14268 loop_11 (x_145)</screen>\r
14269<simpara>which is simplified to</simpara>\r
14270<screen>fun last_0 (x_142) = loopS_1 ()\r
14271 loopS_1 ()\r
14272 case x_142 of\r
14273 nil_1 =&gt; L_73 | ::_0 =&gt; L_118\r
14274 L_73 ()\r
14275 return global_5\r
14276 L_118 (x_230, x_229)\r
14277 L_74 (x_230, x_229, x_142)\r
14278 L_74 (x_145, x_144, x_232)\r
14279 case x_145 of\r
14280 nil_1 =&gt; L_75 | ::_0 =&gt; L_114\r
14281 L_75 ()\r
14282 return x_144\r
14283 L_114 (x_227, x_226)\r
14284 L_74 (x_227, x_226, x_145)</screen>\r
14285</section>\r
14286<section id="_implementation_30">\r
14287<title>Implementation</title>\r
14288<itemizedlist>\r
14289<listitem>\r
14290<simpara>\r
14291<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/known-case.fun"><literal>known-case.fun</literal></ulink>\r
14292</simpara>\r
14293</listitem>\r
14294</itemizedlist>\r
14295</section>\r
14296<section id="_details_and_notes_30">\r
14297<title>Details and Notes</title>\r
14298<simpara>One interesting aspect of <link linkend="KnownCase">KnownCase</link>, is that it often has the\r
14299effect of unrolling list traversals by one iteration, moving the\r
14300<literal>nil</literal>/<literal>::</literal> check to the end of the loop, rather than the beginning.</simpara>\r
14301<simpara><?asciidoc-pagebreak?></simpara>\r
14302</section>\r
14303</section>\r
14304<section id="LambdaCalculus">\r
14305<title>LambdaCalculus</title>\r
14306<simpara>The <ulink url="http://en.wikipedia.org/wiki/Lambda_calculus">lambda calculus</ulink> is\r
14307the formal system underlying <link linkend="StandardML">Standard ML</link>.</simpara>\r
14308<simpara><?asciidoc-pagebreak?></simpara>\r
14309</section>\r
14310<section id="LambdaFree">\r
14311<title>LambdaFree</title>\r
14312<simpara><link linkend="LambdaFree">LambdaFree</link> is an analysis pass for the <link linkend="SXML">SXML</link>\r
14313<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="ClosureConvert">ClosureConvert</link>.</simpara>\r
14314<section id="_description_29">\r
14315<title>Description</title>\r
14316<simpara>This pass descends the entire <link linkend="SXML">SXML</link> program and attaches a property\r
14317to each <literal>Lambda</literal> <literal>PrimExp.t</literal> in the program. Then, you can use\r
14318<literal>lambdaFree</literal> and <literal>lambdaRec</literal> to get free variables of that <literal>Lambda</literal>.</simpara>\r
14319</section>\r
14320<section id="_implementation_31">\r
14321<title>Implementation</title>\r
14322<itemizedlist>\r
14323<listitem>\r
14324<simpara>\r
14325<ulink url="https://github.com/MLton/mlton/blob/master/mlton/closure-convert/lambda-free.sig"><literal>lambda-free.sig</literal></ulink>\r
14326</simpara>\r
14327</listitem>\r
14328<listitem>\r
14329<simpara>\r
14330<ulink url="https://github.com/MLton/mlton/blob/master/mlton/closure-convert/lambda-free.fun"><literal>lambda-free.fun</literal></ulink>\r
14331</simpara>\r
14332</listitem>\r
14333</itemizedlist>\r
14334</section>\r
14335<section id="_details_and_notes_31">\r
14336<title>Details and Notes</title>\r
14337<simpara>For <literal>Lambda</literal>-s bound in a <literal>Fun</literal> dec, <literal>lambdaFree</literal> gives the union of\r
14338the frees of the entire group of mutually recursive functions. Hence,\r
14339<literal>lambdaFree</literal> for every <literal>Lambda</literal> in a single <literal>Fun</literal> dec is the same.\r
14340Furthermore, for a <literal>Lambda</literal> bound in a <literal>Fun</literal> dec, <literal>lambdaRec</literal> gives\r
14341the list of other functions bound in the same dec defining that\r
14342<literal>Lambda</literal>.</simpara>\r
14343<simpara>For example:</simpara>\r
14344<screen>val rec f = fn x =&gt; ... y ... g ... f ...\r
14345and g = fn z =&gt; ... f ... w ...</screen>\r
14346<screen>lambdaFree(fn x =&gt;) = [y, w]\r
14347lambdaFree(fn z =&gt;) = [y, w]\r
14348lambdaRec(fn x =&gt;) = [g, f]\r
14349lambdaRec(fn z =&gt;) = [f]</screen>\r
14350<simpara><?asciidoc-pagebreak?></simpara>\r
14351</section>\r
14352</section>\r
14353<section id="LanguageChanges">\r
14354<title>LanguageChanges</title>\r
14355<simpara>We are sometimes asked to modify MLton to change the language it\r
14356compiles. In short, we are conservative about making such changes.\r
14357There are a number of reasons for this.</simpara>\r
14358<itemizedlist>\r
14359<listitem>\r
14360<simpara>\r
14361<link linkend="DefinitionOfStandardML">The Definition of Standard ML</link> is an\r
14362extremely high standard of specification. The value of the Definition\r
14363would be significantly diluted by changes that are not specified at an\r
14364equally high level, and the dilution increases with the complexity of\r
14365the language change and its interaction with other language features.\r
14366</simpara>\r
14367</listitem>\r
14368<listitem>\r
14369<simpara>\r
14370The SML community is small and there are a number of\r
14371<link linkend="StandardMLImplementations">SML implementations</link>. Without an\r
14372agreed-upon standard, it becomes very difficult to port programs\r
14373between compilers, and the community would be balkanized.\r
14374</simpara>\r
14375</listitem>\r
14376<listitem>\r
14377<simpara>\r
14378Our main goal is to enable programmers to be as effective as\r
14379possible with MLton/SML. There are a number of improvements other\r
14380than language changes that we could spend our time on that would\r
14381provide more benefit to programmers.\r
14382</simpara>\r
14383</listitem>\r
14384<listitem>\r
14385<simpara>\r
14386The more the language that MLton compiles changes over time, the\r
14387more difficult it is to use MLton as a stable platform for serious\r
14388program development.\r
14389</simpara>\r
14390</listitem>\r
14391</itemizedlist>\r
14392<simpara>Despite these drawbacks, we have extended SML in a couple of cases.</simpara>\r
14393<itemizedlist>\r
14394<listitem>\r
14395<simpara>\r
14396<link linkend="ForeignFunctionInterface">Foreign function interface</link>\r
14397</simpara>\r
14398</listitem>\r
14399<listitem>\r
14400<simpara>\r
14401<link linkend="MLBasis">ML Basis system</link>\r
14402</simpara>\r
14403</listitem>\r
14404<listitem>\r
14405<simpara>\r
14406<link linkend="SuccessorML">Successor ML features</link>\r
14407</simpara>\r
14408</listitem>\r
14409</itemizedlist>\r
14410<simpara>We allow these language extensions because they provide functionality\r
14411that is impossible to achieve without them or have non-trivial\r
14412community support. The Definition does not define a foreign function\r
14413interface. So, we must either extend the language or greatly restrict\r
14414the class of programs that can be written. Similarly, the Definition\r
14415does not provide a mechanism for namespace control at the module\r
14416level, making it impossible to deliver packaged libraries and have a\r
14417hope of users using them without name clashes. The ML Basis system\r
14418addresses this problem. We have also provided a formal specification\r
14419of the ML Basis system at the level of the Definition.</simpara>\r
14420<section id="_also_see_8">\r
14421<title>Also see</title>\r
14422<itemizedlist>\r
14423<listitem>\r
14424<simpara>\r
14425<ulink url="http://www.mlton.org/pipermail/mlton/2004-August/016165.html">http://www.mlton.org/pipermail/mlton/2004-August/016165.html</ulink>\r
14426</simpara>\r
14427</listitem>\r
14428<listitem>\r
14429<simpara>\r
14430<ulink url="http://www.mlton.org/pipermail/mlton-user/2004-December/000320.html">http://www.mlton.org/pipermail/mlton-user/2004-December/000320.html</ulink>\r
14431</simpara>\r
14432</listitem>\r
14433</itemizedlist>\r
14434<simpara><?asciidoc-pagebreak?></simpara>\r
14435</section>\r
14436</section>\r
14437<section id="Lazy">\r
14438<title>Lazy</title>\r
14439<simpara>In a lazy (or non-strict) language, the arguments to a function are\r
14440not evaluated before calling the function. Instead, the arguments are\r
14441suspended and only evaluated by the function if needed.</simpara>\r
14442<simpara><link linkend="StandardML">Standard ML</link> is an eager (or strict) language, not a lazy\r
14443language. However, it is easy to delay evaluation of an expression in\r
14444SML by creating a <emphasis>thunk</emphasis>, which is a nullary function. In SML, a\r
14445thunk is written <literal>fn () =&gt; e</literal>. Another essential feature of laziness\r
14446is <emphasis>memoization</emphasis>, meaning that once a suspended argument is evaluated,\r
14447subsequent references look up the value. We can express this in SML\r
14448with a function that maps a thunk to a memoized thunk.</simpara>\r
14449<programlisting language="sml" linenumbering="unnumbered">signature LAZY =\r
14450 sig\r
14451 val lazy: (unit -&gt; 'a) -&gt; unit -&gt; 'a\r
14452 end</programlisting>\r
14453<simpara>This is easy to implement in SML.</simpara>\r
14454<programlisting language="sml" linenumbering="unnumbered">structure Lazy: LAZY =\r
14455 struct\r
14456 fun lazy (th: unit -&gt; 'a): unit -&gt; 'a =\r
14457 let\r
14458 datatype 'a lazy_result = Unevaluated of (unit -&gt; 'a)\r
14459 | Evaluated of 'a\r
14460 | Failed of exn\r
14461\r
14462 val r = ref (Unevaluated th)\r
14463 in\r
14464 fn () =&gt;\r
14465 case !r of\r
14466 Unevaluated th =&gt; let\r
14467 val a = th ()\r
14468 handle x =&gt; (r := Failed x; raise x)\r
14469 val () = r := Evaluated a\r
14470 in\r
14471 a\r
14472 end\r
14473 | Evaluated a =&gt; a\r
14474 | Failed x =&gt; raise x\r
14475 end\r
14476 end</programlisting>\r
14477<simpara><?asciidoc-pagebreak?></simpara>\r
14478</section>\r
14479<section id="Libraries">\r
14480<title>Libraries</title>\r
14481<simpara>In theory every strictly conforming Standard ML program should run on\r
14482MLton. However, often large SML projects use implementation specific\r
14483features so some "porting" is required. Here is a partial list of\r
14484software that is known to run on MLton.</simpara>\r
14485<itemizedlist>\r
14486<listitem>\r
14487<simpara>\r
14488Utility libraries:\r
14489</simpara>\r
14490<itemizedlist>\r
14491<listitem>\r
14492<simpara>\r
14493<link linkend="SMLNJLibrary">SMLNJLibrary</link> - distributed with MLton\r
14494</simpara>\r
14495</listitem>\r
14496<listitem>\r
14497<simpara>\r
14498<link linkend="MLtonLibraryProject">MLtonLibraryProject</link> - various libraries located on the MLton subversion repository\r
14499</simpara>\r
14500</listitem>\r
14501<listitem>\r
14502<simpara>\r
14503<ulink url="https://github.com/MLton/mlton/tree/master/lib/mlton"><literal>mlton</literal></ulink> - the internal MLton utility library, which we hope to cleanup and make more accessible someday\r
14504</simpara>\r
14505</listitem>\r
14506<listitem>\r
14507<simpara>\r
14508<ulink url="http://github.com/seanmcl/sml-ext">sml-ext</ulink>, a grab bag of libraries for MLton and other SML implementations (by Sean McLaughlin)\r
14509</simpara>\r
14510</listitem>\r
14511<listitem>\r
14512<simpara>\r
14513<ulink url="http://tom7misc.cvs.sourceforge.net/tom7misc/sml-lib/">sml-lib</ulink>, a grab bag of libraries for MLton and other SML implementations (by <link linkend="TomMurphy">TomMurphy</link>)\r
14514</simpara>\r
14515</listitem>\r
14516</itemizedlist>\r
14517</listitem>\r
14518<listitem>\r
14519<simpara>\r
14520Scanner generators:\r
14521</simpara>\r
14522<itemizedlist>\r
14523<listitem>\r
14524<simpara>\r
14525<link linkend="MLLPTLibrary">MLLPTLibrary</link> - distributed with MLton\r
14526</simpara>\r
14527</listitem>\r
14528<listitem>\r
14529<simpara>\r
14530<link linkend="MLLex">MLLex</link> - distributed with MLton\r
14531</simpara>\r
14532</listitem>\r
14533<listitem>\r
14534<simpara>\r
14535<link linkend="MLULex">MLULex</link> -\r
14536</simpara>\r
14537</listitem>\r
14538</itemizedlist>\r
14539</listitem>\r
14540<listitem>\r
14541<simpara>\r
14542Parser generators:\r
14543</simpara>\r
14544<itemizedlist>\r
14545<listitem>\r
14546<simpara>\r
14547<link linkend="MLAntlr">MLAntlr</link> -\r
14548</simpara>\r
14549</listitem>\r
14550<listitem>\r
14551<simpara>\r
14552<link linkend="MLLPTLibrary">MLLPTLibrary</link> - distributed with MLton\r
14553</simpara>\r
14554</listitem>\r
14555<listitem>\r
14556<simpara>\r
14557<link linkend="MLYacc">MLYacc</link> - distributed with MLton\r
14558</simpara>\r
14559</listitem>\r
14560</itemizedlist>\r
14561</listitem>\r
14562<listitem>\r
14563<simpara>\r
14564Concurrency: <link linkend="ConcurrentML">ConcurrentML</link> - distributed with MLton\r
14565</simpara>\r
14566</listitem>\r
14567<listitem>\r
14568<simpara>\r
14569Graphics\r
14570</simpara>\r
14571<itemizedlist>\r
14572<listitem>\r
14573<simpara>\r
14574<link linkend="SML3d">SML3d</link>\r
14575</simpara>\r
14576</listitem>\r
14577<listitem>\r
14578<simpara>\r
14579<link linkend="mGTK">mGTK</link>\r
14580</simpara>\r
14581</listitem>\r
14582</itemizedlist>\r
14583</listitem>\r
14584<listitem>\r
14585<simpara>\r
14586Misc. libraries:\r
14587</simpara>\r
14588<itemizedlist>\r
14589<listitem>\r
14590<simpara>\r
14591<link linkend="CKitLibrary">CKitLibrary</link> - distributed with MLton\r
14592</simpara>\r
14593</listitem>\r
14594<listitem>\r
14595<simpara>\r
14596<link linkend="MLRISCLibrary">MLRISCLibrary</link> - distributed with MLton\r
14597</simpara>\r
14598</listitem>\r
14599<listitem>\r
14600<simpara>\r
14601<link linkend="MLNLFFI">ML-NLFFI</link> - distributed with MLton\r
14602</simpara>\r
14603</listitem>\r
14604<listitem>\r
14605<simpara>\r
14606<link linkend="Swerve">Swerve</link>, an HTTP server\r
14607</simpara>\r
14608</listitem>\r
14609<listitem>\r
14610<simpara>\r
14611<link linkend="fxp">fxp</link>, an XML parser\r
14612</simpara>\r
14613</listitem>\r
14614</itemizedlist>\r
14615</listitem>\r
14616</itemizedlist>\r
14617<section id="_ports_in_progress">\r
14618<title>Ports in progress</title>\r
14619<simpara><link linkend="Contact">Contact</link> us for details on any of these.</simpara>\r
14620<itemizedlist>\r
14621<listitem>\r
14622<simpara>\r
14623<link linkend="MLDoc">MLDoc</link> <ulink url="http://people.cs.uchicago.edu/%7Ejhr/tools/ml-doc.html">http://people.cs.uchicago.edu/%7Ejhr/tools/ml-doc.html</ulink>\r
14624</simpara>\r
14625</listitem>\r
14626<listitem>\r
14627<simpara>\r
14628<link linkend="Unicode">Unicode</link>\r
14629</simpara>\r
14630</listitem>\r
14631</itemizedlist>\r
14632</section>\r
14633<section id="_more">\r
14634<title>More</title>\r
14635<simpara>More projects using MLton can be seen on the <link linkend="Users">Users</link> page.</simpara>\r
14636</section>\r
14637<section id="_software_for_sml_implementations_other_than_mlton">\r
14638<title>Software for SML implementations other than MLton</title>\r
14639<itemizedlist>\r
14640<listitem>\r
14641<simpara>\r
14642PostgreSQL\r
14643</simpara>\r
14644<itemizedlist>\r
14645<listitem>\r
14646<simpara>\r
14647Moscow ML: <ulink url="http://www.dina.kvl.dk/%7Esestoft/mosmllib/Postgres.html">http://www.dina.kvl.dk/%7Esestoft/mosmllib/Postgres.html</ulink>\r
14648</simpara>\r
14649</listitem>\r
14650<listitem>\r
14651<simpara>\r
14652SML/NJ NLFFI: <ulink url="http://smlweb.sourceforge.net/smlsql/">http://smlweb.sourceforge.net/smlsql/</ulink>\r
14653</simpara>\r
14654</listitem>\r
14655</itemizedlist>\r
14656</listitem>\r
14657<listitem>\r
14658<simpara>\r
14659Web:\r
14660</simpara>\r
14661<itemizedlist>\r
14662<listitem>\r
14663<simpara>\r
14664ML Kit: <ulink url="http://www.smlserver.org">SMLserver</ulink> (a plugin for AOLserver)\r
14665</simpara>\r
14666</listitem>\r
14667<listitem>\r
14668<simpara>\r
14669Moscow ML: <ulink url="http://ellemose.dina.kvl.dk/%7Esestoft/msp/index.msp">ML Server Pages</ulink> (support for PHP-style CGI scripting)\r
14670</simpara>\r
14671</listitem>\r
14672<listitem>\r
14673<simpara>\r
14674SML/NJ: <ulink url="http://smlweb.sourceforge.net/">smlweb</ulink>\r
14675</simpara>\r
14676</listitem>\r
14677</itemizedlist>\r
14678</listitem>\r
14679</itemizedlist>\r
14680<simpara><?asciidoc-pagebreak?></simpara>\r
14681</section>\r
14682</section>\r
14683<section id="LibrarySupport">\r
14684<title>LibrarySupport</title>\r
14685<simpara>MLton supports both linking to and creating system-level libraries.\r
14686While Standard ML libraries should be designed with the <link linkend="MLBasis">MLBasis</link> system to work with other Standard ML programs,\r
14687system-level library support allows MLton to create libraries for use by other programming languages.\r
14688Even more importantly, system-level library support allows MLton to access libraries from other languages.\r
14689This article will explain how to use libraries portably with MLton.</simpara>\r
14690<section id="_the_basics">\r
14691<title>The Basics</title>\r
14692<simpara>A Dynamic Shared Object (DSO) is a piece of executable code written in a format understood by the operating system.\r
14693Executable programs and dynamic libraries are the two most common examples of a DSO.\r
14694They are called shared because if they are used more than once, they are only loaded once into main memory.\r
14695For example, if you start two instances of your web browser (an executable), there may be two processes running, but the program code of the executable is only loaded once.\r
14696A dynamic library, for example a graphical toolkit, might be used by several different executable programs, each possibly running multiple times.\r
14697Nevertheless, the dynamic library is only loaded once and it&#8217;s program code is shared between all of the processes.</simpara>\r
14698<simpara>In addition to program code, DSOs contain a table of textual strings called symbols.\r
14699These are used in order to make the DSO do something useful, like execute.\r
14700For example, on linux the symbol <literal>_start</literal> refers to the point in the program code where the operating system should start executing the program.\r
14701Dynamic libraries generally provide many symbols, corresponding to functions which can be called and variables which can be read or written.\r
14702Symbols can be used by the DSO itself, or by other DSOs which require services.</simpara>\r
14703<simpara>When a DSO creates a symbol, this is called <emphasis>exporting</emphasis>.\r
14704If a DSO needs to use a symbol, this is called <emphasis>importing</emphasis>.\r
14705A DSO might need to use symbols defined within itself or perhaps from another DSO.\r
14706In both cases, it is importing that symbol, but the scope of the import differs.\r
14707Similarly, a DSO might export a symbol for use only within itself, or it might export a symbol for use by other DSOs.\r
14708Some symbols are resolved at compile time by the linker (those used within the DSO) and some are resolved at runtime by the dynamic link loader (symbols accessed between DSOs).</simpara>\r
14709</section>\r
14710<section id="_symbols_in_mlton">\r
14711<title>Symbols in MLton</title>\r
14712<simpara>Symbols in MLton are both imported and exported via the <link linkend="ForeignFunctionInterface">ForeignFunctionInterface</link>.\r
14713The notation <literal>_import "symbolname"</literal> imports functions, <literal>_symbol "symbolname"</literal> imports variables, and <literal>_address "symbolname"</literal> imports an address.\r
14714To create and export a symbol, <literal>_export "symbolname"</literal> creates a function symbol and <literal>_symbol "symbolname" 'alloc'</literal> creates and exports a variable.\r
14715For details of the syntax and restrictions on the supported FFI types, read the <link linkend="ForeignFunctionInterface">ForeignFunctionInterface</link> page.\r
14716In this discussion it only matters that every FFI use is either an import or an export.</simpara>\r
14717<simpara>When exporting a symbol, MLton supports controlling the export scope.\r
14718If the symbol should only be used within the same DSO, that symbol has <emphasis><literal>private</literal></emphasis> scope.\r
14719Conversely, if the symbol should also be available to other DSOs the symbol has <emphasis><literal>public</literal></emphasis> scope.\r
14720Generally, one should have as few public exports as possible.\r
14721Since they are public, other DSOs will come to depend on them, limiting your ability to change them.\r
14722You specify the export scope in MLton by putting <literal>private</literal> or <literal>public</literal> after the symbol&#8217;s name in an FFI directive.\r
14723eg: <literal>_export "foo" private: int-&gt;int;</literal> or <literal>_export "bar" public: int-&gt;int;</literal> .</simpara>\r
14724<simpara>For technical reasons, the linker and loader on various platforms need to know the scope of a symbol being imported.\r
14725If the symbol is exported by the same DSO, use <literal>public</literal> or <literal>private</literal> as appropriate.\r
14726If the symbol is exported by a different DSO, then the scope <emphasis><literal>external</literal></emphasis> should be used to import it.\r
14727Within a DSO, all references to a symbol must use the same scope.\r
14728MLton will check this at compile time, reporting: <literal>symbol "foo" redeclared as public (previously external)</literal>. This may cause linker errors.\r
14729However, MLton can only check usage within Standard ML.\r
14730All objects being linked into a resulting DSO must agree, and it is the programmer&#8217;s responsibility to ensure this.</simpara>\r
14731<simpara>Summary of symbol scopes:</simpara>\r
14732<itemizedlist>\r
14733<listitem>\r
14734<simpara>\r
14735<literal>private</literal>: used for symbols exported within a DSO only for use within that DSO\r
14736</simpara>\r
14737</listitem>\r
14738<listitem>\r
14739<simpara>\r
14740<literal>public</literal>: used for symbols exported within a DSO that may also be used outside that DSO\r
14741</simpara>\r
14742</listitem>\r
14743<listitem>\r
14744<simpara>\r
14745<literal>external</literal>: used for importing symbols from another DSO\r
14746</simpara>\r
14747</listitem>\r
14748<listitem>\r
14749<simpara>\r
14750All uses of a symbol within a DSO (both imports and exports) must agree on the symbol scope\r
14751</simpara>\r
14752</listitem>\r
14753</itemizedlist>\r
14754</section>\r
14755<section id="_output_formats">\r
14756<title>Output Formats</title>\r
14757<simpara>MLton can create executables (<literal>-format executable</literal>) and dynamic shared libraries (<literal>-format library</literal>).\r
14758To link a shared library, use <literal>-link-opt -l&lt;dso_name&gt;</literal>.\r
14759The default output format is executable.</simpara>\r
14760<simpara>MLton can also create archives.\r
14761An archive is not a DSO, but it does have a collection of symbols.\r
14762When an archive is linked into a DSO, it is completely absorbed.\r
14763Other objects being compiled into the DSO should refer to the public symbols in the archive as public, since they are still in the same DSO.\r
14764However, in the interest of modular programming, private symbols in an archive cannot be used outside of that archive, even within the same DSO.</simpara>\r
14765<simpara>Although both executables and libraries are DSOs, some implementation details differ on some platforms.\r
14766For this reason, MLton can create two types or archives.\r
14767A normal archive (<literal>-format archive</literal>) is appropriate for linking into an executable.\r
14768Conversely, a libarchive (<literal>-format libarchive</literal>) should be used if it will be linked into a dynamic library.</simpara>\r
14769<simpara>When MLton does not create an executable, it creates two special symbols.\r
14770The symbol <literal>libname_open</literal> is a function which must be called before any other symbols are accessed.\r
14771The <literal>libname</literal> is controlled by the <literal>-libname</literal> compile option and defaults to the name of the output, with any prefixing lib stripped (eg: <literal>foo</literal> &#8594; <literal>foo</literal>, <literal>libfoo</literal> &#8594; <literal>foo</literal>).\r
14772The symbol <literal>libname_close</literal> is a function which should be called to clean up memory once done.</simpara>\r
14773<simpara>Summary of <literal>-format</literal> options:</simpara>\r
14774<itemizedlist>\r
14775<listitem>\r
14776<simpara>\r
14777<literal>executable</literal>: create an executable (a DSO)\r
14778</simpara>\r
14779</listitem>\r
14780<listitem>\r
14781<simpara>\r
14782<literal>library</literal>: create a dynamic shared library (a DSO)\r
14783</simpara>\r
14784</listitem>\r
14785<listitem>\r
14786<simpara>\r
14787<literal>archive</literal>: create an archive of symbols (not a DSO) that can be linked into an executable\r
14788</simpara>\r
14789</listitem>\r
14790<listitem>\r
14791<simpara>\r
14792<literal>libarchive</literal>: create an archive of symbols (not a DSO) that can be linked into a library\r
14793</simpara>\r
14794</listitem>\r
14795</itemizedlist>\r
14796<simpara>Related options:</simpara>\r
14797<itemizedlist>\r
14798<listitem>\r
14799<simpara>\r
14800<literal>-libname x</literal>: controls the name of the special <literal>_open</literal> and <literal>_close</literal> functions.\r
14801</simpara>\r
14802</listitem>\r
14803</itemizedlist>\r
14804</section>\r
14805<section id="_interfacing_with_c">\r
14806<title>Interfacing with C</title>\r
14807<simpara>MLton can generate a C header file.\r
14808When the output format is not an executable, it creates one by default named <literal>libname.h</literal>.\r
14809This can be overridden with <literal>-export-header foo.h</literal>.\r
14810This header file should be included by any C files using the exported Standard ML symbols.</simpara>\r
14811<simpara>If C is being linked with Standard ML into the same output archive or DSO,\r
14812then the C code should <literal>#define PART_OF_LIBNAME</literal> before it includes the header file.\r
14813This ensures that the C code is using the symbols with correct scope.\r
14814Any symbols exported from C should also be marked using the <literal>PRIVATE</literal>/<literal>PUBLIC</literal>/<literal>EXTERNAL</literal> macros defined in the Standard ML export header.\r
14815The declared C scope on exported C symbols should match the import scope used in Standard ML.</simpara>\r
14816<simpara>An example:</simpara>\r
14817<programlisting language="c" linenumbering="unnumbered">#define PART_OF_FOO\r
14818#include "foo.h"\r
14819\r
14820PUBLIC int cFoo() {\r
14821 return smlFoo();\r
14822}</programlisting>\r
14823<programlisting language="sml" linenumbering="unnumbered">val () = _export "smlFoo" private: unit -&gt; int; (fn () =&gt; 5)\r
14824val cFoo = _import "cFoo" public: unit -&gt; int;</programlisting>\r
14825</section>\r
14826<section id="_operating_system_specific_details">\r
14827<title>Operating-system specific details</title>\r
14828<simpara>On Windows, <literal>libarchive</literal> and <literal>archive</literal> are the same.\r
14829However, depending on this will lead to portability problems.\r
14830Windows is also especially sensitive to mixups of <emphasis><literal>public</literal></emphasis> and <emphasis><literal>external</literal></emphasis>.\r
14831If an archive is linked, make sure it&#8217;s symbols are imported as <literal>public</literal>.\r
14832If a DLL is linked, make sure it&#8217;s symbols are imported as <literal>external</literal>.\r
14833Using <literal>external</literal> instead of <literal>public</literal> will result in link errors that <literal>__imp__foo is undefined</literal>.\r
14834Using <literal>public</literal> instead of <literal>external</literal> will result in inconsistent function pointer addresses and failure to update the imported variables.</simpara>\r
14835<simpara>On Linux, <literal>libarchive</literal> and <literal>archive</literal> are different.\r
14836Libarchives are quite rare, but necessary if creating a library from an archive.\r
14837It is common for a library to provide both an archive and a dynamic library on this platform.\r
14838The linker will pick one or the other, usually preferring the dynamic library.\r
14839While a quirk of the operating system allows external import to work for both archives and libraries,\r
14840portable projects should not depend on this behaviour.\r
14841On other systems it can matter how the library is linked (static or dynamic).</simpara>\r
14842<simpara><?asciidoc-pagebreak?></simpara>\r
14843</section>\r
14844</section>\r
14845<section id="License">\r
14846<title>License</title>\r
14847<section id="_web_site">\r
14848<title>Web Site</title>\r
14849<simpara>In order to allow the maximum freedom for the future use of the\r
14850content in this web site, we require that contributions to the web\r
14851site be dedicated to the public domain. That means that you can only\r
14852add works that are already in the public domain, or that you must hold\r
14853the copyright on the work that you agree to dedicate the work to the\r
14854public domain.</simpara>\r
14855<simpara>By contributing to this web site, you agree to dedicate your\r
14856contribution to the public domain.</simpara>\r
14857</section>\r
14858<section id="_software">\r
14859<title>Software</title>\r
14860<simpara>As of 20050812, MLton software is licensed under the BSD-style license\r
14861below. By contributing code to the project, you agree to release the\r
14862code under this license. Contributors can retain copyright to their\r
14863contributions by asserting copyright in their code. Contributors may\r
14864also add to the list of copyright holders in\r
14865<literal>doc/license/MLton-LICENSE</literal>, which appears below.</simpara>\r
14866<programlisting language="text" linenumbering="unnumbered">../../LICENSE</programlisting>\r
14867<simpara><?asciidoc-pagebreak?></simpara>\r
14868</section>\r
14869</section>\r
14870<section id="LineDirective">\r
14871<title>LineDirective</title>\r
14872<simpara>To aid in the debugging of code produced by program generators such\r
14873as <ulink url="http://www.eecs.harvard.edu/%7Enr/noweb/">Noweb</ulink>, MLton supports\r
14874comments with line directives of the form</simpara>\r
14875<programlisting language="sml" linenumbering="unnumbered">(*#line l.c "f"*)</programlisting>\r
14876<simpara>Here, <emphasis>l</emphasis> and <emphasis>c</emphasis> are sequences of decimal digits and <emphasis>f</emphasis> is the\r
14877source file. The first character of a source file has the position\r
148781.1. A line directive causes the front end to believe that the\r
14879character following the right parenthesis is at the line and column of\r
14880the specified file. A line directive only affects the reporting of\r
14881error messages and does not affect program semantics (except for\r
14882functions like <literal>MLton.Exn.history</literal> that report source file positions).\r
14883Syntactically invalid line directives are ignored. To prevent\r
14884incompatibilities with SML, the file name may not contain the\r
14885character sequence <literal>*)</literal>.</simpara>\r
14886<simpara><?asciidoc-pagebreak?></simpara>\r
14887</section>\r
14888<section id="LLVM">\r
14889<title>LLVM</title>\r
14890<simpara>The <ulink url="http://www.llvm.org/">LLVM Project</ulink> is a collection of modular and\r
14891reusable compiler and toolchain technologies.</simpara>\r
14892<simpara>MLton supports code generation via LLVM (<literal>-codegen llvm</literal>); see\r
14893<link linkend="LLVMCodegen">LLVMCodegen</link>.</simpara>\r
14894<section id="_also_see_9">\r
14895<title>Also see</title>\r
14896<itemizedlist>\r
14897<listitem>\r
14898<simpara>\r
14899<link linkend="CMinusMinus">CMinusMinus</link>\r
14900</simpara>\r
14901</listitem>\r
14902</itemizedlist>\r
14903<simpara><?asciidoc-pagebreak?></simpara>\r
14904</section>\r
14905</section>\r
14906<section id="LLVMCodegen">\r
14907<title>LLVMCodegen</title>\r
14908<simpara>The <link linkend="LLVMCodegen">LLVMCodegen</link> is a <link linkend="Codegen">code generator</link> that translates the\r
14909<link linkend="Machine">Machine</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link> to <link linkend="LLVM">LLVM</link> assembly, which is\r
14910further optimized and compiled to native object code by the <link linkend="LLVM">LLVM</link>\r
14911toolchain.</simpara>\r
14912<simpara>It requires <link linkend="LLVM">LLVM</link> version 3.7 or greater to be installed.</simpara>\r
14913<simpara>In benchmarks performed on the <link linkend="RunningOnAMD64">AMD64</link> architecture,\r
14914code size with this generator is usually slightly smaller than either\r
14915the <link linkend="AMD64Codegen">native</link> or the <link linkend="CCodegen">C</link> code generators. Compile\r
14916time is worse than <link linkend="AMD64Codegen">native</link>, but slightly better than\r
14917<link linkend="CCodegen">C</link>. Run time is often better than either <link linkend="AMD64Codegen">native</link>\r
14918or <link linkend="CCodegen">C</link>.</simpara>\r
14919<section id="_implementation_32">\r
14920<title>Implementation</title>\r
14921<itemizedlist>\r
14922<listitem>\r
14923<simpara>\r
14924<ulink url="https://github.com/MLton/mlton/blob/master/mlton/codegen/llvm-codegen/llvm-codegen.sig"><literal>llvm-codegen.sig</literal></ulink>\r
14925</simpara>\r
14926</listitem>\r
14927<listitem>\r
14928<simpara>\r
14929<ulink url="https://github.com/MLton/mlton/blob/master/mlton/codegen/llvm-codegen/llvm-codegen.fun"><literal>llvm-codegen.fun</literal></ulink>\r
14930</simpara>\r
14931</listitem>\r
14932</itemizedlist>\r
14933</section>\r
14934<section id="_details_and_notes_32">\r
14935<title>Details and Notes</title>\r
14936<simpara>The <link linkend="LLVMCodegen">LLVMCodegen</link> was initially developed by Brian Leibig (see\r
14937<link linkend="References_Leibig13">An LLVM Back-end for MLton</link>).</simpara>\r
14938<simpara><?asciidoc-pagebreak?></simpara>\r
14939</section>\r
14940</section>\r
14941<section id="LocalFlatten">\r
14942<title>LocalFlatten</title>\r
14943<simpara><link linkend="LocalFlatten">LocalFlatten</link> is an optimization pass for the <link linkend="SSA">SSA</link>\r
14944<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="SSASimplify">SSASimplify</link>.</simpara>\r
14945<section id="_description_30">\r
14946<title>Description</title>\r
14947<simpara>This pass flattens arguments to <link linkend="SSA">SSA</link> blocks.</simpara>\r
14948<simpara>A block argument is flattened as long as it only flows to selects and\r
14949there is some tuple constructed in this function that flows to it.</simpara>\r
14950</section>\r
14951<section id="_implementation_33">\r
14952<title>Implementation</title>\r
14953<itemizedlist>\r
14954<listitem>\r
14955<simpara>\r
14956<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/local-flatten.fun"><literal>local-flatten.fun</literal></ulink>\r
14957</simpara>\r
14958</listitem>\r
14959</itemizedlist>\r
14960</section>\r
14961<section id="_details_and_notes_33">\r
14962<title>Details and Notes</title>\r
14963<simpara></simpara>\r
14964<simpara><?asciidoc-pagebreak?></simpara>\r
14965</section>\r
14966</section>\r
14967<section id="LocalRef">\r
14968<title>LocalRef</title>\r
14969<simpara><link linkend="LocalRef">LocalRef</link> is an optimization pass for the <link linkend="SSA">SSA</link>\r
14970<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="SSASimplify">SSASimplify</link>.</simpara>\r
14971<section id="_description_31">\r
14972<title>Description</title>\r
14973<simpara>This pass optimizes <literal>ref</literal> cells local to a <link linkend="SSA">SSA</link> function:</simpara>\r
14974<itemizedlist>\r
14975<listitem>\r
14976<simpara>\r
14977global <literal>ref</literal>-s only used in one function are moved to the function\r
14978</simpara>\r
14979</listitem>\r
14980<listitem>\r
14981<simpara>\r
14982<literal>ref</literal>-s only created, read from, and written to (i.e., don&#8217;t escape)\r
14983are converted into function local variables\r
14984</simpara>\r
14985</listitem>\r
14986</itemizedlist>\r
14987<simpara>Uses <link linkend="Multi">Multi</link> and <link linkend="Restore">Restore</link>.</simpara>\r
14988</section>\r
14989<section id="_implementation_34">\r
14990<title>Implementation</title>\r
14991<itemizedlist>\r
14992<listitem>\r
14993<simpara>\r
14994<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/local-ref.fun"><literal>local-ref.fun</literal></ulink>\r
14995</simpara>\r
14996</listitem>\r
14997</itemizedlist>\r
14998</section>\r
14999<section id="_details_and_notes_34">\r
15000<title>Details and Notes</title>\r
15001<simpara>Moving a global <literal>ref</literal> requires the <link linkend="Multi">Multi</link> analysis, because a\r
15002global <literal>ref</literal> can only be moved into a function that is executed at\r
15003most once.</simpara>\r
15004<simpara>Conversion of non-escaping <literal>ref</literal>-s is structured in three phases:</simpara>\r
15005<itemizedlist>\r
15006<listitem>\r
15007<simpara>\r
15008analysis&#8201;&#8212;&#8201;a variable <literal>r = Ref_ref x</literal> escapes if\r
15009</simpara>\r
15010<itemizedlist>\r
15011<listitem>\r
15012<simpara>\r
15013<literal>r</literal> is used in any context besides <literal>Ref_assign (r, _)</literal> or <literal>Ref_deref r</literal>\r
15014</simpara>\r
15015</listitem>\r
15016<listitem>\r
15017<simpara>\r
15018all uses <literal>r</literal> reachable from a (direct or indirect) call to <literal>Thread_copyCurrent</literal> are of the same flavor (either <literal>Ref_assign</literal> or <literal>Ref_deref</literal>); this also requires the <link linkend="Multi">Multi</link> analysis.\r
15019</simpara>\r
15020</listitem>\r
15021</itemizedlist>\r
15022</listitem>\r
15023<listitem>\r
15024<simpara>\r
15025transformation\r
15026</simpara>\r
15027<itemizedlist>\r
15028<listitem>\r
15029<simpara>\r
15030rewrites <literal>r = Ref_ref x</literal> to <literal>r = x</literal>\r
15031</simpara>\r
15032</listitem>\r
15033<listitem>\r
15034<simpara>\r
15035rewrites <literal>_ = Ref_assign (r, y)</literal> to <literal>r = y</literal>\r
15036</simpara>\r
15037</listitem>\r
15038<listitem>\r
15039<simpara>\r
15040rewrites <literal>z = Ref_deref r</literal> to <literal>z = r</literal>\r
15041</simpara>\r
15042</listitem>\r
15043</itemizedlist>\r
15044<simpara>Note that the resulting program violates the SSA condition.</simpara>\r
15045</listitem>\r
15046<listitem>\r
15047<simpara>\r
15048<link linkend="Restore">Restore</link>&#8201;&#8212;&#8201;restore the SSA condition.\r
15049</simpara>\r
15050</listitem>\r
15051</itemizedlist>\r
15052<simpara><?asciidoc-pagebreak?></simpara>\r
15053</section>\r
15054</section>\r
15055<section id="Logo">\r
15056<title>Logo</title>\r
15057<informalfigure>\r
15058<mediaobject>\r
15059 <imageobject>\r
15060 <imagedata fileref="Logo.attachments/mlton-128.pdf" align="center"/>\r
15061 </imageobject>\r
15062 <textobject><phrase>Logo.attachments/mlton-128.pdf</phrase></textobject>\r
15063</mediaobject>\r
15064</informalfigure>\r
15065<section id="_files">\r
15066<title>Files</title>\r
15067<itemizedlist>\r
15068<listitem>\r
15069<simpara>\r
15070<ulink url="guide/Logo.attachments/mlton.svg"><literal>mlton.svg</literal></ulink>\r
15071</simpara>\r
15072</listitem>\r
15073<listitem>\r
15074<simpara>\r
15075<ulink url="guide/Logo.attachments/mlton-1024.png"><literal>mlton-1024.png</literal></ulink>\r
15076</simpara>\r
15077</listitem>\r
15078<listitem>\r
15079<simpara>\r
15080<ulink url="guide/Logo.attachments/mlton-512.png"><literal>mlton-512.png</literal></ulink>\r
15081</simpara>\r
15082</listitem>\r
15083<listitem>\r
15084<simpara>\r
15085<ulink url="guide/Logo.attachments/mlton-256.png"><literal>mlton-256.png</literal></ulink>\r
15086</simpara>\r
15087</listitem>\r
15088<listitem>\r
15089<simpara>\r
15090<ulink url="guide/Logo.attachments/mlton-128.png"><literal>mlton-128.png</literal></ulink>\r
15091</simpara>\r
15092</listitem>\r
15093<listitem>\r
15094<simpara>\r
15095<ulink url="guide/Logo.attachments/mlton-64.png"><literal>mlton-64.png</literal></ulink>\r
15096</simpara>\r
15097</listitem>\r
15098<listitem>\r
15099<simpara>\r
15100<ulink url="guide/Logo.attachments/mlton-32.png"><literal>mlton-32.png</literal></ulink>\r
15101</simpara>\r
15102</listitem>\r
15103</itemizedlist>\r
15104<simpara><?asciidoc-pagebreak?></simpara>\r
15105</section>\r
15106</section>\r
15107<section id="LoopInvariant">\r
15108<title>LoopInvariant</title>\r
15109<simpara><link linkend="LoopInvariant">LoopInvariant</link> is an optimization pass for the <link linkend="SSA">SSA</link>\r
15110<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="SSASimplify">SSASimplify</link>.</simpara>\r
15111<section id="_description_32">\r
15112<title>Description</title>\r
15113<simpara>This pass removes loop invariant arguments to local loops.</simpara>\r
15114<screen> loop (x, y)\r
15115 ...\r
15116 ...\r
15117 loop (x, z)\r
15118 ...</screen>\r
15119<simpara>becomes</simpara>\r
15120<screen> loop' (x, y)\r
15121 loop (y)\r
15122 loop (y)\r
15123 ...\r
15124 ...\r
15125 loop (z)\r
15126 ...</screen>\r
15127</section>\r
15128<section id="_implementation_35">\r
15129<title>Implementation</title>\r
15130<itemizedlist>\r
15131<listitem>\r
15132<simpara>\r
15133<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/loop-invariant.fun"><literal>loop-invariant.fun</literal></ulink>\r
15134</simpara>\r
15135</listitem>\r
15136</itemizedlist>\r
15137</section>\r
15138<section id="_details_and_notes_35">\r
15139<title>Details and Notes</title>\r
15140<simpara></simpara>\r
15141<simpara><?asciidoc-pagebreak?></simpara>\r
15142</section>\r
15143</section>\r
15144<section id="LoopUnroll">\r
15145<title>LoopUnroll</title>\r
15146<simpara><link linkend="LoopUnroll">LoopUnroll</link> is an optimization pass for the <link linkend="SSA">SSA</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link>,\r
15147invoked from <link linkend="SSASimplify">SSASimplify</link>.</simpara>\r
15148<section id="_description_33">\r
15149<title>Description</title>\r
15150<simpara>A simple loop unrolling optimization.</simpara>\r
15151</section>\r
15152<section id="_implementation_36">\r
15153<title>Implementation</title>\r
15154<itemizedlist>\r
15155<listitem>\r
15156<simpara>\r
15157<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/loop-unroll.fun"><literal>loop-unroll.fun</literal></ulink>\r
15158</simpara>\r
15159</listitem>\r
15160</itemizedlist>\r
15161</section>\r
15162<section id="_details_and_notes_36">\r
15163<title>Details and Notes</title>\r
15164<simpara></simpara>\r
15165<simpara><?asciidoc-pagebreak?></simpara>\r
15166</section>\r
15167</section>\r
15168<section id="LoopUnswitch">\r
15169<title>LoopUnswitch</title>\r
15170<simpara><link linkend="LoopUnswitch">LoopUnswitch</link> is an optimization pass for the <link linkend="SSA">SSA</link>\r
15171<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="SSASimplify">SSASimplify</link>.</simpara>\r
15172<section id="_description_34">\r
15173<title>Description</title>\r
15174<simpara>A simple loop unswitching optimization.</simpara>\r
15175</section>\r
15176<section id="_implementation_37">\r
15177<title>Implementation</title>\r
15178<itemizedlist>\r
15179<listitem>\r
15180<simpara>\r
15181<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/loop-unswitch.fun"><literal>loop-unswitch.fun</literal></ulink>\r
15182</simpara>\r
15183</listitem>\r
15184</itemizedlist>\r
15185</section>\r
15186<section id="_details_and_notes_37">\r
15187<title>Details and Notes</title>\r
15188<simpara></simpara>\r
15189<simpara><?asciidoc-pagebreak?></simpara>\r
15190</section>\r
15191</section>\r
15192<section id="Machine">\r
15193<title>Machine</title>\r
15194<simpara><link linkend="Machine">Machine</link> is an <link linkend="IntermediateLanguage">IntermediateLanguage</link>, translated from <link linkend="RSSA">RSSA</link>\r
15195by <link linkend="ToMachine">ToMachine</link> and used as input by the <link linkend="Codegen">Codegen</link>.</simpara>\r
15196<section id="_description_35">\r
15197<title>Description</title>\r
15198<simpara><link linkend="Machine">Machine</link> is an <link linkend="Untyped">Untyped</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link>, corresponding\r
15199to a abstract register machine.</simpara>\r
15200</section>\r
15201<section id="_implementation_38">\r
15202<title>Implementation</title>\r
15203<itemizedlist>\r
15204<listitem>\r
15205<simpara>\r
15206<ulink url="https://github.com/MLton/mlton/blob/master/mlton/backend/machine.sig"><literal>machine.sig</literal></ulink>\r
15207</simpara>\r
15208</listitem>\r
15209<listitem>\r
15210<simpara>\r
15211<ulink url="https://github.com/MLton/mlton/blob/master/mlton/backend/machine.fun"><literal>machine.fun</literal></ulink>\r
15212</simpara>\r
15213</listitem>\r
15214</itemizedlist>\r
15215</section>\r
15216<section id="_type_checking_3">\r
15217<title>Type Checking</title>\r
15218<simpara>The <link linkend="Machine">Machine</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link> has a primitive type checker\r
15219(<ulink url="https://github.com/MLton/mlton/blob/master/mlton/backend/machine.sig"><literal>machine.sig</literal></ulink>,\r
15220<ulink url="https://github.com/MLton/mlton/blob/master/mlton/backend/machine.fun"><literal>machine.fun</literal></ulink>), which only checks\r
15221some liveness properties.</simpara>\r
15222</section>\r
15223<section id="_details_and_notes_38">\r
15224<title>Details and Notes</title>\r
15225<simpara>The runtime structure sets some constants according to the\r
15226configuration files on the target architecture and OS.</simpara>\r
15227<simpara><?asciidoc-pagebreak?></simpara>\r
15228</section>\r
15229</section>\r
15230<section id="ManualPage">\r
15231<title>ManualPage</title>\r
15232<simpara>MLton is run from the command line with a collection of options\r
15233followed by a file name and a list of files to compile, assemble, and\r
15234link with.</simpara>\r
15235<screen>mlton [option ...] file.{c|mlb|o|sml} [file.{c|o|s|S} ...]</screen>\r
15236<simpara>The simplest case is to run <literal>mlton foo.sml</literal>, where <literal>foo.sml</literal> contains\r
15237a valid SML program, in which case MLton compiles the program to\r
15238produce an executable <literal>foo</literal>. Since MLton does not support separate\r
15239compilation, the program must be the entire program you wish to\r
15240compile. However, the program may refer to signatures and structures\r
15241defined in the <link linkend="BasisLibrary">Basis Library</link>.</simpara>\r
15242<simpara>Larger programs, spanning many files, can be compiled with the\r
15243<link linkend="MLBasis">ML Basis system</link>. In this case, <literal>mlton foo.mlb</literal> will\r
15244compile the complete SML program described by the basis <literal>foo.mlb</literal>,\r
15245which may specify both SML files and additional bases.</simpara>\r
15246<section id="_next_steps_3">\r
15247<title>Next Steps</title>\r
15248<itemizedlist>\r
15249<listitem>\r
15250<simpara>\r
15251<link linkend="CompileTimeOptions">CompileTimeOptions</link>\r
15252</simpara>\r
15253</listitem>\r
15254<listitem>\r
15255<simpara>\r
15256<link linkend="RunTimeOptions">RunTimeOptions</link>\r
15257</simpara>\r
15258</listitem>\r
15259</itemizedlist>\r
15260<simpara><?asciidoc-pagebreak?></simpara>\r
15261</section>\r
15262</section>\r
15263<section id="MatchCompilation">\r
15264<title>MatchCompilation</title>\r
15265<simpara>Match compilation is the process of translating an SML match into a\r
15266nested tree (or dag) of simple case expressions and tests.</simpara>\r
15267<simpara>MLton&#8217;s match compiler is described <link linkend="MatchCompile">here</link>.</simpara>\r
15268<section id="_match_compilation_in_other_compilers">\r
15269<title>Match compilation in other compilers</title>\r
15270<itemizedlist>\r
15271<listitem>\r
15272<simpara>\r
15273<link linkend="References_BaudinetMacQueen85">BaudinetMacQueen85</link>\r
15274</simpara>\r
15275</listitem>\r
15276<listitem>\r
15277<simpara>\r
15278<link linkend="References_Leroy90">Leroy90</link>, pages 60-69.\r
15279</simpara>\r
15280</listitem>\r
15281<listitem>\r
15282<simpara>\r
15283<link linkend="References_Sestoft96">Sestoft96</link>\r
15284</simpara>\r
15285</listitem>\r
15286<listitem>\r
15287<simpara>\r
15288<link linkend="References_ScottRamsey00">ScottRamsey00</link>\r
15289</simpara>\r
15290</listitem>\r
15291</itemizedlist>\r
15292<simpara><?asciidoc-pagebreak?></simpara>\r
15293</section>\r
15294</section>\r
15295<section id="MatchCompile">\r
15296<title>MatchCompile</title>\r
15297<simpara><link linkend="MatchCompile">MatchCompile</link> is a translation pass, agnostic in the\r
15298<link linkend="IntermediateLanguage">IntermediateLanguage</link>s between which it translates.</simpara>\r
15299<section id="_description_36">\r
15300<title>Description</title>\r
15301<simpara><link linkend="MatchCompilation">Match compilation</link> converts a case expression with\r
15302nested patterns into a case expression with flat patterns.</simpara>\r
15303</section>\r
15304<section id="_implementation_39">\r
15305<title>Implementation</title>\r
15306<itemizedlist>\r
15307<listitem>\r
15308<simpara>\r
15309<ulink url="https://github.com/MLton/mlton/blob/master/mlton/match-compile/match-compile.sig"><literal>match-compile.sig</literal></ulink>\r
15310</simpara>\r
15311</listitem>\r
15312<listitem>\r
15313<simpara>\r
15314<ulink url="https://github.com/MLton/mlton/blob/master/mlton/match-compile/match-compile.fun"><literal>match-compile.fun</literal></ulink>\r
15315</simpara>\r
15316</listitem>\r
15317</itemizedlist>\r
15318</section>\r
15319<section id="_details_and_notes_39">\r
15320<title>Details and Notes</title>\r
15321<programlisting language="sml" linenumbering="unnumbered">val matchCompile:\r
15322 {caseType: Type.t, (* type of entire expression *)\r
15323 cases: (NestedPat.t * ((Var.t -&gt; Var.t) -&gt; Exp.t)) vector,\r
15324 conTycon: Con.t -&gt; Tycon.t,\r
15325 region: Region.t,\r
15326 test: Var.t,\r
15327 testType: Type.t,\r
15328 tyconCons: Tycon.t -&gt; {con: Con.t, hasArg: bool} vector}\r
15329 -&gt; Exp.t * (unit -&gt; ((Layout.t * {isOnlyExns: bool}) vector) vector)</programlisting>\r
15330<simpara><literal>matchCompile</literal> is complicated by the desire for modularity between the\r
15331match compiler and its caller. Its caller is responsible for building\r
15332the right hand side of a rule <literal>p =&gt; e</literal>. On the other hand, the match\r
15333compiler is responsible for destructing the test and binding new\r
15334variables to the components. In order to connect the new variables\r
15335created by the match compiler with the variables in the pattern <literal>p</literal>,\r
15336the match compiler passes an environment back to its caller that maps\r
15337each variable in <literal>p</literal> to the corresponding variable introduced by the\r
15338match compiler.</simpara>\r
15339<simpara>The match compiler builds a tree of n-way case expressions by working\r
15340from outside to inside and left to right in the patterns. For example,</simpara>\r
15341<programlisting language="sml" linenumbering="unnumbered">case x of\r
15342 (_, C1 a) =&gt; e1\r
15343| (C2 b, C3 c) =&gt; e2</programlisting>\r
15344<simpara>is translated to</simpara>\r
15345<programlisting language="sml" linenumbering="unnumbered">let\r
15346 fun f1 a = e1\r
15347 fun f2 (b, c) = e2\r
15348in\r
15349 case x of\r
15350 (x1, x2) =&gt;\r
15351 (case x1 of\r
15352 C2 b' =&gt; (case x2 of\r
15353 C1 a' =&gt; f1 a'\r
15354 | C3 c' =&gt; f2(b',c')\r
15355 | _ =&gt; raise Match)\r
15356 | _ =&gt; (case x2 of\r
15357 C1 a_ =&gt; f1 a_\r
15358 | _ =&gt; raise Match))\r
15359end</programlisting>\r
15360<simpara>Here you can see the necessity of abstracting out the ride hand sides\r
15361of the cases in order to avoid code duplication. Right hand sides are\r
15362always abstracted. The simplifier cleans things up. You can also see\r
15363the new (primed) variables introduced by the match compiler and how\r
15364the renaming works. Finally, you can see how the match compiler\r
15365introduces the necessary default clauses in order to make a match\r
15366exhaustive, i.e. cover all the cases.</simpara>\r
15367<simpara>The match compiler uses <literal>numCons</literal> and <literal>tyconCons</literal> to determine\r
15368the exhaustivity of matches against constructors.</simpara>\r
15369<simpara><?asciidoc-pagebreak?></simpara>\r
15370</section>\r
15371</section>\r
15372<section id="MatthewFluet">\r
15373<title>MatthewFluet</title>\r
15374<simpara>Matthew Fluet (\r
15375<ulink url="mailto:matthew.fluet@gmail.com">matthew.fluet@gmail.com</ulink>\r
15376,\r
15377<ulink url="http://www.cs.rit.edu/%7Emtf">http://www.cs.rit.edu/%7Emtf</ulink>\r
15378)\r
15379is an Assistant Professor at the <ulink url="http://www.rit.edu">Rochester Institute of Technology</ulink>.</simpara>\r
15380<simpara><?asciidoc-hr?></simpara>\r
15381<simpara>Current MLton projects:</simpara>\r
15382<itemizedlist>\r
15383<listitem>\r
15384<simpara>\r
15385general maintenance\r
15386</simpara>\r
15387</listitem>\r
15388<listitem>\r
15389<simpara>\r
15390release new version\r
15391</simpara>\r
15392</listitem>\r
15393</itemizedlist>\r
15394<simpara><?asciidoc-hr?></simpara>\r
15395<simpara>Misc. and underspecified TODOs:</simpara>\r
15396<itemizedlist>\r
15397<listitem>\r
15398<simpara>\r
15399understand <link linkend="RefFlatten">RefFlatten</link> and <link linkend="DeepFlatten">DeepFlatten</link>\r
15400</simpara>\r
15401<itemizedlist>\r
15402<listitem>\r
15403<simpara>\r
15404<ulink url="http://www.mlton.org/pipermail/mlton/2005-April/026990.html">http://www.mlton.org/pipermail/mlton/2005-April/026990.html</ulink>\r
15405</simpara>\r
15406</listitem>\r
15407<listitem>\r
15408<simpara>\r
15409<ulink url="http://www.mlton.org/pipermail/mlton/2007-November/030056.html">http://www.mlton.org/pipermail/mlton/2007-November/030056.html</ulink>\r
15410</simpara>\r
15411</listitem>\r
15412<listitem>\r
15413<simpara>\r
15414<ulink url="http://www.mlton.org/pipermail/mlton/2008-April/030250.html">http://www.mlton.org/pipermail/mlton/2008-April/030250.html</ulink>\r
15415</simpara>\r
15416</listitem>\r
15417<listitem>\r
15418<simpara>\r
15419<ulink url="http://www.mlton.org/pipermail/mlton/2008-July/030279.html">http://www.mlton.org/pipermail/mlton/2008-July/030279.html</ulink>\r
15420</simpara>\r
15421</listitem>\r
15422<listitem>\r
15423<simpara>\r
15424<ulink url="http://www.mlton.org/pipermail/mlton/2008-August/030312.html">http://www.mlton.org/pipermail/mlton/2008-August/030312.html</ulink>\r
15425</simpara>\r
15426</listitem>\r
15427<listitem>\r
15428<simpara>\r
15429<ulink url="http://www.mlton.org/pipermail/mlton/2008-September/030360.html">http://www.mlton.org/pipermail/mlton/2008-September/030360.html</ulink>\r
15430</simpara>\r
15431</listitem>\r
15432<listitem>\r
15433<simpara>\r
15434<ulink url="http://www.mlton.org/pipermail/mlton-user/2009-June/001542.html">http://www.mlton.org/pipermail/mlton-user/2009-June/001542.html</ulink>\r
15435</simpara>\r
15436</listitem>\r
15437</itemizedlist>\r
15438</listitem>\r
15439<listitem>\r
15440<simpara>\r
15441<literal>MSG_DONTWAIT</literal> isn&#8217;t Posix\r
15442</simpara>\r
15443</listitem>\r
15444<listitem>\r
15445<simpara>\r
15446coordinate w/ Dan Spoonhower and Lukasz Ziarek and Armand Navabi on multi-threaded\r
15447</simpara>\r
15448<itemizedlist>\r
15449<listitem>\r
15450<simpara>\r
15451<ulink url="http://www.mlton.org/pipermail/mlton/2008-March/030214.html">http://www.mlton.org/pipermail/mlton/2008-March/030214.html</ulink>\r
15452</simpara>\r
15453</listitem>\r
15454</itemizedlist>\r
15455</listitem>\r
15456<listitem>\r
15457<simpara>\r
15458Intel Research bug: <literal>no tyconRep property</literal> (company won&#8217;t release sample code)\r
15459</simpara>\r
15460<itemizedlist>\r
15461<listitem>\r
15462<simpara>\r
15463<ulink url="http://www.mlton.org/pipermail/mlton-user/2008-March/001358.html">http://www.mlton.org/pipermail/mlton-user/2008-March/001358.html</ulink>\r
15464</simpara>\r
15465</listitem>\r
15466</itemizedlist>\r
15467</listitem>\r
15468<listitem>\r
15469<simpara>\r
15470treatment of real constants\r
15471</simpara>\r
15472<itemizedlist>\r
15473<listitem>\r
15474<simpara>\r
15475<ulink url="http://www.mlton.org/pipermail/mlton/2008-May/030262.html">http://www.mlton.org/pipermail/mlton/2008-May/030262.html</ulink>\r
15476</simpara>\r
15477</listitem>\r
15478<listitem>\r
15479<simpara>\r
15480<ulink url="http://www.mlton.org/pipermail/mlton/2008-June/030271.html">http://www.mlton.org/pipermail/mlton/2008-June/030271.html</ulink>\r
15481</simpara>\r
15482</listitem>\r
15483</itemizedlist>\r
15484</listitem>\r
15485<listitem>\r
15486<simpara>\r
15487representation of <literal>bool</literal> and <literal>_bool</literal> in <link linkend="ForeignFunctionInterface">ForeignFunctionInterface</link>\r
15488</simpara>\r
15489<itemizedlist>\r
15490<listitem>\r
15491<simpara>\r
15492<ulink url="http://www.mlton.org/pipermail/mlton/2008-May/030264.html">http://www.mlton.org/pipermail/mlton/2008-May/030264.html</ulink>\r
15493</simpara>\r
15494</listitem>\r
15495</itemizedlist>\r
15496</listitem>\r
15497<listitem>\r
15498<simpara>\r
15499<ulink url="http://www.icfpcontest.org">http://www.icfpcontest.org</ulink>\r
15500</simpara>\r
15501<itemizedlist>\r
15502<listitem>\r
15503<simpara>\r
15504John Reppy claims that "It looks like the card-marking overhead that one incurs when using generational collection swamps the benefits of generational collection."\r
15505</simpara>\r
15506</listitem>\r
15507</itemizedlist>\r
15508</listitem>\r
15509<listitem>\r
15510<simpara>\r
15511page to disk policy / single heap\r
15512</simpara>\r
15513<itemizedlist>\r
15514<listitem>\r
15515<simpara>\r
15516<ulink url="http://www.mlton.org/pipermail/mlton/2008-June/030278.html">http://www.mlton.org/pipermail/mlton/2008-June/030278.html</ulink>\r
15517</simpara>\r
15518</listitem>\r
15519<listitem>\r
15520<simpara>\r
15521<ulink url="http://www.mlton.org/pipermail/mlton/2008-August/030318.html">http://www.mlton.org/pipermail/mlton/2008-August/030318.html</ulink>\r
15522</simpara>\r
15523</listitem>\r
15524</itemizedlist>\r
15525</listitem>\r
15526<listitem>\r
15527<simpara>\r
15528<literal>MLton.GC.pack</literal> doesn&#8217;t keep a small heap if a garbage collection occurs before <literal>MLton.GC.unpack</literal>.\r
15529</simpara>\r
15530<itemizedlist>\r
15531<listitem>\r
15532<simpara>\r
15533It might be preferable for <literal>MLton.GC.pack</literal> to be implemented as a (new) <literal>MLton.GC.Ratios.setLive 1.1</literal> followed by <literal>MLton.GC.collect ()</literal> and for <literal>MLton.GC.unpack</literal> to be implemented as <literal>MLton.GC.Ratios.setLive 8.0</literal> followed by <literal>MLton.GC.collect ()</literal>.\r
15534</simpara>\r
15535</listitem>\r
15536</itemizedlist>\r
15537</listitem>\r
15538<listitem>\r
15539<simpara>\r
15540The <literal>static struct GC_objectType objectTypes[] =</literal> array includes many duplicates. Objects of distinct source type, but equivalent representations (in terms of size, bytes non-pointers, number pointers) can share the objectType index.\r
15541</simpara>\r
15542</listitem>\r
15543<listitem>\r
15544<simpara>\r
15545PolySpace bug: <link linkend="Redundant">Redundant</link> optimization (company won&#8217;t release sample code)\r
15546</simpara>\r
15547<itemizedlist>\r
15548<listitem>\r
15549<simpara>\r
15550<ulink url="http://www.mlton.org/pipermail/mlton/2008-September/030355.html">http://www.mlton.org/pipermail/mlton/2008-September/030355.html</ulink>\r
15551</simpara>\r
15552</listitem>\r
15553</itemizedlist>\r
15554</listitem>\r
15555<listitem>\r
15556<simpara>\r
15557treatment of exception raised during <link linkend="BasisLibrary">BasisLibrary</link> evaluation\r
15558</simpara>\r
15559<itemizedlist>\r
15560<listitem>\r
15561<simpara>\r
15562<ulink url="http://www.mlton.org/pipermail/mlton/2008-December/030501.html">http://www.mlton.org/pipermail/mlton/2008-December/030501.html</ulink>\r
15563</simpara>\r
15564</listitem>\r
15565<listitem>\r
15566<simpara>\r
15567<ulink url="http://www.mlton.org/pipermail/mlton/2008-December/030502.html">http://www.mlton.org/pipermail/mlton/2008-December/030502.html</ulink>\r
15568</simpara>\r
15569</listitem>\r
15570<listitem>\r
15571<simpara>\r
15572<ulink url="http://www.mlton.org/pipermail/mlton/2008-December/030503.html">http://www.mlton.org/pipermail/mlton/2008-December/030503.html</ulink>\r
15573</simpara>\r
15574</listitem>\r
15575</itemizedlist>\r
15576</listitem>\r
15577<listitem>\r
15578<simpara>\r
15579Use <literal>memcpy</literal>\r
15580</simpara>\r
15581<itemizedlist>\r
15582<listitem>\r
15583<simpara>\r
15584<ulink url="http://www.mlton.org/pipermail/mlton-user/2009-January/001506.html">http://www.mlton.org/pipermail/mlton-user/2009-January/001506.html</ulink>\r
15585</simpara>\r
15586</listitem>\r
15587<listitem>\r
15588<simpara>\r
15589<ulink url="http://www.mlton.org/pipermail/mlton/2009-January/030506.html">http://www.mlton.org/pipermail/mlton/2009-January/030506.html</ulink>\r
15590</simpara>\r
15591</listitem>\r
15592</itemizedlist>\r
15593</listitem>\r
15594<listitem>\r
15595<simpara>\r
15596Implement more 64bit primops in x86 codegen\r
15597</simpara>\r
15598<itemizedlist>\r
15599<listitem>\r
15600<simpara>\r
15601<ulink url="http://www.mlton.org/pipermail/mlton/2009-January/030507.html">http://www.mlton.org/pipermail/mlton/2009-January/030507.html</ulink>\r
15602</simpara>\r
15603</listitem>\r
15604</itemizedlist>\r
15605</listitem>\r
15606<listitem>\r
15607<simpara>\r
15608Enrich path-map file syntax:\r
15609</simpara>\r
15610<itemizedlist>\r
15611<listitem>\r
15612<simpara>\r
15613<ulink url="http://www.mlton.org/pipermail/mlton/2008-September/030348.html">http://www.mlton.org/pipermail/mlton/2008-September/030348.html</ulink>\r
15614</simpara>\r
15615</listitem>\r
15616<listitem>\r
15617<simpara>\r
15618<ulink url="http://www.mlton.org/pipermail/mlton-user/2009-January/001507.html">http://www.mlton.org/pipermail/mlton-user/2009-January/001507.html</ulink>\r
15619</simpara>\r
15620</listitem>\r
15621</itemizedlist>\r
15622</listitem>\r
15623<listitem>\r
15624<simpara>\r
15625PolySpace bug: crash during Cheney-copy collection\r
15626</simpara>\r
15627<itemizedlist>\r
15628<listitem>\r
15629<simpara>\r
15630<ulink url="http://www.mlton.org/pipermail/mlton/2009-February/030513.html">http://www.mlton.org/pipermail/mlton/2009-February/030513.html</ulink>\r
15631</simpara>\r
15632</listitem>\r
15633</itemizedlist>\r
15634</listitem>\r
15635<listitem>\r
15636<simpara>\r
15637eliminate <literal>-build-constants</literal>\r
15638</simpara>\r
15639<itemizedlist>\r
15640<listitem>\r
15641<simpara>\r
15642all <literal>_const</literal>-s are known by <literal>runtime/gen/basis-ffi.def</literal>\r
15643</simpara>\r
15644</listitem>\r
15645<listitem>\r
15646<simpara>\r
15647generate <literal>gen-constants.c</literal> from <literal>basis-ffi.def</literal>\r
15648</simpara>\r
15649</listitem>\r
15650<listitem>\r
15651<simpara>\r
15652generate <literal>constants</literal> from <literal>gen-constants.c</literal> and <literal>libmlton.a</literal>\r
15653</simpara>\r
15654</listitem>\r
15655<listitem>\r
15656<simpara>\r
15657similar to <literal>gen-sizes.c</literal> and <literal>sizes</literal>\r
15658</simpara>\r
15659</listitem>\r
15660</itemizedlist>\r
15661</listitem>\r
15662<listitem>\r
15663<simpara>\r
15664eliminate "Windows hacks" for Cygwin from <literal>Path</literal> module\r
15665</simpara>\r
15666<itemizedlist>\r
15667<listitem>\r
15668<simpara>\r
15669<ulink url="http://www.mlton.org/pipermail/mlton/2009-July/030606.html">http://www.mlton.org/pipermail/mlton/2009-July/030606.html</ulink>\r
15670</simpara>\r
15671</listitem>\r
15672</itemizedlist>\r
15673</listitem>\r
15674<listitem>\r
15675<simpara>\r
15676extend IL type checkers to check for empty property lists\r
15677</simpara>\r
15678</listitem>\r
15679<listitem>\r
15680<simpara>\r
15681make (unsafe) <literal>IntInf</literal> conversions into primitives\r
15682</simpara>\r
15683<itemizedlist>\r
15684<listitem>\r
15685<simpara>\r
15686<ulink url="http://www.mlton.org/pipermail/mlton/2009-July/030622.html">http://www.mlton.org/pipermail/mlton/2009-July/030622.html</ulink>\r
15687</simpara>\r
15688</listitem>\r
15689</itemizedlist>\r
15690</listitem>\r
15691</itemizedlist>\r
15692<simpara><?asciidoc-pagebreak?></simpara>\r
15693</section>\r
15694<section id="mGTK">\r
15695<title>mGTK</title>\r
15696<simpara><ulink url="http://mgtk.sourceforge.net/">mGTK</ulink> is a wrapper for\r
15697<ulink url="http://www.gtk.org/">GTK+</ulink>, a GUI toolkit.</simpara>\r
15698<simpara>We recommend using mGTK 0.93, which is not listed on their home page,\r
15699but is available at the\r
15700<ulink url="http://sourceforge.net/project/showfiles.php?group_id=23226&amp;package_id=16523">file\r
15701release page</ulink>. To test it, after unpacking, do <literal>cd examples; make\r
15702mlton</literal>, after which you should be able to run the many examples\r
15703(<literal>signup-mlton</literal>, <literal>listview-mlton</literal>, &#8230;).</simpara>\r
15704<section id="_also_see_10">\r
15705<title>Also see</title>\r
15706<itemizedlist>\r
15707<listitem>\r
15708<simpara>\r
15709<link linkend="Glade">Glade</link>\r
15710</simpara>\r
15711</listitem>\r
15712</itemizedlist>\r
15713<simpara><?asciidoc-pagebreak?></simpara>\r
15714</section>\r
15715</section>\r
15716<section id="MichaelNorrish">\r
15717<title>MichaelNorrish</title>\r
15718<simpara>I am a researcher at <ulink url="http://nicta.com.au">NICTA</ulink>, with a web-page <ulink url="http://web.rsise.anu.edu.au/%7Emichaeln/">here</ulink>.</simpara>\r
15719<simpara>I&#8217;m interested in MLton because of the chance that it might be a good vehicle for future implementations of the <ulink url="http://hol.sf.net">HOL</ulink> theorem-proving system. It&#8217;s beginning to look as if one route forward will be to embed an SML interpreter into a MLton-compiled executable. I don&#8217;t know if an extensible interpreter of the kind we&#8217;re looking for already exists.</simpara>\r
15720<simpara><?asciidoc-pagebreak?></simpara>\r
15721</section>\r
15722<section id="MikeThomas">\r
15723<title>MikeThomas</title>\r
15724<simpara>Here is a picture at home in Brisbane, Queensland, Australia, taken in January 2004.</simpara>\r
15725<informalfigure>\r
15726<mediaobject>\r
15727 <imageobject>\r
15728 <imagedata fileref="MikeThomas.attachments/picture.jpg" align="center"/>\r
15729 </imageobject>\r
15730 <textobject><phrase>MikeThomas.attachments/picture.jpg</phrase></textobject>\r
15731</mediaobject>\r
15732</informalfigure>\r
15733<simpara><?asciidoc-pagebreak?></simpara>\r
15734</section>\r
15735<section id="ML">\r
15736<title>ML</title>\r
15737<simpara>ML stands for <emphasis>meta language</emphasis>. ML was originally designed in the\r
157381970s as a programming language to assist theorem proving in the logic\r
15739LCF. In the 1980s, ML split into two variants,\r
15740<link linkend="StandardML">Standard ML</link> and <link linkend="OCaml">OCaml</link>, both of which are still used\r
15741today.</simpara>\r
15742<simpara><?asciidoc-pagebreak?></simpara>\r
15743</section>\r
15744<section id="MLAntlr">\r
15745<title>MLAntlr</title>\r
15746<simpara><ulink url="http://smlnj-gforge.cs.uchicago.edu/projects/ml-lpt/">MLAntlr</ulink> is a\r
15747parser generator for <link linkend="StandardML">Standard ML</link>.</simpara>\r
15748<section id="_also_see_11">\r
15749<title>Also see</title>\r
15750<itemizedlist>\r
15751<listitem>\r
15752<simpara>\r
15753<link linkend="MLULex">MLULex</link>\r
15754</simpara>\r
15755</listitem>\r
15756<listitem>\r
15757<simpara>\r
15758<link linkend="MLLPTLibrary">MLLPTLibrary</link>\r
15759</simpara>\r
15760</listitem>\r
15761</itemizedlist>\r
15762<simpara><?asciidoc-pagebreak?></simpara>\r
15763</section>\r
15764</section>\r
15765<section id="MLBasis">\r
15766<title>MLBasis</title>\r
15767<simpara>The ML Basis system extends <link linkend="StandardML">Standard ML</link> to support\r
15768programming-in-the-very-large, namespace management at the module\r
15769level, separate delivery of library sources, and more. While Standard\r
15770ML modules are a sophisticated language for programming-in-the-large,\r
15771it is difficult, if not impossible, to accomplish a number of routine\r
15772namespace management operations when a program draws upon multiple\r
15773libraries provided by different vendors.</simpara>\r
15774<simpara>The ML Basis system is a simple, yet powerful, approach that builds\r
15775upon the programmer&#8217;s intuitive notion (and\r
15776<link linkend="DefinitionOfStandardML">The Definition of Standard ML (Revised)</link>'s\r
15777formal notion) of the top-level environment (a <emphasis>basis</emphasis>). The system\r
15778is designed as a natural extension of <link linkend="StandardML">Standard ML</link>; the\r
15779formal specification of the ML Basis system\r
15780(<ulink url="guide/MLBasis.attachments/mlb-formal.pdf"><literal>mlb-formal.pdf</literal></ulink>) is given in the style\r
15781of the Definition.</simpara>\r
15782<simpara>Here are some of the key features of the ML Basis system:</simpara>\r
15783<orderedlist numeration="arabic">\r
15784<listitem>\r
15785<simpara>\r
15786Explicit file order: The order of files (and, hence, the order of\r
15787evaluation) in the program is explicit. The ML Basis system&#8217;s\r
15788semantics are structured in such a way that for any well-formed\r
15789project, there will be exactly one possible interpretation of the\r
15790project&#8217;s syntax, static semantics, and dynamic semantics.\r
15791</simpara>\r
15792</listitem>\r
15793<listitem>\r
15794<simpara>\r
15795Implicit dependencies: A source file (corresponding to an SML\r
15796top-level declaration) is elaborated in the environment described by\r
15797preceding declarations. It is not necessary to explicitly list the\r
15798dependencies of a file.\r
15799</simpara>\r
15800</listitem>\r
15801<listitem>\r
15802<simpara>\r
15803Scoping and renaming: The ML Basis system provides mechanisms for\r
15804limiting the scope of (i.e, hiding) and renaming identifiers.\r
15805</simpara>\r
15806</listitem>\r
15807<listitem>\r
15808<simpara>\r
15809No naming convention for finding the file that defines a module.\r
15810To import a module, its defining file must appear in some ML Basis\r
15811file.\r
15812</simpara>\r
15813</listitem>\r
15814</orderedlist>\r
15815<section id="_next_steps_4">\r
15816<title>Next steps</title>\r
15817<itemizedlist>\r
15818<listitem>\r
15819<simpara>\r
15820<link linkend="MLBasisSyntaxAndSemantics">MLBasisSyntaxAndSemantics</link>\r
15821</simpara>\r
15822</listitem>\r
15823<listitem>\r
15824<simpara>\r
15825<link linkend="MLBasisExamples">MLBasisExamples</link>\r
15826</simpara>\r
15827</listitem>\r
15828<listitem>\r
15829<simpara>\r
15830<link linkend="MLBasisPathMap">MLBasisPathMap</link>\r
15831</simpara>\r
15832</listitem>\r
15833<listitem>\r
15834<simpara>\r
15835<link linkend="MLBasisAnnotations">MLBasisAnnotations</link>\r
15836</simpara>\r
15837</listitem>\r
15838<listitem>\r
15839<simpara>\r
15840<link linkend="MLBasisAvailableLibraries">MLBasisAvailableLibraries</link>\r
15841</simpara>\r
15842</listitem>\r
15843</itemizedlist>\r
15844<simpara><?asciidoc-pagebreak?></simpara>\r
15845</section>\r
15846</section>\r
15847<section id="MLBasisAnnotationExamples">\r
15848<title>MLBasisAnnotationExamples</title>\r
15849<simpara>Here are some example uses of <link linkend="MLBasisAnnotations">MLBasisAnnotations</link>.</simpara>\r
15850<section id="_eliminate_spurious_warnings_in_automatically_generated_code">\r
15851<title>Eliminate spurious warnings in automatically generated code</title>\r
15852<simpara>Programs that automatically generate source code can often produce\r
15853nonexhaustive patterns, relying on invariants of the generated code to\r
15854ensure that the pattern matchings never fail. A programmer may wish\r
15855to elide the nonexhaustive warnings from this code, in order that\r
15856legitimate warnings are not missed in a flurry of false positives. To\r
15857do so, the programmer simply annotates the generated code with the\r
15858<literal>nonexhaustiveBind ignore</literal> and <literal>nonexhaustiveMatch ignore</literal>\r
15859annotations:</simpara>\r
15860<screen>local\r
15861 $(GEN_ROOT)/gen-lib.mlb\r
15862\r
15863 ann\r
15864 "nonexhaustiveBind ignore"\r
15865 "nonexhaustiveMatch ignore"\r
15866 in\r
15867 foo.gen.sml\r
15868 end\r
15869in\r
15870 signature FOO\r
15871 structure Foo\r
15872end</screen>\r
15873</section>\r
15874<section id="_deliver_a_library">\r
15875<title>Deliver a library</title>\r
15876<simpara>Standard ML libraries can be delivered via <literal>.mlb</literal> files. Authors of\r
15877such libraries should strive to be mindful of the ways in which\r
15878programmers may choose to compile their programs. For example,\r
15879although the defaults for <literal>sequenceNonUnit</literal> and <literal>warnUnused</literal> are\r
15880<literal>ignore</literal> and <literal>false</literal>, periodically compiling with these annotations\r
15881defaulted to <literal>warn</literal> and <literal>true</literal> can help uncover likely bugs. However,\r
15882a programmer is unlikely to be interested in unused modules from an\r
15883imported library, and the behavior of <literal>sequenceNonUnit error</literal> may be\r
15884incompatible with some libraries. Hence, a library author may choose\r
15885to deliver a library as follows:</simpara>\r
15886<screen>ann\r
15887 "nonexhaustiveBind warn" "nonexhaustiveMatch warn"\r
15888 "redundantBind warn" "redundantMatch warn"\r
15889 "sequenceNonUnit warn"\r
15890 "warnUnused true" "forceUsed"\r
15891in\r
15892 local\r
15893 file1.sml\r
15894 ...\r
15895 filen.sml\r
15896 in\r
15897 functor F1\r
15898 ...\r
15899 signature S1\r
15900 ...\r
15901 structure SN\r
15902 ...\r
15903 end\r
15904end</screen>\r
15905<simpara>The annotations <literal>nonexhaustiveBind warn</literal>, <literal>redundantBind warn</literal>,\r
15906<literal>nonexhaustiveMatch warn</literal>, <literal>redundantMatch warn</literal>, and <literal>sequenceNonUnit\r
15907warn</literal> have the obvious effect on elaboration. The annotations\r
15908<literal>warnUnused true</literal> and <literal>forceUsed</literal> work in conjunction&#8201;&#8212;&#8201;warning on\r
15909any identifiers that do not contribute to the exported modules, and\r
15910preventing warnings on exported modules that are not used in the\r
15911remainder of the program. Many of the\r
15912<link linkend="MLBasisAvailableLibraries">available libraries</link> are delivered with\r
15913these annotations.</simpara>\r
15914<simpara><?asciidoc-pagebreak?></simpara>\r
15915</section>\r
15916</section>\r
15917<section id="MLBasisAnnotations">\r
15918<title>MLBasisAnnotations</title>\r
15919<simpara><link linkend="MLBasis">ML Basis</link> annotations control options that affect the\r
15920elaboration of SML source files. Conceptually, a basis file is\r
15921elaborated in a default annotation environment (just as it is\r
15922elaborated in an empty basis). The declaration\r
15923<literal>ann</literal>&#160;<literal>"</literal><emphasis>ann</emphasis><literal>"</literal>&#160;<literal>in</literal>&#160;<emphasis>basdec</emphasis>&#160;<literal>end</literal>\r
15924merges the annotation <emphasis>ann</emphasis> with the "current" annotation environment\r
15925for the elaboration of <emphasis>basdec</emphasis>. To allow for future expansion,\r
15926<literal>"</literal><emphasis>ann</emphasis><literal>"</literal> is lexed as a single SML string constant. To\r
15927conveniently specify multiple annotations, the following derived form\r
15928is provided:</simpara>\r
15929<sidebar>\r
15930<simpara><literal>ann</literal> <literal>"</literal><emphasis>ann</emphasis><literal>"</literal> (<literal>"</literal><emphasis>ann</emphasis><literal>"</literal> )<superscript>+</superscript> <literal>in</literal> <emphasis>basdec</emphasis> <literal>end</literal>\r
15931&#8658;\r
15932<literal>ann</literal> <literal>"</literal><emphasis>ann</emphasis><literal>"</literal> <literal>in</literal> <literal>ann</literal> (<literal>"</literal><emphasis>ann</emphasis><literal>"</literal>)<superscript>+</superscript> <literal>in</literal> <emphasis>basdec</emphasis> <literal>end</literal> <literal>end</literal></simpara>\r
15933</sidebar>\r
15934<simpara>Here are the available annotations. In the explanation below, for\r
15935annotations that take an argument, the first value listed is the\r
15936default.</simpara>\r
15937<itemizedlist>\r
15938<listitem>\r
15939<simpara>\r
15940<literal>allowFFI {false|true}</literal>\r
15941</simpara>\r
15942<simpara>If <literal>true</literal>, allow <literal>_address</literal>, <literal>_export</literal>, <literal>_import</literal>, and <literal>_symbol</literal>\r
15943expressions to appear in source files. See\r
15944<link linkend="ForeignFunctionInterface">ForeignFunctionInterface</link>.</simpara>\r
15945</listitem>\r
15946<listitem>\r
15947<simpara>\r
15948<literal>allowSuccessorML {false|true}</literal>\r
15949</simpara>\r
15950<simpara>Allow or disallow all of the <link linkend="SuccessorML">SuccessorML</link> features. This is a\r
15951proxy for all of the following annotations.</simpara>\r
15952<itemizedlist>\r
15953<listitem>\r
15954<simpara>\r
15955<literal>allowDoDecls {false|true}</literal>\r
15956</simpara>\r
15957<simpara>If <literal>true</literal>, allow a <literal>do <emphasis>exp</emphasis></literal> declaration form.</simpara>\r
15958</listitem>\r
15959<listitem>\r
15960<simpara>\r
15961<literal>allowExtendedConsts {false|true}</literal>\r
15962</simpara>\r
15963<simpara>Allow or disallow all of the extended constants features. This is a\r
15964proxy for all of the following annotations.</simpara>\r
15965<itemizedlist>\r
15966<listitem>\r
15967<simpara>\r
15968<literal>allowExtendedNumConsts {false|true}</literal>\r
15969</simpara>\r
15970<simpara>If <literal>true</literal>, allow extended numeric constants.</simpara>\r
15971</listitem>\r
15972<listitem>\r
15973<simpara>\r
15974<literal>allowExtendedTextConsts {false|true}</literal>\r
15975</simpara>\r
15976<simpara>If <literal>true</literal>, allow extended text constants.</simpara>\r
15977</listitem>\r
15978</itemizedlist>\r
15979</listitem>\r
15980<listitem>\r
15981<simpara>\r
15982<literal>allowLineComments {false|true}</literal>\r
15983</simpara>\r
15984<simpara>If <literal>true</literal>, allow line comments beginning with the token <literal>(*)</literal>.</simpara>\r
15985</listitem>\r
15986<listitem>\r
15987<simpara>\r
15988<literal>allowOptBar {false|true}</literal>\r
15989</simpara>\r
15990<simpara>If <literal>true</literal>, allow a bar to appear before the first match rule of a\r
15991<literal>case</literal>, <literal>fn</literal>, or <literal>handle</literal> expression, allow a bar to appear before the\r
15992first function-value binding of a <literal>fun</literal> declaration, and allow a bar\r
15993to appear before the first constructor binding or description of a\r
15994<literal>datatype</literal> declaration or specification.</simpara>\r
15995</listitem>\r
15996<listitem>\r
15997<simpara>\r
15998<literal>allowOptSemicolon {false|true}</literal>\r
15999</simpara>\r
16000<simpara>If <literal>true</literal>, allows a semicolon to appear after the last expression in a\r
16001sequence expression or <literal>let</literal> body.</simpara>\r
16002</listitem>\r
16003<listitem>\r
16004<simpara>\r
16005<literal>allowOrPats {false|true}</literal>\r
16006</simpara>\r
16007<simpara>If <literal>true</literal>, allows disjunctive (a.k.a., "or") patterns of the form\r
16008<literal><emphasis>pat</emphasis> | <emphasis>pat</emphasis></literal>.</simpara>\r
16009</listitem>\r
16010<listitem>\r
16011<simpara>\r
16012<literal>allowRecordPunExps {false|true}</literal>\r
16013</simpara>\r
16014<simpara>If <literal>true</literal>, allows record punning expressions.</simpara>\r
16015</listitem>\r
16016<listitem>\r
16017<simpara>\r
16018<literal>allowSigWithtype {false|true}</literal>\r
16019</simpara>\r
16020<simpara>If <literal>true</literal>, allows <literal>withtype</literal> to modify a <literal>datatype</literal> specification in a\r
16021signature.</simpara>\r
16022</listitem>\r
16023<listitem>\r
16024<simpara>\r
16025<literal>allowVectorExpsAndPats {false|true}</literal>\r
16026</simpara>\r
16027<simpara>Allow or disallow vector expressions and vector patterns. This is a\r
16028proxy for all of the following annotations.</simpara>\r
16029<itemizedlist>\r
16030<listitem>\r
16031<simpara>\r
16032<literal>allowVectorExps {false|true}</literal>\r
16033</simpara>\r
16034<simpara>If <literal>true</literal>, allow vector expressions.</simpara>\r
16035</listitem>\r
16036<listitem>\r
16037<simpara>\r
16038<literal>allowVectorPats {false|true}</literal>\r
16039</simpara>\r
16040<simpara>If <literal>true</literal>, allow vector patterns.</simpara>\r
16041</listitem>\r
16042</itemizedlist>\r
16043</listitem>\r
16044</itemizedlist>\r
16045</listitem>\r
16046<listitem>\r
16047<simpara>\r
16048<literal>forceUsed</literal>\r
16049</simpara>\r
16050<simpara>Force all identifiers in the basis denoted by the body of the <literal>ann</literal> to\r
16051be considered used; use in conjunction with <literal>warnUnused true</literal>.</simpara>\r
16052</listitem>\r
16053<listitem>\r
16054<simpara>\r
16055<literal>nonexhaustiveBind {warn|error|ignore}</literal>\r
16056</simpara>\r
16057<simpara>If <literal>error</literal> or <literal>warn</literal>, report nonexhaustive patterns in <literal>val</literal>\r
16058declarations (i.e., pattern-match failures that raise the <literal>Bind</literal>\r
16059exception). An error will abort a compile, while a warning will not.</simpara>\r
16060</listitem>\r
16061<listitem>\r
16062<simpara>\r
16063<literal>nonexhaustiveExnBind {default|ignore}</literal>\r
16064</simpara>\r
16065<simpara>If <literal>ignore</literal>, suppress errors and warnings about nonexhaustive matches\r
16066in <literal>val</literal> declarations that arise solely from unmatched exceptions.\r
16067If <literal>default</literal>, follow the behavior of <literal>nonexhaustiveBind</literal>.</simpara>\r
16068</listitem>\r
16069<listitem>\r
16070<simpara>\r
16071<literal>nonexhaustiveExnMatch {default|ignore}</literal>\r
16072</simpara>\r
16073<simpara>If <literal>ignore</literal>, suppress errors and warnings about nonexhaustive matches\r
16074in <literal>fn</literal> expressions, <literal>case</literal> expressions, and <literal>fun</literal> declarations that\r
16075arise solely from unmatched exceptions. If <literal>default</literal>, follow the\r
16076behavior of <literal>nonexhaustiveMatch</literal>.</simpara>\r
16077</listitem>\r
16078<listitem>\r
16079<simpara>\r
16080<literal>nonexhaustiveExnRaise {ignore|default}</literal>\r
16081</simpara>\r
16082<simpara>If <literal>ignore</literal>, suppress errors and warnings about nonexhaustive matches\r
16083in <literal>handle</literal> expressions that arise solely from unmatched exceptions.\r
16084If <literal>default</literal>, follow the behavior of <literal>nonexhaustiveRaise</literal>.</simpara>\r
16085</listitem>\r
16086<listitem>\r
16087<simpara>\r
16088<literal>nonexhaustiveMatch {warn|error|ignore}</literal>\r
16089</simpara>\r
16090<simpara>If <literal>error</literal> or <literal>warn</literal>, report nonexhaustive patterns in <literal>fn</literal>\r
16091expressions, <literal>case</literal> expressions, and <literal>fun</literal> declarations (i.e.,\r
16092pattern-match failures that raise the <literal>Match</literal> exception). An error\r
16093will abort a compile, while a warning will not.</simpara>\r
16094</listitem>\r
16095<listitem>\r
16096<simpara>\r
16097<literal>nonexhaustiveRaise {ignore|warn|error}</literal>\r
16098</simpara>\r
16099<simpara>If <literal>error</literal> or <literal>warn</literal>, report nonexhaustive patterns in <literal>handle</literal>\r
16100expressions (i.e., pattern-match failures that implicitly (re)raise\r
16101the unmatched exception). An error will abort a compile, while a\r
16102warning will not.</simpara>\r
16103</listitem>\r
16104<listitem>\r
16105<simpara>\r
16106<literal>redundantBind {warn|error|ignore}</literal>\r
16107</simpara>\r
16108<simpara>If <literal>error</literal> or <literal>warn</literal>, report redundant patterns in <literal>val</literal> declarations.\r
16109An error will abort a compile, while a warning will not.</simpara>\r
16110</listitem>\r
16111<listitem>\r
16112<simpara>\r
16113<literal>redundantMatch {warn|error|ignore}</literal>\r
16114</simpara>\r
16115<simpara>If <literal>error</literal> or <literal>warn</literal>, report redundant patterns in <literal>fn</literal> expressions,\r
16116<literal>case</literal> expressions, and <literal>fun</literal> declarations. An error will abort a\r
16117compile, while a warning will not.</simpara>\r
16118</listitem>\r
16119<listitem>\r
16120<simpara>\r
16121<literal>redundantRaise {warn|error|ignore}</literal>\r
16122</simpara>\r
16123<simpara>If <literal>error</literal> or <literal>warn</literal>, report redundant patterns in <literal>handle</literal>\r
16124expressions. An error will abort a compile, while a warning will not.</simpara>\r
16125</listitem>\r
16126<listitem>\r
16127<simpara>\r
16128<literal>resolveScope {strdec|dec|topdec|program}</literal>\r
16129</simpara>\r
16130<simpara>Used to control the scope at which overload constraints are resolved\r
16131to default types (if not otherwise resolved by type inference) and the\r
16132scope at which unresolved flexible record constraints are reported.</simpara>\r
16133<simpara>The syntactic-class argument means to perform resolution checks at the\r
16134smallest enclosing syntactic form of the given class. The default\r
16135behavior is to resolve at the smallest enclosing <emphasis>strdec</emphasis> (which is\r
16136equivalent to the largest enclosing <emphasis>dec</emphasis>). Other useful behaviors\r
16137are to resolve at the smallest enclosing <emphasis>topdec</emphasis> (which is equivalent\r
16138to the largest enclosing <emphasis>strdec</emphasis>) and at the smallest enclosing\r
16139<emphasis>program</emphasis> (which corresponds to a single <literal>.sml</literal> file and does not\r
16140correspond to the whole <literal>.mlb</literal> program).</simpara>\r
16141</listitem>\r
16142<listitem>\r
16143<simpara>\r
16144<literal>sequenceNonUnit {ignore|error|warn}</literal>\r
16145</simpara>\r
16146<simpara>If <literal>error</literal> or <literal>warn</literal>, report when <literal>e1</literal> is not of type <literal>unit</literal> in the\r
16147sequence expression <literal>(e1; e2)</literal>. This can be helpful in detecting\r
16148curried applications that are mistakenly not fully applied. To\r
16149silence spurious messages, you can use <literal>ignore e1</literal>.</simpara>\r
16150</listitem>\r
16151<listitem>\r
16152<simpara>\r
16153<literal>valrecConstr {warn|error|ignore}</literal>\r
16154</simpara>\r
16155<simpara>If <literal>error</literal> or <literal>warn</literal>, report when a <literal>val rec</literal> (or <literal>fun</literal>) declaration\r
16156redefines an identifier that previously had constructor status. An\r
16157error will abort a compile, while a warning will not.</simpara>\r
16158</listitem>\r
16159<listitem>\r
16160<simpara>\r
16161<literal>warnUnused {false|true}</literal>\r
16162</simpara>\r
16163<simpara>Report unused identifiers.</simpara>\r
16164</listitem>\r
16165</itemizedlist>\r
16166<section id="_next_steps_5">\r
16167<title>Next Steps</title>\r
16168<itemizedlist>\r
16169<listitem>\r
16170<simpara>\r
16171<link linkend="MLBasisAnnotationExamples">MLBasisAnnotationExamples</link>\r
16172</simpara>\r
16173</listitem>\r
16174<listitem>\r
16175<simpara>\r
16176<link linkend="WarnUnusedAnomalies">WarnUnusedAnomalies</link>\r
16177</simpara>\r
16178</listitem>\r
16179</itemizedlist>\r
16180<simpara><?asciidoc-pagebreak?></simpara>\r
16181</section>\r
16182</section>\r
16183<section id="MLBasisAvailableLibraries">\r
16184<title>MLBasisAvailableLibraries</title>\r
16185<simpara>MLton comes with the following <link linkend="MLBasis">ML Basis</link> files available.</simpara>\r
16186<itemizedlist>\r
16187<listitem>\r
16188<simpara>\r
16189<literal>$(SML_LIB)/basis/basis.mlb</literal>\r
16190</simpara>\r
16191<simpara>The <link linkend="BasisLibrary">Basis Library</link>.</simpara>\r
16192</listitem>\r
16193<listitem>\r
16194<simpara>\r
16195<literal>$(SML_LIB)/basis/basis-1997.mlb</literal>\r
16196</simpara>\r
16197<simpara>The (deprecated) 1997 version of the <link linkend="BasisLibrary">Basis Library</link>.</simpara>\r
16198</listitem>\r
16199<listitem>\r
16200<simpara>\r
16201<literal>$(SML_LIB)/basis/mlton.mlb</literal>\r
16202</simpara>\r
16203<simpara>The <link linkend="MLtonStructure">MLton</link> structure and signatures.</simpara>\r
16204</listitem>\r
16205<listitem>\r
16206<simpara>\r
16207<literal>$(SML_LIB)/basis/c-types.mlb</literal>\r
16208</simpara>\r
16209<simpara>Various structure aliases useful as <link linkend="ForeignFunctionInterfaceTypes">ForeignFunctionInterfaceTypes</link>.</simpara>\r
16210</listitem>\r
16211<listitem>\r
16212<simpara>\r
16213<literal>$(SML_LIB)/basis/unsafe.mlb</literal>\r
16214</simpara>\r
16215<simpara>The <link linkend="UnsafeStructure">Unsafe</link> structure and signature.</simpara>\r
16216</listitem>\r
16217<listitem>\r
16218<simpara>\r
16219<literal>$(SML_LIB)/basis/sml-nj.mlb</literal>\r
16220</simpara>\r
16221<simpara>The <link linkend="SMLofNJStructure">SMLofNJ</link> structure and signature.</simpara>\r
16222</listitem>\r
16223<listitem>\r
16224<simpara>\r
16225<literal>$(SML_LIB)/mlyacc-lib/mlyacc-lib.mlb</literal>\r
16226</simpara>\r
16227<simpara>Modules used by parsers built with <link linkend="MLYacc">MLYacc</link>.</simpara>\r
16228</listitem>\r
16229<listitem>\r
16230<simpara>\r
16231<literal>$(SML_LIB)/cml/cml.mlb</literal>\r
16232</simpara>\r
16233<simpara><link linkend="ConcurrentML">ConcurrentML</link>, a library for message-passing concurrency.</simpara>\r
16234</listitem>\r
16235<listitem>\r
16236<simpara>\r
16237<literal>$(SML_LIB)/mlnlffi-lib/mlnlffi-lib.mlb</literal>\r
16238</simpara>\r
16239<simpara><link linkend="MLNLFFI">ML-NLFFI</link>, a library for foreign function interfaces.</simpara>\r
16240</listitem>\r
16241<listitem>\r
16242<simpara>\r
16243<literal>$(SML_LIB)/mlrisc-lib/...</literal>\r
16244</simpara>\r
16245<simpara><link linkend="MLRISCLibrary">MLRISCLibrary</link>, a library for retargetable and optimizing compiler back ends.</simpara>\r
16246</listitem>\r
16247<listitem>\r
16248<simpara>\r
16249<literal>$(SML_LIB)/smlnj-lib/...</literal>\r
16250</simpara>\r
16251<simpara><link linkend="SMLNJLibrary">SMLNJLibrary</link>, a collection of libraries distributed with SML/NJ.</simpara>\r
16252</listitem>\r
16253<listitem>\r
16254<simpara>\r
16255<literal>$(SML_LIB)/ckit-lib/ckit-lib.mlb</literal>\r
16256</simpara>\r
16257<simpara><link linkend="CKitLibrary">CKitLibrary</link>, a library for C source code.</simpara>\r
16258</listitem>\r
16259<listitem>\r
16260<simpara>\r
16261<literal>$(SML_LIB)/mllpt-lib/mllpt-lib.mlb</literal>\r
16262</simpara>\r
16263<simpara><link linkend="MLLPTLibrary">MLLPTLibrary</link>, a support library for the <link linkend="MLULex">MLULex</link> scanner generator and the <link linkend="MLAntlr">MLAntlr</link> parser generator.</simpara>\r
16264</listitem>\r
16265</itemizedlist>\r
16266<section id="_basis_fragments">\r
16267<title>Basis fragments</title>\r
16268<simpara>There are a number of specialized ML Basis files for importing\r
16269fragments of the <link linkend="BasisLibrary">Basis Library</link> that can not be\r
16270expressed within SML.</simpara>\r
16271<itemizedlist>\r
16272<listitem>\r
16273<simpara>\r
16274<literal>$(SML_LIB)/basis/pervasive-types.mlb</literal>\r
16275</simpara>\r
16276<simpara>The top-level types and constructors of the Basis Library.</simpara>\r
16277</listitem>\r
16278<listitem>\r
16279<simpara>\r
16280<literal>$(SML_LIB)/basis/pervasive-exns.mlb</literal>\r
16281</simpara>\r
16282<simpara>The top-level exception constructors of the Basis Library.</simpara>\r
16283</listitem>\r
16284<listitem>\r
16285<simpara>\r
16286<literal>$(SML_LIB)/basis/pervasive-vals.mlb</literal>\r
16287</simpara>\r
16288<simpara>The top-level values of the Basis Library, without infix status.</simpara>\r
16289</listitem>\r
16290<listitem>\r
16291<simpara>\r
16292<literal>$(SML_LIB)/basis/overloads.mlb</literal>\r
16293</simpara>\r
16294<simpara>The top-level overloaded values of the Basis Library, without infix status.</simpara>\r
16295</listitem>\r
16296<listitem>\r
16297<simpara>\r
16298<literal>$(SML_LIB)/basis/equal.mlb</literal>\r
16299</simpara>\r
16300<simpara>The polymorphic equality <literal>=</literal> and inequality <literal>&lt;&gt;</literal> values, without infix status.</simpara>\r
16301</listitem>\r
16302<listitem>\r
16303<simpara>\r
16304<literal>$(SML_LIB)/basis/infixes.mlb</literal>\r
16305</simpara>\r
16306<simpara>The infix declarations of the Basis Library.</simpara>\r
16307</listitem>\r
16308<listitem>\r
16309<simpara>\r
16310<literal>$(SML_LIB)/basis/pervasive.mlb</literal>\r
16311</simpara>\r
16312<simpara>The entire top-level value and type environment of the Basis Library, with infix status. This is the same as importing the above six MLB files.</simpara>\r
16313</listitem>\r
16314</itemizedlist>\r
16315<simpara><?asciidoc-pagebreak?></simpara>\r
16316</section>\r
16317</section>\r
16318<section id="MLBasisExamples">\r
16319<title>MLBasisExamples</title>\r
16320<simpara>Here are some example uses of <link linkend="MLBasis">ML Basis</link> files.</simpara>\r
16321<section id="_complete_program">\r
16322<title>Complete program</title>\r
16323<simpara>Suppose your complete program consists of the files <literal>file1.sml</literal>, &#8230;,\r
16324<literal>filen.sml</literal>, which depend upon libraries <literal>lib1.mlb</literal>, &#8230;, <literal>libm.mlb</literal>.</simpara>\r
16325<screen>(* import libraries *)\r
16326lib1.mlb\r
16327...\r
16328libm.mlb\r
16329\r
16330(* program files *)\r
16331file1.sml\r
16332...\r
16333filen.sml</screen>\r
16334<simpara>The bases denoted by <literal>lib1.mlb</literal>, &#8230;, <literal>libm.mlb</literal> are merged (bindings\r
16335of names in later bases take precedence over bindings of the same name\r
16336in earlier bases), producing a basis in which <literal>file1.sml</literal>, &#8230;,\r
16337<literal>filen.sml</literal> are elaborated, adding additional bindings to the basis.</simpara>\r
16338</section>\r
16339<section id="_export_filter">\r
16340<title>Export filter</title>\r
16341<simpara>Suppose you only want to export certain structures, signatures, and\r
16342functors from a collection of files.</simpara>\r
16343<screen>local\r
16344 file1.sml\r
16345 ...\r
16346 filen.sml\r
16347in\r
16348 (* export filter here *)\r
16349 functor F\r
16350 structure S\r
16351end</screen>\r
16352<simpara>While <literal>file1.sml</literal>, &#8230;, <literal>filen.sml</literal> may declare top-level identifiers\r
16353in addition to <literal>F</literal> and <literal>S</literal>, such names are not accessible to programs\r
16354and libraries that import this <literal>.mlb</literal>.</simpara>\r
16355</section>\r
16356<section id="_export_filter_with_renaming">\r
16357<title>Export filter with renaming</title>\r
16358<simpara>Suppose you want an export filter, but want to rename one of the\r
16359modules.</simpara>\r
16360<screen>local\r
16361 file1.sml\r
16362 ...\r
16363 filen.sml\r
16364in\r
16365 (* export filter, with renaming, here *)\r
16366 functor F\r
16367 structure S' = S\r
16368end</screen>\r
16369<simpara>Note that <literal>functor F</literal> is an abbreviation for <literal>functor F = F</literal>, which\r
16370simply exports an identifier under the same name.</simpara>\r
16371</section>\r
16372<section id="_import_filter">\r
16373<title>Import filter</title>\r
16374<simpara>Suppose you only want to import a functor <literal>F</literal> from one library and a\r
16375structure <literal>S</literal> from another library.</simpara>\r
16376<screen>local\r
16377 lib1.mlb\r
16378in\r
16379 (* import filter here *)\r
16380 functor F\r
16381end\r
16382local\r
16383 lib2.mlb\r
16384in\r
16385 (* import filter here *)\r
16386 structure S\r
16387end\r
16388file1.sml\r
16389...\r
16390filen.sml</screen>\r
16391</section>\r
16392<section id="_import_filter_with_renaming">\r
16393<title>Import filter with renaming</title>\r
16394<simpara>Suppose you want to import a structure <literal>S</literal> from one library and\r
16395another structure <literal>S</literal> from another library.</simpara>\r
16396<screen>local\r
16397 lib1.mlb\r
16398in\r
16399 (* import filter, with renaming, here *)\r
16400 structure S1 = S\r
16401end\r
16402local\r
16403 lib2.mlb\r
16404in\r
16405 (* import filter, with renaming, here *)\r
16406 structure S2 = S\r
16407end\r
16408file1.sml\r
16409...\r
16410filen.sml</screen>\r
16411</section>\r
16412<section id="_full_basis">\r
16413<title>Full Basis</title>\r
16414<simpara>Since the Modules level of SML is the natural means for organizing\r
16415program and library components, MLB files provide convenient syntax\r
16416for renaming Modules level identifiers (in fact, renaming of functor\r
16417identifiers provides a mechanism that is not available in SML).\r
16418However, please note that <literal>.mlb</literal> files elaborate to full bases\r
16419including top-level types and values (including infix status), in\r
16420addition to structures, signatures, and functors. For example,\r
16421suppose you wished to extend the <link linkend="BasisLibrary">Basis Library</link> with an\r
16422<literal>('a, 'b) either</literal> datatype corresponding to a disjoint sum; the type\r
16423and some operations should be available at the top-level;\r
16424additionally, a signature and structure provide the complete\r
16425interface.</simpara>\r
16426<simpara>We could use the following files.</simpara>\r
16427<simpara><literal>either-sigs.sml</literal></simpara>\r
16428<programlisting language="sml" linenumbering="unnumbered">signature EITHER_GLOBAL =\r
16429 sig\r
16430 datatype ('a, 'b) either = Left of 'a | Right of 'b\r
16431 val &amp; : ('a -&gt; 'c) * ('b -&gt; 'c) -&gt; ('a, 'b) either -&gt; 'c\r
16432 val &amp;&amp; : ('a -&gt; 'c) * ('b -&gt; 'd) -&gt; ('a, 'b) either -&gt; ('c, 'd) either\r
16433 end\r
16434\r
16435signature EITHER =\r
16436 sig\r
16437 include EITHER_GLOBAL\r
16438 val isLeft : ('a, 'b) either -&gt; bool\r
16439 val isRight : ('a, 'b) either -&gt; bool\r
16440 ...\r
16441 end</programlisting>\r
16442<simpara><literal>either-strs.sml</literal></simpara>\r
16443<programlisting language="sml" linenumbering="unnumbered">structure Either : EITHER =\r
16444 struct\r
16445 datatype ('a, 'b) either = Left of 'a | Right of 'b\r
16446 fun f &amp; g = fn x =&gt;\r
16447 case x of Left z =&gt; f z | Right z =&gt; g z\r
16448 fun f &amp;&amp; g = (Left o f) &amp; (Right o g)\r
16449 fun isLeft x = ((fn _ =&gt; true) &amp; (fn _ =&gt; false)) x\r
16450 fun isRight x = (not o isLeft) x\r
16451 ...\r
16452 end\r
16453structure EitherGlobal : EITHER_GLOBAL = Either</programlisting>\r
16454<simpara><literal>either-infixes.sml</literal></simpara>\r
16455<programlisting language="sml" linenumbering="unnumbered">infixr 3 &amp; &amp;&amp;</programlisting>\r
16456<simpara><literal>either-open.sml</literal></simpara>\r
16457<programlisting language="sml" linenumbering="unnumbered">open EitherGlobal</programlisting>\r
16458<simpara><literal>either.mlb</literal></simpara>\r
16459<screen>either-infixes.sml\r
16460local\r
16461 (* import Basis Library *)\r
16462 $(SML_LIB)/basis/basis.mlb\r
16463 either-sigs.sml\r
16464 either-strs.sml\r
16465in\r
16466 signature EITHER\r
16467 structure Either\r
16468 either-open.sml\r
16469end</screen>\r
16470<simpara>A client that imports <literal>either.mlb</literal> will have access to neither\r
16471<literal>EITHER_GLOBAL</literal> nor <literal>EitherGlobal</literal>, but will have access to the type\r
16472<literal>either</literal> and the values <literal>&amp;</literal> and <literal>&amp;&amp;</literal> (with infix status) in the\r
16473top-level environment. Note that <literal>either-infixes.sml</literal> is outside the\r
16474scope of the local, because we want the infixes available in the\r
16475implementation of the library and to clients of the library.</simpara>\r
16476<simpara><?asciidoc-pagebreak?></simpara>\r
16477</section>\r
16478</section>\r
16479<section id="MLBasisPathMap">\r
16480<title>MLBasisPathMap</title>\r
16481<simpara>An <link linkend="MLBasis">ML Basis</link> <emphasis>path map</emphasis> describes a map from ML Basis path\r
16482variables (of the form <literal>$(VAR)</literal>) to file system paths. ML Basis path\r
16483variables provide a flexible way to refer to libraries while allowing\r
16484them to be moved without changing their clients.</simpara>\r
16485<simpara>The format of an <literal>mlb-path-map</literal> file is a sequence of lines; each line\r
16486consists of two, white-space delimited tokens. The first token is a\r
16487path variable <literal>VAR</literal> and the second token is the path to which the\r
16488variable is mapped. The path may include path variables, which are\r
16489recursively expanded.</simpara>\r
16490<simpara>The mapping from path variables to paths is initialized by the compiler.\r
16491Additional path maps can be specified with <literal>-mlb-path-map</literal> and\r
16492individual path variable mappings can be specified with\r
16493<literal>-mlb-path-var</literal> (see <link linkend="CompileTimeOptions">CompileTimeOptions</link>). Configuration files are\r
16494processed from first to last and from top to bottom, later mappings\r
16495take precedence over earlier mappings.</simpara>\r
16496<simpara>The compiler and system-wide configuration file makes the following\r
16497path variables available.</simpara>\r
16498<informaltable\r
16499frame="all"\r
16500rowsep="1" colsep="1"\r
16501>\r
16502<tgroup cols="2">\r
16503<colspec colname="col_1" colwidth="25*"/>\r
16504<colspec colname="col_2" colwidth="75*"/>\r
16505<thead>\r
16506<row>\r
16507<entry align="center" valign="top">MLB path variable</entry>\r
16508<entry align="left" valign="top">Description</entry>\r
16509</row>\r
16510</thead>\r
16511<tbody>\r
16512<row>\r
16513<entry align="center" valign="top"><simpara><literal>SML_LIB</literal></simpara></entry>\r
16514<entry align="left" valign="top"><simpara>path to system-wide libraries, usually <literal>/usr/lib/mlton/sml</literal></simpara></entry>\r
16515</row>\r
16516<row>\r
16517<entry align="center" valign="top"><simpara><literal>TARGET_ARCH</literal></simpara></entry>\r
16518<entry align="left" valign="top"><simpara>string representation of target architecture</simpara></entry>\r
16519</row>\r
16520<row>\r
16521<entry align="center" valign="top"><simpara><literal>TARGET_OS</literal></simpara></entry>\r
16522<entry align="left" valign="top"><simpara>string representation of target operating system</simpara></entry>\r
16523</row>\r
16524<row>\r
16525<entry align="center" valign="top"><simpara><literal>DEFAULT_INT</literal></simpara></entry>\r
16526<entry align="left" valign="top"><simpara>binding for default int, usually <literal>int32</literal></simpara></entry>\r
16527</row>\r
16528<row>\r
16529<entry align="center" valign="top"><simpara><literal>DEFAULT_WORD</literal></simpara></entry>\r
16530<entry align="left" valign="top"><simpara>binding for default word, usually <literal>word32</literal></simpara></entry>\r
16531</row>\r
16532<row>\r
16533<entry align="center" valign="top"><simpara><literal>DEFAULT_REAL</literal></simpara></entry>\r
16534<entry align="left" valign="top"><simpara>binding for default real, usually <literal>real64</literal></simpara></entry>\r
16535</row>\r
16536</tbody>\r
16537</tgroup>\r
16538</informaltable>\r
16539<simpara><?asciidoc-pagebreak?></simpara>\r
16540</section>\r
16541<section id="MLBasisSyntaxAndSemantics">\r
16542<title>MLBasisSyntaxAndSemantics</title>\r
16543<simpara>An <link linkend="MLBasis">ML Basis</link> (MLB) file should have the <literal>.mlb</literal> suffix and\r
16544should contain a basis declaration.</simpara>\r
16545<section id="_syntax">\r
16546<title>Syntax</title>\r
16547<simpara>A basis declaration (<emphasis>basdec</emphasis>) must be one of the following forms.</simpara>\r
16548<itemizedlist>\r
16549<listitem>\r
16550<simpara>\r
16551<literal>basis</literal> <emphasis>basid</emphasis> <literal>=</literal> <emphasis>basexp</emphasis> (<literal>and</literal> <emphasis>basid</emphasis> <literal>=</literal> <emphasis>basexp</emphasis>)<superscript>*</superscript>\r
16552</simpara>\r
16553</listitem>\r
16554<listitem>\r
16555<simpara>\r
16556<literal>open</literal> <emphasis>basid<subscript>1</subscript></emphasis> &#8230; <emphasis>basid<subscript>n</subscript></emphasis>\r
16557</simpara>\r
16558</listitem>\r
16559<listitem>\r
16560<simpara>\r
16561<literal>local</literal> <emphasis>basdec</emphasis> <literal>in</literal> <emphasis>basdec</emphasis> <literal>end</literal>\r
16562</simpara>\r
16563</listitem>\r
16564<listitem>\r
16565<simpara>\r
16566<emphasis>basdec</emphasis> [<literal>;</literal>] <emphasis>basdec</emphasis>\r
16567</simpara>\r
16568</listitem>\r
16569<listitem>\r
16570<simpara>\r
16571<literal>structure</literal> <emphasis>strid</emphasis> [<literal>=</literal> <emphasis>strid</emphasis>] (<literal>and</literal> <emphasis>strid</emphasis>[<literal>=</literal> <emphasis>strid</emphasis>])<superscript>*</superscript>\r
16572</simpara>\r
16573</listitem>\r
16574<listitem>\r
16575<simpara>\r
16576<literal>signature</literal> <emphasis>sigid</emphasis> [<literal>=</literal> <emphasis>sigid</emphasis>] (<literal>and</literal> <emphasis>sigid</emphasis> [<literal>=</literal> <emphasis>sigid</emphasis>])<superscript>*</superscript>\r
16577</simpara>\r
16578</listitem>\r
16579<listitem>\r
16580<simpara>\r
16581<literal>functor</literal> <emphasis>funid</emphasis> [<literal>=</literal> <emphasis>funid</emphasis>] (<literal>and</literal> <emphasis>funid</emphasis> [<literal>=</literal> <emphasis>funid</emphasis>])<superscript>*</superscript>\r
16582</simpara>\r
16583</listitem>\r
16584<listitem>\r
16585<simpara>\r
16586<emphasis>path</emphasis><literal>.sml</literal>, <emphasis>path</emphasis><literal>.sig</literal>, or <emphasis>path</emphasis><literal>.fun</literal>\r
16587</simpara>\r
16588</listitem>\r
16589<listitem>\r
16590<simpara>\r
16591<emphasis>path</emphasis><literal>.mlb</literal>\r
16592</simpara>\r
16593</listitem>\r
16594<listitem>\r
16595<simpara>\r
16596<literal>ann</literal> <literal>"</literal><emphasis>ann</emphasis><literal>"</literal> <literal>in</literal> <emphasis>basdec</emphasis> <literal>end</literal>\r
16597</simpara>\r
16598</listitem>\r
16599</itemizedlist>\r
16600<simpara>A basis expression (<emphasis>basexp</emphasis>) must be of one the following forms.</simpara>\r
16601<itemizedlist>\r
16602<listitem>\r
16603<simpara>\r
16604<literal>bas</literal> <emphasis>basdec</emphasis> <literal>end</literal>\r
16605</simpara>\r
16606</listitem>\r
16607<listitem>\r
16608<simpara>\r
16609<emphasis>basid</emphasis>\r
16610</simpara>\r
16611</listitem>\r
16612<listitem>\r
16613<simpara>\r
16614<literal>let</literal> <emphasis>basdec</emphasis> <literal>in</literal> <emphasis>basexp</emphasis> <literal>end</literal>\r
16615</simpara>\r
16616</listitem>\r
16617</itemizedlist>\r
16618<simpara>Nested SML-style comments (enclosed with <literal>(*</literal> and <literal>*)</literal>) are ignored\r
16619(but <link linkend="LineDirective">LineDirective</link>s are recognized).</simpara>\r
16620<simpara>Paths can be relative or absolute. Relative paths are relative to the\r
16621directory containing the MLB file. Paths may include path variables\r
16622and are expanded according to a <link linkend="MLBasisPathMap">path map</link>. Unquoted\r
16623paths may include alpha-numeric characters and the symbols "<literal>-</literal>" and\r
16624"<literal>_</literal>", along with the arc separator "<literal>/</literal>" and extension separator\r
16625"<literal>.</literal>". More complicated paths, including paths with spaces, may be\r
16626included by quoting the path with <literal>"</literal>. A quoted path is lexed as an\r
16627SML string constant.</simpara>\r
16628<simpara><link linkend="MLBasisAnnotations">Annotations</link> allow a library author to\r
16629control options that affect the elaboration of SML source files.</simpara>\r
16630</section>\r
16631<section id="_semantics">\r
16632<title>Semantics</title>\r
16633<simpara>There is a <ulink url="guide/MLBasis.attachments/mlb-formal.pdf">formal semantics</ulink> for\r
16634ML Basis files in the style of the\r
16635<link linkend="DefinitionOfStandardML">Definition</link>. Here, we give an informal\r
16636explanation.</simpara>\r
16637<simpara>An SML structure is a collection of types, values, and other\r
16638structures. Similarly, a basis is a collection, but of more kinds of\r
16639objects: types, values, structures, fixities, signatures, functors,\r
16640and other bases.</simpara>\r
16641<simpara>A basis declaration denotes a basis. A structure, signature, or\r
16642functor declaration denotes a basis containing the corresponding\r
16643module. Sequencing of basis declarations merges bases, with later\r
16644definitions taking precedence over earlier ones, just like sequencing\r
16645of SML declarations. Local declarations provide name hiding, just\r
16646like SML local declarations. A reference to an SML source file causes\r
16647the file to be elaborated in the basis extant at the point of\r
16648reference. A reference to an MLB file causes the basis denoted by\r
16649that MLB file to be imported&#8201;&#8212;&#8201;the basis at the point of reference\r
16650does <emphasis>not</emphasis> affect the imported basis.</simpara>\r
16651<simpara>Basis expressions and basis identifiers allow binding a basis to a\r
16652name.</simpara>\r
16653<simpara>An MLB file is elaborated starting in an empty basis. Each MLB file\r
16654is elaborated and evaluated only once, with the result being cached.\r
16655Subsequent references use the cached value. Thus, any observable\r
16656effects due to evaluation are not duplicated if the MLB file is\r
16657referred to multiple times.</simpara>\r
16658<simpara><?asciidoc-pagebreak?></simpara>\r
16659</section>\r
16660</section>\r
16661<section id="MLj">\r
16662<title>MLj</title>\r
16663<simpara><ulink url="http://www.dcs.ed.ac.uk/home/mlj/">MLj</ulink> is a\r
16664<link linkend="StandardMLImplementations">Standard ML implementation</link> that targets\r
16665Java bytecode. It is no longer maintained. It has morphed into\r
16666<link linkend="SMLNET">SML.NET</link>.</simpara>\r
16667<section id="_also_see_12">\r
16668<title>Also see</title>\r
16669<itemizedlist>\r
16670<listitem>\r
16671<simpara>\r
16672<link linkend="References_BentonEtAl98">BentonEtAl98</link>\r
16673</simpara>\r
16674</listitem>\r
16675<listitem>\r
16676<simpara>\r
16677<link linkend="References_BentonKennedy99">BentonKennedy99</link>\r
16678</simpara>\r
16679</listitem>\r
16680</itemizedlist>\r
16681<simpara><?asciidoc-pagebreak?></simpara>\r
16682</section>\r
16683</section>\r
16684<section id="MLKit">\r
16685<title>MLKit</title>\r
16686<simpara>The <ulink url="http://sourceforge.net/apps/mediawiki/mlkit">ML Kit</ulink> is a\r
16687<link linkend="StandardMLImplementations">Standard ML implementation</link>.</simpara>\r
16688<simpara>MLKit supports:</simpara>\r
16689<itemizedlist>\r
16690<listitem>\r
16691<simpara>\r
16692<link linkend="DefinitionOfStandardML">SML&#8217;97</link>\r
16693</simpara>\r
16694<itemizedlist>\r
16695<listitem>\r
16696<simpara>\r
16697including most of the latest <link linkend="BasisLibrary">Basis Library</link>\r
16698<ulink url="http://www.standardml.org/Basis">specification</ulink>,\r
16699</simpara>\r
16700</listitem>\r
16701</itemizedlist>\r
16702</listitem>\r
16703<listitem>\r
16704<simpara>\r
16705<link linkend="MLBasis">ML Basis</link> files\r
16706</simpara>\r
16707<itemizedlist>\r
16708<listitem>\r
16709<simpara>\r
16710and separate compilation,\r
16711</simpara>\r
16712</listitem>\r
16713</itemizedlist>\r
16714</listitem>\r
16715<listitem>\r
16716<simpara>\r
16717<link linkend="Regions">Region-Based Memory Management</link>\r
16718</simpara>\r
16719<itemizedlist>\r
16720<listitem>\r
16721<simpara>\r
16722and <link linkend="GarbageCollection">garbage collection</link>,\r
16723</simpara>\r
16724</listitem>\r
16725</itemizedlist>\r
16726</listitem>\r
16727<listitem>\r
16728<simpara>\r
16729Multiple backends, including\r
16730</simpara>\r
16731<itemizedlist>\r
16732<listitem>\r
16733<simpara>\r
16734native x86,\r
16735</simpara>\r
16736</listitem>\r
16737<listitem>\r
16738<simpara>\r
16739bytecode, and\r
16740</simpara>\r
16741</listitem>\r
16742<listitem>\r
16743<simpara>\r
16744JavaScript (see <ulink url="http://www.itu.dk/people/mael/smltojs/">SMLtoJs</ulink>).\r
16745</simpara>\r
16746</listitem>\r
16747</itemizedlist>\r
16748</listitem>\r
16749</itemizedlist>\r
16750<simpara>At the time of writing, MLKit does not support:</simpara>\r
16751<itemizedlist>\r
16752<listitem>\r
16753<simpara>\r
16754concurrent programming / threads,\r
16755</simpara>\r
16756</listitem>\r
16757<listitem>\r
16758<simpara>\r
16759calling from C to SML.\r
16760</simpara>\r
16761</listitem>\r
16762</itemizedlist>\r
16763<simpara><?asciidoc-pagebreak?></simpara>\r
16764</section>\r
16765<section id="MLLex">\r
16766<title>MLLex</title>\r
16767<simpara><link linkend="MLLex">MLLex</link> is a lexical analyzer generator for <link linkend="StandardML">Standard ML</link>\r
16768modeled after the Lex lexical analyzer generator.</simpara>\r
16769<simpara>A version of MLLex, ported from the <link linkend="SMLNJ">SML/NJ</link> sources, is\r
16770distributed with MLton.</simpara>\r
16771<section id="_description_37">\r
16772<title>Description</title>\r
16773<simpara>MLLex takes as input the lex language as defined in the ML-Lex manual,\r
16774and outputs a lexical analyzer in SML.</simpara>\r
16775</section>\r
16776<section id="_implementation_40">\r
16777<title>Implementation</title>\r
16778<itemizedlist>\r
16779<listitem>\r
16780<simpara>\r
16781<ulink url="https://github.com/MLton/mlton/blob/master/mllex/lexgen.sml"><literal>lexgen.sml</literal></ulink>\r
16782</simpara>\r
16783</listitem>\r
16784<listitem>\r
16785<simpara>\r
16786<ulink url="https://github.com/MLton/mlton/blob/master/mllex/main.sml"><literal>main.sml</literal></ulink>\r
16787</simpara>\r
16788</listitem>\r
16789<listitem>\r
16790<simpara>\r
16791<ulink url="https://github.com/MLton/mlton/blob/master/mllex/call-main.sml"><literal>call-main.sml</literal></ulink>\r
16792</simpara>\r
16793</listitem>\r
16794</itemizedlist>\r
16795</section>\r
16796<section id="_details_and_notes_40">\r
16797<title>Details and Notes</title>\r
16798<simpara>There are 3 main passes in the MLLex tool:</simpara>\r
16799<itemizedlist>\r
16800<listitem>\r
16801<simpara>\r
16802Source parsing. In this pass, lex source program are parsed into internal representations. The core part of this pass is a hand-written lexer and an LL(1) parser. The output of this pass is a record of user code, rules (along with start states) and actions. (MLLex definitions are wiped off.)\r
16803</simpara>\r
16804</listitem>\r
16805<listitem>\r
16806<simpara>\r
16807DFA construction. In this pass, a DFA is constructed by the algorithm of H. Yamada et. al.\r
16808</simpara>\r
16809</listitem>\r
16810<listitem>\r
16811<simpara>\r
16812Output. In this pass, the generated DFA is written out as a transition table, along with a table-driven algorithm, to an SML file.\r
16813</simpara>\r
16814</listitem>\r
16815</itemizedlist>\r
16816</section>\r
16817<section id="_also_see_13">\r
16818<title>Also see</title>\r
16819<itemizedlist>\r
16820<listitem>\r
16821<simpara>\r
16822<ulink url="guide/Documentation.attachments/mllex.pdf"><literal>mllex.pdf</literal></ulink>\r
16823</simpara>\r
16824</listitem>\r
16825<listitem>\r
16826<simpara>\r
16827<link linkend="MLYacc">MLYacc</link>\r
16828</simpara>\r
16829</listitem>\r
16830<listitem>\r
16831<simpara>\r
16832<link linkend="References_AppelEtAl94">AppelEtAl94</link>\r
16833</simpara>\r
16834</listitem>\r
16835<listitem>\r
16836<simpara>\r
16837<link linkend="References_Price09">Price09</link>\r
16838</simpara>\r
16839</listitem>\r
16840</itemizedlist>\r
16841<simpara><?asciidoc-pagebreak?></simpara>\r
16842</section>\r
16843</section>\r
16844<section id="MLLPTLibrary">\r
16845<title>MLLPTLibrary</title>\r
16846<simpara>The\r
16847<ulink url="http://smlnj-gforge.cs.uchicago.edu/projects/ml-lpt/">ML-LPT Library</ulink>\r
16848is a support library for the <link linkend="MLULex">MLULex</link> scanner generator and the\r
16849<link linkend="MLAntlr">MLAntlr</link> parser generator. The ML-LPT Library is distributed with\r
16850SML/NJ.</simpara>\r
16851<simpara>As of 20180119, MLton includes the ML-LPT Library synchronized with\r
16852SML/NJ version 110.82.</simpara>\r
16853<section id="_usage_5">\r
16854<title>Usage</title>\r
16855<itemizedlist>\r
16856<listitem>\r
16857<simpara>\r
16858You can import the ML-LPT Library into an MLB file with:\r
16859</simpara>\r
16860<informaltable\r
16861frame="all"\r
16862rowsep="1" colsep="1"\r
16863>\r
16864<tgroup cols="2">\r
16865<colspec colname="col_1" colwidth="50*"/>\r
16866<colspec colname="col_2" colwidth="50*"/>\r
16867<thead>\r
16868<row>\r
16869<entry align="left" valign="top">MLB file</entry>\r
16870<entry align="left" valign="top">Description</entry>\r
16871</row>\r
16872</thead>\r
16873<tbody>\r
16874<row>\r
16875<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/mllpt-lib/mllpt-lib.mlb</literal></simpara></entry>\r
16876<entry align="left" valign="top"><simpara></simpara></entry>\r
16877</row>\r
16878</tbody>\r
16879</tgroup>\r
16880</informaltable>\r
16881</listitem>\r
16882<listitem>\r
16883<simpara>\r
16884If you are porting a project from SML/NJ&#8217;s <link linkend="CompilationManager">CompilationManager</link> to\r
16885MLton&#8217;s <link linkend="MLBasis">ML Basis system</link> using <literal>cm2mlb</literal>, note that the\r
16886following map is included by default:\r
16887</simpara>\r
16888<screen># MLLPT Library\r
16889$ml-lpt-lib.cm $(SML_LIB)/mllpt-lib\r
16890$ml-lpt-lib.cm/ml-lpt-lib.cm $(SML_LIB)/mllpt-lib/mllpt-lib.mlb</screen>\r
16891<simpara>This will automatically convert a <literal>$/mllpt-lib.cm</literal> import in an input\r
16892<literal>.cm</literal> file into a <literal>$(SML_LIB)/mllpt-lib/mllpt-lib.mlb</literal> import in the\r
16893output <literal>.mlb</literal> file.</simpara>\r
16894</listitem>\r
16895</itemizedlist>\r
16896</section>\r
16897<section id="_details_2">\r
16898<title>Details</title>\r
16899<simpara></simpara>\r
16900</section>\r
16901<section id="_patch_2">\r
16902<title>Patch</title>\r
16903<itemizedlist>\r
16904<listitem>\r
16905<simpara>\r
16906<ulink url="https://github.com/MLton/mlton/blob/master/lib/mllpt-lib/ml-lpt.patch"><literal>ml-lpt.patch</literal></ulink>\r
16907</simpara>\r
16908</listitem>\r
16909</itemizedlist>\r
16910<simpara><?asciidoc-pagebreak?></simpara>\r
16911</section>\r
16912</section>\r
16913<section id="MLmon">\r
16914<title>MLmon</title>\r
16915<simpara>An <literal>mlmon.out</literal> file records dynamic <link linkend="Profiling">profiling</link> counts.</simpara>\r
16916<section id="_file_format">\r
16917<title>File format</title>\r
16918<simpara>An <literal>mlmon.out</literal> file is a text file with a sequence of lines.</simpara>\r
16919<itemizedlist>\r
16920<listitem>\r
16921<simpara>\r
16922The string "<literal>MLton prof</literal>".\r
16923</simpara>\r
16924</listitem>\r
16925<listitem>\r
16926<simpara>\r
16927The string "<literal>alloc</literal>", "<literal>count</literal>", or "<literal>time</literal>", depending on the kind\r
16928of profiling information, corresponding to the command-line argument\r
16929supplied to <literal>mlton -profile</literal>.\r
16930</simpara>\r
16931</listitem>\r
16932<listitem>\r
16933<simpara>\r
16934The string "<literal>current</literal>" or "<literal>stack</literal>" depending on whether profiling\r
16935data was gathered for only the current function (the top of the stack)\r
16936or for all functions on the stack. This corresponds to whether the\r
16937executable was compiled with <literal>-profile-stack false</literal> or <literal>-profile-stack\r
16938true</literal>.\r
16939</simpara>\r
16940</listitem>\r
16941<listitem>\r
16942<simpara>\r
16943The magic number of the executable.\r
16944</simpara>\r
16945</listitem>\r
16946<listitem>\r
16947<simpara>\r
16948The number of non-gc ticks, followed by a space, then the number of\r
16949GC ticks.\r
16950</simpara>\r
16951</listitem>\r
16952<listitem>\r
16953<simpara>\r
16954The number of (split) functions for which data is recorded.\r
16955</simpara>\r
16956</listitem>\r
16957<listitem>\r
16958<simpara>\r
16959A line for each (split) function with counts. Each line contains an\r
16960integer count of the number of ticks while the function was current.\r
16961In addition, if stack data was gathered (<literal>-profile-stack true</literal>), then\r
16962the line contains two additional tick counts:\r
16963</simpara>\r
16964<itemizedlist>\r
16965<listitem>\r
16966<simpara>\r
16967the number of ticks while the function was on the stack.\r
16968</simpara>\r
16969</listitem>\r
16970<listitem>\r
16971<simpara>\r
16972the number of ticks while the function was on the stack and a GC\r
16973 was performed.\r
16974</simpara>\r
16975</listitem>\r
16976</itemizedlist>\r
16977</listitem>\r
16978<listitem>\r
16979<simpara>\r
16980The number of (master) functions for which data is recorded.\r
16981</simpara>\r
16982</listitem>\r
16983<listitem>\r
16984<simpara>\r
16985A line for each (master) function with counts. The lines have the\r
16986same format and meaning as with split-function counts.\r
16987</simpara>\r
16988</listitem>\r
16989</itemizedlist>\r
16990<simpara><?asciidoc-pagebreak?></simpara>\r
16991</section>\r
16992</section>\r
16993<section id="MLNLFFI">\r
16994<title>MLNLFFI</title>\r
16995<simpara><link linkend="References_Blume01">ML-NLFFI</link> is the no-longer-foreign-function interface\r
16996library for SML.</simpara>\r
16997<simpara>As of 20050212, MLton has an initial port of ML-NLFFI from SML/NJ to\r
16998MLton. All of the ML-NLFFI functionality is present.</simpara>\r
16999<simpara>Additionally, MLton has an initial port of the\r
17000<link linkend="MLNLFFIGen">mlnlffigen</link> tool from SML/NJ to MLton. Due to low-level\r
17001details, the code generated by SML/NJ&#8217;s <literal>ml-nlffigen</literal> is not\r
17002compatible with MLton, and vice-versa. However, the generated code\r
17003has the same interface, so portable client code can be written.\r
17004MLton&#8217;s <literal>mlnlffigen</literal> does not currently support C functions with\r
17005<literal>struct</literal> or <literal>union</literal> arguments.</simpara>\r
17006<section id="_usage_6">\r
17007<title>Usage</title>\r
17008<itemizedlist>\r
17009<listitem>\r
17010<simpara>\r
17011You can import the ML-NLFFI Library into an MLB file with\r
17012</simpara>\r
17013<informaltable\r
17014frame="all"\r
17015rowsep="1" colsep="1"\r
17016>\r
17017<tgroup cols="2">\r
17018<colspec colname="col_1" colwidth="50*"/>\r
17019<colspec colname="col_2" colwidth="50*"/>\r
17020<thead>\r
17021<row>\r
17022<entry align="left" valign="top">MLB file</entry>\r
17023<entry align="left" valign="top">Description</entry>\r
17024</row>\r
17025</thead>\r
17026<tbody>\r
17027<row>\r
17028<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/mlnlffi-lib/mlnlffi-lib.mlb</literal></simpara></entry>\r
17029<entry align="left" valign="top"><simpara></simpara></entry>\r
17030</row>\r
17031</tbody>\r
17032</tgroup>\r
17033</informaltable>\r
17034</listitem>\r
17035<listitem>\r
17036<simpara>\r
17037If you are porting a project from SML/NJ&#8217;s <link linkend="CompilationManager">CompilationManager</link> to\r
17038MLton&#8217;s <link linkend="MLBasis">ML Basis system</link> using <literal>cm2mlb</literal>, note that the\r
17039following maps are included by default:\r
17040</simpara>\r
17041<screen># MLNLFFI Library\r
17042$c $(SML_LIB)/mlnlffi-lib\r
17043$c/c.cm $(SML_LIB)/mlnlffi-lib/mlnlffi-lib.mlb</screen>\r
17044<simpara>This will automatically convert a <literal>$/c.cm</literal> import in an input <literal>.cm</literal>\r
17045file into a <literal>$(SML_LIB)/mlnlffi-lib/mlnlffi-lib.mlb</literal> import in the\r
17046output <literal>.mlb</literal> file.</simpara>\r
17047</listitem>\r
17048</itemizedlist>\r
17049</section>\r
17050<section id="_also_see_14">\r
17051<title>Also see</title>\r
17052<itemizedlist>\r
17053<listitem>\r
17054<simpara>\r
17055<link linkend="References_Blume01">Blume01</link>\r
17056</simpara>\r
17057</listitem>\r
17058<listitem>\r
17059<simpara>\r
17060<link linkend="MLNLFFIImplementation">MLNLFFIImplementation</link>\r
17061</simpara>\r
17062</listitem>\r
17063<listitem>\r
17064<simpara>\r
17065<link linkend="MLNLFFIGen">MLNLFFIGen</link>\r
17066</simpara>\r
17067</listitem>\r
17068</itemizedlist>\r
17069<simpara><?asciidoc-pagebreak?></simpara>\r
17070</section>\r
17071</section>\r
17072<section id="MLNLFFIGen">\r
17073<title>MLNLFFIGen</title>\r
17074<simpara><literal>mlnlffigen</literal> generates a <link linkend="MLNLFFI">MLNLFFI</link> binding from a collection of <literal>.c</literal>\r
17075files. It is based on the <link linkend="CKitLibrary">CKitLibrary</link>, which is primarily designed\r
17076to handle standardized C and thus does not understand many (any?)\r
17077compiler extensions; however, it attempts to recover from errors when\r
17078seeing unrecognized definitions.</simpara>\r
17079<simpara>In order to work around common gcc extensions, it may be useful to add\r
17080<literal>-cppopt</literal> options to the command line; for example\r
17081<literal>-cppopt '-D__extension__'</literal> may be occasionally useful. Fortunately,\r
17082most portable libraries largely avoid the use of these types of\r
17083extensions in header files.</simpara>\r
17084<simpara><literal>mlnlffigen</literal> will normally not generate bindings for <literal>#included</literal>\r
17085files; see <literal>-match</literal> and <literal>-allSU</literal> if this is desirable.</simpara>\r
17086<simpara><?asciidoc-pagebreak?></simpara>\r
17087</section>\r
17088<section id="MLNLFFIImplementation">\r
17089<title>MLNLFFIImplementation</title>\r
17090<simpara>MLton&#8217;s implementation(s) of the <link linkend="MLNLFFI">MLNLFFI</link> library differs from the\r
17091SML/NJ implementation in two important ways:</simpara>\r
17092<itemizedlist>\r
17093<listitem>\r
17094<simpara>\r
17095MLton cannot utilize the <literal>Unsafe.cast</literal> "cheat" described in Section\r
170963.7 of <link linkend="References_Blume01">Blume01</link>. (MLton&#8217;s representation of\r
17097<link linkend="Closure">closures</link> and\r
17098<link linkend="PackedRepresentation">aggressive representation</link> optimizations make\r
17099an <literal>Unsafe.cast</literal> even more "unsafe" than in other implementations.)\r
17100</simpara>\r
17101<simpara>We have considered two solutions:</simpara>\r
17102<itemizedlist>\r
17103<listitem>\r
17104<simpara>\r
17105One solution is to utilize an additional type parameter (as\r
17106described in Section 3.7 of <link linkend="References_Blume01">Blume01</link>):\r
17107</simpara>\r
17108<blockquote>\r
17109<programlisting language="sml" linenumbering="unnumbered">signature C = sig\r
17110 type ('t, 'f, 'c) obj\r
17111 eqtype ('t, 'f, 'c) obj'\r
17112 ...\r
17113 type ('o, 'f) ptr\r
17114 eqtype ('o, 'f) ptr'\r
17115 ...\r
17116 type 'f fptr\r
17117 type 'f ptr'\r
17118 ...\r
17119 structure T : sig\r
17120 type ('t, 'f) typ\r
17121 ...\r
17122 end\r
17123end</programlisting>\r
17124<simpara>The rule for <literal>('t, 'f, 'c) obj</literal>,<literal>('t, 'f, 'c) ptr</literal>, and also <literal>('t, 'f)\r
17125T.typ</literal> is that whenever <literal>F fptr</literal> occurs within the instantiation of\r
17126<literal>'t</literal>, then <literal>'f</literal> must be instantiated to <literal>F</literal>. In all other cases, <literal>'f</literal>\r
17127will be instantiated to <literal>unit</literal>.</simpara>\r
17128</blockquote>\r
17129<simpara>(In the actual MLton implementation, an abstract type <literal>naf</literal>\r
17130(not-a-function) is used instead of <literal>unit</literal>.)</simpara>\r
17131<simpara>While this means that type-annotated programs may not type-check under\r
17132both the SML/NJ implementation and the MLton implementation, this\r
17133should not be a problem in practice. Tools, like <literal>ml-nlffigen</literal>, which\r
17134are necessarily implementation dependent (in order to make\r
17135<link linkend="CallingFromSMLToCFunctionPointer">calls through a C function pointer</link>), may be easily extended to emit the additional type\r
17136parameter. Client code which uses such generated glue-code (e.g.,\r
17137Section 1 of <link linkend="References_Blume01">Blume01</link>) need rarely write type-annotations,\r
17138thanks to the magic of type inference.</simpara>\r
17139</listitem>\r
17140<listitem>\r
17141<simpara>\r
17142The above implementation suffers from two disadvantages.\r
17143</simpara>\r
17144<simpara>First, it changes the MLNLFFI Library interface, meaning that the same\r
17145program may not type-check under both the SML/NJ implementation and\r
17146the MLton implementation (though, in light of type inference and the\r
17147richer <literal>MLRep</literal> structure provided by MLton, this point is mostly\r
17148moot).</simpara>\r
17149<simpara>Second, it appears to unnecessarily duplicate type information. For\r
17150example, an external C variable of type <literal>int (* f[3])(int)</literal> (that is,\r
17151an array of three function pointers), would be represented by the SML\r
17152type <literal>(((sint -&gt; sint) fptr, dec dg3) arr, sint -&gt; sint, rw) obj</literal>.\r
17153One might well ask why the <literal>'f</literal> instantiation (<literal>sint -&gt; sint</literal> in this\r
17154case) cannot be <emphasis>extracted</emphasis> from the <literal>'t</literal> instantiation\r
17155(<literal>((sint -&gt; sint) fptr, dec dg3) arr</literal> in this case), obviating the\r
17156need for a separate <emphasis>function-type</emphasis> type argument. There are a number\r
17157of components to an complete answer to this question. Foremost is the\r
17158fact that <link linkend="StandardML">Standard ML</link> supports neither (general)\r
17159type-level functions nor intensional polymorphism.</simpara>\r
17160<simpara>A more direct answer for MLNLFFI is that in the SML/NJ implemention,\r
17161the definition of the types <literal>('t, 'c) obj</literal> and <literal>('t, 'c) ptr</literal> are made\r
17162in such a way that the type variables <literal>'t</literal> and <literal>'c</literal> are <link linkend="PhantomType">phantom</link> (not contributing to the run-time representation of an\r
17163<literal>('t, 'c) obj</literal> or <literal>('t, 'c) ptr</literal> value), despite the fact that the\r
17164types <literal>((sint -&gt; sint) fptr, rw) ptr</literal> and\r
17165<literal>((double -&gt; double) fptr, rw) ptr</literal> necessarily carry distinct (and\r
17166type incompatible) run-time (C-)type information (RTTI), corresponding\r
17167to the different calling conventions of the two C functions. The\r
17168<literal>Unsafe.cast</literal> "cheat" overcomes the type incompatibility without\r
17169introducing a new type variable (as in the first solution above).</simpara>\r
17170<simpara>Hence, the reason that <emphasis>function-type</emphasis> type cannot be extracted from\r
17171the <literal>'t</literal> type variable instantiation is that the type of the\r
17172representation of RTTI doesn&#8217;t even <emphasis>see</emphasis> the (phantom) <literal>'t</literal> type\r
17173variable. The solution which presents itself is to give up on the\r
17174phantomness of the <literal>'t</literal> type variable, making it available to the\r
17175representation of RTTI.</simpara>\r
17176<simpara>This is not without some small drawbacks. Because many of the types\r
17177used to instantiate <literal>'t</literal> carry more structure than is strictly\r
17178necessary for <literal>'t</literal>'s RTTI, it is sometimes necessary to wrap and\r
17179unwrap RTTI to accommodate the additional structure. (In the other\r
17180implementations, the corresponding operations can pass along the RTTI\r
17181unchanged.) However, these coercions contribute minuscule overhead;\r
17182in fact, in a majority of cases, MLton&#8217;s optimizations will completely\r
17183eliminate the RTTI from the final program.</simpara>\r
17184</listitem>\r
17185</itemizedlist>\r
17186<simpara>The implementation distributed with MLton uses the second solution.</simpara>\r
17187<simpara>Bonus question: Why can&#8217;t one use a <link linkend="UniversalType">universal type</link>\r
17188to eliminate the use of <literal>Unsafe.cast</literal>?</simpara>\r
17189<itemizedlist>\r
17190<listitem>\r
17191<simpara>\r
17192Answer: ???\r
17193</simpara>\r
17194</listitem>\r
17195</itemizedlist>\r
17196</listitem>\r
17197<listitem>\r
17198<simpara>\r
17199MLton (in both of the above implementations) provides a richer\r
17200<literal>MLRep</literal> structure, utilizing <literal>Int<emphasis>&lt;N&gt;</emphasis></literal> and <literal>Word<emphasis>&lt;N&gt;</emphasis></literal>\r
17201structures.\r
17202</simpara>\r
17203<programlisting language="sml" linenumbering="unnumbered">structure MLRep = struct\r
17204 structure Char =\r
17205 struct\r
17206 structure Signed = Int8\r
17207 structure Unsigned = Word8\r
17208 (* word-style bit-operations on integers... *)\r
17209 structure &lt;:SignedBitops:&gt; = IntBitOps(structure I = Signed\r
17210 structure W = Unsigned)\r
17211 end\r
17212 structure Short =\r
17213 struct\r
17214 structure Signed = Int16\r
17215 structure Unsigned = Word16\r
17216 (* word-style bit-operations on integers... *)\r
17217 structure &lt;:SignedBitops:&gt; = IntBitOps(structure I = Signed\r
17218 structure W = Unsigned)\r
17219 end\r
17220 structure Int =\r
17221 struct\r
17222 structure Signed = Int32\r
17223 structure Unsigned = Word32\r
17224 (* word-style bit-operations on integers... *)\r
17225 structure &lt;:SignedBitops:&gt; = IntBitOps(structure I = Signed\r
17226 structure W = Unsigned)\r
17227 end\r
17228 structure Long =\r
17229 struct\r
17230 structure Signed = Int32\r
17231 structure Unsigned = Word32\r
17232 (* word-style bit-operations on integers... *)\r
17233 structure &lt;:SignedBitops:&gt; = IntBitOps(structure I = Signed\r
17234 structure W = Unsigned)\r
17235 end\r
17236 structure &lt;:LongLong:&gt; =\r
17237 struct\r
17238 structure Signed = Int64\r
17239 structure Unsigned = Word64\r
17240 (* word-style bit-operations on integers... *)\r
17241 structure &lt;:SignedBitops:&gt; = IntBitOps(structure I = Signed\r
17242 structure W = Unsigned)\r
17243 end\r
17244 structure Float = Real32\r
17245 structure Double = Real64\r
17246end</programlisting>\r
17247<simpara>This would appear to be a better interface, even when an\r
17248implementation must choose <literal>Int32</literal> and <literal>Word32</literal> as the representation\r
17249for smaller C-types.</simpara>\r
17250</listitem>\r
17251</itemizedlist>\r
17252<simpara><?asciidoc-pagebreak?></simpara>\r
17253</section>\r
17254<section id="MLRISCLibrary">\r
17255<title>MLRISCLibrary</title>\r
17256<simpara>The <ulink url="http://www.cs.nyu.edu/leunga/www/MLRISC/Doc/html/index.html">MLRISC\r
17257Library</ulink> is a framework for retargetable and optimizing compiler back\r
17258ends. The MLRISC Library is distributed with SML/NJ. Due to\r
17259differences between SML/NJ and MLton, this library will not work\r
17260out-of-the box with MLton.</simpara>\r
17261<simpara>As of 20180119, MLton includes a port of the MLRISC Library\r
17262synchronized with SML/NJ version 110.82.</simpara>\r
17263<section id="_usage_7">\r
17264<title>Usage</title>\r
17265<itemizedlist>\r
17266<listitem>\r
17267<simpara>\r
17268You can import a sub-library of the MLRISC Library into an MLB file with:\r
17269</simpara>\r
17270<informaltable\r
17271frame="all"\r
17272rowsep="1" colsep="1"\r
17273>\r
17274<tgroup cols="2">\r
17275<colspec colname="col_1" colwidth="50*"/>\r
17276<colspec colname="col_2" colwidth="50*"/>\r
17277<thead>\r
17278<row>\r
17279<entry align="left" valign="top">MLB file</entry>\r
17280<entry align="left" valign="top">Description</entry>\r
17281</row>\r
17282</thead>\r
17283<tbody>\r
17284<row>\r
17285<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/mlrisc-lib/mlb/ALPHA.mlb</literal></simpara></entry>\r
17286<entry align="left" valign="top"><simpara>The ALPHA backend</simpara></entry>\r
17287</row>\r
17288<row>\r
17289<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/mlrisc-lib/mlb/AMD64.mlb</literal></simpara></entry>\r
17290<entry align="left" valign="top"><simpara>The AMD64 backend</simpara></entry>\r
17291</row>\r
17292<row>\r
17293<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/mlrisc-lib/mlb/AMD64-Peephole.mlb</literal></simpara></entry>\r
17294<entry align="left" valign="top"><simpara>The AMD64 peephole optimizer</simpara></entry>\r
17295</row>\r
17296<row>\r
17297<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/mlrisc-lib/mlb/CCall.mlb</literal></simpara></entry>\r
17298<entry align="left" valign="top"><simpara></simpara></entry>\r
17299</row>\r
17300<row>\r
17301<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/mlrisc-lib/mlb/CCall-sparc.mlb</literal></simpara></entry>\r
17302<entry align="left" valign="top"><simpara></simpara></entry>\r
17303</row>\r
17304<row>\r
17305<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/mlrisc-lib/mlb/CCall-x86-64.mlb</literal></simpara></entry>\r
17306<entry align="left" valign="top"><simpara></simpara></entry>\r
17307</row>\r
17308<row>\r
17309<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/mlrisc-lib/mlb/CCall-x86.mlb</literal></simpara></entry>\r
17310<entry align="left" valign="top"><simpara></simpara></entry>\r
17311</row>\r
17312<row>\r
17313<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/mlrisc-lib/mlb/Control.mlb</literal></simpara></entry>\r
17314<entry align="left" valign="top"><simpara></simpara></entry>\r
17315</row>\r
17316<row>\r
17317<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/mlrisc-lib/mlb/Graphs.mlb</literal></simpara></entry>\r
17318<entry align="left" valign="top"><simpara></simpara></entry>\r
17319</row>\r
17320<row>\r
17321<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/mlrisc-lib/mlb/HPPA.mlb</literal></simpara></entry>\r
17322<entry align="left" valign="top"><simpara>The HPPA backend</simpara></entry>\r
17323</row>\r
17324<row>\r
17325<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/mlrisc-lib/mlb/IA32.mlb</literal></simpara></entry>\r
17326<entry align="left" valign="top"><simpara>The IA32 backend</simpara></entry>\r
17327</row>\r
17328<row>\r
17329<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/mlrisc-lib/mlb/IA32-Peephole.mlb</literal></simpara></entry>\r
17330<entry align="left" valign="top"><simpara>The IA32 peephole optimizer</simpara></entry>\r
17331</row>\r
17332<row>\r
17333<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/mlrisc-lib/mlb/Lib.mlb</literal></simpara></entry>\r
17334<entry align="left" valign="top"><simpara></simpara></entry>\r
17335</row>\r
17336<row>\r
17337<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/mlrisc-lib/mlb/MLRISC.mlb</literal></simpara></entry>\r
17338<entry align="left" valign="top"><simpara></simpara></entry>\r
17339</row>\r
17340<row>\r
17341<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/mlrisc-lib/mlb/MLTREE.mlb</literal></simpara></entry>\r
17342<entry align="left" valign="top"><simpara></simpara></entry>\r
17343</row>\r
17344<row>\r
17345<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/mlrisc-lib/mlb/Peephole.mlb</literal></simpara></entry>\r
17346<entry align="left" valign="top"><simpara></simpara></entry>\r
17347</row>\r
17348<row>\r
17349<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/mlrisc-lib/mlb/PPC.mlb</literal></simpara></entry>\r
17350<entry align="left" valign="top"><simpara>The PPC backend</simpara></entry>\r
17351</row>\r
17352<row>\r
17353<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/mlrisc-lib/mlb/RA.mlb</literal></simpara></entry>\r
17354<entry align="left" valign="top"><simpara></simpara></entry>\r
17355</row>\r
17356<row>\r
17357<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/mlrisc-lib/mlb/SPARC.mlb</literal></simpara></entry>\r
17358<entry align="left" valign="top"><simpara>The Sparc backend</simpara></entry>\r
17359</row>\r
17360<row>\r
17361<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/mlrisc-lib/mlb/StagedAlloc.mlb</literal></simpara></entry>\r
17362<entry align="left" valign="top"><simpara></simpara></entry>\r
17363</row>\r
17364<row>\r
17365<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/mlrisc-lib/mlb/Visual.mlb</literal></simpara></entry>\r
17366<entry align="left" valign="top"><simpara></simpara></entry>\r
17367</row>\r
17368</tbody>\r
17369</tgroup>\r
17370</informaltable>\r
17371</listitem>\r
17372<listitem>\r
17373<simpara>\r
17374If you are porting a project from SML/NJ&#8217;s <link linkend="CompilationManager">CompilationManager</link> to\r
17375MLton&#8217;s <link linkend="MLBasis">ML Basis system</link> using <literal>cm2mlb</literal>, note that the\r
17376following map is included by default:\r
17377</simpara>\r
17378<screen># MLRISC Library\r
17379$SMLNJ-MLRISC $(SML_LIB)/mlrisc-lib/mlb</screen>\r
17380<simpara>This will automatically convert a <literal>$SMLNJ-MLRISC/MLRISC.cm</literal> import in\r
17381an input <literal>.cm</literal> file into a <literal>$(SML_LIB)/mlrisc-lib/mlb/MLRISC.mlb</literal>\r
17382import in the output <literal>.mlb</literal> file.</simpara>\r
17383</listitem>\r
17384</itemizedlist>\r
17385</section>\r
17386<section id="_details_3">\r
17387<title>Details</title>\r
17388<simpara>The following changes were made to the MLRISC Library, in addition to\r
17389deriving the <literal>.mlb</literal> files from the <literal>.cm</literal> files:</simpara>\r
17390<itemizedlist>\r
17391<listitem>\r
17392<simpara>\r
17393eliminate sequential <literal>withtype</literal> expansions: Most could be rewritten as a sequence of type definitions and datatype definitions.\r
17394</simpara>\r
17395</listitem>\r
17396<listitem>\r
17397<simpara>\r
17398eliminate higher-order functors: Every higher-order functor definition and application could be uncurried in the obvious way.\r
17399</simpara>\r
17400</listitem>\r
17401<listitem>\r
17402<simpara>\r
17403eliminate <literal>where &lt;str&gt; = &lt;str&gt;</literal>: Quite painful to expand out all the flexible types in the respective structures. Furthermore, many of the implied type equalities aren&#8217;t needed, but it&#8217;s too hard to pick out the right ones.\r
17404</simpara>\r
17405</listitem>\r
17406<listitem>\r
17407<simpara>\r
17408<literal>library/array-noneq.sml</literal> (added, not exported): Implements <literal>signature ARRAY_NONEQ</literal>, similar to <literal>signature ARRAY</literal> from the <link linkend="BasisLibrary">Basis Library</link>, but replacing the latter&#8217;s <literal>eqtype 'a array = 'a array</literal> and <literal>type 'a vector = 'a Vector.vector</literal> with <literal>type 'a array</literal> and <literal>type 'a vector</literal>. Thus, array-like containers may match <literal>ARRAY_NONEQ</literal>, whereas only the pervasive <literal>'a array</literal> container may math <literal>ARRAY</literal>. (SML/NJ&#8217;s implementation of <literal>signature ARRAY</literal> omits the type realizations.)\r
17409</simpara>\r
17410</listitem>\r
17411<listitem>\r
17412<simpara>\r
17413<literal>library/dynamic-array.sml</literal> and <literal>library/hash-array.sml</literal> (modifed): Replace <literal>include ARRAY</literal> with <literal>include ARRAY_NONEQ</literal>; see above.\r
17414</simpara>\r
17415</listitem>\r
17416</itemizedlist>\r
17417</section>\r
17418<section id="_patch_3">\r
17419<title>Patch</title>\r
17420<itemizedlist>\r
17421<listitem>\r
17422<simpara>\r
17423<ulink url="https://github.com/MLton/mlton/blob/master/lib/mlrisc-lib/MLRISC.patch"><literal>MLRISC.patch</literal></ulink>\r
17424</simpara>\r
17425</listitem>\r
17426</itemizedlist>\r
17427<simpara><?asciidoc-pagebreak?></simpara>\r
17428</section>\r
17429</section>\r
17430<section id="MLtonArray">\r
17431<title>MLtonArray</title>\r
17432<programlisting language="sml" linenumbering="unnumbered">signature MLTON_ARRAY =\r
17433 sig\r
17434 val unfoldi: int * 'b * (int * 'b -&gt; 'a * 'b) -&gt; 'a array * 'b\r
17435 end</programlisting>\r
17436<itemizedlist>\r
17437<listitem>\r
17438<simpara>\r
17439<literal>unfoldi (n, b, f)</literal>\r
17440</simpara>\r
17441<simpara>constructs an array <emphasis>a</emphasis> of length <literal>n</literal>, whose elements <emphasis>a<subscript>i</subscript></emphasis> are\r
17442determined by the equations <emphasis>b<subscript>0</subscript> = b</emphasis> and\r
17443<emphasis>(a<subscript>i</subscript>, b<subscript>i+1</subscript>) = f (i, b<subscript>i</subscript>)</emphasis>.</simpara>\r
17444</listitem>\r
17445</itemizedlist>\r
17446<simpara><?asciidoc-pagebreak?></simpara>\r
17447</section>\r
17448<section id="MLtonBinIO">\r
17449<title>MLtonBinIO</title>\r
17450<programlisting language="sml" linenumbering="unnumbered">signature MLTON_BIN_IO = MLTON_IO</programlisting>\r
17451<simpara>See <link linkend="MLtonIO">MLtonIO</link>.</simpara>\r
17452<simpara><?asciidoc-pagebreak?></simpara>\r
17453</section>\r
17454<section id="MLtonCont">\r
17455<title>MLtonCont</title>\r
17456<programlisting language="sml" linenumbering="unnumbered">signature MLTON_CONT =\r
17457 sig\r
17458 type 'a t\r
17459\r
17460 val callcc: ('a t -&gt; 'a) -&gt; 'a\r
17461 val isolate: ('a -&gt; unit) -&gt; 'a t\r
17462 val prepend: 'a t * ('b -&gt; 'a) -&gt; 'b t\r
17463 val throw: 'a t * 'a -&gt; 'b\r
17464 val throw': 'a t * (unit -&gt; 'a) -&gt; 'b\r
17465 end</programlisting>\r
17466<itemizedlist>\r
17467<listitem>\r
17468<simpara>\r
17469<literal>type 'a t</literal>\r
17470</simpara>\r
17471<simpara>the type of continuations that expect a value of type <literal>'a</literal>.</simpara>\r
17472</listitem>\r
17473<listitem>\r
17474<simpara>\r
17475<literal>callcc f</literal>\r
17476</simpara>\r
17477<simpara>applies <literal>f</literal> to the current continuation. This copies the entire\r
17478stack; hence, <literal>callcc</literal> takes time proportional to the size of the\r
17479current stack.</simpara>\r
17480</listitem>\r
17481<listitem>\r
17482<simpara>\r
17483<literal>isolate f</literal>\r
17484</simpara>\r
17485<simpara>creates a continuation that evaluates <literal>f</literal> in an empty context. This\r
17486is a constant time operation, and yields a constant size stack.</simpara>\r
17487</listitem>\r
17488<listitem>\r
17489<simpara>\r
17490<literal>prepend (k, f)</literal>\r
17491</simpara>\r
17492<simpara>composes a function <literal>f</literal> with a continuation <literal>k</literal> to create a\r
17493continuation that first does <literal>f</literal> and then does <literal>k</literal>. This is a\r
17494constant time operation.</simpara>\r
17495</listitem>\r
17496<listitem>\r
17497<simpara>\r
17498<literal>throw (k, v)</literal>\r
17499</simpara>\r
17500<simpara>throws value <literal>v</literal> to continuation <literal>k</literal>. This copies the entire stack of\r
17501<literal>k</literal>; hence, <literal>throw</literal> takes time proportional to the size of this stack.</simpara>\r
17502</listitem>\r
17503<listitem>\r
17504<simpara>\r
17505<literal>throw' (k, th)</literal>\r
17506</simpara>\r
17507<simpara>a generalization of throw that evaluates <literal>th ()</literal> in the context of\r
17508<literal>k</literal>. Thus, for example, if <literal>th ()</literal> raises an exception or captures\r
17509another continuation, it will see <literal>k</literal>, not the current continuation.</simpara>\r
17510</listitem>\r
17511</itemizedlist>\r
17512<section id="_also_see_15">\r
17513<title>Also see</title>\r
17514<itemizedlist>\r
17515<listitem>\r
17516<simpara>\r
17517<link linkend="MLtonContIsolateImplementation">MLtonContIsolateImplementation</link>\r
17518</simpara>\r
17519</listitem>\r
17520</itemizedlist>\r
17521<simpara><?asciidoc-pagebreak?></simpara>\r
17522</section>\r
17523</section>\r
17524<section id="MLtonContIsolateImplementation">\r
17525<title>MLtonContIsolateImplementation</title>\r
17526<simpara>As noted before, it is fairly easy to get the operational behavior of <literal>isolate</literal> with just <literal>callcc</literal> and <literal>throw</literal>, but establishing the right space behavior is trickier. Here, we show how to start from the obvious, but inefficient, implementation of <literal>isolate</literal> using only <literal>callcc</literal> and <literal>throw</literal>, and <emphasis>derive</emphasis> an equivalent, but more efficient, implementation of <literal>isolate</literal> using MLton&#8217;s primitive stack capture and copy operations. This isn&#8217;t a formal derivation, as we are not formally showing the equivalence of the programs (though I believe that they are all equivalent, modulo the space behavior).</simpara>\r
17527<simpara>Here is a direct implementation of isolate using only <literal>callcc</literal> and <literal>throw</literal>:</simpara>\r
17528<programlisting language="sml" linenumbering="unnumbered">val isolate: ('a -&gt; unit) -&gt; 'a t =\r
17529 fn (f: 'a -&gt; unit) =&gt;\r
17530 callcc\r
17531 (fn k1 =&gt;\r
17532 let\r
17533 val x = callcc (fn k2 =&gt; throw (k1, k2))\r
17534 val _ = (f x ; Exit.topLevelSuffix ())\r
17535 handle exn =&gt; MLtonExn.topLevelHandler exn\r
17536 in\r
17537 raise Fail "MLton.Cont.isolate: return from (wrapped) func"\r
17538 end)</programlisting>\r
17539<simpara>We use the standard nested <literal>callcc</literal> trick to return a continuation that is ready to receive an argument, execute the isolated function, and exit the program. Both <literal>Exit.topLevelSuffix</literal> and <literal>MLtonExn.topLevelHandler</literal> will terminate the program.</simpara>\r
17540<simpara>Throwing to an isolated function will execute the function in a <emphasis>semantically</emphasis> empty context, in the sense that we never re-execute the <emphasis>original</emphasis> continuation of the call to isolate (i.e., the context that was in place at the time <literal>isolate</literal> was called). However, we assume that the compiler isn&#8217;t able to recognize that the <emphasis>original</emphasis> continuation is unused; for example, while we (the programmer) know that <literal>Exit.topLevelSuffix</literal> and <literal>MLtonExn.topLevelHandler</literal> will terminate the program, the compiler may only see opaque calls to unknown foreign-functions. So, that original continuation (in its entirety) is part of the continuation returned by <literal>isolate</literal> and throwing to the continuation returned by <literal>isolate</literal> will execute <literal>f x</literal> (with the exit wrapper) in the context of that original continuation. Thus, the garbage collector will retain everything reachable from that original continuation during the evaluation of <literal>f x</literal>, even though it is <emphasis>semantically</emphasis> garbage.</simpara>\r
17541<simpara>Note that this space-leak is independent of the implementation of continuations (it arises in both MLton&#8217;s stack copying implementation of continuations and would arise in SML/NJ&#8217;s CPS-translation implementation); we are only assuming that the implementation can&#8217;t <emphasis>see</emphasis> the program termination, and so must retain the original continuation (and anything reachable from it).</simpara>\r
17542<simpara>So, we need an <emphasis>empty</emphasis> continuation in which to execute <literal>f x</literal>. (No surprise there, as that is the written description of <literal>isolate</literal>.) To do this, we capture a top-level continuation and throw to that in order to execute <literal>f x</literal>:</simpara>\r
17543<programlisting language="sml" linenumbering="unnumbered">local\r
17544val base: (unit -&gt; unit) t =\r
17545 callcc\r
17546 (fn k1 =&gt;\r
17547 let\r
17548 val th = callcc (fn k2 =&gt; throw (k1, k2))\r
17549 val _ = (th () ; Exit.topLevelSuffix ())\r
17550 handle exn =&gt; MLtonExn.topLevelHandler exn\r
17551 in\r
17552 raise Fail "MLton.Cont.isolate: return from (wrapped) func"\r
17553 end)\r
17554in\r
17555val isolate: ('a -&gt; unit) -&gt; 'a t =\r
17556 fn (f: 'a -&gt; unit) =&gt;\r
17557 callcc\r
17558 (fn k1 =&gt;\r
17559 let\r
17560 val x = callcc (fn k2 =&gt; throw (k1, k2))\r
17561 in\r
17562 throw (base, fn () =&gt; f x)\r
17563 end)\r
17564end</programlisting>\r
17565<simpara>We presume that <literal>base</literal> is evaluated <emphasis>early</emphasis> in the program. There is a subtlety here, because one needs to believe that this <literal>base</literal> continuation (which technically corresponds to the entire rest of the program evaluation) <emphasis>works</emphasis> as an empty context; in particular, we want it to be the case that executing <literal>f x</literal> in the <literal>base</literal> context retains less space than executing <literal>f x</literal> in the context in place at the call to <literal>isolate</literal> (as occurred in the previous implementation of <literal>isolate</literal>). This isn&#8217;t particularly easy to believe if one takes a normal substitution-based operational semantics, because it seems that the context captured and bound to <literal>base</literal> is arbitrarily large. However, this context is mostly unevaluated code; the only heap-allocated values that are reachable from it are those that were evaluated before the evaluation of <literal>base</literal> (and used in the program after the evaluation of <literal>base</literal>). Assuming that <literal>base</literal> is evaluated <emphasis>early</emphasis> in the program, we conclude that there are few heap-allocated values reachable from its continuation. In contrast, the previous implementation of <literal>isolate</literal> could capture a context that has many heap-allocated values reachable from it (because we could evaluate <literal>isolate f</literal> <emphasis>late</emphasis> in the program and <emphasis>deep</emphasis> in a call stack), which would all remain reachable during the evaluation of\r
17566<literal>f x</literal>. [We&#8217;ll return to this point later, as it is taking a slightly MLton-esque view of the evaluation of a program, and may not apply as strongly to other implementations (e.g., SML/NJ).]</simpara>\r
17567<simpara>Now, once we throw to <literal>base</literal> and begin executing <literal>f x</literal>, only the heap-allocated values reachable from <literal>f</literal> and <literal>x</literal> and the few heap-allocated values reachable from <literal>base</literal> are retained by the garbage collector. So, it seems that <literal>base</literal> <emphasis>works</emphasis> as an empty context.</simpara>\r
17568<simpara>But, what about the continuation returned from <literal>isolate f</literal>? Note that the continuation returned by <literal>isolate</literal> is one that receives an argument <literal>x</literal> and then\r
17569throws to <literal>base</literal> to evaluate <literal>f x</literal>. If we used a CPS-translation implementation (and assume sufficient beta-contractions to eliminate administrative redexes), then the original continuation passed to <literal>isolate</literal> (i.e., the continuation bound to <literal>k1</literal>) will not be free in the continuation returned by <literal>isolate f</literal>. Rather, the only free variables in the continuation returned by <literal>isolate f</literal> will be <literal>base</literal> and <literal>f</literal>, so the only heap-allocated values reachable from the continuation returned by <literal>isolate f</literal> will be those values reachable from <literal>base</literal> (assumed to be few) and those values reachable from <literal>f</literal> (necessary in order to execute <literal>f</literal> at some later point).</simpara>\r
17570<simpara>But, MLton doesn&#8217;t use a CPS-translation implementation. Rather, at each call to <literal>callcc</literal> in the body of <literal>isolate</literal>, MLton will copy the current execution stack. Thus, <literal>k2</literal> (the continuation returned by <literal>isolate f</literal>) will include execution stack at the time of the call to <literal>isolate f</literal>&#8201;&#8212;&#8201;that is, it will include the <emphasis>original</emphasis> continuation of the call to <literal>isolate f</literal>. Thus, the heap-allocated values reachable from the continuation returned by <literal>isolate f</literal> will include those values reachable from <literal>base</literal>, those values reachable from <literal>f</literal>, and those values reachable from the original continuation of the call to <literal>isolate f</literal>. So, just holding on to the continuation returned by <literal>isolate f</literal> will retain all of the heap-allocated values live at the time <literal>isolate f</literal> was called. This leaks space, since, <emphasis>semantically</emphasis>, the\r
17571continuation returned by <literal>isolate f</literal> only needs the heap-allocated values reachable from <literal>f</literal> (and <literal>base</literal>).</simpara>\r
17572<simpara>In practice, this probably isn&#8217;t a significant issue. A common use of <literal>isolate</literal> is implement <literal>abort</literal>:</simpara>\r
17573<programlisting language="sml" linenumbering="unnumbered">fun abort th = throw (isolate th, ())</programlisting>\r
17574<simpara>The continuation returned by <literal>isolate th</literal> is dead immediately after being thrown to&#8201;&#8212;&#8201;the continuation isn&#8217;t retained, so neither is the <emphasis>semantic</emphasis>\r
17575garbage it would have retained.</simpara>\r
17576<simpara>But, it is easy enough to <emphasis>move</emphasis> onto the <emphasis>empty</emphasis> context <literal>base</literal> the capturing of the context that we want to be returned by <literal>isolate f</literal>:</simpara>\r
17577<programlisting language="sml" linenumbering="unnumbered">local\r
17578val base: (unit -&gt; unit) t =\r
17579 callcc\r
17580 (fn k1 =&gt;\r
17581 let\r
17582 val th = callcc (fn k2 =&gt; throw (k1, k2))\r
17583 val _ = (th () ; Exit.topLevelSuffix ())\r
17584 handle exn =&gt; MLtonExn.topLevelHandler exn\r
17585 in\r
17586 raise Fail "MLton.Cont.isolate: return from (wrapped) func"\r
17587 end)\r
17588in\r
17589val isolate: ('a -&gt; unit) -&gt; 'a t =\r
17590 fn (f: 'a -&gt; unit) =&gt;\r
17591 callcc\r
17592 (fn k1 =&gt;\r
17593 throw (base, fn () =&gt;\r
17594 let\r
17595 val x = callcc (fn k2 =&gt; throw (k1, k2))\r
17596 in\r
17597 throw (base, fn () =&gt; f x)\r
17598 end))\r
17599end</programlisting>\r
17600<simpara>This implementation now has the right space behavior; the continuation returned by <literal>isolate f</literal> will only retain the heap-allocated values reachable from <literal>f</literal> and from <literal>base</literal>. (Technically, the continuation will retain two copies of the stack that was in place at the time <literal>base</literal> was evaluated, but we are assuming that that stack small.)</simpara>\r
17601<simpara>One minor inefficiency of this implementation (given MLton&#8217;s implementation of continuations) is that every <literal>callcc</literal> and <literal>throw</literal> entails copying a stack (albeit, some of them are small). We can avoid this in the evaluation of <literal>base</literal> by using a reference cell, because <literal>base</literal> is evaluated at the top-level:</simpara>\r
17602<programlisting language="sml" linenumbering="unnumbered">local\r
17603val base: (unit -&gt; unit) option t =\r
17604 let\r
17605 val baseRef: (unit -&gt; unit) option t option ref = ref NONE\r
17606 val th = callcc (fn k =&gt; (base := SOME k; NONE))\r
17607 in\r
17608 case th of\r
17609 NONE =&gt; (case !baseRef of\r
17610 NONE =&gt; raise Fail "MLton.Cont.isolate: missing base"\r
17611 | SOME base =&gt; base)\r
17612 | SOME th =&gt; let\r
17613 val _ = (th () ; Exit.topLevelSuffix ())\r
17614 handle exn =&gt; MLtonExn.topLevelHandler exn\r
17615 in\r
17616 raise Fail "MLton.Cont.isolate: return from (wrapped)\r
17617 func"\r
17618 end\r
17619 end\r
17620in\r
17621val isolate: ('a -&gt; unit) -&gt; 'a t =\r
17622 fn (f: 'a -&gt; unit) =&gt;\r
17623 callcc\r
17624 (fn k1 =&gt;\r
17625 throw (base, SOME (fn () =&gt;\r
17626 let\r
17627 val x = callcc (fn k2 =&gt; throw (k1, k2))\r
17628 in\r
17629 throw (base, SOME (fn () =&gt; f x))\r
17630 end)))\r
17631end</programlisting>\r
17632<simpara>Now, to evaluate <literal>base</literal>, we only copy the stack once (instead of 3 times). Because we don&#8217;t have a dummy continuation around to initialize the reference cell, the reference cell holds a continuation <literal>option</literal>. To distinguish between the original evaluation of <literal>base</literal> (when we want to return the continuation) and the subsequent evaluations of <literal>base</literal> (when we want to evaluate a thunk), we capture a <literal>(unit -&gt; unit) option</literal> continuation.</simpara>\r
17633<simpara>This seems to be as far as we can go without exploiting the concrete implementation of continuations in <link linkend="MLtonCont">MLtonCont</link>. Examining the implementation, we note that the type of\r
17634continuations is given by</simpara>\r
17635<programlisting language="sml" linenumbering="unnumbered">type 'a t = (unit -&gt; 'a) -&gt; unit</programlisting>\r
17636<simpara>and the implementation of <literal>throw</literal> is given by</simpara>\r
17637<programlisting language="sml" linenumbering="unnumbered">fun ('a, 'b) throw' (k: 'a t, v: unit -&gt; 'a): 'b =\r
17638 (k v; raise Fail "MLton.Cont.throw': return from continuation")\r
17639\r
17640fun ('a, 'b) throw (k: 'a t, v: 'a): 'b = throw' (k, fn () =&gt; v)</programlisting>\r
17641<simpara>Suffice to say, a continuation is simply a function that accepts a thunk to yield the thrown value and the body of the function performs the actual throw. Using this knowledge, we can create a dummy continuation to initialize <literal>baseRef</literal> and greatly simplify the body of <literal>isolate</literal>:</simpara>\r
17642<programlisting language="sml" linenumbering="unnumbered">local\r
17643val base: (unit -&gt; unit) option t =\r
17644 let\r
17645 val baseRef: (unit -&gt; unit) option t ref =\r
17646 ref (fn _ =&gt; raise Fail "MLton.Cont.isolate: missing base")\r
17647 val th = callcc (fn k =&gt; (baseRef := k; NONE))\r
17648 in\r
17649 case th of\r
17650 NONE =&gt; !baseRef\r
17651 | SOME th =&gt; let\r
17652 val _ = (th () ; Exit.topLevelSuffix ())\r
17653 handle exn =&gt; MLtonExn.topLevelHandler exn\r
17654 in\r
17655 raise Fail "MLton.Cont.isolate: return from (wrapped)\r
17656 func"\r
17657 end\r
17658 end\r
17659in\r
17660val isolate: ('a -&gt; unit) -&gt; 'a t =\r
17661 fn (f: 'a -&gt; unit) =&gt;\r
17662 fn (v: unit -&gt; 'a) =&gt;\r
17663 throw (base, SOME (f o v))\r
17664end</programlisting>\r
17665<simpara>Note that this implementation of <literal>isolate</literal> makes it clear that the continuation returned by <literal>isolate f</literal> only retains the heap-allocated values reachable from <literal>f</literal> and <literal>base</literal>. It also retains only one copy of the stack that was in place at the time <literal>base</literal> was evaluated. Finally, it completely avoids making any copies of the stack that is in place at the time <literal>isolate f</literal> is evaluated; indeed, <literal>isolate f</literal> is a constant-time operation.</simpara>\r
17666<simpara>Next, suppose we limited ourselves to capturing <literal>unit</literal> continuations with <literal>callcc</literal>. We can&#8217;t pass the thunk to be evaluated in the <emphasis>empty</emphasis> context directly, but we can use a reference cell.</simpara>\r
17667<programlisting language="sml" linenumbering="unnumbered">local\r
17668val thRef: (unit -&gt; unit) option ref = ref NONE\r
17669val base: unit t =\r
17670 let\r
17671 val baseRef: unit t ref =\r
17672 ref (fn _ =&gt; raise Fail "MLton.Cont.isolate: missing base")\r
17673 val () = callcc (fn k =&gt; baseRef := k)\r
17674 in\r
17675 case !thRef of\r
17676 NONE =&gt; !baseRef\r
17677 | SOME th =&gt;\r
17678 let\r
17679 val _ = thRef := NONE\r
17680 val _ = (th () ; Exit.topLevelSuffix ())\r
17681 handle exn =&gt; MLtonExn.topLevelHandler exn\r
17682 in\r
17683 raise Fail "MLton.Cont.isolate: return from (wrapped) func"\r
17684 end\r
17685 end\r
17686in\r
17687val isolate: ('a -&gt; unit) -&gt; 'a t =\r
17688 fn (f: 'a -&gt; unit) =&gt;\r
17689 fn (v: unit -&gt; 'a) =&gt;\r
17690 let\r
17691 val () = thRef := SOME (f o v)\r
17692 in\r
17693 throw (base, ())\r
17694 end\r
17695end</programlisting>\r
17696<simpara>Note that it is important to set <literal>thRef</literal> to <literal>NONE</literal> before evaluating the thunk, so that the garbage collector doesn&#8217;t retain all the heap-allocated values reachable from <literal>f</literal> and <literal>v</literal> during the evaluation of <literal>f (v ())</literal>. This is because <literal>thRef</literal> is still live during the evaluation of the thunk; in particular, it was allocated before the evaluation of <literal>base</literal> (and used after), and so is retained by continuation on which the thunk is evaluated.</simpara>\r
17697<simpara>This implementation can be easily adapted to use MLton&#8217;s primitive stack copying operations.</simpara>\r
17698<programlisting language="sml" linenumbering="unnumbered">local\r
17699val thRef: (unit -&gt; unit) option ref = ref NONE\r
17700val base: Thread.preThread =\r
17701 let\r
17702 val () = Thread.copyCurrent ()\r
17703 in\r
17704 case !thRef of\r
17705 NONE =&gt; Thread.savedPre ()\r
17706 | SOME th =&gt;\r
17707 let\r
17708 val () = thRef := NONE\r
17709 val _ = (th () ; Exit.topLevelSuffix ())\r
17710 handle exn =&gt; MLtonExn.topLevelHandler exn\r
17711 in\r
17712 raise Fail "MLton.Cont.isolate: return from (wrapped) func"\r
17713 end\r
17714 end\r
17715in\r
17716val isolate: ('a -&gt; unit) -&gt; 'a t =\r
17717 fn (f: 'a -&gt; unit) =&gt;\r
17718 fn (v: unit -&gt; 'a) =&gt;\r
17719 let\r
17720 val () = thRef := SOME (f o v)\r
17721 val new = Thread.copy base\r
17722 in\r
17723 Thread.switchTo new\r
17724 end\r
17725end</programlisting>\r
17726<simpara>In essence, <literal>Thread.copyCurrent</literal> copies the current execution stack and stores it in an implicit reference cell in the runtime system, which is fetchable with <literal>Thread.savedPre</literal>. When we are ready to throw to the isolated function, <literal>Thread.copy</literal> copies the saved execution stack (because the stack is modified in place during execution, we need to retain a pristine copy in case the isolated function itself throws to other isolated functions) and <literal>Thread.switchTo</literal> abandons the current execution stack, installing the newly copied execution stack.</simpara>\r
17727<simpara>The actual implementation of <literal>MLton.Cont.isolate</literal> simply adds some <literal>Thread.atomicBegin</literal> and <literal>Thread.atomicEnd</literal> commands, which effectively protect the global <literal>thRef</literal> and accommodate the fact that <literal>Thread.switchTo</literal> does an implicit <literal>Thread.atomicEnd</literal> (used for leaving a signal handler thread).</simpara>\r
17728<programlisting language="sml" linenumbering="unnumbered">local\r
17729val thRef: (unit -&gt; unit) option ref = ref NONE\r
17730val base: Thread.preThread =\r
17731 let\r
17732 val () = Thread.copyCurrent ()\r
17733 in\r
17734 case !thRef of\r
17735 NONE =&gt; Thread.savedPre ()\r
17736 | SOME th =&gt;\r
17737 let\r
17738 val () = thRef := NONE\r
17739 val _ = MLton.atomicEnd (* Match 1 *)\r
17740 val _ = (th () ; Exit.topLevelSuffix ())\r
17741 handle exn =&gt; MLtonExn.topLevelHandler exn\r
17742 in\r
17743 raise Fail "MLton.Cont.isolate: return from (wrapped) func"\r
17744 end\r
17745 end\r
17746in\r
17747val isolate: ('a -&gt; unit) -&gt; 'a t =\r
17748 fn (f: 'a -&gt; unit) =&gt;\r
17749 fn (v: unit -&gt; 'a) =&gt;\r
17750 let\r
17751 val _ = MLton.atomicBegin (* Match 1 *)\r
17752 val () = thRef := SOME (f o v)\r
17753 val new = Thread.copy base\r
17754 val _ = MLton.atomicBegin (* Match 2 *)\r
17755 in\r
17756 Thread.switchTo new (* Match 2 *)\r
17757 end\r
17758end</programlisting>\r
17759<simpara>It is perhaps interesting to note that the above implementation was originally <emphasis>derived</emphasis> by specializing implementations of the <link linkend="MLtonThread">MLtonThread</link> <literal>new</literal>, <literal>prepare</literal>, and <literal>switch</literal> functions as if their only use was in the following implementation of <literal>isolate</literal>:</simpara>\r
17760<programlisting language="sml" linenumbering="unnumbered">val isolate: ('a -&gt; unit) -&gt; 'a t =\r
17761 fn (f: 'a -&gt; unit) =&gt;\r
17762 fn (v: unit -&gt; 'a) =&gt;\r
17763 let\r
17764 val th = (f (v ()) ; Exit.topLevelSuffix ())\r
17765 handle exn =&gt; MLtonExn.topLevelHandler exn\r
17766 val t = MLton.Thread.prepare (MLton.Thread.new th, ())\r
17767 in\r
17768 MLton.Thread.switch (fn _ =&gt; t)\r
17769 end</programlisting>\r
17770<simpara>It was pleasant to discover that it could equally well be <emphasis>derived</emphasis> starting from the <literal>callcc</literal> and <literal>throw</literal> implementation.</simpara>\r
17771<simpara>As a final comment, we noted that the degree to which the context of <literal>base</literal> could be considered <emphasis>empty</emphasis> (i.e., retaining few heap-allocated values) depended upon a slightly MLton-esque view. In particular, MLton does not heap allocate executable code. So, although the <literal>base</literal> context keeps a lot of unevaluated code <emphasis>live</emphasis>, such code is not heap allocated. In a system like SML/NJ, that does heap allocate executable code, one might want it to be the case that after throwing to an isolated function, the garbage collector retains only the code necessary to evaluate the function, and not any code that was necessary to evaluate the <literal>base</literal> context.</simpara>\r
17772<simpara><?asciidoc-pagebreak?></simpara>\r
17773</section>\r
17774<section id="MLtonCross">\r
17775<title>MLtonCross</title>\r
17776<simpara>The debian package MLton-Cross adds various targets to MLton. In\r
17777combination with the emdebian project, this allows a debian system to\r
17778compile SML files to other architectures.</simpara>\r
17779<simpara>Currently, these targets are supported:</simpara>\r
17780<itemizedlist>\r
17781<listitem>\r
17782<simpara>\r
17783<emphasis>Windows (MinGW)</emphasis>\r
17784</simpara>\r
17785<itemizedlist>\r
17786<listitem>\r
17787<simpara>\r
17788-target i586-mingw32msvc (mlton-target-i586-mingw32msvc)\r
17789</simpara>\r
17790</listitem>\r
17791<listitem>\r
17792<simpara>\r
17793-target amd64-mingw32msvc( mlton-target-amd64-mingw32msvc)\r
17794</simpara>\r
17795</listitem>\r
17796</itemizedlist>\r
17797</listitem>\r
17798<listitem>\r
17799<simpara>\r
17800<emphasis>Linux (Debian)</emphasis>\r
17801</simpara>\r
17802<itemizedlist>\r
17803<listitem>\r
17804<simpara>\r
17805-target alpha-linux-gnu (mlton-target-alpha-linux-gnu)\r
17806</simpara>\r
17807</listitem>\r
17808<listitem>\r
17809<simpara>\r
17810-target arm-linux-gnueabi (mlton-target-arm-linux-gnueabi)\r
17811</simpara>\r
17812</listitem>\r
17813<listitem>\r
17814<simpara>\r
17815-target hppa-linux-gnu (mlton-target-hppa-linux-gnu)\r
17816</simpara>\r
17817</listitem>\r
17818<listitem>\r
17819<simpara>\r
17820-target i486-linux-gnu (mlton-target-i486-linux-gnu)\r
17821</simpara>\r
17822</listitem>\r
17823<listitem>\r
17824<simpara>\r
17825-target ia64-linux-gnu (mlton-target-ia64-linux-gnu)\r
17826</simpara>\r
17827</listitem>\r
17828<listitem>\r
17829<simpara>\r
17830-target mips-linux-gnu (mlton-target-mips-linux-gnu)\r
17831</simpara>\r
17832</listitem>\r
17833<listitem>\r
17834<simpara>\r
17835-target mipsel-linux-gnu (mlton-target-mipsel-linux-gnu)\r
17836</simpara>\r
17837</listitem>\r
17838<listitem>\r
17839<simpara>\r
17840-target powerpc-linux-gnu (mlton-target-powerpc-linux-gnu)\r
17841</simpara>\r
17842</listitem>\r
17843<listitem>\r
17844<simpara>\r
17845-target s390-linux-gnu (mlton-target-s390-linux-gnu)\r
17846</simpara>\r
17847</listitem>\r
17848<listitem>\r
17849<simpara>\r
17850-target sparc-linux-gnu (mlton-target-sparc-linux-gnu)\r
17851</simpara>\r
17852</listitem>\r
17853<listitem>\r
17854<simpara>\r
17855-target x86-64-linux-gnu (mlton-target-x86-64-linux-gnu)\r
17856</simpara>\r
17857</listitem>\r
17858</itemizedlist>\r
17859</listitem>\r
17860</itemizedlist>\r
17861<section id="_download_6">\r
17862<title>Download</title>\r
17863<simpara>MLton-Cross is kept in-sync with the current MLton release.</simpara>\r
17864<itemizedlist>\r
17865<listitem>\r
17866<simpara>\r
17867<ulink url="guide/MLtonCross.attachments/mlton-cross_20100608.orig.tar.gz"><literal>mlton-cross_20100608.orig.tar.gz</literal></ulink>\r
17868</simpara>\r
17869</listitem>\r
17870</itemizedlist>\r
17871<simpara><?asciidoc-pagebreak?></simpara>\r
17872</section>\r
17873</section>\r
17874<section id="MLtonExn">\r
17875<title>MLtonExn</title>\r
17876<programlisting language="sml" linenumbering="unnumbered">signature MLTON_EXN =\r
17877 sig\r
17878 val addExnMessager: (exn -&gt; string option) -&gt; unit\r
17879 val history: exn -&gt; string list\r
17880\r
17881 val defaultTopLevelHandler: exn -&gt; 'a\r
17882 val getTopLevelHandler: unit -&gt; (exn -&gt; unit)\r
17883 val setTopLevelHandler: (exn -&gt; unit) -&gt; unit\r
17884 val topLevelHandler: exn -&gt; 'a\r
17885 end</programlisting>\r
17886<itemizedlist>\r
17887<listitem>\r
17888<simpara>\r
17889<literal>addExnMessager f</literal>\r
17890</simpara>\r
17891<simpara>adds <literal>f</literal> as a pretty-printer to be used by <literal>General.exnMessage</literal> for\r
17892converting exceptions to strings. Messagers are tried in order from\r
17893most recently added to least recently added.</simpara>\r
17894</listitem>\r
17895<listitem>\r
17896<simpara>\r
17897<literal>history e</literal>\r
17898</simpara>\r
17899<simpara>returns call stack at the point that <literal>e</literal> was first raised. Each\r
17900element of the list is a file position. The elements are in reverse\r
17901chronological order, i.e. the function called last is at the front of\r
17902the list.</simpara>\r
17903<simpara><literal>history e</literal> will return <literal>[]</literal> unless the program is compiled with\r
17904<literal>-const 'Exn.keepHistory true'</literal>.</simpara>\r
17905</listitem>\r
17906<listitem>\r
17907<simpara>\r
17908<literal>defaultTopLevelHandler e</literal>\r
17909</simpara>\r
17910<simpara>function that behaves as the default top level handler; that is, print\r
17911out the unhandled exception message for <literal>e</literal> and exit.</simpara>\r
17912</listitem>\r
17913<listitem>\r
17914<simpara>\r
17915<literal>getTopLevelHandler ()</literal>\r
17916</simpara>\r
17917<simpara>get the top level handler.</simpara>\r
17918</listitem>\r
17919<listitem>\r
17920<simpara>\r
17921<literal>setTopLevelHandler f</literal>\r
17922</simpara>\r
17923<simpara>set the top level handler to the function <literal>f</literal>. The function <literal>f</literal>\r
17924should not raise an exception or return normally.</simpara>\r
17925</listitem>\r
17926<listitem>\r
17927<simpara>\r
17928<literal>topLevelHandler e</literal>\r
17929</simpara>\r
17930<simpara>behaves as if the top level handler received the exception <literal>e</literal>.</simpara>\r
17931</listitem>\r
17932</itemizedlist>\r
17933<simpara><?asciidoc-pagebreak?></simpara>\r
17934</section>\r
17935<section id="MLtonFinalizable">\r
17936<title>MLtonFinalizable</title>\r
17937<programlisting language="sml" linenumbering="unnumbered">signature MLTON_FINALIZABLE =\r
17938 sig\r
17939 type 'a t\r
17940\r
17941 val addFinalizer: 'a t * ('a -&gt; unit) -&gt; unit\r
17942 val finalizeBefore: 'a t * 'b t -&gt; unit\r
17943 val new: 'a -&gt; 'a t\r
17944 val touch: 'a t -&gt; unit\r
17945 val withValue: 'a t * ('a -&gt; 'b) -&gt; 'b\r
17946 end</programlisting>\r
17947<simpara>A <emphasis>finalizable</emphasis> value is a container to which finalizers can be\r
17948attached. A container holds a value, which is reachable as long as\r
17949the container itself is reachable. A <emphasis>finalizer</emphasis> is a function that\r
17950runs at some point after garbage collection determines that the\r
17951container to which it is attached has become\r
17952<link linkend="Reachability">unreachable</link>. A finalizer is treated like a signal\r
17953handler, in that it runs asynchronously in a separate thread, with\r
17954signals blocked, and will not interrupt a critical section (see\r
17955<link linkend="MLtonThread">MLtonThread</link>).</simpara>\r
17956<itemizedlist>\r
17957<listitem>\r
17958<simpara>\r
17959<literal>addFinalizer (v, f)</literal>\r
17960</simpara>\r
17961<simpara>adds <literal>f</literal> as a finalizer to <literal>v</literal>. This means that sometime after the\r
17962last call to <literal>withValue</literal> on <literal>v</literal> completes and <literal>v</literal> becomes unreachable,\r
17963<literal>f</literal> will be called with the value of <literal>v</literal>.</simpara>\r
17964</listitem>\r
17965<listitem>\r
17966<simpara>\r
17967<literal>finalizeBefore (v1, v2)</literal>\r
17968</simpara>\r
17969<simpara>ensures that <literal>v1</literal> will be finalized before <literal>v2</literal>. A cycle of values\r
17970<literal>v</literal> = <literal>v1</literal>, &#8230;, <literal>vn</literal> = <literal>v</literal> with <literal>finalizeBefore (vi, vi+1)</literal> will\r
17971result in none of the <literal>vi</literal> being finalized.</simpara>\r
17972</listitem>\r
17973<listitem>\r
17974<simpara>\r
17975<literal>new x</literal>\r
17976</simpara>\r
17977<simpara>creates a new finalizable value, <literal>v</literal>, with value <literal>x</literal>. The finalizers\r
17978of <literal>v</literal> will run sometime after the last call to <literal>withValue</literal> on <literal>v</literal>\r
17979when the garbage collector determines that <literal>v</literal> is unreachable.</simpara>\r
17980</listitem>\r
17981<listitem>\r
17982<simpara>\r
17983<literal>touch v</literal>\r
17984</simpara>\r
17985<simpara>ensures that <literal>v</literal>'s finalizers will not run before the call to <literal>touch</literal>.</simpara>\r
17986</listitem>\r
17987<listitem>\r
17988<simpara>\r
17989<literal>withValue (v, f)</literal>\r
17990</simpara>\r
17991<simpara>returns the result of applying <literal>f</literal> to the value of <literal>v</literal> and ensures\r
17992that <literal>v</literal>'s finalizers will not run before <literal>f</literal> completes. The call to\r
17993<literal>f</literal> is a nontail call.</simpara>\r
17994</listitem>\r
17995</itemizedlist>\r
17996<section id="_example_4">\r
17997<title>Example</title>\r
17998<simpara>Suppose that <literal>finalizable.sml</literal> contains the following:</simpara>\r
17999<programlisting language="sml" linenumbering="unnumbered">signature CLIST =\r
18000 sig\r
18001 type t\r
18002\r
18003 val cons: int * t -&gt; t\r
18004 val sing: int -&gt; t\r
18005 val sum: t -&gt; int\r
18006 end\r
18007\r
18008functor CList (structure F: MLTON_FINALIZABLE\r
18009 structure P: MLTON_POINTER\r
18010 structure Prim:\r
18011 sig\r
18012 val cons: int * P.t -&gt; P.t\r
18013 val free: P.t -&gt; unit\r
18014 val sing: int -&gt; P.t\r
18015 val sum: P.t -&gt; int\r
18016 end): CLIST =\r
18017 struct\r
18018 type t = P.t F.t\r
18019\r
18020 fun cons (n: int, l: t) =\r
18021 F.withValue\r
18022 (l, fn w' =&gt;\r
18023 let\r
18024 val c = F.new (Prim.cons (n, w'))\r
18025 val _ = F.addFinalizer (c, Prim.free)\r
18026 val _ = F.finalizeBefore (c, l)\r
18027 in\r
18028 c\r
18029 end)\r
18030\r
18031 fun sing n =\r
18032 let\r
18033 val c = F.new (Prim.sing n)\r
18034 val _ = F.addFinalizer (c, Prim.free)\r
18035 in\r
18036 c\r
18037 end\r
18038\r
18039 fun sum c = F.withValue (c, Prim.sum)\r
18040 end\r
18041\r
18042functor Test (structure CList: CLIST\r
18043 structure MLton: sig\r
18044 structure GC:\r
18045 sig\r
18046 val collect: unit -&gt; unit\r
18047 end\r
18048 end) =\r
18049 struct\r
18050 fun f n =\r
18051 if n = 1\r
18052 then ()\r
18053 else\r
18054 let\r
18055 val a = Array.tabulate (n, fn i =&gt; i)\r
18056 val _ = Array.sub (a, 0) + Array.sub (a, 1)\r
18057 in\r
18058 f (n - 1)\r
18059 end\r
18060\r
18061 val l = CList.sing 2\r
18062 val l = CList.cons (2,l)\r
18063 val l = CList.cons (2,l)\r
18064 val l = CList.cons (2,l)\r
18065 val l = CList.cons (2,l)\r
18066 val l = CList.cons (2,l)\r
18067 val l = CList.cons (2,l)\r
18068 val _ = MLton.GC.collect ()\r
18069 val _ = f 100\r
18070 val _ = print (concat ["listSum(l) = ",\r
18071 Int.toString (CList.sum l),\r
18072 "\n"])\r
18073 val _ = MLton.GC.collect ()\r
18074 val _ = f 100\r
18075 end\r
18076\r
18077structure CList =\r
18078 CList (structure F = MLton.Finalizable\r
18079 structure P = MLton.Pointer\r
18080 structure Prim =\r
18081 struct\r
18082 val cons = _import "listCons": int * P.t -&gt; P.t;\r
18083 val free = _import "listFree": P.t -&gt; unit;\r
18084 val sing = _import "listSing": int -&gt; P.t;\r
18085 val sum = _import "listSum": P.t -&gt; int;\r
18086 end)\r
18087\r
18088structure S = Test (structure CList = CList\r
18089 structure MLton = MLton)</programlisting>\r
18090<simpara>Suppose that <literal>cons.c</literal> contains the following.</simpara>\r
18091<programlisting language="c" linenumbering="unnumbered">#include &lt;stdio.h&gt;\r
18092\r
18093typedef unsigned int uint;\r
18094\r
18095typedef struct Cons {\r
18096 struct Cons *next;\r
18097 int value;\r
18098} *Cons;\r
18099\r
18100Cons listCons (int n, Cons c) {\r
18101 Cons res;\r
18102\r
18103 res = (Cons) malloc (sizeof(*res));\r
18104 fprintf (stderr, "0x%08x = listCons (%d)\n", (uint)res, n);\r
18105 res-&gt;next = c;\r
18106 res-&gt;value = n;\r
18107 return res;\r
18108}\r
18109\r
18110Cons listSing (int n) {\r
18111 Cons res;\r
18112\r
18113 res = (Cons) malloc (sizeof(*res));\r
18114 fprintf (stderr, "0x%08x = listSing (%d)\n", (uint)res, n);\r
18115 res-&gt;next = NULL;\r
18116 res-&gt;value = n;\r
18117 return res;\r
18118}\r
18119\r
18120void listFree (Cons p) {\r
18121 fprintf (stderr, "listFree (0x%08x)\n", (uint)p);\r
18122 free (p);\r
18123}\r
18124\r
18125int listSum (Cons c) {\r
18126 int res;\r
18127\r
18128 fprintf (stderr, "listSum\n");\r
18129 res = 0;\r
18130 for (; c != NULL; c = c-&gt;next)\r
18131 res += c-&gt;value;\r
18132 return res;\r
18133}</programlisting>\r
18134<simpara>We can compile these to create an executable with</simpara>\r
18135<screen>% mlton -default-ann 'allowFFI true' finalizable.sml cons.c</screen>\r
18136<simpara>Running this executable will create output like the following.</simpara>\r
18137<screen>% finalizable\r
181380x08072890 = listSing (2)\r
181390x080728a0 = listCons (2)\r
181400x080728b0 = listCons (2)\r
181410x080728c0 = listCons (2)\r
181420x080728d0 = listCons (2)\r
181430x080728e0 = listCons (2)\r
181440x080728f0 = listCons (2)\r
18145listSum\r
18146listSum(l) = 14\r
18147listFree (0x080728f0)\r
18148listFree (0x080728e0)\r
18149listFree (0x080728d0)\r
18150listFree (0x080728c0)\r
18151listFree (0x080728b0)\r
18152listFree (0x080728a0)\r
18153listFree (0x08072890)</screen>\r
18154</section>\r
18155<section id="_synchronous_finalizers">\r
18156<title>Synchronous Finalizers</title>\r
18157<simpara>Finalizers in MLton are asynchronous. That is, they run at an\r
18158unspecified time, interrupting the user program. It is also possible,\r
18159and sometimes useful, to have synchronous finalizers, where the user\r
18160program explicitly decides when to run enabled finalizers. We have\r
18161considered this in MLton, and it seems possible, but there are some\r
18162unresolved design issues. See the thread at</simpara>\r
18163<itemizedlist>\r
18164<listitem>\r
18165<simpara>\r
18166<ulink url="http://www.mlton.org/pipermail/mlton/2004-September/016570.html">http://www.mlton.org/pipermail/mlton/2004-September/016570.html</ulink>\r
18167</simpara>\r
18168</listitem>\r
18169</itemizedlist>\r
18170</section>\r
18171<section id="_also_see_16">\r
18172<title>Also see</title>\r
18173<itemizedlist>\r
18174<listitem>\r
18175<simpara>\r
18176<link linkend="References_Boehm03">Boehm03</link>\r
18177</simpara>\r
18178</listitem>\r
18179</itemizedlist>\r
18180<simpara><?asciidoc-pagebreak?></simpara>\r
18181</section>\r
18182</section>\r
18183<section id="MLtonGC">\r
18184<title>MLtonGC</title>\r
18185<programlisting language="sml" linenumbering="unnumbered">signature MLTON_GC =\r
18186 sig\r
18187 val collect: unit -&gt; unit\r
18188 val pack: unit -&gt; unit\r
18189 val setMessages: bool -&gt; unit\r
18190 val setSummary: bool -&gt; unit\r
18191 val unpack: unit -&gt; unit\r
18192 structure Statistics :\r
18193 sig\r
18194 val bytesAllocated: unit -&gt; IntInf.int\r
18195 val lastBytesLive: unit -&gt; IntInf.int\r
18196 val numCopyingGCs: unit -&gt; IntInf.int\r
18197 val numMarkCompactGCs: unit -&gt; IntInf.int\r
18198 val numMinorGCs: unit -&gt; IntInf.int\r
18199 val maxBytesLive: unit -&gt; IntInf.int\r
18200 end\r
18201 end</programlisting>\r
18202<itemizedlist>\r
18203<listitem>\r
18204<simpara>\r
18205<literal>collect ()</literal>\r
18206</simpara>\r
18207<simpara>causes a garbage collection to occur.</simpara>\r
18208</listitem>\r
18209<listitem>\r
18210<simpara>\r
18211<literal>pack ()</literal>\r
18212</simpara>\r
18213<simpara>shrinks the heap as much as possible so that other processes can use\r
18214available RAM.</simpara>\r
18215</listitem>\r
18216<listitem>\r
18217<simpara>\r
18218<literal>setMessages b</literal>\r
18219</simpara>\r
18220<simpara>controls whether diagnostic messages are printed at the beginning and\r
18221end of each garbage collection. It is the same as the <literal>gc-messages</literal>\r
18222runtime system option.</simpara>\r
18223</listitem>\r
18224<listitem>\r
18225<simpara>\r
18226<literal>setSummary b</literal>\r
18227</simpara>\r
18228<simpara>controls whether a summary of garbage collection statistics is printed\r
18229upon termination of the program. It is the same as the <literal>gc-summary</literal>\r
18230runtime system option.</simpara>\r
18231</listitem>\r
18232<listitem>\r
18233<simpara>\r
18234<literal>unpack ()</literal>\r
18235</simpara>\r
18236<simpara>resizes a packed heap to the size desired by the runtime.</simpara>\r
18237</listitem>\r
18238<listitem>\r
18239<simpara>\r
18240<literal>Statistics.bytesAllocated ()</literal>\r
18241</simpara>\r
18242<simpara>returns bytes allocated (as of the most recent garbage collection).</simpara>\r
18243</listitem>\r
18244<listitem>\r
18245<simpara>\r
18246<literal>Statistics.lastBytesLive ()</literal>\r
18247</simpara>\r
18248<simpara>returns bytes live (as of the most recent garbage collection).</simpara>\r
18249</listitem>\r
18250<listitem>\r
18251<simpara>\r
18252<literal>Statistics.numCopyingGCs ()</literal>\r
18253</simpara>\r
18254<simpara>returns number of (major) copying garbage collections performed (as of\r
18255the most recent garbage collection).</simpara>\r
18256</listitem>\r
18257<listitem>\r
18258<simpara>\r
18259<literal>Statistics.numMarkCompactGCs ()</literal>\r
18260</simpara>\r
18261<simpara>returns number of (major) mark-compact garbage collections performed\r
18262(as of the most recent garbage collection).</simpara>\r
18263</listitem>\r
18264<listitem>\r
18265<simpara>\r
18266<literal>Statistics.numMinorGCs ()</literal>\r
18267</simpara>\r
18268<simpara>returns number of minor garbage collections performed (as of the most\r
18269recent garbage collection).</simpara>\r
18270</listitem>\r
18271<listitem>\r
18272<simpara>\r
18273<literal>Statistics.maxBytesLive ()</literal>\r
18274</simpara>\r
18275<simpara>returns maximum bytes live (as of the most recent garbage collection).</simpara>\r
18276</listitem>\r
18277</itemizedlist>\r
18278<simpara><?asciidoc-pagebreak?></simpara>\r
18279</section>\r
18280<section id="MLtonIntInf">\r
18281<title>MLtonIntInf</title>\r
18282<programlisting language="sml" linenumbering="unnumbered">signature MLTON_INT_INF =\r
18283 sig\r
18284 type t = IntInf.int\r
18285\r
18286 val areSmall: t * t -&gt; bool\r
18287 val gcd: t * t -&gt; t\r
18288 val isSmall: t -&gt; bool\r
18289\r
18290 structure BigWord : WORD\r
18291 structure SmallInt : INTEGER\r
18292 datatype rep =\r
18293 Big of BigWord.word vector\r
18294 | Small of SmallInt.int\r
18295 val rep: t -&gt; rep\r
18296 val fromRep : rep -&gt; t option\r
18297 end</programlisting>\r
18298<simpara>MLton represents an arbitrary precision integer either as an unboxed\r
18299word with the bottom bit set to 1 and the top bits representing a\r
18300small signed integer, or as a pointer to a vector of words, where the\r
18301first word indicates the sign and the rest are the limbs of a\r
18302<link linkend="GnuMP">GnuMP</link> big integer.</simpara>\r
18303<itemizedlist>\r
18304<listitem>\r
18305<simpara>\r
18306<literal>type t</literal>\r
18307</simpara>\r
18308<simpara>the same as type <literal>IntInf.int</literal>.</simpara>\r
18309</listitem>\r
18310<listitem>\r
18311<simpara>\r
18312<literal>areSmall (a, b)</literal>\r
18313</simpara>\r
18314<simpara>returns true iff both <literal>a</literal> and <literal>b</literal> are small.</simpara>\r
18315</listitem>\r
18316<listitem>\r
18317<simpara>\r
18318<literal>gcd (a, b)</literal>\r
18319</simpara>\r
18320<simpara>uses the <link linkend="GnuMP">GnuMP&#8217;s</link> fast gcd implementation.</simpara>\r
18321</listitem>\r
18322<listitem>\r
18323<simpara>\r
18324<literal>isSmall a</literal>\r
18325</simpara>\r
18326<simpara>returns true iff <literal>a</literal> is small.</simpara>\r
18327</listitem>\r
18328<listitem>\r
18329<simpara>\r
18330<literal>BigWord : WORD</literal>\r
18331</simpara>\r
18332<simpara>representation of a big <literal>IntInf.int</literal> as a vector of words; on 32-bit\r
18333platforms, <literal>BigWord</literal> is likely to be equivalent to <literal>Word32</literal>, and on\r
1833464-bit platforms, <literal>BigWord</literal> is likely to be equivalent to <literal>Word64</literal>.</simpara>\r
18335</listitem>\r
18336<listitem>\r
18337<simpara>\r
18338<literal>SmallInt : INTEGER</literal>\r
18339</simpara>\r
18340<simpara>representation of a small <literal>IntInf.int</literal> as a signed integer; on 32-bit\r
18341platforms, <literal>SmallInt</literal> is likely to be equivalent to <literal>Int32</literal>, and on\r
1834264-bit platforms, <literal>SmallInt</literal> is likely to be equivalent to <literal>Int64</literal>.</simpara>\r
18343</listitem>\r
18344<listitem>\r
18345<simpara>\r
18346<literal>datatype rep</literal>\r
18347</simpara>\r
18348<simpara>the underlying representation of an <literal>IntInf.int</literal>.</simpara>\r
18349</listitem>\r
18350<listitem>\r
18351<simpara>\r
18352<literal>rep i</literal>\r
18353</simpara>\r
18354<simpara>returns the underlying representation of <literal>i</literal>.</simpara>\r
18355</listitem>\r
18356<listitem>\r
18357<simpara>\r
18358<literal>fromRep r</literal>\r
18359</simpara>\r
18360<simpara>converts from the underlying representation back to an <literal>IntInf.int</literal>.\r
18361If <literal>fromRep r</literal> is given anything besides the valid result of <literal>rep i</literal>\r
18362for some <literal>i</literal>, this function call will return <literal>NONE</literal>.</simpara>\r
18363</listitem>\r
18364</itemizedlist>\r
18365<simpara><?asciidoc-pagebreak?></simpara>\r
18366</section>\r
18367<section id="MLtonIO">\r
18368<title>MLtonIO</title>\r
18369<programlisting language="sml" linenumbering="unnumbered">signature MLTON_IO =\r
18370 sig\r
18371 type instream\r
18372 type outstream\r
18373\r
18374 val inFd: instream -&gt; Posix.IO.file_desc\r
18375 val mkstemp: string -&gt; string * outstream\r
18376 val mkstemps: {prefix: string, suffix: string} -&gt; string * outstream\r
18377 val newIn: Posix.IO.file_desc * string -&gt; instream\r
18378 val newOut: Posix.IO.file_desc * string -&gt; outstream\r
18379 val outFd: outstream -&gt; Posix.IO.file_desc\r
18380 val tempPrefix: string -&gt; string\r
18381 end</programlisting>\r
18382<itemizedlist>\r
18383<listitem>\r
18384<simpara>\r
18385<literal>inFd ins</literal>\r
18386</simpara>\r
18387<simpara>returns the file descriptor corresponding to <literal>ins</literal>.</simpara>\r
18388</listitem>\r
18389<listitem>\r
18390<simpara>\r
18391<literal>mkstemp s</literal>\r
18392</simpara>\r
18393<simpara>like the C <literal>mkstemp</literal> function, generates and open a temporary file\r
18394with prefix <literal>s</literal>.</simpara>\r
18395</listitem>\r
18396<listitem>\r
18397<simpara>\r
18398<literal>mkstemps {prefix, suffix}</literal>\r
18399</simpara>\r
18400<simpara>like <literal>mkstemp</literal>, except it has both a prefix and suffix.</simpara>\r
18401</listitem>\r
18402<listitem>\r
18403<simpara>\r
18404<literal>newIn (fd, name)</literal>\r
18405</simpara>\r
18406<simpara>creates a new instream from file descriptor <literal>fd</literal>, with <literal>name</literal> used in\r
18407any <literal>Io</literal> exceptions later raised.</simpara>\r
18408</listitem>\r
18409<listitem>\r
18410<simpara>\r
18411<literal>newOut (fd, name)</literal>\r
18412</simpara>\r
18413<simpara>creates a new outstream from file descriptor <literal>fd</literal>, with <literal>name</literal> used in\r
18414any <literal>Io</literal> exceptions later raised.</simpara>\r
18415</listitem>\r
18416<listitem>\r
18417<simpara>\r
18418<literal>outFd out</literal>\r
18419</simpara>\r
18420<simpara>returns the file descriptor corresponding to <literal>out</literal>.</simpara>\r
18421</listitem>\r
18422<listitem>\r
18423<simpara>\r
18424<literal>tempPrefix s</literal>\r
18425</simpara>\r
18426<simpara>adds a suitable system or user specific prefix (directory) for temp\r
18427files.</simpara>\r
18428</listitem>\r
18429</itemizedlist>\r
18430<simpara><?asciidoc-pagebreak?></simpara>\r
18431</section>\r
18432<section id="MLtonItimer">\r
18433<title>MLtonItimer</title>\r
18434<programlisting language="sml" linenumbering="unnumbered">signature MLTON_ITIMER =\r
18435 sig\r
18436 datatype t =\r
18437 Prof\r
18438 | Real\r
18439 | Virtual\r
18440\r
18441 val set: t * {interval: Time.time, value: Time.time} -&gt; unit\r
18442 val signal: t -&gt; Posix.Signal.signal\r
18443 end</programlisting>\r
18444<itemizedlist>\r
18445<listitem>\r
18446<simpara>\r
18447<literal>set (t, {interval, value})</literal>\r
18448</simpara>\r
18449<simpara>sets the interval timer (using <literal>setitimer</literal>) specified by <literal>t</literal> to the\r
18450given <literal>interval</literal> and <literal>value</literal>.</simpara>\r
18451</listitem>\r
18452<listitem>\r
18453<simpara>\r
18454<literal>signal t</literal>\r
18455</simpara>\r
18456<simpara>returns the signal corresponding to <literal>t</literal>.</simpara>\r
18457</listitem>\r
18458</itemizedlist>\r
18459<simpara><?asciidoc-pagebreak?></simpara>\r
18460</section>\r
18461<section id="MLtonLibraryProject">\r
18462<title>MLtonLibraryProject</title>\r
18463<simpara>We have a <ulink url="https://github.com/MLton/mltonlib">MLton Library repository</ulink>\r
18464that is intended to collect libraries.</simpara>\r
18465<informalexample>\r
18466<literallayout class="monospaced">https://github.com/MLton/mltonlib</literallayout>\r
18467</informalexample>\r
18468<simpara>Libraries are kept in the <literal>master</literal> branch, and are grouped according\r
18469to domain name, in the Java package style. For example,\r
18470<link linkend="VesaKarvonen">VesaKarvonen</link>, who works at <literal>ssh.com</literal>, has been putting code at:</simpara>\r
18471<informalexample>\r
18472<literallayout class="monospaced">https://github.com/MLton/mltonlib/tree/master/com/ssh</literallayout>\r
18473</informalexample>\r
18474<simpara><link linkend="StephenWeeks">StephenWeeks</link>, owning <literal>sweeks.com</literal>, has been putting code at:</simpara>\r
18475<informalexample>\r
18476<literallayout class="monospaced">https://github.com/MLton/mltonlib/tree/master/com/sweeks</literallayout>\r
18477</informalexample>\r
18478<simpara>A "library" is a subdirectory of some such directory. For example,\r
18479Stephen&#8217;s basis-library replacement library is at</simpara>\r
18480<informalexample>\r
18481<literallayout class="monospaced">https://github.com/MLton/mltonlib/tree/master/com/sweeks/basic</literallayout>\r
18482</informalexample>\r
18483<simpara>We use "transparent per-library branching" to handle library\r
18484versioning. Each library has an "unstable" subdirectory in which work\r
18485happens. When one is happy with a library, one tags it by copying it\r
18486to a stable version directory. Stable libraries are immutable&#8201;&#8212;&#8201;when\r
18487one refers to a stable library, one always gets exactly the same code.\r
18488No one has actually made a stable library yet, but, when I&#8217;m ready to\r
18489tag my library, I was thinking that I would do something like copying</simpara>\r
18490<informalexample>\r
18491<literallayout class="monospaced">https://github.com/MLton/mltonlib/tree/master/com/sweeks/basic/unstable</literallayout>\r
18492</informalexample>\r
18493<simpara>to</simpara>\r
18494<informalexample>\r
18495<literallayout class="monospaced">https://github.com/MLton/mltonlib/tree/master/com/sweeks/basic/v1</literallayout>\r
18496</informalexample>\r
18497<simpara>So far, libraries in the MLton repository have been licensed under\r
18498MLton&#8217;s <link linkend="License">License</link>. We haven&#8217;t decided on whether that will be a\r
18499requirement to be in the repository or not. For the sake of\r
18500simplicity (a single license) and encouraging widest use of code,\r
18501contributors are encouraged to use that license. But it may be too\r
18502strict to require it.</simpara>\r
18503<simpara>If someone wants to contribute a new library to our repository or to\r
18504work on an old one, they can make a pull request. If people want to\r
18505work in their own repository, they can do so&#8201;&#8212;&#8201;that&#8217;s the point of\r
18506using domain names to prevent clashes. The idea is that a user should\r
18507be able to bring library collections in from many different\r
18508repositories without problems. And those libraries could even work\r
18509with each other.</simpara>\r
18510<simpara>At some point we may want to settle on an <link linkend="MLBasisPathMap">MLBasisPathMap</link> variable\r
18511for the root of the library project. Or, we could reuse <literal>SML_LIB</literal>,\r
18512and migrate what we currently keep there into the library\r
18513infrastructure.</simpara>\r
18514<simpara><?asciidoc-pagebreak?></simpara>\r
18515</section>\r
18516<section id="MLtonMonoArray">\r
18517<title>MLtonMonoArray</title>\r
18518<programlisting language="sml" linenumbering="unnumbered">signature MLTON_MONO_ARRAY =\r
18519 sig\r
18520 type t\r
18521 type elem\r
18522 val fromPoly: elem array -&gt; t\r
18523 val toPoly: t -&gt; elem array\r
18524 end</programlisting>\r
18525<itemizedlist>\r
18526<listitem>\r
18527<simpara>\r
18528<literal>type t</literal>\r
18529</simpara>\r
18530<simpara>type of monomorphic array</simpara>\r
18531</listitem>\r
18532<listitem>\r
18533<simpara>\r
18534<literal>type elem</literal>\r
18535</simpara>\r
18536<simpara>type of array elements</simpara>\r
18537</listitem>\r
18538<listitem>\r
18539<simpara>\r
18540<literal>fromPoly a</literal>\r
18541</simpara>\r
18542<simpara>type cast a polymorphic array to its monomorphic counterpart; the\r
18543argument and result arrays share the same identity</simpara>\r
18544</listitem>\r
18545<listitem>\r
18546<simpara>\r
18547<literal>toPoly a</literal>\r
18548</simpara>\r
18549<simpara>type cast a monomorphic array to its polymorphic counterpart; the\r
18550argument and result arrays share the same identity</simpara>\r
18551</listitem>\r
18552</itemizedlist>\r
18553<simpara><?asciidoc-pagebreak?></simpara>\r
18554</section>\r
18555<section id="MLtonMonoVector">\r
18556<title>MLtonMonoVector</title>\r
18557<programlisting language="sml" linenumbering="unnumbered">signature MLTON_MONO_VECTOR =\r
18558 sig\r
18559 type t\r
18560 type elem\r
18561 val fromPoly: elem vector -&gt; t\r
18562 val toPoly: t -&gt; elem vector\r
18563 end</programlisting>\r
18564<itemizedlist>\r
18565<listitem>\r
18566<simpara>\r
18567<literal>type t</literal>\r
18568</simpara>\r
18569<simpara>type of monomorphic vector</simpara>\r
18570</listitem>\r
18571<listitem>\r
18572<simpara>\r
18573<literal>type elem</literal>\r
18574</simpara>\r
18575<simpara>type of vector elements</simpara>\r
18576</listitem>\r
18577<listitem>\r
18578<simpara>\r
18579<literal>fromPoly v</literal>\r
18580</simpara>\r
18581<simpara>type cast a polymorphic vector to its monomorphic counterpart; in\r
18582MLton, this is a constant-time operation</simpara>\r
18583</listitem>\r
18584<listitem>\r
18585<simpara>\r
18586<literal>toPoly v</literal>\r
18587</simpara>\r
18588<simpara>type cast a monomorphic vector to its polymorphic counterpart; in\r
18589MLton, this is a constant-time operation</simpara>\r
18590</listitem>\r
18591</itemizedlist>\r
18592<simpara><?asciidoc-pagebreak?></simpara>\r
18593</section>\r
18594<section id="MLtonPlatform">\r
18595<title>MLtonPlatform</title>\r
18596<programlisting language="sml" linenumbering="unnumbered">signature MLTON_PLATFORM =\r
18597 sig\r
18598 structure Arch:\r
18599 sig\r
18600 datatype t = Alpha | AMD64 | ARM | ARM64 | HPPA | IA64 | m68k\r
18601 | MIPS | PowerPC | PowerPC64 | S390 | Sparc | X86\r
18602\r
18603 val fromString: string -&gt; t option\r
18604 val host: t\r
18605 val toString: t -&gt; string\r
18606 end\r
18607\r
18608 structure OS:\r
18609 sig\r
18610 datatype t = AIX | Cygwin | Darwin | FreeBSD | Hurd | HPUX\r
18611 | Linux | MinGW | NetBSD | OpenBSD | Solaris\r
18612\r
18613 val fromString: string -&gt; t option\r
18614 val host: t\r
18615 val toString: t -&gt; string\r
18616 end\r
18617 end</programlisting>\r
18618<itemizedlist>\r
18619<listitem>\r
18620<simpara>\r
18621<literal>datatype Arch.t</literal>\r
18622</simpara>\r
18623<simpara>processor architectures</simpara>\r
18624</listitem>\r
18625<listitem>\r
18626<simpara>\r
18627<literal>Arch.fromString a</literal>\r
18628</simpara>\r
18629<simpara>converts from string to architecture. Case insensitive.</simpara>\r
18630</listitem>\r
18631<listitem>\r
18632<simpara>\r
18633<literal>Arch.host</literal>\r
18634</simpara>\r
18635<simpara>the architecture for which the program is compiled.</simpara>\r
18636</listitem>\r
18637<listitem>\r
18638<simpara>\r
18639<literal>Arch.toString</literal>\r
18640</simpara>\r
18641<simpara>string for architecture.</simpara>\r
18642</listitem>\r
18643<listitem>\r
18644<simpara>\r
18645<literal>datatype OS.t</literal>\r
18646</simpara>\r
18647<simpara>operating systems</simpara>\r
18648</listitem>\r
18649<listitem>\r
18650<simpara>\r
18651<literal>OS.fromString</literal>\r
18652</simpara>\r
18653<simpara>converts from string to operating system. Case insensitive.</simpara>\r
18654</listitem>\r
18655<listitem>\r
18656<simpara>\r
18657<literal>OS.host</literal>\r
18658</simpara>\r
18659<simpara>the operating system for which the program is compiled.</simpara>\r
18660</listitem>\r
18661<listitem>\r
18662<simpara>\r
18663<literal>OS.toString</literal>\r
18664</simpara>\r
18665<simpara>string for operating system.</simpara>\r
18666</listitem>\r
18667</itemizedlist>\r
18668<simpara><?asciidoc-pagebreak?></simpara>\r
18669</section>\r
18670<section id="MLtonPointer">\r
18671<title>MLtonPointer</title>\r
18672<programlisting language="sml" linenumbering="unnumbered">signature MLTON_POINTER =\r
18673 sig\r
18674 eqtype t\r
18675\r
18676 val add: t * word -&gt; t\r
18677 val compare: t * t -&gt; order\r
18678 val diff: t * t -&gt; word\r
18679 val getInt8: t * int -&gt; Int8.int\r
18680 val getInt16: t * int -&gt; Int16.int\r
18681 val getInt32: t * int -&gt; Int32.int\r
18682 val getInt64: t * int -&gt; Int64.int\r
18683 val getPointer: t * int -&gt; t\r
18684 val getReal32: t * int -&gt; Real32.real\r
18685 val getReal64: t * int -&gt; Real64.real\r
18686 val getWord8: t * int -&gt; Word8.word\r
18687 val getWord16: t * int -&gt; Word16.word\r
18688 val getWord32: t * int -&gt; Word32.word\r
18689 val getWord64: t * int -&gt; Word64.word\r
18690 val null: t\r
18691 val setInt8: t * int * Int8.int -&gt; unit\r
18692 val setInt16: t * int * Int16.int -&gt; unit\r
18693 val setInt32: t * int * Int32.int -&gt; unit\r
18694 val setInt64: t * int * Int64.int -&gt; unit\r
18695 val setPointer: t * int * t -&gt; unit\r
18696 val setReal32: t * int * Real32.real -&gt; unit\r
18697 val setReal64: t * int * Real64.real -&gt; unit\r
18698 val setWord8: t * int * Word8.word -&gt; unit\r
18699 val setWord16: t * int * Word16.word -&gt; unit\r
18700 val setWord32: t * int * Word32.word -&gt; unit\r
18701 val setWord64: t * int * Word64.word -&gt; unit\r
18702 val sizeofPointer: word\r
18703 val sub: t * word -&gt; t\r
18704 end</programlisting>\r
18705<itemizedlist>\r
18706<listitem>\r
18707<simpara>\r
18708<literal>eqtype t</literal>\r
18709</simpara>\r
18710<simpara>the type of pointers, i.e. machine addresses.</simpara>\r
18711</listitem>\r
18712<listitem>\r
18713<simpara>\r
18714<literal>add (p, w)</literal>\r
18715</simpara>\r
18716<simpara>returns the pointer <literal>w</literal> bytes after than <literal>p</literal>. Does not check for\r
18717overflow.</simpara>\r
18718</listitem>\r
18719<listitem>\r
18720<simpara>\r
18721<literal>compare (p1, p2)</literal>\r
18722</simpara>\r
18723<simpara>compares the pointer <literal>p1</literal> to the pointer <literal>p2</literal> (as addresses).</simpara>\r
18724</listitem>\r
18725<listitem>\r
18726<simpara>\r
18727<literal>diff (p1, p2)</literal>\r
18728</simpara>\r
18729<simpara>returns the number of bytes <literal>w</literal> such that <literal>add (p2, w) = p1</literal>. Does\r
18730not check for overflow.</simpara>\r
18731</listitem>\r
18732<listitem>\r
18733<simpara>\r
18734<literal>get<emphasis>&lt;X&gt;</emphasis> (p, i)</literal>\r
18735</simpara>\r
18736<simpara>returns the object stored at index i of the array of <emphasis>X</emphasis> objects\r
18737pointed to by <literal>p</literal>. For example, <literal>getWord32 (p, 7)</literal> returns the 32-bit\r
18738word stored 28 bytes beyond <literal>p</literal>.</simpara>\r
18739</listitem>\r
18740<listitem>\r
18741<simpara>\r
18742<literal>null</literal>\r
18743</simpara>\r
18744<simpara>the null pointer, i.e. 0.</simpara>\r
18745</listitem>\r
18746<listitem>\r
18747<simpara>\r
18748<literal>set<emphasis>&lt;X&gt;</emphasis> (p, i, v)</literal>\r
18749</simpara>\r
18750<simpara>assigns <literal>v</literal> to the object stored at index i of the array of <emphasis>X</emphasis>\r
18751objects pointed to by <literal>p</literal>. For example, <literal>setWord32 (p, 7, w)</literal> stores\r
18752the 32-bit word <literal>w</literal> at the address 28 bytes beyond <literal>p</literal>.</simpara>\r
18753</listitem>\r
18754<listitem>\r
18755<simpara>\r
18756<literal>sizeofPointer</literal>\r
18757</simpara>\r
18758<simpara>size, in bytes, of a pointer.</simpara>\r
18759</listitem>\r
18760<listitem>\r
18761<simpara>\r
18762<literal>sub (p, w)</literal>\r
18763</simpara>\r
18764<simpara>returns the pointer <literal>w</literal> bytes before <literal>p</literal>. Does not check for\r
18765overflow.</simpara>\r
18766</listitem>\r
18767</itemizedlist>\r
18768<simpara><?asciidoc-pagebreak?></simpara>\r
18769</section>\r
18770<section id="MLtonProcEnv">\r
18771<title>MLtonProcEnv</title>\r
18772<programlisting language="sml" linenumbering="unnumbered">signature MLTON_PROC_ENV =\r
18773 sig\r
18774 type gid\r
18775\r
18776 val setenv: {name: string, value: string} -&gt; unit\r
18777 val setgroups: gid list -&gt; unit\r
18778 end</programlisting>\r
18779<itemizedlist>\r
18780<listitem>\r
18781<simpara>\r
18782<literal>setenv {name, value}</literal>\r
18783</simpara>\r
18784<simpara>like the C <literal>setenv</literal> function. Does not require <literal>name</literal> or <literal>value</literal> to\r
18785be null terminated.</simpara>\r
18786</listitem>\r
18787<listitem>\r
18788<simpara>\r
18789<literal>setgroups grps</literal>\r
18790</simpara>\r
18791<simpara>like the C <literal>setgroups</literal> function.</simpara>\r
18792</listitem>\r
18793</itemizedlist>\r
18794<simpara><?asciidoc-pagebreak?></simpara>\r
18795</section>\r
18796<section id="MLtonProcess">\r
18797<title>MLtonProcess</title>\r
18798<programlisting language="sml" linenumbering="unnumbered">signature MLTON_PROCESS =\r
18799 sig\r
18800 type pid\r
18801\r
18802 val spawn: {args: string list, path: string} -&gt; pid\r
18803 val spawne: {args: string list, env: string list, path: string} -&gt; pid\r
18804 val spawnp: {args: string list, file: string} -&gt; pid\r
18805\r
18806 type ('stdin, 'stdout, 'stderr) t\r
18807\r
18808 type input\r
18809 type output\r
18810\r
18811 type none\r
18812 type chain\r
18813 type any\r
18814\r
18815 exception MisuseOfForget\r
18816 exception DoublyRedirected\r
18817\r
18818 structure Child:\r
18819 sig\r
18820 type ('use, 'dir) t\r
18821\r
18822 val binIn: (BinIO.instream, input) t -&gt; BinIO.instream\r
18823 val binOut: (BinIO.outstream, output) t -&gt; BinIO.outstream\r
18824 val fd: (Posix.FileSys.file_desc, 'dir) t -&gt; Posix.FileSys.file_desc\r
18825 val remember: (any, 'dir) t -&gt; ('use, 'dir) t\r
18826 val textIn: (TextIO.instream, input) t -&gt; TextIO.instream\r
18827 val textOut: (TextIO.outstream, output) t -&gt; TextIO.outstream\r
18828 end\r
18829\r
18830 structure Param:\r
18831 sig\r
18832 type ('use, 'dir) t\r
18833\r
18834 val child: (chain, 'dir) Child.t -&gt; (none, 'dir) t\r
18835 val fd: Posix.FileSys.file_desc -&gt; (none, 'dir) t\r
18836 val file: string -&gt; (none, 'dir) t\r
18837 val forget: ('use, 'dir) t -&gt; (any, 'dir) t\r
18838 val null: (none, 'dir) t\r
18839 val pipe: ('use, 'dir) t\r
18840 val self: (none, 'dir) t\r
18841 end\r
18842\r
18843 val create:\r
18844 {args: string list,\r
18845 env: string list option,\r
18846 path: string,\r
18847 stderr: ('stderr, output) Param.t,\r
18848 stdin: ('stdin, input) Param.t,\r
18849 stdout: ('stdout, output) Param.t}\r
18850 -&gt; ('stdin, 'stdout, 'stderr) t\r
18851 val getStderr: ('stdin, 'stdout, 'stderr) t -&gt; ('stderr, input) Child.t\r
18852 val getStdin: ('stdin, 'stdout, 'stderr) t -&gt; ('stdin, output) Child.t\r
18853 val getStdout: ('stdin, 'stdout, 'stderr) t -&gt; ('stdout, input) Child.t\r
18854 val kill: ('stdin, 'stdout, 'stderr) t * Posix.Signal.signal -&gt; unit\r
18855 val reap: ('stdin, 'stdout, 'stderr) t -&gt; Posix.Process.exit_status\r
18856 end</programlisting>\r
18857<section id="_spawn">\r
18858<title>Spawn</title>\r
18859<simpara>The <literal>spawn</literal> functions provide an alternative to the\r
18860<literal>fork</literal>/<literal>exec</literal> idiom that is typically used to create a new\r
18861process. On most platforms, the <literal>spawn</literal> functions are simple\r
18862wrappers around <literal>fork</literal>/<literal>exec</literal>. However, under Windows, the\r
18863<literal>spawn</literal> functions are primitive. All <literal>spawn</literal> functions return\r
18864the process id of the spawned process. They differ in how the\r
18865executable is found and the environment that it uses.</simpara>\r
18866<itemizedlist>\r
18867<listitem>\r
18868<simpara>\r
18869<literal>spawn {args, path}</literal>\r
18870</simpara>\r
18871<simpara>starts a new process running the executable specified by <literal>path</literal>\r
18872with the arguments <literal>args</literal>. Like <literal>Posix.Process.exec</literal>.</simpara>\r
18873</listitem>\r
18874<listitem>\r
18875<simpara>\r
18876<literal>spawne {args, env, path}</literal>\r
18877</simpara>\r
18878<simpara>starts a new process running the executable specified by <literal>path</literal> with\r
18879the arguments <literal>args</literal> and environment <literal>env</literal>. Like\r
18880<literal>Posix.Process.exece</literal>.</simpara>\r
18881</listitem>\r
18882<listitem>\r
18883<simpara>\r
18884<literal>spawnp {args, file}</literal>\r
18885</simpara>\r
18886<simpara>search the <literal>PATH</literal> environment variable for an executable named <literal>file</literal>,\r
18887and start a new process running that executable with the arguments\r
18888<literal>args</literal>. Like <literal>Posix.Process.execp</literal>.</simpara>\r
18889</listitem>\r
18890</itemizedlist>\r
18891</section>\r
18892<section id="_create">\r
18893<title>Create</title>\r
18894<simpara><literal>MLton.Process.create</literal> provides functionality similar to\r
18895<literal>Unix.executeInEnv</literal>, but provides more control control over the input,\r
18896output, and error streams. In addition, <literal>create</literal> works on all\r
18897platforms, including Cygwin and MinGW (Windows) where <literal>Posix.fork</literal> is\r
18898unavailable. For greatest portability programs should still use the\r
18899standard <literal>Unix.execute</literal>, <literal>Unix.executeInEnv</literal>, and <literal>OS.Process.system</literal>.</simpara>\r
18900<simpara>The following types and sub-structures are used by the <literal>create</literal>\r
18901function. They provide static type checking of correct stream usage.</simpara>\r
18902<section id="_child">\r
18903<title>Child</title>\r
18904<itemizedlist>\r
18905<listitem>\r
18906<simpara>\r
18907<literal>('use, 'dir) Child.t</literal>\r
18908</simpara>\r
18909<simpara>This represents a handle to one of a child&#8217;s standard streams. The\r
18910<literal>'dir</literal> is viewed with respect to the parent. Thus a <literal>('a, input)\r
18911Child.t</literal> handle means that the parent may input the output from the\r
18912child.</simpara>\r
18913</listitem>\r
18914<listitem>\r
18915<simpara>\r
18916<literal>Child.{bin,text}{In,Out} h</literal>\r
18917</simpara>\r
18918<simpara>These functions take a handle and bind it to a stream of the named\r
18919type. The type system will detect attempts to reverse the direction\r
18920of a stream or to use the same stream in multiple, incompatible ways.</simpara>\r
18921</listitem>\r
18922<listitem>\r
18923<simpara>\r
18924<literal>Child.fd h</literal>\r
18925</simpara>\r
18926<simpara>This function behaves like the other <literal>Child.*</literal> functions; it opens a\r
18927stream. However, it does not enforce that you read or write from the\r
18928handle. If you use the descriptor in an inappropriate direction, the\r
18929behavior is undefined. Furthermore, this function may potentially be\r
18930unavailable on future MLton host platforms.</simpara>\r
18931</listitem>\r
18932<listitem>\r
18933<simpara>\r
18934<literal>Child.remember h</literal>\r
18935</simpara>\r
18936<simpara>This function takes a stream of use <literal>any</literal> and resets the use of the\r
18937stream so that the stream may be used by <literal>Child.*</literal>. An <literal>any</literal> stream\r
18938may have had use <literal>none</literal> or <literal>'use</literal> prior to calling <literal>Param.forget</literal>. If\r
18939the stream was <literal>none</literal> and is used, <literal>MisuseOfForget</literal> is raised.</simpara>\r
18940</listitem>\r
18941</itemizedlist>\r
18942</section>\r
18943<section id="_param">\r
18944<title>Param</title>\r
18945<itemizedlist>\r
18946<listitem>\r
18947<simpara>\r
18948<literal>('use, 'dir) Param.t</literal>\r
18949</simpara>\r
18950<simpara>This is a handle to an input/output source and will be passed to the\r
18951created child process. The <literal>'dir</literal> is relative to the child process.\r
18952Input means that the child process will read from this stream.</simpara>\r
18953</listitem>\r
18954<listitem>\r
18955<simpara>\r
18956<literal>Param.child h</literal>\r
18957</simpara>\r
18958<simpara>Connect the stream of the new child process to the stream of a\r
18959previously created child process. A single child stream should be\r
18960connected to only one child process or else <literal>DoublyRedirected</literal> will be\r
18961raised.</simpara>\r
18962</listitem>\r
18963<listitem>\r
18964<simpara>\r
18965<literal>Param.fd fd</literal>\r
18966</simpara>\r
18967<simpara>This creates a stream from the provided file descriptor which will be\r
18968closed when <literal>create</literal> is called. This function may not be available on\r
18969future MLton host platforms.</simpara>\r
18970</listitem>\r
18971<listitem>\r
18972<simpara>\r
18973<literal>Param.forget h</literal>\r
18974</simpara>\r
18975<simpara>This hides the type of the actual parameter as <literal>any</literal>. This is useful\r
18976if you are implementing an application which conditionally attaches\r
18977the child process to files or pipes. However, you must ensure that\r
18978your use after <literal>Child.remember</literal> matches the original type.</simpara>\r
18979</listitem>\r
18980<listitem>\r
18981<simpara>\r
18982<literal>Param.file s</literal>\r
18983</simpara>\r
18984<simpara>Open the given file and connect it to the child process. Note that the\r
18985file will be opened only when <literal>create</literal> is called. So any exceptions\r
18986will be raised there and not by this function. If used for <literal>input</literal>,\r
18987the file is opened read-only. If used for <literal>output</literal>, the file is opened\r
18988read-write.</simpara>\r
18989</listitem>\r
18990<listitem>\r
18991<simpara>\r
18992<literal>Param.null</literal>\r
18993</simpara>\r
18994<simpara>In some situations, the child process should have its output\r
18995discarded. The <literal>null</literal> param when passed as <literal>stdout</literal> or <literal>stderr</literal> does\r
18996this. When used for <literal>stdin</literal>, the child process will either receive\r
18997<literal>EOF</literal> or a failure condition if it attempts to read from <literal>stdin</literal>.</simpara>\r
18998</listitem>\r
18999<listitem>\r
19000<simpara>\r
19001<literal>Param.pipe</literal>\r
19002</simpara>\r
19003<simpara>This will connect the input/output of the child process to a pipe\r
19004which the parent process holds. This may later form the input to one\r
19005of the <literal>Child.*</literal> functions and/or the <literal>Param.child</literal> function.</simpara>\r
19006</listitem>\r
19007<listitem>\r
19008<simpara>\r
19009<literal>Param.self</literal>\r
19010</simpara>\r
19011<simpara>This will connect the input/output of the child process to the\r
19012corresponding stream of the parent process.</simpara>\r
19013</listitem>\r
19014</itemizedlist>\r
19015</section>\r
19016<section id="_process">\r
19017<title>Process</title>\r
19018<itemizedlist>\r
19019<listitem>\r
19020<simpara>\r
19021<literal>type ('stdin, 'stdout, 'stderr) t</literal>\r
19022</simpara>\r
19023<simpara>represents a handle to a child process. The type arguments capture\r
19024how the named stream of the child process may be used.</simpara>\r
19025</listitem>\r
19026<listitem>\r
19027<simpara>\r
19028<literal>type any</literal>\r
19029</simpara>\r
19030<simpara>bypasses the type system in situations where an application does not\r
19031want the it to enforce correct usage. See <literal>Child.remember</literal> and\r
19032<literal>Param.forget</literal>.</simpara>\r
19033</listitem>\r
19034<listitem>\r
19035<simpara>\r
19036<literal>type chain</literal>\r
19037</simpara>\r
19038<simpara>means that the child process&#8217;s stream was connected via a pipe to the\r
19039parent process. The parent process may pass this pipe in turn to\r
19040another child, thus chaining them together.</simpara>\r
19041</listitem>\r
19042<listitem>\r
19043<simpara>\r
19044<literal>type input, output</literal>\r
19045</simpara>\r
19046<simpara>record the direction that a stream flows. They are used as a part of\r
19047<literal>Param.t</literal> and <literal>Child.t</literal> and is detailed there.</simpara>\r
19048</listitem>\r
19049<listitem>\r
19050<simpara>\r
19051<literal>type none</literal>\r
19052</simpara>\r
19053<simpara>means that the child process&#8217;s stream my not be used by the parent\r
19054process. This happens when the child process is connected directly to\r
19055some source.</simpara>\r
19056<simpara>The types <literal>BinIO.instream</literal>, <literal>BinIO.outstream</literal>, <literal>TextIO.instream</literal>,\r
19057<literal>TextIO.outstream</literal>, and <literal>Posix.FileSys.file_desc</literal> are also valid types\r
19058with which to instantiate child streams.</simpara>\r
19059</listitem>\r
19060<listitem>\r
19061<simpara>\r
19062<literal>exception MisuseOfForget</literal>\r
19063</simpara>\r
19064<simpara>may be raised if <literal>Child.remember</literal> and <literal>Param.forget</literal> are used to\r
19065bypass the normal type checking. This exception will only be raised\r
19066in cases where the <literal>forget</literal> mechanism allows a misuse that would be\r
19067impossible with the type-safe versions.</simpara>\r
19068</listitem>\r
19069<listitem>\r
19070<simpara>\r
19071<literal>exception DoublyRedirected</literal>\r
19072</simpara>\r
19073<simpara>raised if a stream connected to a child process is redirected to two\r
19074separate child processes. It is safe, though bad style, to use the a\r
19075<literal>Child.t</literal> with the same <literal>Child.*</literal> function repeatedly.</simpara>\r
19076</listitem>\r
19077<listitem>\r
19078<simpara>\r
19079<literal>create {args, path, env, stderr, stdin, stdout}</literal>\r
19080</simpara>\r
19081<simpara>starts a child process with the given command-line <literal>args</literal> (excluding\r
19082the program name). <literal>path</literal> should be an absolute path to the executable\r
19083run in the new child process; relative paths work, but are less\r
19084robust. Optionally, the environment may be overridden with <literal>env</literal>\r
19085where each string element has the form <literal>"key=value"</literal>. The <literal>std*</literal>\r
19086options must be provided by the <literal>Param.*</literal> functions documented above.</simpara>\r
19087<simpara>Processes which are <literal>create</literal>-d must be either <literal>reap</literal>-ed or <literal>kill</literal>-ed.</simpara>\r
19088</listitem>\r
19089<listitem>\r
19090<simpara>\r
19091<literal>getStd{in,out,err} proc</literal>\r
19092</simpara>\r
19093<simpara>gets a handle to the specified stream. These should be used by the\r
19094<literal>Child.*</literal> functions. Failure to use a stream connected via pipe to a\r
19095child process may result in runtime dead-lock and elicits a compiler\r
19096warning.</simpara>\r
19097</listitem>\r
19098<listitem>\r
19099<simpara>\r
19100<literal>kill (proc, sig)</literal>\r
19101</simpara>\r
19102<simpara>terminates the child process immediately. The signal may or may not\r
19103mean anything depending on the host platform. A good value is\r
19104<literal>Posix.Signal.term</literal>.</simpara>\r
19105</listitem>\r
19106<listitem>\r
19107<simpara>\r
19108<literal>reap proc</literal>\r
19109</simpara>\r
19110<simpara>waits for the child process to terminate and return its exit status.</simpara>\r
19111</listitem>\r
19112</itemizedlist>\r
19113</section>\r
19114</section>\r
19115<section id="_important_usage_notes">\r
19116<title>Important usage notes</title>\r
19117<simpara>When building an application with many pipes between child processes,\r
19118it is important to ensure that there are no cycles in the undirected\r
19119pipe graph. If this property is not maintained, deadlocks are a very\r
19120serious potential bug which may only appear under difficult to\r
19121reproduce conditions.</simpara>\r
19122<simpara>The danger lies in that most operating systems implement pipes with a\r
19123fixed buffer size. If process A has two output pipes which process B\r
19124reads, it can happen that process A blocks writing to pipe 2 because\r
19125it is full while process B blocks reading from pipe 1 because it is\r
19126empty. This same situation can happen with any undirected cycle formed\r
19127between processes (vertexes) and pipes (undirected edges) in the\r
19128graph.</simpara>\r
19129<simpara>It is possible to make this safe using low-level I/O primitives for\r
19130polling. However, these primitives are not very portable and\r
19131difficult to use properly. A far better approach is to make sure you\r
19132never create a cycle in the first place.</simpara>\r
19133<simpara>For these reasons, the <literal>Unix.executeInEnv</literal> is a very dangerous\r
19134function. Be careful when using it to ensure that the child process\r
19135only operates on either <literal>stdin</literal> or <literal>stdout</literal>, but not both.</simpara>\r
19136</section>\r
19137<section id="_example_use_of_mlton_process_create">\r
19138<title>Example use of MLton.Process.create</title>\r
19139<simpara>The following example program launches the <literal>ipconfig</literal> utility, pipes\r
19140its output through <literal>grep</literal>, and then reads the result back into the\r
19141program.</simpara>\r
19142<programlisting language="sml" linenumbering="unnumbered">open MLton.Process\r
19143val p =\r
19144 create {args = [ "/all" ],\r
19145 env = NONE,\r
19146 path = "C:\\WINDOWS\\system32\\ipconfig.exe",\r
19147 stderr = Param.self,\r
19148 stdin = Param.null,\r
19149 stdout = Param.pipe}\r
19150val q =\r
19151 create {args = [ "IP-Ad" ],\r
19152 env = NONE,\r
19153 path = "C:\\msys\\bin\\grep.exe",\r
19154 stderr = Param.self,\r
19155 stdin = Param.child (getStdout p),\r
19156 stdout = Param.pipe}\r
19157fun suck h =\r
19158 case TextIO.inputLine h of\r
19159 NONE =&gt; ()\r
19160 | SOME s =&gt; (print ("'" ^ s ^ "'\n"); suck h)\r
19161\r
19162val () = suck (Child.textIn (getStdout q))</programlisting>\r
19163<simpara><?asciidoc-pagebreak?></simpara>\r
19164</section>\r
19165</section>\r
19166<section id="MLtonProfile">\r
19167<title>MLtonProfile</title>\r
19168<programlisting language="sml" linenumbering="unnumbered">signature MLTON_PROFILE =\r
19169 sig\r
19170 structure Data:\r
19171 sig\r
19172 type t\r
19173\r
19174 val equals: t * t -&gt; bool\r
19175 val free: t -&gt; unit\r
19176 val malloc: unit -&gt; t\r
19177 val write: t * string -&gt; unit\r
19178 end\r
19179\r
19180 val isOn: bool\r
19181 val withData: Data.t * (unit -&gt; 'a) -&gt; 'a\r
19182 end</programlisting>\r
19183<simpara><literal>MLton.Profile</literal> provides <link linkend="Profiling">Profiling</link> control from within the\r
19184program, allowing you to profile individual portions of your\r
19185program. With <literal>MLton.Profile</literal>, you can create many units of profiling\r
19186data (essentially, mappings from functions to counts) during a run of\r
19187a program, switch between them while the program is running, and\r
19188output multiple <literal>mlmon.out</literal> files.</simpara>\r
19189<itemizedlist>\r
19190<listitem>\r
19191<simpara>\r
19192<literal>isOn</literal>\r
19193</simpara>\r
19194<simpara>a compile-time constant that is false only when compiling <literal>-profile no</literal>.</simpara>\r
19195</listitem>\r
19196<listitem>\r
19197<simpara>\r
19198<literal>type Data.t</literal>\r
19199</simpara>\r
19200<simpara>the type of a unit of profiling data. In order to most efficiently\r
19201execute non-profiled programs, when compiling <literal>-profile no</literal> (the\r
19202default), <literal>Data.t</literal> is equivalent to <literal>unit ref</literal>.</simpara>\r
19203</listitem>\r
19204<listitem>\r
19205<simpara>\r
19206<literal>Data.equals (x, y)</literal>\r
19207</simpara>\r
19208<simpara>returns true if the <literal>x</literal> and <literal>y</literal> are the same unit of profiling data.</simpara>\r
19209</listitem>\r
19210<listitem>\r
19211<simpara>\r
19212<literal>Data.free x</literal>\r
19213</simpara>\r
19214<simpara>frees the memory associated with the unit of profiling data <literal>x</literal>. It\r
19215is an error to free the current unit of profiling data or to free a\r
19216previously freed unit of profiling data. When compiling\r
19217<literal>-profile no</literal>, <literal>Data.free x</literal> is a no-op.</simpara>\r
19218</listitem>\r
19219<listitem>\r
19220<simpara>\r
19221<literal>Data.malloc ()</literal>\r
19222</simpara>\r
19223<simpara>returns a new unit of profiling data. Each unit of profiling data is\r
19224allocated from the process address space (but is <emphasis>not</emphasis> in the MLton\r
19225heap) and consumes memory proportional to the number of source\r
19226functions. When compiling <literal>-profile no</literal>, <literal>Data.malloc ()</literal> is\r
19227equivalent to allocating a new <literal>unit ref</literal>.</simpara>\r
19228</listitem>\r
19229<listitem>\r
19230<simpara>\r
19231<literal>write (x, f)</literal>\r
19232</simpara>\r
19233<simpara>writes the accumulated ticks in the unit of profiling data <literal>x</literal> to file\r
19234<literal>f</literal>. It is an error to write a previously freed unit of profiling\r
19235data. When compiling <literal>-profile no</literal>, <literal>write (x, f)</literal> is a no-op. A\r
19236profiled program will always write the current unit of profiling data\r
19237at program exit to a file named <literal>mlmon.out</literal>.</simpara>\r
19238</listitem>\r
19239<listitem>\r
19240<simpara>\r
19241<literal>withData (d, f)</literal>\r
19242</simpara>\r
19243<simpara>runs <literal>f</literal> with <literal>d</literal> as the unit of profiling data, and returns the\r
19244result of <literal>f</literal> after restoring the current unit of profiling data.\r
19245When compiling <literal>-profile no</literal>, <literal>withData (d, f)</literal> is equivalent to\r
19246<literal>f ()</literal>.</simpara>\r
19247</listitem>\r
19248</itemizedlist>\r
19249<section id="_example_5">\r
19250<title>Example</title>\r
19251<simpara>Here is an example, taken from the <literal>examples/profiling</literal> directory,\r
19252showing how to profile the executions of the <literal>fib</literal> and <literal>tak</literal> functions\r
19253separately. Suppose that <literal>fib-tak.sml</literal> contains the following.</simpara>\r
19254<programlisting language="sml" linenumbering="unnumbered">structure Profile = MLton.Profile\r
19255\r
19256val fibData = Profile.Data.malloc ()\r
19257val takData = Profile.Data.malloc ()\r
19258\r
19259fun wrap (f, d) x =\r
19260 Profile.withData (d, fn () =&gt; f x)\r
19261\r
19262val rec fib =\r
19263 fn 0 =&gt; 0\r
19264 | 1 =&gt; 1\r
19265 | n =&gt; fib (n - 1) + fib (n - 2)\r
19266val fib = wrap (fib, fibData)\r
19267\r
19268fun tak (x,y,z) =\r
19269 if not (y &lt; x)\r
19270 then z\r
19271 else tak (tak (x - 1, y, z),\r
19272 tak (y - 1, z, x),\r
19273 tak (z - 1, x, y))\r
19274val tak = wrap (tak, takData)\r
19275\r
19276val rec f =\r
19277 fn 0 =&gt; ()\r
19278 | n =&gt; (fib 38; f (n-1))\r
19279val _ = f 2\r
19280\r
19281val rec g =\r
19282 fn 0 =&gt; ()\r
19283 | n =&gt; (tak (18,12,6); g (n-1))\r
19284val _ = g 500\r
19285\r
19286fun done (data, file) =\r
19287 (Profile.Data.write (data, file)\r
19288 ; Profile.Data.free data)\r
19289\r
19290val _ = done (fibData, "mlmon.fib.out")\r
19291val _ = done (takData, "mlmon.tak.out")</programlisting>\r
19292<simpara>Compile and run the program.</simpara>\r
19293<screen>% mlton -profile time fib-tak.sml\r
19294% ./fib-tak</screen>\r
19295<simpara>Separately display the profiling data for <literal>fib</literal></simpara>\r
19296<screen>% mlprof fib-tak mlmon.fib.out\r
192975.77 seconds of CPU time (0.00 seconds GC)\r
19298function cur\r
19299--------- -----\r
19300fib 96.9%\r
19301&lt;unknown&gt; 3.1%</screen>\r
19302<simpara>and for <literal>tak</literal></simpara>\r
19303<screen>% mlprof fib-tak mlmon.tak.out\r
193040.68 seconds of CPU time (0.00 seconds GC)\r
19305function cur\r
19306-------- ------\r
19307tak 100.0%</screen>\r
19308<simpara>Combine the data for <literal>fib</literal> and <literal>tak</literal> by calling <literal>mlprof</literal>\r
19309with multiple <literal>mlmon.out</literal> files.</simpara>\r
19310<screen>% mlprof fib-tak mlmon.fib.out mlmon.tak.out mlmon.out\r
193116.45 seconds of CPU time (0.00 seconds GC)\r
19312function cur\r
19313--------- -----\r
19314fib 86.7%\r
19315tak 10.5%\r
19316&lt;unknown&gt; 2.8%</screen>\r
19317<simpara><?asciidoc-pagebreak?></simpara>\r
19318</section>\r
19319</section>\r
19320<section id="MLtonRandom">\r
19321<title>MLtonRandom</title>\r
19322<programlisting language="sml" linenumbering="unnumbered">signature MLTON_RANDOM =\r
19323 sig\r
19324 val alphaNumChar: unit -&gt; char\r
19325 val alphaNumString: int -&gt; string\r
19326 val rand: unit -&gt; word\r
19327 val seed: unit -&gt; word option\r
19328 val srand: word -&gt; unit\r
19329 val useed: unit -&gt; word option\r
19330 end</programlisting>\r
19331<itemizedlist>\r
19332<listitem>\r
19333<simpara>\r
19334<literal>alphaNumChar ()</literal>\r
19335</simpara>\r
19336<simpara>returns a random alphanumeric character.</simpara>\r
19337</listitem>\r
19338<listitem>\r
19339<simpara>\r
19340<literal>alphaNumString n</literal>\r
19341</simpara>\r
19342<simpara>returns a string of length <literal>n</literal> of random alphanumeric characters.</simpara>\r
19343</listitem>\r
19344<listitem>\r
19345<simpara>\r
19346<literal>rand ()</literal>\r
19347</simpara>\r
19348<simpara>returns the next pseudo-random number.</simpara>\r
19349</listitem>\r
19350<listitem>\r
19351<simpara>\r
19352<literal>seed ()</literal>\r
19353</simpara>\r
19354<simpara>returns a random word from <literal>/dev/random</literal>. Useful as an arg to\r
19355<literal>srand</literal>. If <literal>/dev/random</literal> can not be read from, <literal>seed ()</literal> returns\r
19356<literal>NONE</literal>. A call to <literal>seed</literal> may block until enough random bits are\r
19357available.</simpara>\r
19358</listitem>\r
19359<listitem>\r
19360<simpara>\r
19361<literal>srand w</literal>\r
19362</simpara>\r
19363<simpara>sets the seed used by <literal>rand</literal> to <literal>w</literal>.</simpara>\r
19364</listitem>\r
19365<listitem>\r
19366<simpara>\r
19367<literal>useed ()</literal>\r
19368</simpara>\r
19369<simpara>returns a random word from <literal>/dev/urandom</literal>. Useful as an arg to\r
19370<literal>srand</literal>. If <literal>/dev/urandom</literal> can not be read from, <literal>useed ()</literal> returns\r
19371<literal>NONE</literal>. A call to <literal>useed</literal> will never block&#8201;&#8212;&#8201;it will instead return\r
19372lower quality random bits.</simpara>\r
19373</listitem>\r
19374</itemizedlist>\r
19375<simpara><?asciidoc-pagebreak?></simpara>\r
19376</section>\r
19377<section id="MLtonReal">\r
19378<title>MLtonReal</title>\r
19379<programlisting language="sml" linenumbering="unnumbered">signature MLTON_REAL =\r
19380 sig\r
19381 type t\r
19382\r
19383 val fromWord: word -&gt; t\r
19384 val fromLargeWord: LargeWord.word -&gt; t\r
19385 val toWord: IEEEReal.rounding_mode -&gt; t -&gt; word\r
19386 val toLargeWord: IEEEReal.rounding_mode -&gt; t -&gt; LargeWord.word\r
19387 end</programlisting>\r
19388<itemizedlist>\r
19389<listitem>\r
19390<simpara>\r
19391<literal>type t</literal>\r
19392</simpara>\r
19393<simpara>the type of reals. For <literal>MLton.LargeReal</literal> this is <literal>LargeReal.real</literal>,\r
19394for <literal>MLton.Real</literal> this is <literal>Real.real</literal>, for <literal>MLton.Real32</literal> this is\r
19395<literal>Real32.real</literal>, for <literal>MLton.Real64</literal> this is <literal>Real64.real</literal>.</simpara>\r
19396</listitem>\r
19397<listitem>\r
19398<simpara>\r
19399<literal>fromWord w</literal>\r
19400</simpara>\r
19401</listitem>\r
19402<listitem>\r
19403<simpara>\r
19404<literal>fromLargeWord w</literal>\r
19405</simpara>\r
19406<simpara>convert the word <literal>w</literal> to a real value. If the value of <literal>w</literal> is larger\r
19407than (the appropriate) <literal>REAL.maxFinite</literal>, then infinity is returned.\r
19408If <literal>w</literal> cannot be exactly represented as a real value, then the current\r
19409rounding mode is used to determine the resulting value.</simpara>\r
19410</listitem>\r
19411<listitem>\r
19412<simpara>\r
19413<literal>toWord mode r</literal>\r
19414</simpara>\r
19415</listitem>\r
19416<listitem>\r
19417<simpara>\r
19418<literal>toLargeWord mode r</literal>\r
19419</simpara>\r
19420<simpara>convert the argument <literal>r</literal> to a word type using the specified rounding\r
19421mode. They raise <literal>Overflow</literal> if the result is not representable, in\r
19422particular, if <literal>r</literal> is an infinity. They raise <literal>Domain</literal> if <literal>r</literal> is NaN.</simpara>\r
19423</listitem>\r
19424<listitem>\r
19425<simpara>\r
19426<literal>MLton.Real32.castFromWord w</literal>\r
19427</simpara>\r
19428</listitem>\r
19429<listitem>\r
19430<simpara>\r
19431<literal>MLton.Real64.castFromWord w</literal>\r
19432</simpara>\r
19433<simpara>convert the argument <literal>w</literal> to a real type as a bit-wise cast.</simpara>\r
19434</listitem>\r
19435<listitem>\r
19436<simpara>\r
19437<literal>MLton.Real32.castToWord r</literal>\r
19438</simpara>\r
19439</listitem>\r
19440<listitem>\r
19441<simpara>\r
19442<literal>MLton.Real64.castToWord r</literal>\r
19443</simpara>\r
19444<simpara>convert the argument <literal>r</literal> to a word type as a bit-wise cast.</simpara>\r
19445</listitem>\r
19446</itemizedlist>\r
19447<simpara><?asciidoc-pagebreak?></simpara>\r
19448</section>\r
19449<section id="MLtonRlimit">\r
19450<title>MLtonRlimit</title>\r
19451<programlisting language="sml" linenumbering="unnumbered">signature MLTON_RLIMIT =\r
19452 sig\r
19453 structure RLim : sig\r
19454 type t\r
19455 val castFromSysWord: SysWord.word -&gt; t\r
19456 val castToSysWord: t -&gt; SysWord.word\r
19457 end\r
19458\r
19459 val infinity: RLim.t\r
19460\r
19461 type t\r
19462\r
19463 val coreFileSize: t (* CORE max core file size *)\r
19464 val cpuTime: t (* CPU CPU time in seconds *)\r
19465 val dataSize: t (* DATA max data size *)\r
19466 val fileSize: t (* FSIZE Maximum filesize *)\r
19467 val numFiles: t (* NOFILE max number of open files *)\r
19468 val lockedInMemorySize: t (* MEMLOCK max locked address space *)\r
19469 val numProcesses: t (* NPROC max number of processes *)\r
19470 val residentSetSize: t (* RSS max resident set size *)\r
19471 val stackSize: t (* STACK max stack size *)\r
19472 val virtualMemorySize: t (* AS virtual memory limit *)\r
19473\r
19474 val get: t -&gt; {hard: rlim, soft: rlim}\r
19475 val set: t * {hard: rlim, soft: rlim} -&gt; unit\r
19476 end</programlisting>\r
19477<simpara><literal>MLton.Rlimit</literal> provides a wrapper around the C <literal>getrlimit</literal> and\r
19478<literal>setrlimit</literal> functions.</simpara>\r
19479<itemizedlist>\r
19480<listitem>\r
19481<simpara>\r
19482<literal>type Rlim.t</literal>\r
19483</simpara>\r
19484<simpara>the type of resource limits.</simpara>\r
19485</listitem>\r
19486<listitem>\r
19487<simpara>\r
19488<literal>infinity</literal>\r
19489</simpara>\r
19490<simpara>indicates that a resource is unlimited.</simpara>\r
19491</listitem>\r
19492<listitem>\r
19493<simpara>\r
19494<literal>type t</literal>\r
19495</simpara>\r
19496<simpara>the types of resources that can be inspected and modified.</simpara>\r
19497</listitem>\r
19498<listitem>\r
19499<simpara>\r
19500<literal>get r</literal>\r
19501</simpara>\r
19502<simpara>returns the current hard and soft limits for resource <literal>r</literal>. May raise\r
19503<literal>OS.SysErr</literal>.</simpara>\r
19504</listitem>\r
19505<listitem>\r
19506<simpara>\r
19507<literal>set (r, {hard, soft})</literal>\r
19508</simpara>\r
19509<simpara>sets the hard and soft limits for resource <literal>r</literal>. May raise\r
19510<literal>OS.SysErr</literal>.</simpara>\r
19511</listitem>\r
19512</itemizedlist>\r
19513<simpara><?asciidoc-pagebreak?></simpara>\r
19514</section>\r
19515<section id="MLtonRusage">\r
19516<title>MLtonRusage</title>\r
19517<programlisting language="sml" linenumbering="unnumbered">signature MLTON_RUSAGE =\r
19518 sig\r
19519 type t = {utime: Time.time, (* user time *)\r
19520 stime: Time.time} (* system time *)\r
19521\r
19522 val measureGC: bool -&gt; unit\r
19523 val rusage: unit -&gt; {children: t, gc: t, self: t}\r
19524 end</programlisting>\r
19525<itemizedlist>\r
19526<listitem>\r
19527<simpara>\r
19528<literal>type t</literal>\r
19529</simpara>\r
19530<simpara>corresponds to a subset of the C <literal>struct rusage</literal>.</simpara>\r
19531</listitem>\r
19532<listitem>\r
19533<simpara>\r
19534<literal>measureGC b</literal>\r
19535</simpara>\r
19536<simpara>controls whether garbage collection time is separately measured during\r
19537program execution. This affects the behavior of both <literal>rusage</literal> and\r
19538<literal>Timer.checkCPUTimes</literal>, both of which will return gc times of zero with\r
19539<literal>measureGC false</literal>. Garbage collection time is always measured when\r
19540either <literal>gc-messages</literal> or <literal>gc-summary</literal> is given as a\r
19541<link linkend="RunTimeOptions">runtime system option</link>.</simpara>\r
19542</listitem>\r
19543<listitem>\r
19544<simpara>\r
19545<literal>rusage ()</literal>\r
19546</simpara>\r
19547<simpara>corresponds to the C <literal>getrusage</literal> function. It returns the resource\r
19548usage of the exited children, the garbage collector, and the process\r
19549itself. The <literal>self</literal> component includes the usage of the <literal>gc</literal>\r
19550component, regardless of whether <literal>measureGC</literal> is <literal>true</literal> or <literal>false</literal>. If\r
19551<literal>rusage</literal> is used in a program, either directly, or indirectly via the\r
19552<literal>Timer</literal> structure, then <literal>measureGC true</literal> is automatically called at\r
19553the start of the program (it can still be disable by user code later).</simpara>\r
19554</listitem>\r
19555</itemizedlist>\r
19556<simpara><?asciidoc-pagebreak?></simpara>\r
19557</section>\r
19558<section id="MLtonSignal">\r
19559<title>MLtonSignal</title>\r
19560<programlisting language="sml" linenumbering="unnumbered">signature MLTON_SIGNAL =\r
19561 sig\r
19562 type t = Posix.Signal.signal\r
19563 type signal = t\r
19564\r
19565 structure Handler:\r
19566 sig\r
19567 type t\r
19568\r
19569 val default: t\r
19570 val handler: (Thread.Runnable.t -&gt; Thread.Runnable.t) -&gt; t\r
19571 val ignore: t\r
19572 val isDefault: t -&gt; bool\r
19573 val isIgnore: t -&gt; bool\r
19574 val simple: (unit -&gt; unit) -&gt; t\r
19575 end\r
19576\r
19577 structure Mask:\r
19578 sig\r
19579 type t\r
19580\r
19581 val all: t\r
19582 val allBut: signal list -&gt; t\r
19583 val block: t -&gt; unit\r
19584 val getBlocked: unit -&gt; t\r
19585 val isMember: t * signal -&gt; bool\r
19586 val none: t\r
19587 val setBlocked: t -&gt; unit\r
19588 val some: signal list -&gt; t\r
19589 val unblock: t -&gt; unit\r
19590 end\r
19591\r
19592 val getHandler: t -&gt; Handler.t\r
19593 val handled: unit -&gt; Mask.t\r
19594 val prof: t\r
19595 val restart: bool ref\r
19596 val setHandler: t * Handler.t -&gt; unit\r
19597 val suspend: Mask.t -&gt; unit\r
19598 val vtalrm: t\r
19599 end</programlisting>\r
19600<simpara>Signals handlers are functions from (runnable) threads to (runnable)\r
19601threads. When a signal arrives, the corresponding signal handler is\r
19602invoked, its argument being the thread that was interrupted by the\r
19603signal. The signal handler runs asynchronously, in its own thread.\r
19604The signal handler returns the thread that it would like to resume\r
19605execution (this is often the thread that it was passed). It is an\r
19606error for a signal handler to raise an exception that is not handled\r
19607within the signal handler itself.</simpara>\r
19608<simpara>A signal handler is never invoked while the running thread is in a\r
19609critical section (see <link linkend="MLtonThread">MLtonThread</link>). Invoking a signal handler\r
19610implicitly enters a critical section and the normal return of a signal\r
19611handler implicitly exits the critical section; hence, a signal handler\r
19612is never interrupted by another signal handler.</simpara>\r
19613<itemizedlist>\r
19614<listitem>\r
19615<simpara>\r
19616<literal>type t</literal>\r
19617</simpara>\r
19618<simpara>the type of signals.</simpara>\r
19619</listitem>\r
19620<listitem>\r
19621<simpara>\r
19622<literal>type Handler.t</literal>\r
19623</simpara>\r
19624<simpara>the type of signal handlers.</simpara>\r
19625</listitem>\r
19626<listitem>\r
19627<simpara>\r
19628<literal>Handler.default</literal>\r
19629</simpara>\r
19630<simpara>handles the signal with the default action.</simpara>\r
19631</listitem>\r
19632<listitem>\r
19633<simpara>\r
19634<literal>Handler.handler f</literal>\r
19635</simpara>\r
19636<simpara>returns a handler <literal>h</literal> such that when a signal <literal>s</literal> is handled by <literal>h</literal>,\r
19637<literal>f</literal> will be passed the thread that was interrupted by <literal>s</literal> and should\r
19638return the thread that will resume execution.</simpara>\r
19639</listitem>\r
19640<listitem>\r
19641<simpara>\r
19642<literal>Handler.ignore</literal>\r
19643</simpara>\r
19644<simpara>is a handler that will ignore the signal.</simpara>\r
19645</listitem>\r
19646<listitem>\r
19647<simpara>\r
19648<literal>Handler.isDefault</literal>\r
19649</simpara>\r
19650<simpara>returns true if the handler is the default handler.</simpara>\r
19651</listitem>\r
19652<listitem>\r
19653<simpara>\r
19654<literal>Handler.isIgnore</literal>\r
19655</simpara>\r
19656<simpara>returns true if the handler is the ignore handler.</simpara>\r
19657</listitem>\r
19658<listitem>\r
19659<simpara>\r
19660<literal>Handler.simple f</literal>\r
19661</simpara>\r
19662<simpara>returns a handler that executes <literal>f ()</literal> and does not switch threads.</simpara>\r
19663</listitem>\r
19664<listitem>\r
19665<simpara>\r
19666<literal>type Mask.t</literal>\r
19667</simpara>\r
19668<simpara>the type of signal masks, which are sets of blocked signals.</simpara>\r
19669</listitem>\r
19670<listitem>\r
19671<simpara>\r
19672<literal>Mask.all</literal>\r
19673</simpara>\r
19674<simpara>a mask of all signals.</simpara>\r
19675</listitem>\r
19676<listitem>\r
19677<simpara>\r
19678<literal>Mask.allBut l</literal>\r
19679</simpara>\r
19680<simpara>a mask of all signals except for those in <literal>l</literal>.</simpara>\r
19681</listitem>\r
19682<listitem>\r
19683<simpara>\r
19684<literal>Mask.block m</literal>\r
19685</simpara>\r
19686<simpara>blocks all signals in <literal>m</literal>.</simpara>\r
19687</listitem>\r
19688<listitem>\r
19689<simpara>\r
19690<literal>Mask.getBlocked ()</literal>\r
19691</simpara>\r
19692<simpara>gets the signal mask <literal>m</literal>, i.e. a signal is blocked if and only if it\r
19693is in <literal>m</literal>.</simpara>\r
19694</listitem>\r
19695<listitem>\r
19696<simpara>\r
19697<literal>Mask.isMember (m, s)</literal>\r
19698</simpara>\r
19699<simpara>returns true if the signal <literal>s</literal> is in <literal>m</literal>.</simpara>\r
19700</listitem>\r
19701<listitem>\r
19702<simpara>\r
19703<literal>Mask.none</literal>\r
19704</simpara>\r
19705<simpara>a mask of no signals.</simpara>\r
19706</listitem>\r
19707<listitem>\r
19708<simpara>\r
19709<literal>Mask.setBlocked m</literal>\r
19710</simpara>\r
19711<simpara>sets the signal mask to <literal>m</literal>, i.e. a signal is blocked if and only if\r
19712it is in <literal>m</literal>.</simpara>\r
19713</listitem>\r
19714<listitem>\r
19715<simpara>\r
19716<literal>Mask.some l</literal>\r
19717</simpara>\r
19718<simpara>a mask of the signals in <literal>l</literal>.</simpara>\r
19719</listitem>\r
19720<listitem>\r
19721<simpara>\r
19722<literal>Mask.unblock m</literal>\r
19723</simpara>\r
19724<simpara>unblocks all signals in <literal>m</literal>.</simpara>\r
19725</listitem>\r
19726<listitem>\r
19727<simpara>\r
19728<literal>getHandler s</literal>\r
19729</simpara>\r
19730<simpara>returns the current handler for signal <literal>s</literal>.</simpara>\r
19731</listitem>\r
19732<listitem>\r
19733<simpara>\r
19734<literal>handled ()</literal>\r
19735</simpara>\r
19736<simpara>returns the signal mask <literal>m</literal> corresponding to the currently handled\r
19737signals; i.e., a signal is handled if and only if it is in <literal>m</literal>.</simpara>\r
19738</listitem>\r
19739<listitem>\r
19740<simpara>\r
19741<literal>prof</literal>\r
19742</simpara>\r
19743<simpara><literal>SIGPROF</literal>, the profiling signal.</simpara>\r
19744</listitem>\r
19745<listitem>\r
19746<simpara>\r
19747<literal>restart</literal>\r
19748</simpara>\r
19749<simpara>dynamically determines the behavior of interrupted system calls; when\r
19750<literal>true</literal>, interrupted system calls are restarted; when <literal>false</literal>,\r
19751interrupted system calls raise <literal>OS.SysError</literal>.</simpara>\r
19752</listitem>\r
19753<listitem>\r
19754<simpara>\r
19755<literal>setHandler (s, h)</literal>\r
19756</simpara>\r
19757<simpara>sets the handler for signal <literal>s</literal> to <literal>h</literal>.</simpara>\r
19758</listitem>\r
19759<listitem>\r
19760<simpara>\r
19761<literal>suspend m</literal>\r
19762</simpara>\r
19763<simpara>temporarily sets the signal mask to <literal>m</literal> and suspends until an unmasked\r
19764signal is received and handled, at which point <literal>suspend</literal> resets the\r
19765mask and returns.</simpara>\r
19766</listitem>\r
19767<listitem>\r
19768<simpara>\r
19769<literal>vtalrm</literal>\r
19770</simpara>\r
19771<simpara><literal>SIGVTALRM</literal>, the signal for virtual timers.</simpara>\r
19772</listitem>\r
19773</itemizedlist>\r
19774<section id="_interruptible_system_calls">\r
19775<title>Interruptible System Calls</title>\r
19776<simpara>Signal handling interacts in a non-trivial way with those functions in\r
19777the <link linkend="BasisLibrary">Basis Library</link> that correspond directly to\r
19778interruptible system calls (a subset of those functions that may raise\r
19779<literal>OS.SysError</literal>). The desire is that these functions should have\r
19780predictable semantics. The principal concerns are:</simpara>\r
19781<orderedlist numeration="arabic">\r
19782<listitem>\r
19783<simpara>\r
19784System calls that are interrupted by signals should, by default, be\r
19785restarted; the alternative is to raise\r
19786</simpara>\r
19787<programlisting language="sml" linenumbering="unnumbered">OS.SysError (Posix.Error.errorMsg Posix.Error.intr,\r
19788 SOME Posix.Error.intr)</programlisting>\r
19789<simpara>This behavior is determined dynamically by the value of <literal>Signal.restart</literal>.</simpara>\r
19790</listitem>\r
19791<listitem>\r
19792<simpara>\r
19793Signal handlers should always get a chance to run (when outside a\r
19794critical region). If a system call is interrupted by a signal, then\r
19795the signal handler will run before the call is restarted or\r
19796<literal>OS.SysError</literal> is raised; that is, before the <literal>Signal.restart</literal> check.\r
19797</simpara>\r
19798</listitem>\r
19799<listitem>\r
19800<simpara>\r
19801A system call that must be restarted while in a critical section\r
19802will be restarted with the handled signals blocked (and the previously\r
19803blocked signals remembered). This encourages the system call to\r
19804complete, allowing the program to make progress towards leaving the\r
19805critical section where the signal can be handled. If the system call\r
19806completes, the set of blocked signals are restored to those previously\r
19807blocked.\r
19808</simpara>\r
19809</listitem>\r
19810</orderedlist>\r
19811<simpara><?asciidoc-pagebreak?></simpara>\r
19812</section>\r
19813</section>\r
19814<section id="MLtonStructure">\r
19815<title>MLtonStructure</title>\r
19816<simpara>The <literal>MLton</literal> structure contains a lot of functionality that is not\r
19817available in the <link linkend="BasisLibrary">Basis Library</link>. As a warning,\r
19818please keep in mind that the <literal>MLton</literal> structure and its\r
19819substructures do change from release to release of MLton.</simpara>\r
19820<programlisting language="sml" linenumbering="unnumbered">structure MLton:\r
19821 sig\r
19822 val eq: 'a * 'a -&gt; bool\r
19823 val equal: 'a * 'a -&gt; bool\r
19824 val hash: 'a -&gt; Word32.word\r
19825 val isMLton: bool\r
19826 val share: 'a -&gt; unit\r
19827 val shareAll: unit -&gt; unit\r
19828 val size: 'a -&gt; int\r
19829\r
19830 structure Array: MLTON_ARRAY\r
19831 structure BinIO: MLTON_BIN_IO\r
19832 structure CharArray: MLTON_MONO_ARRAY where type t = CharArray.array\r
19833 where type elem = CharArray.elem\r
19834 structure CharVector: MLTON_MONO_VECTOR where type t = CharVector.vector\r
19835 where type elem = CharVector.elem\r
19836 structure Cont: MLTON_CONT\r
19837 structure Exn: MLTON_EXN\r
19838 structure Finalizable: MLTON_FINALIZABLE\r
19839 structure GC: MLTON_GC\r
19840 structure IntInf: MLTON_INT_INF\r
19841 structure Itimer: MLTON_ITIMER\r
19842 structure LargeReal: MLTON_REAL where type t = LargeReal.real\r
19843 structure LargeWord: MLTON_WORD where type t = LargeWord.word\r
19844 structure Platform: MLTON_PLATFORM\r
19845 structure Pointer: MLTON_POINTER\r
19846 structure ProcEnv: MLTON_PROC_ENV\r
19847 structure Process: MLTON_PROCESS\r
19848 structure Profile: MLTON_PROFILE\r
19849 structure Random: MLTON_RANDOM\r
19850 structure Real: MLTON_REAL where type t = Real.real\r
19851 structure Real32: sig\r
19852 include MLTON_REAL\r
19853 val castFromWord: Word32.word -&gt; t\r
19854 val castToWord: t -&gt; Word32.word\r
19855 end where type t = Real32.real\r
19856 structure Real64: sig\r
19857 include MLTON_REAL\r
19858 val castFromWord: Word64.word -&gt; t\r
19859 val castToWord: t -&gt; Word64.word\r
19860 end where type t = Real64.real\r
19861 structure Rlimit: MLTON_RLIMIT\r
19862 structure Rusage: MLTON_RUSAGE\r
19863 structure Signal: MLTON_SIGNAL\r
19864 structure Syslog: MLTON_SYSLOG\r
19865 structure TextIO: MLTON_TEXT_IO\r
19866 structure Thread: MLTON_THREAD\r
19867 structure Vector: MLTON_VECTOR\r
19868 structure Weak: MLTON_WEAK\r
19869 structure Word: MLTON_WORD where type t = Word.word\r
19870 structure Word8: MLTON_WORD where type t = Word8.word\r
19871 structure Word16: MLTON_WORD where type t = Word16.word\r
19872 structure Word32: MLTON_WORD where type t = Word32.word\r
19873 structure Word64: MLTON_WORD where type t = Word64.word\r
19874 structure Word8Array: MLTON_MONO_ARRAY where type t = Word8Array.array\r
19875 where type elem = Word8Array.elem\r
19876 structure Word8Vector: MLTON_MONO_VECTOR where type t = Word8Vector.vector\r
19877 where type elem = Word8Vector.elem\r
19878 structure World: MLTON_WORLD\r
19879 end</programlisting>\r
19880<section id="_substructures">\r
19881<title>Substructures</title>\r
19882<itemizedlist>\r
19883<listitem>\r
19884<simpara>\r
19885<link linkend="MLtonArray">MLtonArray</link>\r
19886</simpara>\r
19887</listitem>\r
19888<listitem>\r
19889<simpara>\r
19890<link linkend="MLtonBinIO">MLtonBinIO</link>\r
19891</simpara>\r
19892</listitem>\r
19893<listitem>\r
19894<simpara>\r
19895<link linkend="MLtonCont">MLtonCont</link>\r
19896</simpara>\r
19897</listitem>\r
19898<listitem>\r
19899<simpara>\r
19900<link linkend="MLtonExn">MLtonExn</link>\r
19901</simpara>\r
19902</listitem>\r
19903<listitem>\r
19904<simpara>\r
19905<link linkend="MLtonFinalizable">MLtonFinalizable</link>\r
19906</simpara>\r
19907</listitem>\r
19908<listitem>\r
19909<simpara>\r
19910<link linkend="MLtonGC">MLtonGC</link>\r
19911</simpara>\r
19912</listitem>\r
19913<listitem>\r
19914<simpara>\r
19915<link linkend="MLtonIntInf">MLtonIntInf</link>\r
19916</simpara>\r
19917</listitem>\r
19918<listitem>\r
19919<simpara>\r
19920<link linkend="MLtonIO">MLtonIO</link>\r
19921</simpara>\r
19922</listitem>\r
19923<listitem>\r
19924<simpara>\r
19925<link linkend="MLtonItimer">MLtonItimer</link>\r
19926</simpara>\r
19927</listitem>\r
19928<listitem>\r
19929<simpara>\r
19930<link linkend="MLtonMonoArray">MLtonMonoArray</link>\r
19931</simpara>\r
19932</listitem>\r
19933<listitem>\r
19934<simpara>\r
19935<link linkend="MLtonMonoVector">MLtonMonoVector</link>\r
19936</simpara>\r
19937</listitem>\r
19938<listitem>\r
19939<simpara>\r
19940<link linkend="MLtonPlatform">MLtonPlatform</link>\r
19941</simpara>\r
19942</listitem>\r
19943<listitem>\r
19944<simpara>\r
19945<link linkend="MLtonPointer">MLtonPointer</link>\r
19946</simpara>\r
19947</listitem>\r
19948<listitem>\r
19949<simpara>\r
19950<link linkend="MLtonProcEnv">MLtonProcEnv</link>\r
19951</simpara>\r
19952</listitem>\r
19953<listitem>\r
19954<simpara>\r
19955<link linkend="MLtonProcess">MLtonProcess</link>\r
19956</simpara>\r
19957</listitem>\r
19958<listitem>\r
19959<simpara>\r
19960<link linkend="MLtonRandom">MLtonRandom</link>\r
19961</simpara>\r
19962</listitem>\r
19963<listitem>\r
19964<simpara>\r
19965<link linkend="MLtonReal">MLtonReal</link>\r
19966</simpara>\r
19967</listitem>\r
19968<listitem>\r
19969<simpara>\r
19970<link linkend="MLtonRlimit">MLtonRlimit</link>\r
19971</simpara>\r
19972</listitem>\r
19973<listitem>\r
19974<simpara>\r
19975<link linkend="MLtonRusage">MLtonRusage</link>\r
19976</simpara>\r
19977</listitem>\r
19978<listitem>\r
19979<simpara>\r
19980<link linkend="MLtonSignal">MLtonSignal</link>\r
19981</simpara>\r
19982</listitem>\r
19983<listitem>\r
19984<simpara>\r
19985<link linkend="MLtonSyslog">MLtonSyslog</link>\r
19986</simpara>\r
19987</listitem>\r
19988<listitem>\r
19989<simpara>\r
19990<link linkend="MLtonTextIO">MLtonTextIO</link>\r
19991</simpara>\r
19992</listitem>\r
19993<listitem>\r
19994<simpara>\r
19995<link linkend="MLtonThread">MLtonThread</link>\r
19996</simpara>\r
19997</listitem>\r
19998<listitem>\r
19999<simpara>\r
20000<link linkend="MLtonVector">MLtonVector</link>\r
20001</simpara>\r
20002</listitem>\r
20003<listitem>\r
20004<simpara>\r
20005<link linkend="MLtonWeak">MLtonWeak</link>\r
20006</simpara>\r
20007</listitem>\r
20008<listitem>\r
20009<simpara>\r
20010<link linkend="MLtonWord">MLtonWord</link>\r
20011</simpara>\r
20012</listitem>\r
20013<listitem>\r
20014<simpara>\r
20015<link linkend="MLtonWorld">MLtonWorld</link>\r
20016</simpara>\r
20017</listitem>\r
20018</itemizedlist>\r
20019</section>\r
20020<section id="_values">\r
20021<title>Values</title>\r
20022<itemizedlist>\r
20023<listitem>\r
20024<simpara>\r
20025<literal>eq (x, y)</literal>\r
20026</simpara>\r
20027<simpara>returns true if <literal>x</literal> and <literal>y</literal> are equal as pointers. For simple types\r
20028like <literal>char</literal>, <literal>int</literal>, and <literal>word</literal>, this is the same as equals. For\r
20029arrays, datatypes, strings, tuples, and vectors, this is a simple\r
20030pointer equality. The semantics is a bit murky.</simpara>\r
20031</listitem>\r
20032<listitem>\r
20033<simpara>\r
20034<literal>equal (x, y)</literal>\r
20035</simpara>\r
20036<simpara>returns true if <literal>x</literal> and <literal>y</literal> are structurally equal. For equality\r
20037types, this is the same as <link linkend="PolymorphicEquality">PolymorphicEquality</link>. For other types,\r
20038it is a conservative approximation of equivalence.</simpara>\r
20039</listitem>\r
20040<listitem>\r
20041<simpara>\r
20042<literal>hash x</literal>\r
20043</simpara>\r
20044<simpara>returns a structural hash of <literal>x</literal>. The hash function is consistent\r
20045between execution of the same program, but may not be consistent\r
20046between different programs.</simpara>\r
20047</listitem>\r
20048<listitem>\r
20049<simpara>\r
20050<literal>isMLton</literal>\r
20051</simpara>\r
20052<simpara>is always <literal>true</literal> in a MLton implementation, and is always <literal>false</literal> in a\r
20053stub implementation.</simpara>\r
20054</listitem>\r
20055<listitem>\r
20056<simpara>\r
20057<literal>share x</literal>\r
20058</simpara>\r
20059<simpara>maximizes sharing in the heap for the object graph reachable from <literal>x</literal>.</simpara>\r
20060</listitem>\r
20061<listitem>\r
20062<simpara>\r
20063<literal>shareAll ()</literal>\r
20064</simpara>\r
20065<simpara>maximizes sharing in the heap by sharing space for equivalent\r
20066immutable objects. A call to <literal>shareAll</literal> performs a major garbage\r
20067collection, and takes time proportional to the size of the heap.</simpara>\r
20068</listitem>\r
20069<listitem>\r
20070<simpara>\r
20071<literal>size x</literal>\r
20072</simpara>\r
20073<simpara>returns the amount of heap space (in bytes) taken by the value of <literal>x</literal>,\r
20074including all objects reachable from <literal>x</literal> by following pointers. It\r
20075takes time proportional to the size of <literal>x</literal>. See below for an example.</simpara>\r
20076</listitem>\r
20077</itemizedlist>\r
20078</section>\r
20079<section id="_anchor_id_mltonstructure_size_xreflabel_mltonstructure_size_example_of_literal_mlton_size_literal">\r
20080<title><anchor id="MLtonStructure_size" xreflabel="[MLtonStructure_size]"/>Example of <literal>MLton.size</literal></title>\r
20081<simpara>This example, <literal>size.sml</literal>, demonstrates the application of <literal>MLton.size</literal>\r
20082to many different kinds of objects.</simpara>\r
20083<programlisting language="sml" linenumbering="unnumbered">fun 'a printSize (name: string, value: 'a): unit=\r
20084 (print "The size of "\r
20085 ; print name\r
20086 ; print " is "\r
20087 ; print (Int.toString (MLton.size value))\r
20088 ; print " bytes.\n")\r
20089\r
20090val l = [1, 2, 3, 4]\r
20091\r
20092val _ =\r
20093 (\r
20094 printSize ("an int list of length 4", l)\r
20095 ; printSize ("a string of length 10", "0123456789")\r
20096 ; printSize ("an int array of length 10", Array.tabulate (10, fn _ =&gt; 0))\r
20097 ; printSize ("a double array of length 10",\r
20098 Array.tabulate (10, fn _ =&gt; 0.0))\r
20099 ; printSize ("an array of length 10 of 2-ples of ints",\r
20100 Array.tabulate (10, fn i =&gt; (i, i + 1)))\r
20101 ; printSize ("a useless function", fn _ =&gt; 13)\r
20102 )\r
20103\r
20104(* This is here so that the list is "useful".\r
20105 * If it were removed, then the optimizer (remove-unused-constructors)\r
20106 * would remove l entirely.\r
20107 *)\r
20108val _ = if 10 = foldl (op +) 0 l\r
20109 then ()\r
20110 else raise Fail "bug"\r
20111\r
20112local\r
20113 open MLton.Cont\r
20114in\r
20115 val rc: int option t option ref = ref NONE\r
20116 val _ =\r
20117 case callcc (fn k: int option t =&gt; (rc := SOME k; throw (k, NONE))) of\r
20118 NONE =&gt; ()\r
20119 | SOME i =&gt; print (concat [Int.toString i, "\n"])\r
20120end\r
20121\r
20122val _ = printSize ("a continuation option ref", rc)\r
20123\r
20124val _ =\r
20125 case !rc of\r
20126 NONE =&gt; ()\r
20127 | SOME k =&gt; (rc := NONE; MLton.Cont.throw (k, SOME 13))</programlisting>\r
20128<simpara>Compile and run as usual.</simpara>\r
20129<screen>% mlton size.sml\r
20130% ./size\r
20131The size of an int list of length 4 is 48 bytes.\r
20132The size of a string of length 10 is 24 bytes.\r
20133The size of an int array of length 10 is 52 bytes.\r
20134The size of a double array of length 10 is 92 bytes.\r
20135The size of an array of length 10 of 2-ples of ints is 92 bytes.\r
20136The size of a useless function is 0 bytes.\r
20137The size of a continuation option ref is 4544 bytes.\r
2013813\r
20139The size of a continuation option ref is 8 bytes.</screen>\r
20140<simpara>Note that sizes are dependent upon the target platform and compiler\r
20141optimizations.</simpara>\r
20142<simpara><?asciidoc-pagebreak?></simpara>\r
20143</section>\r
20144</section>\r
20145<section id="MLtonSyslog">\r
20146<title>MLtonSyslog</title>\r
20147<programlisting language="sml" linenumbering="unnumbered">signature MLTON_SYSLOG =\r
20148 sig\r
20149 type openflag\r
20150\r
20151 val CONS : openflag\r
20152 val NDELAY : openflag\r
20153 val NOWAIT : openflag\r
20154 val ODELAY : openflag\r
20155 val PERROR : openflag\r
20156 val PID : openflag\r
20157\r
20158 type facility\r
20159\r
20160 val AUTHPRIV : facility\r
20161 val CRON : facility\r
20162 val DAEMON : facility\r
20163 val KERN : facility\r
20164 val LOCAL0 : facility\r
20165 val LOCAL1 : facility\r
20166 val LOCAL2 : facility\r
20167 val LOCAL3 : facility\r
20168 val LOCAL4 : facility\r
20169 val LOCAL5 : facility\r
20170 val LOCAL6 : facility\r
20171 val LOCAL7 : facility\r
20172 val LPR : facility\r
20173 val MAIL : facility\r
20174 val NEWS : facility\r
20175 val SYSLOG : facility\r
20176 val USER : facility\r
20177 val UUCP : facility\r
20178\r
20179 type loglevel\r
20180\r
20181 val EMERG : loglevel\r
20182 val ALERT : loglevel\r
20183 val CRIT : loglevel\r
20184 val ERR : loglevel\r
20185 val WARNING : loglevel\r
20186 val NOTICE : loglevel\r
20187 val INFO : loglevel\r
20188 val DEBUG : loglevel\r
20189\r
20190 val closelog: unit -&gt; unit\r
20191 val log: loglevel * string -&gt; unit\r
20192 val openlog: string * openflag list * facility -&gt; unit\r
20193 end</programlisting>\r
20194<simpara><literal>MLton.Syslog</literal> is a complete interface to the system logging\r
20195facilities. See <literal>man 3 syslog</literal> for more details.</simpara>\r
20196<itemizedlist>\r
20197<listitem>\r
20198<simpara>\r
20199<literal>closelog ()</literal>\r
20200</simpara>\r
20201<simpara>closes the connection to the system logger.</simpara>\r
20202</listitem>\r
20203<listitem>\r
20204<simpara>\r
20205<literal>log (l, s)</literal>\r
20206</simpara>\r
20207<simpara>logs message <literal>s</literal> at a loglevel <literal>l</literal>.</simpara>\r
20208</listitem>\r
20209<listitem>\r
20210<simpara>\r
20211<literal>openlog (name, flags, facility)</literal>\r
20212</simpara>\r
20213<simpara>opens a connection to the system logger. <literal>name</literal> will be prefixed to\r
20214each message, and is typically set to the program name.</simpara>\r
20215</listitem>\r
20216</itemizedlist>\r
20217<simpara><?asciidoc-pagebreak?></simpara>\r
20218</section>\r
20219<section id="MLtonTextIO">\r
20220<title>MLtonTextIO</title>\r
20221<programlisting language="sml" linenumbering="unnumbered">signature MLTON_TEXT_IO = MLTON_IO</programlisting>\r
20222<simpara>See <link linkend="MLtonIO">MLtonIO</link>.</simpara>\r
20223<simpara><?asciidoc-pagebreak?></simpara>\r
20224</section>\r
20225<section id="MLtonThread">\r
20226<title>MLtonThread</title>\r
20227<programlisting language="sml" linenumbering="unnumbered">signature MLTON_THREAD =\r
20228 sig\r
20229 structure AtomicState:\r
20230 sig\r
20231 datatype t = NonAtomic | Atomic of int\r
20232 end\r
20233\r
20234 val atomically: (unit -&gt; 'a) -&gt; 'a\r
20235 val atomicBegin: unit -&gt; unit\r
20236 val atomicEnd: unit -&gt; unit\r
20237 val atomicState: unit -&gt; AtomicState.t\r
20238\r
20239 structure Runnable:\r
20240 sig\r
20241 type t\r
20242 end\r
20243\r
20244 type 'a t\r
20245\r
20246 val atomicSwitch: ('a t -&gt; Runnable.t) -&gt; 'a\r
20247 val new: ('a -&gt; unit) -&gt; 'a t\r
20248 val prepend: 'a t * ('b -&gt; 'a) -&gt; 'b t\r
20249 val prepare: 'a t * 'a -&gt; Runnable.t\r
20250 val switch: ('a t -&gt; Runnable.t) -&gt; 'a\r
20251 end</programlisting>\r
20252<simpara><literal>MLton.Thread</literal> provides access to MLton&#8217;s user-level thread\r
20253implementation (i.e. not OS-level threads). Threads are lightweight\r
20254data structures that represent a paused computation. Runnable threads\r
20255are threads that will begin or continue computing when <literal>switch</literal>-ed to.\r
20256<literal>MLton.Thread</literal> does not include a default scheduling mechanism, but it\r
20257can be used to implement both preemptive and non-preemptive threads.</simpara>\r
20258<itemizedlist>\r
20259<listitem>\r
20260<simpara>\r
20261<literal>type AtomicState.t</literal>\r
20262</simpara>\r
20263<simpara>the type of atomic states.</simpara>\r
20264</listitem>\r
20265<listitem>\r
20266<simpara>\r
20267<literal>atomically f</literal>\r
20268</simpara>\r
20269<simpara>runs <literal>f</literal> in a critical section.</simpara>\r
20270</listitem>\r
20271<listitem>\r
20272<simpara>\r
20273<literal>atomicBegin ()</literal>\r
20274</simpara>\r
20275<simpara>begins a critical section.</simpara>\r
20276</listitem>\r
20277<listitem>\r
20278<simpara>\r
20279<literal>atomicEnd ()</literal>\r
20280</simpara>\r
20281<simpara>ends a critical section.</simpara>\r
20282</listitem>\r
20283<listitem>\r
20284<simpara>\r
20285<literal>atomicState ()</literal>\r
20286</simpara>\r
20287<simpara>returns the current atomic state.</simpara>\r
20288</listitem>\r
20289<listitem>\r
20290<simpara>\r
20291<literal>type Runnable.t</literal>\r
20292</simpara>\r
20293<simpara>the type of threads that can be resumed.</simpara>\r
20294</listitem>\r
20295<listitem>\r
20296<simpara>\r
20297<literal>type 'a t</literal>\r
20298</simpara>\r
20299<simpara>the type of threads that expect a value of type <literal>'a</literal>.</simpara>\r
20300</listitem>\r
20301<listitem>\r
20302<simpara>\r
20303<literal>atomicSwitch f</literal>\r
20304</simpara>\r
20305<simpara>like <literal>switch</literal>, but assumes an atomic calling context. Upon\r
20306<literal>switch</literal>-ing back to the current thread, an implicit <literal>atomicEnd</literal> is\r
20307performed.</simpara>\r
20308</listitem>\r
20309<listitem>\r
20310<simpara>\r
20311<literal>new f</literal>\r
20312</simpara>\r
20313<simpara>creates a new thread that, when run, applies <literal>f</literal> to the value given to\r
20314the thread. <literal>f</literal> must terminate by `switch`ing to another thread or\r
20315exiting the process.</simpara>\r
20316</listitem>\r
20317<listitem>\r
20318<simpara>\r
20319<literal>prepend (t, f)</literal>\r
20320</simpara>\r
20321<simpara>creates a new thread (destroying <literal>t</literal> in the process) that first\r
20322applies <literal>f</literal> to the value given to the thread and then continues with\r
20323<literal>t</literal>. This is a constant time operation.</simpara>\r
20324</listitem>\r
20325<listitem>\r
20326<simpara>\r
20327<literal>prepare (t, v)</literal>\r
20328</simpara>\r
20329<simpara>prepares a new runnable thread (destroying <literal>t</literal> in the process) that\r
20330will evaluate <literal>t</literal> on <literal>v</literal>.</simpara>\r
20331</listitem>\r
20332<listitem>\r
20333<simpara>\r
20334<literal>switch f</literal>\r
20335</simpara>\r
20336<simpara>applies <literal>f</literal> to the current thread to get <literal>rt</literal>, and then start running\r
20337thread <literal>rt</literal>. It is an error for <literal>f</literal> to perform another <literal>switch</literal>. <literal>f</literal>\r
20338is guaranteed to run atomically.</simpara>\r
20339</listitem>\r
20340</itemizedlist>\r
20341<section id="_example_of_non_preemptive_threads">\r
20342<title>Example of non-preemptive threads</title>\r
20343<programlisting language="sml" linenumbering="unnumbered">structure Queue:\r
20344 sig\r
20345 type 'a t\r
20346\r
20347 val new: unit -&gt; 'a t\r
20348 val enque: 'a t * 'a -&gt; unit\r
20349 val deque: 'a t -&gt; 'a option\r
20350 end =\r
20351 struct\r
20352 datatype 'a t = T of {front: 'a list ref, back: 'a list ref}\r
20353\r
20354 fun new () = T {front = ref [], back = ref []}\r
20355\r
20356 fun enque (T {back, ...}, x) = back := x :: !back\r
20357\r
20358 fun deque (T {front, back}) =\r
20359 case !front of\r
20360 [] =&gt; (case !back of\r
20361 [] =&gt; NONE\r
20362 | l =&gt; let val l = rev l\r
20363 in case l of\r
20364 [] =&gt; raise Fail "deque"\r
20365 | x :: l =&gt; (back := []; front := l; SOME x)\r
20366 end)\r
20367 | x :: l =&gt; (front := l; SOME x)\r
20368 end\r
20369\r
20370structure Thread:\r
20371 sig\r
20372 val exit: unit -&gt; 'a\r
20373 val run: unit -&gt; unit\r
20374 val spawn: (unit -&gt; unit) -&gt; unit\r
20375 val yield: unit -&gt; unit\r
20376 end =\r
20377 struct\r
20378 open MLton\r
20379 open Thread\r
20380\r
20381 val topLevel: Thread.Runnable.t option ref = ref NONE\r
20382\r
20383 local\r
20384 val threads: Thread.Runnable.t Queue.t = Queue.new ()\r
20385 in\r
20386 fun ready (t: Thread.Runnable.t) : unit =\r
20387 Queue.enque(threads, t)\r
20388 fun next () : Thread.Runnable.t =\r
20389 case Queue.deque threads of\r
20390 NONE =&gt; valOf (!topLevel)\r
20391 | SOME t =&gt; t\r
20392 end\r
20393\r
20394 fun 'a exit (): 'a = switch (fn _ =&gt; next ())\r
20395\r
20396 fun new (f: unit -&gt; unit): Thread.Runnable.t =\r
20397 Thread.prepare\r
20398 (Thread.new (fn () =&gt; ((f () handle _ =&gt; exit ())\r
20399 ; exit ())),\r
20400 ())\r
20401\r
20402 fun schedule t = (ready t; next ())\r
20403\r
20404 fun yield (): unit = switch (fn t =&gt; schedule (Thread.prepare (t, ())))\r
20405\r
20406 val spawn = ready o new\r
20407\r
20408 fun run(): unit =\r
20409 (switch (fn t =&gt;\r
20410 (topLevel := SOME (Thread.prepare (t, ()))\r
20411 ; next()))\r
20412 ; topLevel := NONE)\r
20413 end\r
20414\r
20415val rec loop =\r
20416 fn 0 =&gt; ()\r
20417 | n =&gt; (print(concat[Int.toString n, "\n"])\r
20418 ; Thread.yield()\r
20419 ; loop(n - 1))\r
20420\r
20421val rec loop' =\r
20422 fn 0 =&gt; ()\r
20423 | n =&gt; (Thread.spawn (fn () =&gt; loop n); loop' (n - 2))\r
20424\r
20425val _ = Thread.spawn (fn () =&gt; loop' 10)\r
20426\r
20427val _ = Thread.run ()\r
20428\r
20429val _ = print "success\n"</programlisting>\r
20430</section>\r
20431<section id="_example_of_preemptive_threads">\r
20432<title>Example of preemptive threads</title>\r
20433<programlisting language="sml" linenumbering="unnumbered">structure Queue:\r
20434 sig\r
20435 type 'a t\r
20436\r
20437 val new: unit -&gt; 'a t\r
20438 val enque: 'a t * 'a -&gt; unit\r
20439 val deque: 'a t -&gt; 'a option\r
20440 end =\r
20441 struct\r
20442 datatype 'a t = T of {front: 'a list ref, back: 'a list ref}\r
20443\r
20444 fun new () = T {front = ref [], back = ref []}\r
20445\r
20446 fun enque (T {back, ...}, x) = back := x :: !back\r
20447\r
20448 fun deque (T {front, back}) =\r
20449 case !front of\r
20450 [] =&gt; (case !back of\r
20451 [] =&gt; NONE\r
20452 | l =&gt; let val l = rev l\r
20453 in case l of\r
20454 [] =&gt; raise Fail "deque"\r
20455 | x :: l =&gt; (back := []; front := l; SOME x)\r
20456 end)\r
20457 | x :: l =&gt; (front := l; SOME x)\r
20458 end\r
20459\r
20460structure Thread:\r
20461 sig\r
20462 val exit: unit -&gt; 'a\r
20463 val run: unit -&gt; unit\r
20464 val spawn: (unit -&gt; unit) -&gt; unit\r
20465 val yield: unit -&gt; unit\r
20466 end =\r
20467 struct\r
20468 open Posix.Signal\r
20469 open MLton\r
20470 open Itimer Signal Thread\r
20471\r
20472 val topLevel: Thread.Runnable.t option ref = ref NONE\r
20473\r
20474 local\r
20475 val threads: Thread.Runnable.t Queue.t = Queue.new ()\r
20476 in\r
20477 fun ready (t: Thread.Runnable.t) : unit =\r
20478 Queue.enque(threads, t)\r
20479 fun next () : Thread.Runnable.t =\r
20480 case Queue.deque threads of\r
20481 NONE =&gt; valOf (!topLevel)\r
20482 | SOME t =&gt; t\r
20483 end\r
20484\r
20485 fun 'a exit (): 'a = switch (fn _ =&gt; next ())\r
20486\r
20487 fun new (f: unit -&gt; unit): Thread.Runnable.t =\r
20488 Thread.prepare\r
20489 (Thread.new (fn () =&gt; ((f () handle _ =&gt; exit ())\r
20490 ; exit ())),\r
20491 ())\r
20492\r
20493 fun schedule t = (ready t; next ())\r
20494\r
20495 fun yield (): unit = switch (fn t =&gt; schedule (Thread.prepare (t, ())))\r
20496\r
20497 val spawn = ready o new\r
20498\r
20499 fun setItimer t =\r
20500 Itimer.set (Itimer.Real,\r
20501 {value = t,\r
20502 interval = t})\r
20503\r
20504 fun run (): unit =\r
20505 (switch (fn t =&gt;\r
20506 (topLevel := SOME (Thread.prepare (t, ()))\r
20507 ; new (fn () =&gt; (setHandler (alrm, Handler.handler schedule)\r
20508 ; setItimer (Time.fromMilliseconds 20)))))\r
20509 ; setItimer Time.zeroTime\r
20510 ; ignore alrm\r
20511 ; topLevel := NONE)\r
20512 end\r
20513\r
20514val rec delay =\r
20515 fn 0 =&gt; ()\r
20516 | n =&gt; delay (n - 1)\r
20517\r
20518val rec loop =\r
20519 fn 0 =&gt; ()\r
20520 | n =&gt; (delay 500000; loop (n - 1))\r
20521\r
20522val rec loop' =\r
20523 fn 0 =&gt; ()\r
20524 | n =&gt; (Thread.spawn (fn () =&gt; loop n); loop' (n - 1))\r
20525\r
20526val _ = Thread.spawn (fn () =&gt; loop' 10)\r
20527\r
20528val _ = Thread.run ()\r
20529\r
20530val _ = print "success\n"</programlisting>\r
20531<simpara><?asciidoc-pagebreak?></simpara>\r
20532</section>\r
20533</section>\r
20534<section id="MLtonVector">\r
20535<title>MLtonVector</title>\r
20536<programlisting language="sml" linenumbering="unnumbered">signature MLTON_VECTOR =\r
20537 sig\r
20538 val create: int -&gt; {done: unit -&gt; 'a vector,\r
20539 sub: int -&gt; 'a,\r
20540 update: int * 'a -&gt; unit}\r
20541 val unfoldi: int * 'b * (int * 'b -&gt; 'a * 'b) -&gt; 'a vector * 'b\r
20542 end</programlisting>\r
20543<itemizedlist>\r
20544<listitem>\r
20545<simpara>\r
20546<literal>create n</literal>\r
20547</simpara>\r
20548<simpara>initiates the construction a vector <emphasis>v</emphasis> of length <literal>n</literal>, returning\r
20549functions to manipulate the vector. The <literal>done</literal> function may be called\r
20550to return the created vector; it is an error to call <literal>done</literal> before all\r
20551entries have been initialized; it is an error to call <literal>done</literal> after\r
20552having called <literal>done</literal>. The <literal>sub</literal> function may be called to return an\r
20553initialized vector entry; it is not an error to call <literal>sub</literal> after\r
20554having called <literal>done</literal>. The <literal>update</literal> function may be called to\r
20555initialize a vector entry; it is an error to call <literal>update</literal> after\r
20556having called <literal>done</literal>. One must initialize vector entries in order\r
20557from lowest to highest; that is, before calling <literal>update (i, x)</literal>, one\r
20558must have already called <literal>update (j, x)</literal> for all <literal>j</literal> in <literal>[0, i)</literal>. The\r
20559<literal>done</literal>, <literal>sub</literal>, and <literal>update</literal> functions are all constant-time\r
20560operations.</simpara>\r
20561</listitem>\r
20562<listitem>\r
20563<simpara>\r
20564<literal>unfoldi (n, b, f)</literal>\r
20565</simpara>\r
20566<simpara>constructs a vector <emphasis>v</emphasis> of length <literal>n</literal>, whose elements <emphasis>v<subscript>i</subscript></emphasis> are\r
20567determined by the equations <emphasis>b<subscript>0</subscript> = b</emphasis> and\r
20568<emphasis>(v<subscript>i</subscript>, b<subscript>i+1</subscript>) = f (i, b<subscript>i</subscript>)</emphasis>.</simpara>\r
20569</listitem>\r
20570</itemizedlist>\r
20571<simpara><?asciidoc-pagebreak?></simpara>\r
20572</section>\r
20573<section id="MLtonWeak">\r
20574<title>MLtonWeak</title>\r
20575<programlisting language="sml" linenumbering="unnumbered">signature MLTON_WEAK =\r
20576 sig\r
20577 type 'a t\r
20578\r
20579 val get: 'a t -&gt; 'a option\r
20580 val new: 'a -&gt; 'a t\r
20581 end</programlisting>\r
20582<simpara>A weak pointer is a pointer to an object that is nulled if the object\r
20583becomes <link linkend="Reachability">unreachable</link> due to garbage collection. The\r
20584weak pointer does not itself cause the object it points to be retained\r
20585by the garbage collector&#8201;&#8212;&#8201;only other strong pointers can do that.\r
20586For objects that are not allocated in the heap, like integers, a weak\r
20587pointer will always be nulled. So, if <literal>w: int Weak.t</literal>, then\r
20588<literal>Weak.get w = NONE</literal>.</simpara>\r
20589<itemizedlist>\r
20590<listitem>\r
20591<simpara>\r
20592<literal>type 'a t</literal>\r
20593</simpara>\r
20594<simpara>the type of weak pointers to objects of type <literal>'a</literal></simpara>\r
20595</listitem>\r
20596<listitem>\r
20597<simpara>\r
20598<literal>get w</literal>\r
20599</simpara>\r
20600<simpara>returns <literal>NONE</literal> if the object pointed to by <literal>w</literal> no longer exists.\r
20601Otherwise, returns <literal>SOME</literal> of the object pointed to by <literal>w</literal>.</simpara>\r
20602</listitem>\r
20603<listitem>\r
20604<simpara>\r
20605<literal>new x</literal>\r
20606</simpara>\r
20607<simpara>returns a weak pointer to <literal>x</literal>.</simpara>\r
20608</listitem>\r
20609</itemizedlist>\r
20610<simpara><?asciidoc-pagebreak?></simpara>\r
20611</section>\r
20612<section id="MLtonWord">\r
20613<title>MLtonWord</title>\r
20614<programlisting language="sml" linenumbering="unnumbered">signature MLTON_WORD =\r
20615 sig\r
20616 type t\r
20617\r
20618 val bswap: t -&gt; t\r
20619 val rol: t * word -&gt; t\r
20620 val ror: t * word -&gt; t\r
20621 end</programlisting>\r
20622<itemizedlist>\r
20623<listitem>\r
20624<simpara>\r
20625<literal>type t</literal>\r
20626</simpara>\r
20627<simpara>the type of words. For <literal>MLton.LargeWord</literal> this is <literal>LargeWord.word</literal>,\r
20628for <literal>MLton.Word</literal> this is <literal>Word.word</literal>, for <literal>MLton.Word8</literal> this is\r
20629<literal>Word8.word</literal>, for <literal>MLton.Word16</literal> this is <literal>Word16.word</literal>, for\r
20630<literal>MLton.Word32</literal> this is <literal>Word32.word</literal>, for <literal>MLton.Word64</literal> this is\r
20631<literal>Word64.word</literal>.</simpara>\r
20632</listitem>\r
20633<listitem>\r
20634<simpara>\r
20635<literal>bswap w</literal>\r
20636</simpara>\r
20637<simpara>byte swap.</simpara>\r
20638</listitem>\r
20639<listitem>\r
20640<simpara>\r
20641<literal>rol (w, w')</literal>\r
20642</simpara>\r
20643<simpara>rotates left (circular).</simpara>\r
20644</listitem>\r
20645<listitem>\r
20646<simpara>\r
20647<literal>ror (w, w')</literal>\r
20648</simpara>\r
20649<simpara>rotates right (circular).</simpara>\r
20650</listitem>\r
20651</itemizedlist>\r
20652<simpara><?asciidoc-pagebreak?></simpara>\r
20653</section>\r
20654<section id="MLtonWorld">\r
20655<title>MLtonWorld</title>\r
20656<programlisting language="sml" linenumbering="unnumbered">signature MLTON_WORLD =\r
20657 sig\r
20658 datatype status = Clone | Original\r
20659\r
20660 val load: string -&gt; 'a\r
20661 val save: string -&gt; status\r
20662 val saveThread: string * Thread.Runnable.t -&gt; unit\r
20663 end</programlisting>\r
20664<itemizedlist>\r
20665<listitem>\r
20666<simpara>\r
20667<literal>datatype status</literal>\r
20668</simpara>\r
20669<simpara>specifies whether a world is original or restarted (a clone).</simpara>\r
20670</listitem>\r
20671<listitem>\r
20672<simpara>\r
20673<literal>load f</literal>\r
20674</simpara>\r
20675<simpara>loads the saved computation from file <literal>f</literal>.</simpara>\r
20676</listitem>\r
20677<listitem>\r
20678<simpara>\r
20679<literal>save f</literal>\r
20680</simpara>\r
20681<simpara>saves the entire state of the computation to the file <literal>f</literal>. The\r
20682computation can then be restarted at a later time using <literal>World.load</literal>\r
20683or the <literal>load-world</literal> <link linkend="RunTimeOptions">runtime option</link>. The call to\r
20684<literal>save</literal> in the original computation returns <literal>Original</literal> and the call in\r
20685the restarted world returns <literal>Clone</literal>.</simpara>\r
20686</listitem>\r
20687<listitem>\r
20688<simpara>\r
20689<literal>saveThread (f, rt)</literal>\r
20690</simpara>\r
20691<simpara>saves the entire state of the computation to the file <literal>f</literal> that will\r
20692resume with thread <literal>rt</literal> upon restart.</simpara>\r
20693</listitem>\r
20694</itemizedlist>\r
20695<section id="_notes_2">\r
20696<title>Notes</title>\r
20697<simpara><anchor id="MLtonWorld_ASLR" xreflabel="[MLtonWorld_ASLR]"/>\r
20698Executables that save and load worlds are incompatible with\r
20699<ulink url="http://en.wikipedia.org/wiki/Address_space_layout_randomization">address space layout randomization (ASLR)</ulink>\r
20700of the executable (though, not of shared libraries). The state of a\r
20701computation includes addresses into the code and data segments of the\r
20702executable (e.g., static runtime-system data, return addresses); such\r
20703addresses are invalid when interpreted by the executable loaded at a\r
20704different base address.</simpara>\r
20705<simpara>Executables that save and load worlds should be compiled with an\r
20706option to suppress the generation of position-independent executables.</simpara>\r
20707<itemizedlist>\r
20708<listitem>\r
20709<simpara>\r
20710<link linkend="RunningOnDarwin">Darwin 11 (Mac OS X Lion) and higher</link> : <literal>-link-opt -fno-PIE</literal>\r
20711</simpara>\r
20712</listitem>\r
20713</itemizedlist>\r
20714</section>\r
20715<section id="_example_6">\r
20716<title>Example</title>\r
20717<simpara>Suppose that <literal>save-world.sml</literal> contains the following.</simpara>\r
20718<programlisting language="sml" linenumbering="unnumbered">open MLton.World\r
20719\r
20720val _ =\r
20721 case save "world" of\r
20722 Original =&gt; print "I am the original\n"\r
20723 | Clone =&gt; print "I am the clone\n"</programlisting>\r
20724<simpara>Then, if we compile <literal>save-world.sml</literal> and run it, the <literal>Original</literal>\r
20725branch will execute, and a file named <literal>world</literal> will be created.</simpara>\r
20726<screen>% mlton save-world.sml\r
20727% ./save-world\r
20728I am the original</screen>\r
20729<simpara>We can then load <literal>world</literal> using the <literal>load-world</literal>\r
20730<link linkend="RunTimeOptions">run time option</link>.</simpara>\r
20731<screen>% ./save-world @MLton load-world world --\r
20732I am the clone</screen>\r
20733<simpara><?asciidoc-pagebreak?></simpara>\r
20734</section>\r
20735</section>\r
20736<section id="MLULex">\r
20737<title>MLULex</title>\r
20738<simpara><ulink url="http://smlnj-gforge.cs.uchicago.edu/projects/ml-lpt/">MLULex</ulink> is a\r
20739scanner generator for <link linkend="StandardML">Standard ML</link>.</simpara>\r
20740<section id="_also_see_17">\r
20741<title>Also see</title>\r
20742<itemizedlist>\r
20743<listitem>\r
20744<simpara>\r
20745<link linkend="MLAntlr">MLAntlr</link>\r
20746</simpara>\r
20747</listitem>\r
20748<listitem>\r
20749<simpara>\r
20750<link linkend="MLLPTLibrary">MLLPTLibrary</link>\r
20751</simpara>\r
20752</listitem>\r
20753<listitem>\r
20754<simpara>\r
20755<link linkend="References_OwensEtAl09">OwensEtAl09</link>\r
20756</simpara>\r
20757</listitem>\r
20758</itemizedlist>\r
20759<simpara><?asciidoc-pagebreak?></simpara>\r
20760</section>\r
20761</section>\r
20762<section id="MLYacc">\r
20763<title>MLYacc</title>\r
20764<simpara><link linkend="MLYacc">MLYacc</link> is a parser generator for <link linkend="StandardML">Standard ML</link> modeled\r
20765after the Yacc parser generator.</simpara>\r
20766<simpara>A version of MLYacc, ported from the <link linkend="SMLNJ">SML/NJ</link> sources, is\r
20767distributed with MLton.</simpara>\r
20768<section id="_also_see_18">\r
20769<title>Also see</title>\r
20770<itemizedlist>\r
20771<listitem>\r
20772<simpara>\r
20773<ulink url="guide/Documentation.attachments/mlyacc.pdf"><literal>mlyacc.pdf</literal></ulink>\r
20774</simpara>\r
20775</listitem>\r
20776<listitem>\r
20777<simpara>\r
20778<link linkend="MLLex">MLLex</link>\r
20779</simpara>\r
20780</listitem>\r
20781<listitem>\r
20782<simpara>\r
20783<link linkend="References_TarditiAppel00">TarditiAppel00</link>\r
20784</simpara>\r
20785</listitem>\r
20786<listitem>\r
20787<simpara>\r
20788<link linkend="References_Price09">Price09</link>\r
20789</simpara>\r
20790</listitem>\r
20791</itemizedlist>\r
20792<simpara><?asciidoc-pagebreak?></simpara>\r
20793</section>\r
20794</section>\r
20795<section id="Monomorphise">\r
20796<title>Monomorphise</title>\r
20797<simpara><link linkend="Monomorphise">Monomorphise</link> is a translation pass from the <link linkend="XML">XML</link>\r
20798<link linkend="IntermediateLanguage">IntermediateLanguage</link> to the <link linkend="SXML">SXML</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link>.</simpara>\r
20799<section id="_description_38">\r
20800<title>Description</title>\r
20801<simpara>Monomorphisation eliminates polymorphic values and datatype\r
20802declarations by duplicating them for each type at which they are used.</simpara>\r
20803<simpara>Consider the following <link linkend="XML">XML</link> program.</simpara>\r
20804<programlisting language="sml" linenumbering="unnumbered">datatype 'a t = T of 'a\r
20805fun 'a f (x: 'a) = T x\r
20806val a = f 1\r
20807val b = f 2\r
20808val z = f (3, 4)</programlisting>\r
20809<simpara>The result of monomorphising this program is the following <link linkend="SXML">SXML</link> program:</simpara>\r
20810<programlisting language="sml" linenumbering="unnumbered">datatype t1 = T1 of int\r
20811datatype t2 = T2 of int * int\r
20812fun f1 (x: int) = T1 x\r
20813fun f2 (x: int * int) = T2 x\r
20814val a = f1 1\r
20815val b = f1 2\r
20816val z = f2 (3, 4)</programlisting>\r
20817</section>\r
20818<section id="_implementation_41">\r
20819<title>Implementation</title>\r
20820<itemizedlist>\r
20821<listitem>\r
20822<simpara>\r
20823<ulink url="https://github.com/MLton/mlton/blob/master/mlton/xml/monomorphise.sig"><literal>monomorphise.sig</literal></ulink>\r
20824</simpara>\r
20825</listitem>\r
20826<listitem>\r
20827<simpara>\r
20828<ulink url="https://github.com/MLton/mlton/blob/master/mlton/xml/monomorphise.fun"><literal>monomorphise.fun</literal></ulink>\r
20829</simpara>\r
20830</listitem>\r
20831</itemizedlist>\r
20832</section>\r
20833<section id="_details_and_notes_41">\r
20834<title>Details and Notes</title>\r
20835<simpara>The monomorphiser works by making one pass over the entire program.\r
20836On the way down, it creates a cache for each variable declared in a\r
20837polymorphic declaration that maps a lists of type arguments to a new\r
20838variable name. At a variable reference, it consults the cache (based\r
20839on the types the variable is applied to). If there is already an\r
20840entry in the cache, it is used. If not, a new entry is created. On\r
20841the way up, the monomorphiser duplicates a variable declaration for\r
20842each entry in the cache.</simpara>\r
20843<simpara>As with variables, the monomorphiser records all of the type at which\r
20844constructors are used. After the entire program is processed, the\r
20845monomorphiser duplicates each datatype declaration and its associated\r
20846constructors.</simpara>\r
20847<simpara>The monomorphiser duplicates all of the functions declared in a\r
20848<literal>fun</literal> declaration as a unit. Consider the following program</simpara>\r
20849<programlisting language="sml" linenumbering="unnumbered">fun 'a f (x: 'a) = g x\r
20850and g (y: 'a) = f y\r
20851val a = f 13\r
20852val b = g 14\r
20853val c = f (1, 2)</programlisting>\r
20854<simpara>and its monomorphisation</simpara>\r
20855<programlisting language="sml" linenumbering="unnumbered">fun f1 (x: int) = g1 x\r
20856and g1 (y: int) = f1 y\r
20857fun f2 (x : int * int) = g2 x\r
20858and g2 (y : int * int) = f2 y\r
20859val a = f1 13\r
20860val b = g1 14\r
20861val c = f2 (1, 2)</programlisting>\r
20862</section>\r
20863<section id="_pathological_datatype_declarations">\r
20864<title>Pathological datatype declarations</title>\r
20865<simpara>SML allows a pathological polymorphic datatype declaration in which\r
20866recursive uses of the defined type constructor are applied to\r
20867different type arguments than the definition. This has been\r
20868disallowed by others on type theoretic grounds. A canonical example\r
20869is the following.</simpara>\r
20870<programlisting language="sml" linenumbering="unnumbered">datatype 'a t = A of 'a | B of ('a * 'a) t\r
20871val z : int t = B (B (A ((1, 2), (3, 4))))</programlisting>\r
20872<simpara>The presence of the recursion in the datatype declaration might appear\r
20873to cause the need for the monomorphiser to create an infinite number\r
20874of types. However, due to the absence of polymorphic recursion in\r
20875SML, there are in fact only a finite number of instances of such types\r
20876in any given program. The monomorphiser translates the above program\r
20877to the following one.</simpara>\r
20878<programlisting language="sml" linenumbering="unnumbered">datatype t1 = B1 of t2\r
20879datatype t2 = B2 of t3\r
20880datatype t3 = A3 of (int * int) * (int * int)\r
20881val z : int t = B1 (B2 (A3 ((1, 2), (3, 4))))</programlisting>\r
20882<simpara>It is crucial that the monomorphiser be allowed to drop unused\r
20883constructors from datatype declarations in order for the translation\r
20884to terminate.</simpara>\r
20885<simpara><?asciidoc-pagebreak?></simpara>\r
20886</section>\r
20887</section>\r
20888<section id="MoscowML">\r
20889<title>MoscowML</title>\r
20890<simpara><ulink url="http://mosml.org">Moscow ML</ulink> is a\r
20891<link linkend="StandardMLImplementations">Standard ML implementation</link>. It is a\r
20892byte-code compiler, so it compiles code quickly, but the code runs\r
20893slowly. See <link linkend="Performance">Performance</link>.</simpara>\r
20894<simpara><?asciidoc-pagebreak?></simpara>\r
20895</section>\r
20896<section id="Multi">\r
20897<title>Multi</title>\r
20898<simpara><link linkend="Multi">Multi</link> is an analysis pass for the <link linkend="SSA">SSA</link>\r
20899<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="ConstantPropagation">ConstantPropagation</link> and\r
20900<link linkend="LocalRef">LocalRef</link>.</simpara>\r
20901<section id="_description_39">\r
20902<title>Description</title>\r
20903<simpara>This pass analyzes the control flow of a <link linkend="SSA">SSA</link> program to determine\r
20904which <link linkend="SSA">SSA</link> functions and blocks might be executed more than once or\r
20905by more than one thread. It also determines when a program uses\r
20906threads and when functions and blocks directly or indirectly invoke\r
20907<literal>Thread_copyCurrent</literal>.</simpara>\r
20908</section>\r
20909<section id="_implementation_42">\r
20910<title>Implementation</title>\r
20911<itemizedlist>\r
20912<listitem>\r
20913<simpara>\r
20914<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/multi.sig"><literal>multi.sig</literal></ulink>\r
20915</simpara>\r
20916</listitem>\r
20917<listitem>\r
20918<simpara>\r
20919<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/multi.fun"><literal>multi.fun</literal></ulink>\r
20920</simpara>\r
20921</listitem>\r
20922</itemizedlist>\r
20923</section>\r
20924<section id="_details_and_notes_42">\r
20925<title>Details and Notes</title>\r
20926<simpara></simpara>\r
20927<simpara><?asciidoc-pagebreak?></simpara>\r
20928</section>\r
20929</section>\r
20930<section id="Mutable">\r
20931<title>Mutable</title>\r
20932<simpara>Mutable is an adjective meaning "can be modified". In\r
20933<link linkend="StandardML">Standard ML</link>, ref cells and arrays are mutable, while all\r
20934other values are <link linkend="Immutable">immutable</link>.</simpara>\r
20935<simpara><?asciidoc-pagebreak?></simpara>\r
20936</section>\r
20937<section id="NeedsReview">\r
20938<title>NeedsReview</title>\r
20939<simpara>This page documents some patches and bug fixes that need additional review by experienced developers:</simpara>\r
20940<itemizedlist>\r
20941<listitem>\r
20942<simpara>\r
20943Bug in transparent signature match:\r
20944</simpara>\r
20945<itemizedlist>\r
20946<listitem>\r
20947<simpara>\r
20948What is an <emphasis>original</emphasis> interface and why does the equivalence of original interfaces implies the equivalence of the actual interfaces?\r
20949</simpara>\r
20950</listitem>\r
20951<listitem>\r
20952<simpara>\r
20953<ulink url="http://www.mlton.org/pipermail/mlton/2007-September/029991.html">http://www.mlton.org/pipermail/mlton/2007-September/029991.html</ulink>\r
20954</simpara>\r
20955</listitem>\r
20956<listitem>\r
20957<simpara>\r
20958<ulink url="http://www.mlton.org/pipermail/mlton/2007-September/029995.html">http://www.mlton.org/pipermail/mlton/2007-September/029995.html</ulink>\r
20959</simpara>\r
20960</listitem>\r
20961<listitem>\r
20962<simpara>\r
20963SVN Revision: <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r6046"><literal>r6046</literal></ulink>\r
20964</simpara>\r
20965</listitem>\r
20966</itemizedlist>\r
20967</listitem>\r
20968<listitem>\r
20969<simpara>\r
20970Bug in <link linkend="DeepFlatten">DeepFlatten</link> pass:\r
20971</simpara>\r
20972<itemizedlist>\r
20973<listitem>\r
20974<simpara>\r
20975Should we allow argument to <literal>Weak_new</literal> to be flattened?\r
20976</simpara>\r
20977</listitem>\r
20978<listitem>\r
20979<simpara>\r
20980SVN Revision: <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r6189"><literal>r6189</literal></ulink> (regression test demonstrating bug)\r
20981</simpara>\r
20982</listitem>\r
20983<listitem>\r
20984<simpara>\r
20985SVN Revision: <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r6191"><literal>r6191</literal></ulink>\r
20986</simpara>\r
20987</listitem>\r
20988</itemizedlist>\r
20989</listitem>\r
20990</itemizedlist>\r
20991<simpara><?asciidoc-pagebreak?></simpara>\r
20992</section>\r
20993<section id="NumericLiteral">\r
20994<title>NumericLiteral</title>\r
20995<simpara>Numeric literals in <link linkend="StandardML">Standard ML</link> can be written in either\r
20996decimal or hexadecimal notation. Sometimes it can be convenient to\r
20997write numbers down in other bases. Fortunately, using <link linkend="Fold">Fold</link>, it is\r
20998possible to define a concise syntax for numeric literals that allows\r
20999one to write numeric constants in any base and of various types\r
21000(<literal>int</literal>, <literal>IntInf.int</literal>, <literal>word</literal>, and more).</simpara>\r
21001<simpara>We will define constants <literal>I</literal>, <literal>II</literal>, <literal>W</literal>, and <literal>`</literal> so\r
21002that, for example,</simpara>\r
21003<programlisting language="sml" linenumbering="unnumbered">I 10 `1`2`3 $</programlisting>\r
21004<simpara>denotes <literal>123:int</literal> in base 10, while</simpara>\r
21005<programlisting language="sml" linenumbering="unnumbered">II 8 `2`3 $</programlisting>\r
21006<simpara>denotes <literal>19:IntInf.int</literal> in base 8, and</simpara>\r
21007<programlisting language="sml" linenumbering="unnumbered">W 2 `1`1`0`1 $</programlisting>\r
21008<simpara>denotes <literal>0w13: word</literal>.</simpara>\r
21009<simpara>Here is the code.</simpara>\r
21010<programlisting language="sml" linenumbering="unnumbered">structure Num =\r
21011 struct\r
21012 fun make (op *, op +, i2x) iBase =\r
21013 let\r
21014 val xBase = i2x iBase\r
21015 in\r
21016 Fold.fold\r
21017 ((i2x 0,\r
21018 fn (i, x) =&gt;\r
21019 if 0 &lt;= i andalso i &lt; iBase then\r
21020 x * xBase + i2x i\r
21021 else\r
21022 raise Fail (concat\r
21023 ["Num: ", Int.toString i,\r
21024 " is not a valid\\r
21025 \ digit in base ",\r
21026 Int.toString iBase])),\r
21027 fst)\r
21028 end\r
21029\r
21030 fun I ? = make (op *, op +, id) ?\r
21031 fun II ? = make (op *, op +, IntInf.fromInt) ?\r
21032 fun W ? = make (op *, op +, Word.fromInt) ?\r
21033\r
21034 fun ` ? = Fold.step1 (fn (i, (x, step)) =&gt;\r
21035 (step (i, x), step)) ?\r
21036\r
21037 val a = 10\r
21038 val b = 11\r
21039 val c = 12\r
21040 val d = 13\r
21041 val e = 14\r
21042 val f = 15\r
21043 end</programlisting>\r
21044<simpara>where</simpara>\r
21045<programlisting language="sml" linenumbering="unnumbered">fun fst (x, _) = x</programlisting>\r
21046<simpara>The idea is for the fold to start with zero and to construct the\r
21047result one digit at a time, with each stepper multiplying the previous\r
21048result by the base and adding the next digit. The code is abstracted\r
21049in two different ways for extra generality. First, the <literal>make</literal>\r
21050function abstracts over the various primitive operations (addition,\r
21051multiplication, etc) that are needed to construct a number. This\r
21052allows the same code to be shared for constants <literal>I</literal>, <literal>II</literal>, <literal>W</literal> used to\r
21053write down the various numeric types. It also allows users to add new\r
21054constants for additional numeric types, by supplying the necessary\r
21055arguments to make.</simpara>\r
21056<simpara>Second, the step function, <literal>&grave;</literal>, is abstracted over the actual\r
21057construction operation, which is created by make, and passed along the\r
21058fold. This allows the same constant, <literal>&grave;</literal>, to be used for all\r
21059numeric types. The alternative approach, having a different step\r
21060function for each numeric type, would be more painful to use.</simpara>\r
21061<simpara>On the surface, it appears that the code checks the digits dynamically\r
21062to ensure they are valid for the base. However, MLton will simplify\r
21063everything away at compile time, leaving just the final numeric\r
21064constant.</simpara>\r
21065<simpara><?asciidoc-pagebreak?></simpara>\r
21066</section>\r
21067<section id="ObjectOrientedProgramming">\r
21068<title>ObjectOrientedProgramming</title>\r
21069<simpara><link linkend="StandardML">Standard ML</link> does not have explicit support for\r
21070object-oriented programming. Here are some papers that show how to\r
21071express certain object-oriented concepts in SML.</simpara>\r
21072<itemizedlist>\r
21073<listitem>\r
21074<simpara>\r
21075<link linkend="References_Berthomieu00">OO Programming styles in ML</link>\r
21076</simpara>\r
21077</listitem>\r
21078<listitem>\r
21079<simpara>\r
21080<link linkend="References_ThorupTofte94">Object-oriented programming and Standard ML</link>\r
21081</simpara>\r
21082</listitem>\r
21083<listitem>\r
21084<simpara>\r
21085<link linkend="References_LarsenNiss04">mGTK: An SML binding of Gtk+</link>\r
21086</simpara>\r
21087</listitem>\r
21088<listitem>\r
21089<simpara>\r
21090<link linkend="References_FluetPucella06">Phantom Types and Subtyping</link>\r
21091</simpara>\r
21092</listitem>\r
21093</itemizedlist>\r
21094<simpara>The question of OO programming in SML comes up every now and then.\r
21095The following discusses a simple object-oriented (OO) programming\r
21096technique in Standard ML. The reader is assumed to be able to read\r
21097Java and SML code.</simpara>\r
21098<section id="_motivation">\r
21099<title>Motivation</title>\r
21100<simpara>SML doesn&#8217;t provide subtyping, but it does provide parametric\r
21101polymorphism, which can be used to encode some forms of subtyping.\r
21102Most articles on OO programming in SML concentrate on such encoding\r
21103techniques. While those techniques are interesting&#8201;&#8212;&#8201;and it is\r
21104recommended to read such articles&#8201;&#8212;&#8201;and sometimes useful, it seems\r
21105that basically all OO gurus agree that (deep) subtyping (or\r
21106inheritance) hierarchies aren&#8217;t as practical as they were thought to\r
21107be in the early OO days. "Good", flexible, "OO" designs tend to have\r
21108a flat structure</simpara>\r
21109<screen> Interface\r
21110 ^\r
21111 |\r
21112- - -+-------+-------+- - -\r
21113 | | |\r
21114 ImplA ImplB ImplC</screen>\r
21115<simpara>and deep inheritance hierarchies</simpara>\r
21116<screen>ClassA\r
21117 ^\r
21118 |\r
21119ClassB\r
21120 ^\r
21121 |\r
21122ClassC\r
21123 ^\r
21124 |</screen>\r
21125<simpara>tend to be signs of design mistakes. There are good underlying\r
21126reasons for this, but a thorough discussion is not in the scope of\r
21127this article. However, the point is that perhaps the encoding of\r
21128subtyping is not as important as one might believe. In the following\r
21129we ignore subtyping and rather concentrate on a very simple and basic\r
21130dynamic dispatch technique.</simpara>\r
21131</section>\r
21132<section id="_dynamic_dispatch_using_a_recursive_record_of_functions">\r
21133<title>Dynamic Dispatch Using a Recursive Record of Functions</title>\r
21134<simpara>Quite simply, the basic idea is to implement a "virtual function\r
21135table" using a record that is wrapped inside a (possibly recursive)\r
21136datatype. Let&#8217;s first take a look at a simple concrete example.</simpara>\r
21137<simpara>Consider the following Java interface:</simpara>\r
21138<screen>public interface Counter {\r
21139 public void inc();\r
21140 public int get();\r
21141}</screen>\r
21142<simpara>We can translate the <literal>Counter</literal> interface to SML as follows:</simpara>\r
21143<programlisting language="sml" linenumbering="unnumbered">datatype counter = Counter of {inc : unit -&gt; unit, get : unit -&gt; int}</programlisting>\r
21144<simpara>Each value of type <literal>counter</literal> can be thought of as an object that\r
21145responds to two messages <literal>inc</literal> and <literal>get</literal>. To actually send messages\r
21146to a counter, it is useful to define auxiliary functions</simpara>\r
21147<programlisting language="sml" linenumbering="unnumbered">local\r
21148 fun mk m (Counter t) = m t ()\r
21149in\r
21150 val cGet = mk#get\r
21151 val cInc = mk#inc\r
21152end</programlisting>\r
21153<simpara>that basically extract the "function table" <literal>t</literal> from a counter object\r
21154and then select the specified method <literal>m</literal> from the table.</simpara>\r
21155<simpara>Let&#8217;s then implement a simple function that increments a counter until a\r
21156given maximum is reached:</simpara>\r
21157<programlisting language="sml" linenumbering="unnumbered">fun incUpto counter max = while cGet counter &lt; max do cInc counter</programlisting>\r
21158<simpara>You can easily verify that the above code compiles even without any\r
21159concrete implementation of a counter, thus it is clear that it doesn&#8217;t\r
21160depend on a particular counter implementation.</simpara>\r
21161<simpara>Let&#8217;s then implement a couple of counters. First consider the\r
21162following Java class implementing the <literal>Counter</literal> interface given earlier.</simpara>\r
21163<screen>public class BasicCounter implements Counter {\r
21164 private int cnt;\r
21165 public BasicCounter(int initialCnt) { this.cnt = initialCnt; }\r
21166 public void inc() { this.cnt += 1; }\r
21167 public int get() { return this.cnt; }\r
21168}</screen>\r
21169<simpara>We can translate the above to SML as follows:</simpara>\r
21170<programlisting language="sml" linenumbering="unnumbered">fun newBasicCounter initialCnt = let\r
21171 val cnt = ref initialCnt\r
21172 in\r
21173 Counter {inc = fn () =&gt; cnt := !cnt + 1,\r
21174 get = fn () =&gt; !cnt}\r
21175 end</programlisting>\r
21176<simpara>The SML function <literal>newBasicCounter</literal> can be described as a constructor\r
21177function for counter objects of the <literal>BasicCounter</literal> "class". We can\r
21178also have other counter implementations. Here is the constructor for\r
21179a counter decorator that logs messages:</simpara>\r
21180<programlisting language="sml" linenumbering="unnumbered">fun newLoggedCounter counter =\r
21181 Counter {inc = fn () =&gt; (print "inc\n" ; cInc counter),\r
21182 get = fn () =&gt; (print "get\n" ; cGet counter)}</programlisting>\r
21183<simpara>The <literal>incUpto</literal> function works just as well with objects of either\r
21184class:</simpara>\r
21185<programlisting language="sml" linenumbering="unnumbered">val aCounter = newBasicCounter 0\r
21186val () = incUpto aCounter 5\r
21187val () = print (Int.toString (cGet aCounter) ^"\n")\r
21188\r
21189val aCounter = newLoggedCounter (newBasicCounter 0)\r
21190val () = incUpto aCounter 5\r
21191val () = print (Int.toString (cGet aCounter) ^"\n")</programlisting>\r
21192<simpara>In general, a dynamic dispatch interface is represented as a record\r
21193type wrapped inside a datatype. Each field of the record corresponds\r
21194to a public method or field of the object:</simpara>\r
21195<programlisting language="sml" linenumbering="unnumbered">datatype interface =\r
21196 Interface of {method : t1 -&gt; t2,\r
21197 immutableField : t,\r
21198 mutableField : t ref}</programlisting>\r
21199<simpara>The reason for wrapping the record inside a datatype is that records,\r
21200in SML, can not be recursive. However, SML datatypes can be\r
21201recursive. A record wrapped in a datatype can contain fields that\r
21202contain the datatype. For example, an interface such as <literal>Cloneable</literal></simpara>\r
21203<programlisting language="sml" linenumbering="unnumbered">datatype cloneable = Cloneable of {clone : unit -&gt; cloneable}</programlisting>\r
21204<simpara>can be represented using recursive datatypes.</simpara>\r
21205<simpara>Like in OO languages, interfaces are abstract and can not be\r
21206instantiated to produce objects. To be able to instantiate objects,\r
21207the constructors of a concrete class are needed. In SML, we can\r
21208implement constructors as simple functions from arbitrary arguments to\r
21209values of the interface type. Such a constructor function can\r
21210encapsulate arbitrary private state and functions using lexical\r
21211closure. It is also easy to share implementations of methods between\r
21212two or more constructors.</simpara>\r
21213<simpara>While the <literal>Counter</literal> example is rather trivial, it should not be\r
21214difficult to see that this technique quite simply doesn&#8217;t require a huge\r
21215amount of extra verbiage and is more than usable in practice.</simpara>\r
21216</section>\r
21217<section id="_sml_modules_and_dynamic_dispatch">\r
21218<title>SML Modules and Dynamic Dispatch</title>\r
21219<simpara>One might wonder about how SML modules and the dynamic dispatch\r
21220technique work together. Let&#8217;s investigate! Let&#8217;s use a simple\r
21221dispenser framework as a concrete example. (Note that this isn&#8217;t\r
21222intended to be an introduction to the SML module system.)</simpara>\r
21223<section id="_programming_with_sml_modules">\r
21224<title>Programming with SML Modules</title>\r
21225<simpara>Using SML signatures we can specify abstract data types (ADTs) such as\r
21226dispensers. Here is a signature for an "abstract" functional (as\r
21227opposed to imperative) dispenser:</simpara>\r
21228<programlisting language="sml" linenumbering="unnumbered">signature ABSTRACT_DISPENSER = sig\r
21229 type 'a t\r
21230 val isEmpty : 'a t -&gt; bool\r
21231 val push : 'a * 'a t -&gt; 'a t\r
21232 val pop : 'a t -&gt; ('a * 'a t) option\r
21233end</programlisting>\r
21234<simpara>The term "abstract" in the name of the signature refers to the fact that\r
21235the signature gives no way to instantiate a dispenser. It has nothing to\r
21236do with the concept of abstract data types.</simpara>\r
21237<simpara>Using SML functors we can write "generic" algorithms that manipulate\r
21238dispensers of an unknown type. Here are a couple of very simple\r
21239algorithms:</simpara>\r
21240<programlisting language="sml" linenumbering="unnumbered">functor DispenserAlgs (D : ABSTRACT_DISPENSER) = struct\r
21241 open D\r
21242\r
21243 fun pushAll (xs, d) = foldl push d xs\r
21244\r
21245 fun popAll d = let\r
21246 fun lp (xs, NONE) = rev xs\r
21247 | lp (xs, SOME (x, d)) = lp (x::xs, pop d)\r
21248 in\r
21249 lp ([], pop d)\r
21250 end\r
21251\r
21252 fun cp (from, to) = pushAll (popAll from, to)\r
21253end</programlisting>\r
21254<simpara>As one can easily verify, the above compiles even without any concrete\r
21255dispenser structure. Functors essentially provide a form a static\r
21256dispatch that one can use to break compile-time dependencies.</simpara>\r
21257<simpara>We can also give a signature for a concrete dispenser</simpara>\r
21258<programlisting language="sml" linenumbering="unnumbered">signature DISPENSER = sig\r
21259 include ABSTRACT_DISPENSER\r
21260 val empty : 'a t\r
21261end</programlisting>\r
21262<simpara>and write any number of concrete structures implementing the signature.\r
21263For example, we could implement stacks</simpara>\r
21264<programlisting language="sml" linenumbering="unnumbered">structure Stack :&gt; DISPENSER = struct\r
21265 type 'a t = 'a list\r
21266 val empty = []\r
21267 val isEmpty = null\r
21268 val push = op ::\r
21269 val pop = List.getItem\r
21270end</programlisting>\r
21271<simpara>and queues</simpara>\r
21272<programlisting language="sml" linenumbering="unnumbered">structure Queue :&gt; DISPENSER = struct\r
21273 datatype 'a t = T of 'a list * 'a list\r
21274 val empty = T ([], [])\r
21275 val isEmpty = fn T ([], _) =&gt; true | _ =&gt; false\r
21276 val normalize = fn ([], ys) =&gt; (rev ys, []) | q =&gt; q\r
21277 fun push (y, T (xs, ys)) = T (normalize (xs, y::ys))\r
21278 val pop = fn (T (x::xs, ys)) =&gt; SOME (x, T (normalize (xs, ys))) | _ =&gt; NONE\r
21279end</programlisting>\r
21280<simpara>One can now write code that uses either the <literal>Stack</literal> or the <literal>Queue</literal>\r
21281dispenser. One can also instantiate the previously defined functor to\r
21282create functions for manipulating dispensers of a type:</simpara>\r
21283<programlisting language="sml" linenumbering="unnumbered">structure S = DispenserAlgs (Stack)\r
21284val [4,3,2,1] = S.popAll (S.pushAll ([1,2,3,4], Stack.empty))\r
21285\r
21286structure Q = DispenserAlgs (Queue)\r
21287val [1,2,3,4] = Q.popAll (Q.pushAll ([1,2,3,4], Queue.empty))</programlisting>\r
21288<simpara>There is no dynamic dispatch involved at the module level in SML. An\r
21289attempt to do dynamic dispatch</simpara>\r
21290<programlisting language="sml" linenumbering="unnumbered">val q = Q.push (1, Stack.empty)</programlisting>\r
21291<simpara>will give a type error.</simpara>\r
21292</section>\r
21293<section id="_combining_sml_modules_and_dynamic_dispatch">\r
21294<title>Combining SML Modules and Dynamic Dispatch</title>\r
21295<simpara>Let&#8217;s then combine SML modules and the dynamic dispatch technique\r
21296introduced in this article. First we define an interface for\r
21297dispensers:</simpara>\r
21298<programlisting language="sml" linenumbering="unnumbered">structure Dispenser = struct\r
21299 datatype 'a t =\r
21300 I of {isEmpty : unit -&gt; bool,\r
21301 push : 'a -&gt; 'a t,\r
21302 pop : unit -&gt; ('a * 'a t) option}\r
21303\r
21304 fun O m (I t) = m t\r
21305\r
21306 fun isEmpty t = O#isEmpty t ()\r
21307 fun push (v, t) = O#push t v\r
21308 fun pop t = O#pop t ()\r
21309end</programlisting>\r
21310<simpara>The <literal>Dispenser</literal> module, which we can think of as an interface for\r
21311dispensers, implements the <literal>ABSTRACT_DISPENSER</literal> signature using\r
21312the dynamic dispatch technique, but we leave the signature ascription\r
21313until later.</simpara>\r
21314<simpara>Then we define a <literal>DispenserClass</literal> functor that makes a "class" out of\r
21315a given dispenser module:</simpara>\r
21316<programlisting language="sml" linenumbering="unnumbered">functor DispenserClass (D : DISPENSER) : DISPENSER = struct\r
21317 open Dispenser\r
21318\r
21319 fun make d =\r
21320 I {isEmpty = fn () =&gt; D.isEmpty d,\r
21321 push = fn x =&gt; make (D.push (x, d)),\r
21322 pop = fn () =&gt;\r
21323 case D.pop d of\r
21324 NONE =&gt; NONE\r
21325 | SOME (x, d) =&gt; SOME (x, make d)}\r
21326\r
21327 val empty =\r
21328 I {isEmpty = fn () =&gt; true,\r
21329 push = fn x =&gt; make (D.push (x, D.empty)),\r
21330 pop = fn () =&gt; NONE}\r
21331end</programlisting>\r
21332<simpara>Finally we seal the <literal>Dispenser</literal> module:</simpara>\r
21333<programlisting language="sml" linenumbering="unnumbered">structure Dispenser : ABSTRACT_DISPENSER = Dispenser</programlisting>\r
21334<simpara>This isn&#8217;t necessary for type safety, because the unsealed <literal>Dispenser</literal>\r
21335module does not allow one to break encapsulation, but makes sure that\r
21336only the <literal>DispenserClass</literal> functor can create dispenser classes\r
21337(because the constructor <literal>Dispenser.I</literal> is no longer accessible).</simpara>\r
21338<simpara>Using the <literal>DispenserClass</literal> functor we can turn any concrete dispenser\r
21339module into a dispenser class:</simpara>\r
21340<programlisting language="sml" linenumbering="unnumbered">structure StackClass = DispenserClass (Stack)\r
21341structure QueueClass = DispenserClass (Queue)</programlisting>\r
21342<simpara>Each dispenser class implements the same dynamic dispatch interface\r
21343and the <literal>ABSTRACT_DISPENSER</literal> -signature.</simpara>\r
21344<simpara>Because the dynamic dispatch <literal>Dispenser</literal> module implements the\r
21345<literal>ABSTRACT_DISPENSER</literal>-signature, we can use it to instantiate the\r
21346<literal>DispenserAlgs</literal>-functor:</simpara>\r
21347<programlisting language="sml" linenumbering="unnumbered">structure D = DispenserAlgs (Dispenser)</programlisting>\r
21348<simpara>The resulting <literal>D</literal> module, like the <literal>Dispenser</literal> module, works with\r
21349any dispenser class and uses dynamic dispatch:</simpara>\r
21350<programlisting language="sml" linenumbering="unnumbered">val [4, 3, 2, 1] = D.popAll (D.pushAll ([1, 2, 3, 4], StackClass.empty))\r
21351val [1, 2, 3, 4] = D.popAll (D.pushAll ([1, 2, 3, 4], QueueClass.empty))</programlisting>\r
21352<simpara><?asciidoc-pagebreak?></simpara>\r
21353</section>\r
21354</section>\r
21355</section>\r
21356<section id="OCaml">\r
21357<title>OCaml</title>\r
21358<simpara><ulink url="http://caml.inria.fr/">OCaml</ulink> is a variant of <link linkend="ML">ML</link> and is similar to\r
21359<link linkend="StandardML">Standard ML</link>.</simpara>\r
21360<section id="_ocaml_and_sml">\r
21361<title>OCaml and SML</title>\r
21362<simpara>Here&#8217;s a comparison of some aspects of the OCaml and SML languages.</simpara>\r
21363<itemizedlist>\r
21364<listitem>\r
21365<simpara>\r
21366Standard ML has a formal <link linkend="DefinitionOfStandardML">Definition</link>, while\r
21367OCaml is specified by its lone implementation and informal\r
21368documentation.\r
21369</simpara>\r
21370</listitem>\r
21371<listitem>\r
21372<simpara>\r
21373Standard ML has a number of <link linkend="StandardMLImplementations">compilers</link>,\r
21374while OCaml has only one.\r
21375</simpara>\r
21376</listitem>\r
21377<listitem>\r
21378<simpara>\r
21379OCaml has built-in support for object-oriented programming, while\r
21380Standard ML does not (however, see <link linkend="ObjectOrientedProgramming">ObjectOrientedProgramming</link>).\r
21381</simpara>\r
21382</listitem>\r
21383<listitem>\r
21384<simpara>\r
21385Andreas Rossberg has a\r
21386<ulink url="http://www.mpi-sws.org/%7Erossberg/sml-vs-ocaml.html">side-by-side\r
21387comparison</ulink> of the syntax of SML and OCaml.\r
21388</simpara>\r
21389</listitem>\r
21390<listitem>\r
21391<simpara>\r
21392Adam Chlipala has a\r
21393<ulink url="http://adam.chlipala.net/mlcomp">point-by-point comparison</ulink> of OCaml\r
21394and SML.\r
21395</simpara>\r
21396</listitem>\r
21397</itemizedlist>\r
21398</section>\r
21399<section id="_ocaml_and_mlton">\r
21400<title>OCaml and MLton</title>\r
21401<simpara>Here&#8217;s a comparison of some aspects of OCaml and MLton.</simpara>\r
21402<itemizedlist>\r
21403<listitem>\r
21404<simpara>\r
21405Performance\r
21406</simpara>\r
21407<itemizedlist>\r
21408<listitem>\r
21409<simpara>\r
21410Both OCaml and MLton have excellent performance.\r
21411</simpara>\r
21412</listitem>\r
21413<listitem>\r
21414<simpara>\r
21415MLton performs extensive <link linkend="WholeProgramOptimization">WholeProgramOptimization</link>, which can\r
21416provide substantial improvements in large, modular programs.\r
21417</simpara>\r
21418</listitem>\r
21419<listitem>\r
21420<simpara>\r
21421MLton uses native types, like 32-bit integers, without any penalty\r
21422due to tagging or boxing. OCaml uses 31-bit integers with a penalty\r
21423due to tagging, and 32-bit integers with a penalty due to boxing.\r
21424</simpara>\r
21425</listitem>\r
21426<listitem>\r
21427<simpara>\r
21428MLton uses native types, like 64-bit floats, without any penalty\r
21429due to boxing. OCaml, in some situations, boxes 64-bit floats.\r
21430</simpara>\r
21431</listitem>\r
21432<listitem>\r
21433<simpara>\r
21434MLton represents arrays of all types unboxed. In OCaml, only\r
21435arrays of 64-bit floats are unboxed, and then only when it is\r
21436syntactically apparent.\r
21437</simpara>\r
21438</listitem>\r
21439<listitem>\r
21440<simpara>\r
21441MLton represents records compactly by reordering and packing the\r
21442fields.\r
21443</simpara>\r
21444</listitem>\r
21445<listitem>\r
21446<simpara>\r
21447In MLton, polymorphic and monomorphic code have the same\r
21448performance. In OCaml, polymorphism can introduce a performance\r
21449penalty.\r
21450</simpara>\r
21451</listitem>\r
21452<listitem>\r
21453<simpara>\r
21454In MLton, module boundaries have no impact on performance. In\r
21455OCaml, moving code between modules can cause a performance penalty.\r
21456</simpara>\r
21457</listitem>\r
21458<listitem>\r
21459<simpara>\r
21460MLton&#8217;s <link linkend="ForeignFunctionInterface">ForeignFunctionInterface</link> is simpler than OCaml&#8217;s.\r
21461</simpara>\r
21462</listitem>\r
21463</itemizedlist>\r
21464</listitem>\r
21465<listitem>\r
21466<simpara>\r
21467Tools\r
21468</simpara>\r
21469<itemizedlist>\r
21470<listitem>\r
21471<simpara>\r
21472OCaml has a debugger, while MLton does not.\r
21473</simpara>\r
21474</listitem>\r
21475<listitem>\r
21476<simpara>\r
21477OCaml supports separate compilation, while MLton does not.\r
21478</simpara>\r
21479</listitem>\r
21480<listitem>\r
21481<simpara>\r
21482OCaml compiles faster than MLton.\r
21483</simpara>\r
21484</listitem>\r
21485<listitem>\r
21486<simpara>\r
21487MLton supports profiling of both time and allocation.\r
21488</simpara>\r
21489</listitem>\r
21490</itemizedlist>\r
21491</listitem>\r
21492<listitem>\r
21493<simpara>\r
21494Libraries\r
21495</simpara>\r
21496<itemizedlist>\r
21497<listitem>\r
21498<simpara>\r
21499OCaml has more available libraries.\r
21500</simpara>\r
21501</listitem>\r
21502</itemizedlist>\r
21503</listitem>\r
21504<listitem>\r
21505<simpara>\r
21506Community\r
21507</simpara>\r
21508<itemizedlist>\r
21509<listitem>\r
21510<simpara>\r
21511OCaml has a larger community than MLton.\r
21512</simpara>\r
21513</listitem>\r
21514<listitem>\r
21515<simpara>\r
21516MLton has a very responsive\r
21517 <ulink url="http://www.mlton.org/mailman/listinfo/mlton">developer list</ulink>.\r
21518</simpara>\r
21519</listitem>\r
21520</itemizedlist>\r
21521</listitem>\r
21522</itemizedlist>\r
21523<simpara><?asciidoc-pagebreak?></simpara>\r
21524</section>\r
21525</section>\r
21526<section id="OpenGL">\r
21527<title>OpenGL</title>\r
21528<simpara>There are at least two interfaces to OpenGL for MLton/SML, both of\r
21529which should be considered alpha quality.</simpara>\r
21530<itemizedlist>\r
21531<listitem>\r
21532<simpara>\r
21533<link linkend="MikeThomas">MikeThomas</link> built a low-level interface, directly translating\r
21534many of the functions, covering GL, GLU, and GLUT. This is available\r
21535in the MLton <link linkend="Sources">Sources</link>:\r
21536<ulink url="https://github.com/MLton/mltonlib/tree/master/org/mlton/mike/opengl"><literal>opengl</literal></ulink>. The code\r
21537contains a number of small, standard OpenGL examples translated to\r
21538SML.\r
21539</simpara>\r
21540</listitem>\r
21541<listitem>\r
21542<simpara>\r
21543<link linkend="ChrisClearwater">ChrisClearwater</link> has written at least an interface to GL, and\r
21544possibly more. See\r
21545</simpara>\r
21546<itemizedlist>\r
21547<listitem>\r
21548<simpara>\r
21549<ulink url="http://mlton.org/pipermail/mlton/2005-January/026669.html">http://mlton.org/pipermail/mlton/2005-January/026669.html</ulink>\r
21550</simpara>\r
21551</listitem>\r
21552</itemizedlist>\r
21553</listitem>\r
21554</itemizedlist>\r
21555<simpara><link linkend="Contact">Contact</link> us for more information or an update on the status of\r
21556these projects.</simpara>\r
21557<simpara><?asciidoc-pagebreak?></simpara>\r
21558</section>\r
21559<section id="OperatorPrecedence">\r
21560<title>OperatorPrecedence</title>\r
21561<simpara><link linkend="StandardML">Standard ML</link> has a built in notion of precedence for\r
21562certain symbols. Every program that includes the\r
21563<link linkend="BasisLibrary">Basis Library</link> automatically gets the following infix\r
21564declarations. Higher number indicates higher precedence.</simpara>\r
21565<programlisting language="sml" linenumbering="unnumbered">infix 7 * / mod div\r
21566infix 6 + - ^\r
21567infixr 5 :: @\r
21568infix 4 = &lt;&gt; &gt; &gt;= &lt; &lt;=\r
21569infix 3 := o\r
21570infix 0 before</programlisting>\r
21571<simpara><?asciidoc-pagebreak?></simpara>\r
21572</section>\r
21573<section id="OptionalArguments">\r
21574<title>OptionalArguments</title>\r
21575<simpara><link linkend="StandardML">Standard ML</link> does not have built-in support for optional\r
21576arguments. Nevertheless, using <link linkend="Fold">Fold</link>, it is easy to define\r
21577functions that take optional arguments.</simpara>\r
21578<simpara>For example, suppose that we have the following definition of a\r
21579function <literal>f</literal>.</simpara>\r
21580<programlisting language="sml" linenumbering="unnumbered">fun f (i, r, s) =\r
21581 concat [Int.toString i, ", ", Real.toString r, ", ", s]</programlisting>\r
21582<simpara>Using the <literal>OptionalArg</literal> structure described below, we can define a\r
21583function <literal>f'</literal>, an optionalized version of <literal>f</literal>, that takes 0, 1, 2, or\r
215843 arguments. Embedded within <literal>f'</literal> will be default values for <literal>i</literal>,\r
21585<literal>r</literal>, and <literal>s</literal>. If <literal>f'</literal> gets no arguments, then all the defaults are\r
21586used. If <literal>f'</literal> gets one argument, then that will be used for <literal>i</literal>. Two\r
21587arguments will be used for <literal>i</literal> and <literal>r</literal> respectively. Three arguments\r
21588will override all default values. Calls to <literal>f'</literal> will look like the\r
21589following.</simpara>\r
21590<programlisting language="sml" linenumbering="unnumbered">f' $\r
21591f' `2 $\r
21592f' `2 `3.0 $\r
21593f' `2 `3.0 `"four" $</programlisting>\r
21594<simpara>The optional argument indicator, <literal>&grave;</literal>, is not special syntax ---\r
21595it is a normal SML value, defined in the <literal>OptionalArg</literal> structure\r
21596below.</simpara>\r
21597<simpara>Here is the definition of <literal>f'</literal> using the <literal>OptionalArg</literal> structure, in\r
21598particular, <literal>OptionalArg.make</literal> and <literal>OptionalArg.D</literal>.</simpara>\r
21599<programlisting language="sml" linenumbering="unnumbered">val f' =\r
21600 fn z =&gt;\r
21601 let open OptionalArg in\r
21602 make (D 1) (D 2.0) (D "three") $\r
21603 end (fn i &amp; r &amp; s =&gt; f (i, r, s))\r
21604 z</programlisting>\r
21605<simpara>The definition of <literal>f'</literal> is eta expanded as with all uses of fold. A\r
21606call to <literal>OptionalArg.make</literal> is supplied with a variable number of\r
21607defaults (in this case, three), the end-of-arguments terminator, <literal>$</literal>,\r
21608and the function to run, taking its arguments as an n-ary\r
21609<link linkend="ProductType">product</link>. In this case, the function simply converts\r
21610the product to an ordinary tuple and calls <literal>f</literal>. Often, the function\r
21611body will simply be written directly.</simpara>\r
21612<simpara>In general, the definition of an optional-argument function looks like\r
21613the following.</simpara>\r
21614<programlisting language="sml" linenumbering="unnumbered">val f =\r
21615 fn z =&gt;\r
21616 let open OptionalArg in\r
21617 make (D &lt;default1&gt;) (D &lt;default2&gt;) ... (D &lt;defaultn&gt;) $\r
21618 end (fn x1 &amp; x2 &amp; ... &amp; xn =&gt;\r
21619 &lt;function code goes here&gt;)\r
21620 z</programlisting>\r
21621<simpara>Here is the definition of <literal>OptionalArg</literal>.</simpara>\r
21622<programlisting language="sml" linenumbering="unnumbered">structure OptionalArg =\r
21623 struct\r
21624 val make =\r
21625 fn z =&gt;\r
21626 Fold.fold\r
21627 ((id, fn (f, x) =&gt; f x),\r
21628 fn (d, r) =&gt; fn func =&gt;\r
21629 Fold.fold ((id, d ()), fn (f, d) =&gt;\r
21630 let\r
21631 val d &amp; () = r (id, f d)\r
21632 in\r
21633 func d\r
21634 end))\r
21635 z\r
21636\r
21637 fun D d = Fold.step0 (fn (f, r) =&gt;\r
21638 (fn ds =&gt; f (d &amp; ds),\r
21639 fn (f, a &amp; b) =&gt; r (fn x =&gt; f a &amp; x, b)))\r
21640\r
21641 val ` =\r
21642 fn z =&gt;\r
21643 Fold.step1 (fn (x, (f, _ &amp; d)) =&gt; (fn d =&gt; f (x &amp; d), d))\r
21644 z\r
21645 end</programlisting>\r
21646<simpara><literal>OptionalArg.make</literal> uses a nested fold. The first <literal>fold</literal> accumulates\r
21647the default values in a product, associated to the right, and a\r
21648reversal function that converts a product (of the same arity as the\r
21649number of defaults) from right associativity to left associativity.\r
21650The accumulated defaults are used by the second fold, which recurs\r
21651over the product, replacing the appropriate component as it encounters\r
21652optional arguments. The second fold also constructs a "fill"\r
21653function, <literal>f</literal>, that is used to reconstruct the product once the\r
21654end-of-arguments is reached. Finally, the finisher reconstructs the\r
21655product and uses the reversal function to convert the product from\r
21656right associative to left associative, at which point it is passed to\r
21657the user-supplied function.</simpara>\r
21658<simpara>Much of the complexity comes from the fact that while recurring over a\r
21659product from left to right, one wants it to be right-associative,\r
21660e.g., look like</simpara>\r
21661<programlisting language="sml" linenumbering="unnumbered">a &amp; (b &amp; (c &amp; d))</programlisting>\r
21662<simpara>but the user function in the end wants the product to be left\r
21663associative, so that the product argument pattern can be written\r
21664without parentheses (since <literal>&amp;</literal> is left associative).</simpara>\r
21665<section id="_labelled_optional_arguments">\r
21666<title>Labelled optional arguments</title>\r
21667<simpara>In addition to the positional optional arguments described above, it\r
21668is sometimes useful to have labelled optional arguments. These allow\r
21669one to define a function, <literal>f</literal>, with defaults, say <literal>a</literal> and <literal>b</literal>. Then,\r
21670a caller of <literal>f</literal> can supply values for <literal>a</literal> and <literal>b</literal> by name. If no\r
21671value is supplied then the default is used.</simpara>\r
21672<simpara>Labelled optional arguments are a simple extension of\r
21673<link linkend="FunctionalRecordUpdate">FunctionalRecordUpdate</link> using post composition. Suppose, for\r
21674example, that one wants a function <literal>f</literal> with labelled optional\r
21675arguments <literal>a</literal> and <literal>b</literal> with default values <literal>0</literal> and <literal>0.0</literal> respectively.\r
21676If one has a functional-record-update function <literal>updateAB</literal> for records\r
21677with <literal>a</literal> and <literal>b</literal> fields, then one can define <literal>f</literal> in the following way.</simpara>\r
21678<programlisting language="sml" linenumbering="unnumbered">val f =\r
21679 fn z =&gt;\r
21680 Fold.post\r
21681 (updateAB {a = 0, b = 0.0},\r
21682 fn {a, b} =&gt; print (concat [Int.toString a, " ",\r
21683 Real.toString b, "\n"]))\r
21684 z</programlisting>\r
21685<simpara>The idea is that <literal>f</literal> is the post composition (using <literal>Fold.post</literal>) of\r
21686the actual code for the function with a functional-record updater that\r
21687starts with the defaults.</simpara>\r
21688<simpara>Here are some example calls to <literal>f</literal>.</simpara>\r
21689<programlisting language="sml" linenumbering="unnumbered">val () = f $\r
21690val () = f (U#a 13) $\r
21691val () = f (U#a 13) (U#b 17.5) $\r
21692val () = f (U#b 17.5) (U#a 13) $</programlisting>\r
21693<simpara>Notice that a caller can supply neither of the arguments, either of\r
21694the arguments, or both of the arguments, and in either order. All\r
21695that matter is that the arguments be labelled correctly (and of the\r
21696right type, of course).</simpara>\r
21697<simpara>Here is another example.</simpara>\r
21698<programlisting language="sml" linenumbering="unnumbered">val f =\r
21699 fn z =&gt;\r
21700 Fold.post\r
21701 (updateBCD {b = 0, c = 0.0, d = "&lt;&gt;"},\r
21702 fn {b, c, d} =&gt;\r
21703 print (concat [Int.toString b, " ",\r
21704 Real.toString c, " ",\r
21705 d, "\n"]))\r
21706 z</programlisting>\r
21707<simpara>Here are some example calls.</simpara>\r
21708<programlisting language="sml" linenumbering="unnumbered">val () = f $\r
21709val () = f (U#d "goodbye") $\r
21710val () = f (U#d "hello") (U#b 17) (U#c 19.3) $</programlisting>\r
21711<simpara><?asciidoc-pagebreak?></simpara>\r
21712</section>\r
21713</section>\r
21714<section id="Overloading">\r
21715<title>Overloading</title>\r
21716<simpara>In <link linkend="StandardML">Standard ML</link>, constants (like <literal>13</literal>, <literal>0w13</literal>, <literal>13.0</literal>)\r
21717are overloaded, meaning that they can denote a constant of the\r
21718appropriate type as determined by context. SML defines the\r
21719overloading classes <emphasis>Int</emphasis>, <emphasis>Real</emphasis>, and <emphasis>Word</emphasis>, which denote the sets\r
21720of types that integer, real, and word constants may take on. In\r
21721MLton, these are defined as follows.</simpara>\r
21722<informaltable\r
21723frame="all"\r
21724rowsep="1" colsep="1"\r
21725>\r
21726<tgroup cols="2">\r
21727<colspec colname="col_1" colwidth="25*"/>\r
21728<colspec colname="col_2" colwidth="75*"/>\r
21729<tbody>\r
21730<row>\r
21731<entry align="center" valign="top"><simpara><emphasis>Int</emphasis></simpara></entry>\r
21732<entry align="left" valign="top"><simpara><literal>Int2.int</literal>, <literal>Int3.int</literal>, &#8230; <literal>Int32.int</literal>, <literal>Int64.int</literal>, <literal>Int.int</literal>, <literal>IntInf.int</literal>, <literal>LargeInt.int</literal>, <literal>FixedInt.int</literal>, <literal>Position.int</literal></simpara></entry>\r
21733</row>\r
21734<row>\r
21735<entry align="center" valign="top"><simpara><emphasis>Real</emphasis></simpara></entry>\r
21736<entry align="left" valign="top"><simpara><literal>Real32.real</literal>, <literal>Real64.real</literal>, <literal>Real.real</literal>, <literal>LargeReal.real</literal></simpara></entry>\r
21737</row>\r
21738<row>\r
21739<entry align="center" valign="top"><simpara><emphasis>Word</emphasis></simpara></entry>\r
21740<entry align="left" valign="top"><simpara><literal>Word2.word</literal>, <literal>Word3.word</literal>, &#8230; <literal>Word32.word</literal>, <literal>Word64.word</literal>, <literal>Word.word</literal>, <literal>LargeWord.word</literal>, <literal>SysWord.word</literal></simpara></entry>\r
21741</row>\r
21742</tbody>\r
21743</tgroup>\r
21744</informaltable>\r
21745<simpara>The <link linkend="DefinitionOfStandardML">Definition</link> allows flexibility in how\r
21746much context is used to resolve overloading. It says that the context\r
21747is <emphasis>no larger than the smallest enclosing structure-level\r
21748declaration</emphasis>, but that <emphasis>an implementation may require that a smaller\r
21749context determines the type</emphasis>. MLton uses the largest possible context\r
21750allowed by SML in resolving overloading. If the type of a constant is\r
21751not determined by context, then it takes on a default type. In MLton,\r
21752these are defined as follows.</simpara>\r
21753<informaltable\r
21754frame="all"\r
21755rowsep="1" colsep="1"\r
21756>\r
21757<tgroup cols="2">\r
21758<colspec colname="col_1" colwidth="25*"/>\r
21759<colspec colname="col_2" colwidth="75*"/>\r
21760<tbody>\r
21761<row>\r
21762<entry align="center" valign="top"><simpara><emphasis>Int</emphasis></simpara></entry>\r
21763<entry align="left" valign="top"><simpara><literal>Int.int</literal></simpara></entry>\r
21764</row>\r
21765<row>\r
21766<entry align="center" valign="top"><simpara><emphasis>Real</emphasis></simpara></entry>\r
21767<entry align="left" valign="top"><simpara><literal>Real.real</literal></simpara></entry>\r
21768</row>\r
21769<row>\r
21770<entry align="center" valign="top"><simpara><emphasis>Word</emphasis></simpara></entry>\r
21771<entry align="left" valign="top"><simpara><literal>Word.word</literal></simpara></entry>\r
21772</row>\r
21773</tbody>\r
21774</tgroup>\r
21775</informaltable>\r
21776<simpara>Other implementations may use a smaller context or different default\r
21777types.</simpara>\r
21778<section id="_also_see_19">\r
21779<title>Also see</title>\r
21780<itemizedlist>\r
21781<listitem>\r
21782<simpara>\r
21783<ulink url="http://www.standardml.org/Basis/top-level-chapter.html">discussion of overloading in the Basis Library</ulink>\r
21784</simpara>\r
21785</listitem>\r
21786</itemizedlist>\r
21787</section>\r
21788<section id="_examples_3">\r
21789<title>Examples</title>\r
21790<itemizedlist>\r
21791<listitem>\r
21792<simpara>\r
21793The following program is rejected.\r
21794</simpara>\r
21795<programlisting language="sml" linenumbering="unnumbered">structure S:\r
21796 sig\r
21797 val x: Word8.word\r
21798 end =\r
21799 struct\r
21800 val x = 0w0\r
21801 end</programlisting>\r
21802<simpara>The smallest enclosing structure declaration for <literal>0w0</literal> is\r
21803<literal>val x = 0w0</literal>. Hence, <literal>0w0</literal> receives the default type for words,\r
21804which is <literal>Word.word</literal>.</simpara>\r
21805</listitem>\r
21806</itemizedlist>\r
21807<simpara><?asciidoc-pagebreak?></simpara>\r
21808</section>\r
21809</section>\r
21810<section id="PackedRepresentation">\r
21811<title>PackedRepresentation</title>\r
21812<simpara><link linkend="PackedRepresentation">PackedRepresentation</link> is an analysis pass for the <link linkend="SSA2">SSA2</link>\r
21813<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="ToRSSA">ToRSSA</link>.</simpara>\r
21814<section id="_description_40">\r
21815<title>Description</title>\r
21816<simpara>This pass analyzes a <link linkend="SSA2">SSA2</link> program to compute a packed\r
21817representation for each object.</simpara>\r
21818</section>\r
21819<section id="_implementation_43">\r
21820<title>Implementation</title>\r
21821<itemizedlist>\r
21822<listitem>\r
21823<simpara>\r
21824<ulink url="https://github.com/MLton/mlton/blob/master/mlton/backend/representation.sig"><literal>representation.sig</literal></ulink>\r
21825</simpara>\r
21826</listitem>\r
21827<listitem>\r
21828<simpara>\r
21829<ulink url="https://github.com/MLton/mlton/blob/master/mlton/backend/packed-representation.fun"><literal>packed-representation.fun</literal></ulink>\r
21830</simpara>\r
21831</listitem>\r
21832</itemizedlist>\r
21833</section>\r
21834<section id="_details_and_notes_43">\r
21835<title>Details and Notes</title>\r
21836<simpara>Has a special case to make sure that <literal>true</literal> is represented as <literal>1</literal> and\r
21837<literal>false</literal> is represented as <literal>0</literal>.</simpara>\r
21838<simpara><?asciidoc-pagebreak?></simpara>\r
21839</section>\r
21840</section>\r
21841<section id="ParallelMove">\r
21842<title>ParallelMove</title>\r
21843<simpara><link linkend="ParallelMove">ParallelMove</link> is a rewrite pass, agnostic in the\r
21844<link linkend="IntermediateLanguage">IntermediateLanguage</link> which it produces.</simpara>\r
21845<section id="_description_41">\r
21846<title>Description</title>\r
21847<simpara>This function computes a sequence of individual moves to effect a\r
21848parallel move (with possibly overlapping froms and tos).</simpara>\r
21849</section>\r
21850<section id="_implementation_44">\r
21851<title>Implementation</title>\r
21852<itemizedlist>\r
21853<listitem>\r
21854<simpara>\r
21855<ulink url="https://github.com/MLton/mlton/blob/master/mlton/backend/parallel-move.sig"><literal>parallel-move.sig</literal></ulink>\r
21856</simpara>\r
21857</listitem>\r
21858<listitem>\r
21859<simpara>\r
21860<ulink url="https://github.com/MLton/mlton/blob/master/mlton/backend/parallel-move.fun"><literal>parallel-move.fun</literal></ulink>\r
21861</simpara>\r
21862</listitem>\r
21863</itemizedlist>\r
21864</section>\r
21865<section id="_details_and_notes_44">\r
21866<title>Details and Notes</title>\r
21867<simpara></simpara>\r
21868<simpara><?asciidoc-pagebreak?></simpara>\r
21869</section>\r
21870</section>\r
21871<section id="Performance">\r
21872<title>Performance</title>\r
21873<simpara>This page compares the performance of a number of SML compilers on a\r
21874range of benchmarks.</simpara>\r
21875<simpara>This page compares the following SML compiler versions.</simpara>\r
21876<itemizedlist>\r
21877<listitem>\r
21878<simpara>\r
21879<link linkend="Home">MLton</link> 20171211 (git 79d4a623c)\r
21880</simpara>\r
21881</listitem>\r
21882<listitem>\r
21883<simpara>\r
21884<link linkend="MLKit">ML Kit</link> 4.3.12 (20171210)\r
21885</simpara>\r
21886</listitem>\r
21887<listitem>\r
21888<simpara>\r
21889<link linkend="MoscowML">Moscow ML</link> 2.10.1 ++ (git f529b33bb, 20170711)\r
21890</simpara>\r
21891</listitem>\r
21892<listitem>\r
21893<simpara>\r
21894<link linkend="PolyML">Poly/ML</link> 5.7.2 Testing (git 5.7.1-35-gcb73407a)\r
21895</simpara>\r
21896</listitem>\r
21897<listitem>\r
21898<simpara>\r
21899<link linkend="SMLNJ">SML/NJ</link> 110.81 (20170501)\r
21900</simpara>\r
21901</listitem>\r
21902</itemizedlist>\r
21903<simpara>There are tables for <link linkend="Performance_RunTime">run time</link>, <link linkend="Performance_CodeSize">code size</link>, and\r
21904<link linkend="Performance_CompileTime">compile time</link>.</simpara>\r
21905<section id="_setup_3">\r
21906<title>Setup</title>\r
21907<simpara>All benchmarks were compiled and run on a 2.6 GHz Core i7-5600U with 16G of\r
21908RAM. The benchmarks were compiled with the default settings for all\r
21909the compilers, except for Moscow ML, which was passed the\r
21910<literal>-orthodox -standalone -toplevel</literal> switches. The Poly/ML executables\r
21911were produced using <literal>polyc</literal>.\r
21912The SML/NJ executables were produced by wrapping the entire program in\r
21913a <literal>local</literal> declaration whose body performs an <literal>SMLofNJ.exportFn</literal>.</simpara>\r
21914<simpara>For more details, or if you want to run the benchmarks yourself,\r
21915please see the <ulink url="https://github.com/MLton/mlton/tree/master/benchmark"><literal>benchmark</literal></ulink> directory of our\r
21916<link linkend="Sources">Sources</link>.</simpara>\r
21917<simpara>All of the benchmarks are available for download from this page. Some\r
21918of the benchmarks were obtained from the SML/NJ benchmark suite. Some\r
21919of the benchmarks expect certain input files to exist in the\r
21920<ulink url="https://github.com/MLton/mlton/tree/master/benchmark/tests/DATA"><literal>DATA</literal></ulink> subdirectory.</simpara>\r
21921<itemizedlist>\r
21922<listitem>\r
21923<simpara>\r
21924<ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/hamlet.sml"><literal>hamlet.sml</literal></ulink> <ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/DATA/hamlet-input.sml"><literal>hamlet-input.sml</literal></ulink>\r
21925</simpara>\r
21926</listitem>\r
21927<listitem>\r
21928<simpara>\r
21929<ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/ray.sml"><literal>ray.sml</literal></ulink> <ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/DATA/ray"><literal>ray</literal></ulink>\r
21930</simpara>\r
21931</listitem>\r
21932<listitem>\r
21933<simpara>\r
21934<ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/raytrace.sml"><literal>raytrace.sml</literal></ulink> <ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/DATA/chess.gml"><literal>chess.gml</literal></ulink>\r
21935</simpara>\r
21936</listitem>\r
21937<listitem>\r
21938<simpara>\r
21939<ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/vliw.sml"><literal>vliw.sml</literal></ulink> <ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/DATA/ndotprod.s"><literal>ndotprod.s</literal></ulink>\r
21940</simpara>\r
21941</listitem>\r
21942</itemizedlist>\r
21943</section>\r
21944<section id="_anchor_id_performance_runtime_xreflabel_performance_runtime_run_time_ratio">\r
21945<title><anchor id="Performance_RunTime" xreflabel="[Performance_RunTime]"/>Run-time ratio</title>\r
21946<simpara>The following table gives the ratio of the run time of each benchmark\r
21947when compiled by another compiler to the run time when compiled by\r
21948MLton. That is, the larger the number, the slower the generated code\r
21949runs. A number larger than one indicates that the corresponding\r
21950compiler produces code that runs more slowly than MLton. A * in an\r
21951entry means the compiler failed to compile the benchmark or that the\r
21952benchmark failed to run.</simpara>\r
21953<informaltable\r
21954frame="all"\r
21955rowsep="1" colsep="1"\r
21956>\r
21957<tgroup cols="6">\r
21958<colspec colname="col_1" colwidth="28*"/>\r
21959<colspec colname="col_2" colwidth="14*"/>\r
21960<colspec colname="col_3" colwidth="14*"/>\r
21961<colspec colname="col_4" colwidth="14*"/>\r
21962<colspec colname="col_5" colwidth="14*"/>\r
21963<colspec colname="col_6" colwidth="14*"/>\r
21964<thead>\r
21965<row>\r
21966<entry align="left" valign="top">benchmark</entry>\r
21967<entry align="left" valign="top">MLton</entry>\r
21968<entry align="left" valign="top">ML-Kit</entry>\r
21969<entry align="left" valign="top">MosML</entry>\r
21970<entry align="left" valign="top">Poly/ML</entry>\r
21971<entry align="left" valign="top">SML/NJ</entry>\r
21972</row>\r
21973</thead>\r
21974<tbody>\r
21975<row>\r
21976<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/barnes-hut.sml"><literal>barnes-hut.sml</literal></ulink></simpara></entry>\r
21977<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
21978<entry align="left" valign="top"><simpara>10.11</simpara></entry>\r
21979<entry align="left" valign="top"><simpara>19.36</simpara></entry>\r
21980<entry align="left" valign="top"><simpara>2.98</simpara></entry>\r
21981<entry align="left" valign="top"><simpara>1.24</simpara></entry>\r
21982</row>\r
21983<row>\r
21984<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/boyer.sml"><literal>boyer.sml</literal></ulink></simpara></entry>\r
21985<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
21986<entry align="left" valign="top"><simpara>*</simpara></entry>\r
21987<entry align="left" valign="top"><simpara>7.87</simpara></entry>\r
21988<entry align="left" valign="top"><simpara>1.22</simpara></entry>\r
21989<entry align="left" valign="top"><simpara>1.75</simpara></entry>\r
21990</row>\r
21991<row>\r
21992<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/checksum.sml"><literal>checksum.sml</literal></ulink></simpara></entry>\r
21993<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
21994<entry align="left" valign="top"><simpara>30.79</simpara></entry>\r
21995<entry align="left" valign="top"><simpara>*</simpara></entry>\r
21996<entry align="left" valign="top"><simpara>10.94</simpara></entry>\r
21997<entry align="left" valign="top"><simpara>9.08</simpara></entry>\r
21998</row>\r
21999<row>\r
22000<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/count-graphs.sml"><literal>count-graphs.sml</literal></ulink></simpara></entry>\r
22001<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22002<entry align="left" valign="top"><simpara>6.51</simpara></entry>\r
22003<entry align="left" valign="top"><simpara>40.42</simpara></entry>\r
22004<entry align="left" valign="top"><simpara>2.34</simpara></entry>\r
22005<entry align="left" valign="top"><simpara>2.32</simpara></entry>\r
22006</row>\r
22007<row>\r
22008<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/DLXSimulator.sml"><literal>DLXSimulator.sml</literal></ulink></simpara></entry>\r
22009<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22010<entry align="left" valign="top"><simpara>0.97</simpara></entry>\r
22011<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22012<entry align="left" valign="top"><simpara>0.60</simpara></entry>\r
22013<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22014</row>\r
22015<row>\r
22016<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/even-odd.sml"><literal>even-odd.sml</literal></ulink></simpara></entry>\r
22017<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22018<entry align="left" valign="top"><simpara>0.50</simpara></entry>\r
22019<entry align="left" valign="top"><simpara>11.50</simpara></entry>\r
22020<entry align="left" valign="top"><simpara>0.42</simpara></entry>\r
22021<entry align="left" valign="top"><simpara>0.42</simpara></entry>\r
22022</row>\r
22023<row>\r
22024<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/fft.sml"><literal>fft.sml</literal></ulink></simpara></entry>\r
22025<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22026<entry align="left" valign="top"><simpara>7.35</simpara></entry>\r
22027<entry align="left" valign="top"><simpara>81.51</simpara></entry>\r
22028<entry align="left" valign="top"><simpara>4.03</simpara></entry>\r
22029<entry align="left" valign="top"><simpara>1.19</simpara></entry>\r
22030</row>\r
22031<row>\r
22032<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/fib.sml"><literal>fib.sml</literal></ulink></simpara></entry>\r
22033<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22034<entry align="left" valign="top"><simpara>1.41</simpara></entry>\r
22035<entry align="left" valign="top"><simpara>10.94</simpara></entry>\r
22036<entry align="left" valign="top"><simpara>1.25</simpara></entry>\r
22037<entry align="left" valign="top"><simpara>1.17</simpara></entry>\r
22038</row>\r
22039<row>\r
22040<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/flat-array.sml"><literal>flat-array.sml</literal></ulink></simpara></entry>\r
22041<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22042<entry align="left" valign="top"><simpara>7.19</simpara></entry>\r
22043<entry align="left" valign="top"><simpara>68.33</simpara></entry>\r
22044<entry align="left" valign="top"><simpara>5.28</simpara></entry>\r
22045<entry align="left" valign="top"><simpara>13.16</simpara></entry>\r
22046</row>\r
22047<row>\r
22048<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/hamlet.sml"><literal>hamlet.sml</literal></ulink></simpara></entry>\r
22049<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22050<entry align="left" valign="top"><simpara>4.97</simpara></entry>\r
22051<entry align="left" valign="top"><simpara>22.85</simpara></entry>\r
22052<entry align="left" valign="top"><simpara>1.58</simpara></entry>\r
22053<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22054</row>\r
22055<row>\r
22056<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/imp-for.sml"><literal>imp-for.sml</literal></ulink></simpara></entry>\r
22057<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22058<entry align="left" valign="top"><simpara>4.99</simpara></entry>\r
22059<entry align="left" valign="top"><simpara>57.84</simpara></entry>\r
22060<entry align="left" valign="top"><simpara>3.34</simpara></entry>\r
22061<entry align="left" valign="top"><simpara>4.67</simpara></entry>\r
22062</row>\r
22063<row>\r
22064<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/knuth-bendix.sml"><literal>knuth-bendix.sml</literal></ulink></simpara></entry>\r
22065<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22066<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22067<entry align="left" valign="top"><simpara>18.43</simpara></entry>\r
22068<entry align="left" valign="top"><simpara>3.18</simpara></entry>\r
22069<entry align="left" valign="top"><simpara>3.06</simpara></entry>\r
22070</row>\r
22071<row>\r
22072<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/lexgen.sml"><literal>lexgen.sml</literal></ulink></simpara></entry>\r
22073<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22074<entry align="left" valign="top"><simpara>2.76</simpara></entry>\r
22075<entry align="left" valign="top"><simpara>7.94</simpara></entry>\r
22076<entry align="left" valign="top"><simpara>3.19</simpara></entry>\r
22077<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22078</row>\r
22079<row>\r
22080<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/life.sml"><literal>life.sml</literal></ulink></simpara></entry>\r
22081<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22082<entry align="left" valign="top"><simpara>1.80</simpara></entry>\r
22083<entry align="left" valign="top"><simpara>20.19</simpara></entry>\r
22084<entry align="left" valign="top"><simpara>0.89</simpara></entry>\r
22085<entry align="left" valign="top"><simpara>1.50</simpara></entry>\r
22086</row>\r
22087<row>\r
22088<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/logic.sml"><literal>logic.sml</literal></ulink></simpara></entry>\r
22089<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22090<entry align="left" valign="top"><simpara>5.10</simpara></entry>\r
22091<entry align="left" valign="top"><simpara>11.06</simpara></entry>\r
22092<entry align="left" valign="top"><simpara>1.15</simpara></entry>\r
22093<entry align="left" valign="top"><simpara>1.27</simpara></entry>\r
22094</row>\r
22095<row>\r
22096<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/mandelbrot.sml"><literal>mandelbrot.sml</literal></ulink></simpara></entry>\r
22097<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22098<entry align="left" valign="top"><simpara>3.50</simpara></entry>\r
22099<entry align="left" valign="top"><simpara>25.52</simpara></entry>\r
22100<entry align="left" valign="top"><simpara>1.33</simpara></entry>\r
22101<entry align="left" valign="top"><simpara>1.28</simpara></entry>\r
22102</row>\r
22103<row>\r
22104<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/matrix-multiply.sml"><literal>matrix-multiply.sml</literal></ulink></simpara></entry>\r
22105<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22106<entry align="left" valign="top"><simpara>29.40</simpara></entry>\r
22107<entry align="left" valign="top"><simpara>183.02</simpara></entry>\r
22108<entry align="left" valign="top"><simpara>7.41</simpara></entry>\r
22109<entry align="left" valign="top"><simpara>15.19</simpara></entry>\r
22110</row>\r
22111<row>\r
22112<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/md5.sml"><literal>md5.sml</literal></ulink></simpara></entry>\r
22113<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22114<entry align="left" valign="top"><simpara>95.18</simpara></entry>\r
22115<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22116<entry align="left" valign="top"><simpara>32.61</simpara></entry>\r
22117<entry align="left" valign="top"><simpara>47.47</simpara></entry>\r
22118</row>\r
22119<row>\r
22120<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/merge.sml"><literal>merge.sml</literal></ulink></simpara></entry>\r
22121<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22122<entry align="left" valign="top"><simpara>1.42</simpara></entry>\r
22123<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22124<entry align="left" valign="top"><simpara>0.74</simpara></entry>\r
22125<entry align="left" valign="top"><simpara>3.24</simpara></entry>\r
22126</row>\r
22127<row>\r
22128<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/mlyacc.sml"><literal>mlyacc.sml</literal></ulink></simpara></entry>\r
22129<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22130<entry align="left" valign="top"><simpara>1.83</simpara></entry>\r
22131<entry align="left" valign="top"><simpara>8.45</simpara></entry>\r
22132<entry align="left" valign="top"><simpara>0.84</simpara></entry>\r
22133<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22134</row>\r
22135<row>\r
22136<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/model-elimination.sml"><literal>model-elimination.sml</literal></ulink></simpara></entry>\r
22137<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22138<entry align="left" valign="top"><simpara>4.03</simpara></entry>\r
22139<entry align="left" valign="top"><simpara>12.42</simpara></entry>\r
22140<entry align="left" valign="top"><simpara>1.70</simpara></entry>\r
22141<entry align="left" valign="top"><simpara>2.25</simpara></entry>\r
22142</row>\r
22143<row>\r
22144<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/mpuz.sml"><literal>mpuz.sml</literal></ulink></simpara></entry>\r
22145<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22146<entry align="left" valign="top"><simpara>3.73</simpara></entry>\r
22147<entry align="left" valign="top"><simpara>57.44</simpara></entry>\r
22148<entry align="left" valign="top"><simpara>2.05</simpara></entry>\r
22149<entry align="left" valign="top"><simpara>3.22</simpara></entry>\r
22150</row>\r
22151<row>\r
22152<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/nucleic.sml"><literal>nucleic.sml</literal></ulink></simpara></entry>\r
22153<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22154<entry align="left" valign="top"><simpara>3.96</simpara></entry>\r
22155<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22156<entry align="left" valign="top"><simpara>1.73</simpara></entry>\r
22157<entry align="left" valign="top"><simpara>1.20</simpara></entry>\r
22158</row>\r
22159<row>\r
22160<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/output1.sml"><literal>output1.sml</literal></ulink></simpara></entry>\r
22161<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22162<entry align="left" valign="top"><simpara>6.26</simpara></entry>\r
22163<entry align="left" valign="top"><simpara>30.85</simpara></entry>\r
22164<entry align="left" valign="top"><simpara>7.82</simpara></entry>\r
22165<entry align="left" valign="top"><simpara>5.99</simpara></entry>\r
22166</row>\r
22167<row>\r
22168<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/peek.sml"><literal>peek.sml</literal></ulink></simpara></entry>\r
22169<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22170<entry align="left" valign="top"><simpara>9.37</simpara></entry>\r
22171<entry align="left" valign="top"><simpara>44.78</simpara></entry>\r
22172<entry align="left" valign="top"><simpara>2.18</simpara></entry>\r
22173<entry align="left" valign="top"><simpara>2.15</simpara></entry>\r
22174</row>\r
22175<row>\r
22176<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/psdes-random.sml"><literal>psdes-random.sml</literal></ulink></simpara></entry>\r
22177<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22178<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22179<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22180<entry align="left" valign="top"><simpara>2.79</simpara></entry>\r
22181<entry align="left" valign="top"><simpara>3.59</simpara></entry>\r
22182</row>\r
22183<row>\r
22184<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/ratio-regions.sml"><literal>ratio-regions.sml</literal></ulink></simpara></entry>\r
22185<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22186<entry align="left" valign="top"><simpara>5.68</simpara></entry>\r
22187<entry align="left" valign="top"><simpara>165.56</simpara></entry>\r
22188<entry align="left" valign="top"><simpara>3.92</simpara></entry>\r
22189<entry align="left" valign="top"><simpara>37.52</simpara></entry>\r
22190</row>\r
22191<row>\r
22192<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/ray.sml"><literal>ray.sml</literal></ulink></simpara></entry>\r
22193<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22194<entry align="left" valign="top"><simpara>12.05</simpara></entry>\r
22195<entry align="left" valign="top"><simpara>25.08</simpara></entry>\r
22196<entry align="left" valign="top"><simpara>8.73</simpara></entry>\r
22197<entry align="left" valign="top"><simpara>1.75</simpara></entry>\r
22198</row>\r
22199<row>\r
22200<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/raytrace.sml"><literal>raytrace.sml</literal></ulink></simpara></entry>\r
22201<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22202<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22203<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22204<entry align="left" valign="top"><simpara>2.11</simpara></entry>\r
22205<entry align="left" valign="top"><simpara>3.33</simpara></entry>\r
22206</row>\r
22207<row>\r
22208<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/simple.sml"><literal>simple.sml</literal></ulink></simpara></entry>\r
22209<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22210<entry align="left" valign="top"><simpara>2.95</simpara></entry>\r
22211<entry align="left" valign="top"><simpara>24.03</simpara></entry>\r
22212<entry align="left" valign="top"><simpara>3.67</simpara></entry>\r
22213<entry align="left" valign="top"><simpara>1.93</simpara></entry>\r
22214</row>\r
22215<row>\r
22216<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/smith-normal-form.sml"><literal>smith-normal-form.sml</literal></ulink></simpara></entry>\r
22217<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22218<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22219<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22220<entry align="left" valign="top"><simpara>1.04</simpara></entry>\r
22221<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22222</row>\r
22223<row>\r
22224<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/string-concat.sml"><literal>string-concat.sml</literal></ulink></simpara></entry>\r
22225<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22226<entry align="left" valign="top"><simpara>1.88</simpara></entry>\r
22227<entry align="left" valign="top"><simpara>28.01</simpara></entry>\r
22228<entry align="left" valign="top"><simpara>0.70</simpara></entry>\r
22229<entry align="left" valign="top"><simpara>2.67</simpara></entry>\r
22230</row>\r
22231<row>\r
22232<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/tailfib.sml"><literal>tailfib.sml</literal></ulink></simpara></entry>\r
22233<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22234<entry align="left" valign="top"><simpara>1.58</simpara></entry>\r
22235<entry align="left" valign="top"><simpara>23.57</simpara></entry>\r
22236<entry align="left" valign="top"><simpara>0.90</simpara></entry>\r
22237<entry align="left" valign="top"><simpara>1.04</simpara></entry>\r
22238</row>\r
22239<row>\r
22240<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/tak.sml"><literal>tak.sml</literal></ulink></simpara></entry>\r
22241<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22242<entry align="left" valign="top"><simpara>1.69</simpara></entry>\r
22243<entry align="left" valign="top"><simpara>15.90</simpara></entry>\r
22244<entry align="left" valign="top"><simpara>1.57</simpara></entry>\r
22245<entry align="left" valign="top"><simpara>2.01</simpara></entry>\r
22246</row>\r
22247<row>\r
22248<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/tensor.sml"><literal>tensor.sml</literal></ulink></simpara></entry>\r
22249<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22250<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22251<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22252<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22253<entry align="left" valign="top"><simpara>2.07</simpara></entry>\r
22254</row>\r
22255<row>\r
22256<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/tsp.sml"><literal>tsp.sml</literal></ulink></simpara></entry>\r
22257<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22258<entry align="left" valign="top"><simpara>2.19</simpara></entry>\r
22259<entry align="left" valign="top"><simpara>66.76</simpara></entry>\r
22260<entry align="left" valign="top"><simpara>3.27</simpara></entry>\r
22261<entry align="left" valign="top"><simpara>1.48</simpara></entry>\r
22262</row>\r
22263<row>\r
22264<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/tyan.sml"><literal>tyan.sml</literal></ulink></simpara></entry>\r
22265<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22266<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22267<entry align="left" valign="top"><simpara>19.43</simpara></entry>\r
22268<entry align="left" valign="top"><simpara>1.08</simpara></entry>\r
22269<entry align="left" valign="top"><simpara>1.03</simpara></entry>\r
22270</row>\r
22271<row>\r
22272<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/vector32-concat.sml"><literal>vector32-concat.sml</literal></ulink></simpara></entry>\r
22273<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22274<entry align="left" valign="top"><simpara>13.85</simpara></entry>\r
22275<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22276<entry align="left" valign="top"><simpara>1.80</simpara></entry>\r
22277<entry align="left" valign="top"><simpara>12.48</simpara></entry>\r
22278</row>\r
22279<row>\r
22280<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/vector64-concat.sml"><literal>vector64-concat.sml</literal></ulink></simpara></entry>\r
22281<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22282<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22283<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22284<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22285<entry align="left" valign="top"><simpara>13.92</simpara></entry>\r
22286</row>\r
22287<row>\r
22288<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/vector-rev.sml"><literal>vector-rev.sml</literal></ulink></simpara></entry>\r
22289<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22290<entry align="left" valign="top"><simpara>7.88</simpara></entry>\r
22291<entry align="left" valign="top"><simpara>68.85</simpara></entry>\r
22292<entry align="left" valign="top"><simpara>9.39</simpara></entry>\r
22293<entry align="left" valign="top"><simpara>68.80</simpara></entry>\r
22294</row>\r
22295<row>\r
22296<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/vliw.sml"><literal>vliw.sml</literal></ulink></simpara></entry>\r
22297<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22298<entry align="left" valign="top"><simpara>2.46</simpara></entry>\r
22299<entry align="left" valign="top"><simpara>15.39</simpara></entry>\r
22300<entry align="left" valign="top"><simpara>1.43</simpara></entry>\r
22301<entry align="left" valign="top"><simpara>1.55</simpara></entry>\r
22302</row>\r
22303<row>\r
22304<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/wc-input1.sml"><literal>wc-input1.sml</literal></ulink></simpara></entry>\r
22305<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22306<entry align="left" valign="top"><simpara>6.00</simpara></entry>\r
22307<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22308<entry align="left" valign="top"><simpara>29.25</simpara></entry>\r
22309<entry align="left" valign="top"><simpara>9.54</simpara></entry>\r
22310</row>\r
22311<row>\r
22312<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/wc-scanStream.sml"><literal>wc-scanStream.sml</literal></ulink></simpara></entry>\r
22313<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22314<entry align="left" valign="top"><simpara>80.43</simpara></entry>\r
22315<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22316<entry align="left" valign="top"><simpara>19.45</simpara></entry>\r
22317<entry align="left" valign="top"><simpara>8.71</simpara></entry>\r
22318</row>\r
22319<row>\r
22320<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/zebra.sml"><literal>zebra.sml</literal></ulink></simpara></entry>\r
22321<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22322<entry align="left" valign="top"><simpara>4.62</simpara></entry>\r
22323<entry align="left" valign="top"><simpara>35.56</simpara></entry>\r
22324<entry align="left" valign="top"><simpara>1.68</simpara></entry>\r
22325<entry align="left" valign="top"><simpara>9.97</simpara></entry>\r
22326</row>\r
22327<row>\r
22328<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/zern.sml"><literal>zern.sml</literal></ulink></simpara></entry>\r
22329<entry align="left" valign="top"><simpara>1.00</simpara></entry>\r
22330<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22331<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22332<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22333<entry align="left" valign="top"><simpara>1.60</simpara></entry>\r
22334</row>\r
22335</tbody>\r
22336</tgroup>\r
22337</informaltable>\r
22338<simpara><anchor id="Performance_SNFNote" xreflabel="[Performance_SNFNote]"/>\r
22339Note: for SML/NJ, the\r
22340<ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/smith-normal-form.sml"><literal>smith-normal-form.sml</literal></ulink>\r
22341benchmark was killed after running for over 51,000 seconds.</simpara>\r
22342</section>\r
22343<section id="_anchor_id_performance_codesize_xreflabel_performance_codesize_code_size">\r
22344<title><anchor id="Performance_CodeSize" xreflabel="[Performance_CodeSize]"/>Code size</title>\r
22345<simpara>The following table gives the code size of each benchmark in bytes.\r
22346The size for MLton and the ML Kit is the sum of text and data for the\r
22347standalone executable as reported by <literal>size</literal>. The size for Moscow\r
22348ML is the size in bytes of the executable <literal>a.out</literal>. The size for\r
22349Poly/ML is the difference in size of the database before the session\r
22350start and after the commit. The size for SML/NJ is the size of the\r
22351heap file created by <literal>exportFn</literal> and does not include the size of\r
22352the SML/NJ runtime system (approximately 100K). A * in an entry means\r
22353that the compiler failed to compile the benchmark.</simpara>\r
22354<informaltable\r
22355frame="all"\r
22356rowsep="1" colsep="1"\r
22357>\r
22358<tgroup cols="6">\r
22359<colspec colname="col_1" colwidth="28*"/>\r
22360<colspec colname="col_2" colwidth="14*"/>\r
22361<colspec colname="col_3" colwidth="14*"/>\r
22362<colspec colname="col_4" colwidth="14*"/>\r
22363<colspec colname="col_5" colwidth="14*"/>\r
22364<colspec colname="col_6" colwidth="14*"/>\r
22365<thead>\r
22366<row>\r
22367<entry align="left" valign="top">benchmark</entry>\r
22368<entry align="left" valign="top">MLton</entry>\r
22369<entry align="left" valign="top">ML-Kit</entry>\r
22370<entry align="left" valign="top">MosML</entry>\r
22371<entry align="left" valign="top">Poly/ML</entry>\r
22372<entry align="left" valign="top">SML/NJ</entry>\r
22373</row>\r
22374</thead>\r
22375<tbody>\r
22376<row>\r
22377<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/barnes-hut.sml"><literal>barnes-hut.sml</literal></ulink></simpara></entry>\r
22378<entry align="left" valign="top"><simpara>180,788</simpara></entry>\r
22379<entry align="left" valign="top"><simpara>810,267</simpara></entry>\r
22380<entry align="left" valign="top"><simpara>199,503</simpara></entry>\r
22381<entry align="left" valign="top"><simpara>148,120</simpara></entry>\r
22382<entry align="left" valign="top"><simpara>402,480</simpara></entry>\r
22383</row>\r
22384<row>\r
22385<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/boyer.sml"><literal>boyer.sml</literal></ulink></simpara></entry>\r
22386<entry align="left" valign="top"><simpara>250,246</simpara></entry>\r
22387<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22388<entry align="left" valign="top"><simpara>248,018</simpara></entry>\r
22389<entry align="left" valign="top"><simpara>196,984</simpara></entry>\r
22390<entry align="left" valign="top"><simpara>496,664</simpara></entry>\r
22391</row>\r
22392<row>\r
22393<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/checksum.sml"><literal>checksum.sml</literal></ulink></simpara></entry>\r
22394<entry align="left" valign="top"><simpara>122,422</simpara></entry>\r
22395<entry align="left" valign="top"><simpara>225,274</simpara></entry>\r
22396<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22397<entry align="left" valign="top"><simpara>106,088</simpara></entry>\r
22398<entry align="left" valign="top"><simpara>406,560</simpara></entry>\r
22399</row>\r
22400<row>\r
22401<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/count-graphs.sml"><literal>count-graphs.sml</literal></ulink></simpara></entry>\r
22402<entry align="left" valign="top"><simpara>151,878</simpara></entry>\r
22403<entry align="left" valign="top"><simpara>250,126</simpara></entry>\r
22404<entry align="left" valign="top"><simpara>187,048</simpara></entry>\r
22405<entry align="left" valign="top"><simpara>144,032</simpara></entry>\r
22406<entry align="left" valign="top"><simpara>428,136</simpara></entry>\r
22407</row>\r
22408<row>\r
22409<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/DLXSimulator.sml"><literal>DLXSimulator.sml</literal></ulink></simpara></entry>\r
22410<entry align="left" valign="top"><simpara>223,073</simpara></entry>\r
22411<entry align="left" valign="top"><simpara>827,483</simpara></entry>\r
22412<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22413<entry align="left" valign="top"><simpara>272,664</simpara></entry>\r
22414<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22415</row>\r
22416<row>\r
22417<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/even-odd.sml"><literal>even-odd.sml</literal></ulink></simpara></entry>\r
22418<entry align="left" valign="top"><simpara>122,350</simpara></entry>\r
22419<entry align="left" valign="top"><simpara>87,586</simpara></entry>\r
22420<entry align="left" valign="top"><simpara>181,415</simpara></entry>\r
22421<entry align="left" valign="top"><simpara>106,072</simpara></entry>\r
22422<entry align="left" valign="top"><simpara>380,928</simpara></entry>\r
22423</row>\r
22424<row>\r
22425<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/fft.sml"><literal>fft.sml</literal></ulink></simpara></entry>\r
22426<entry align="left" valign="top"><simpara>145,008</simpara></entry>\r
22427<entry align="left" valign="top"><simpara>237,230</simpara></entry>\r
22428<entry align="left" valign="top"><simpara>186,228</simpara></entry>\r
22429<entry align="left" valign="top"><simpara>131,400</simpara></entry>\r
22430<entry align="left" valign="top"><simpara>418,896</simpara></entry>\r
22431</row>\r
22432<row>\r
22433<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/fib.sml"><literal>fib.sml</literal></ulink></simpara></entry>\r
22434<entry align="left" valign="top"><simpara>122,310</simpara></entry>\r
22435<entry align="left" valign="top"><simpara>87,402</simpara></entry>\r
22436<entry align="left" valign="top"><simpara>181,312</simpara></entry>\r
22437<entry align="left" valign="top"><simpara>106,088</simpara></entry>\r
22438<entry align="left" valign="top"><simpara>380,928</simpara></entry>\r
22439</row>\r
22440<row>\r
22441<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/flat-array.sml"><literal>flat-array.sml</literal></ulink></simpara></entry>\r
22442<entry align="left" valign="top"><simpara>121,958</simpara></entry>\r
22443<entry align="left" valign="top"><simpara>104,102</simpara></entry>\r
22444<entry align="left" valign="top"><simpara>181,464</simpara></entry>\r
22445<entry align="left" valign="top"><simpara>106,072</simpara></entry>\r
22446<entry align="left" valign="top"><simpara>394,256</simpara></entry>\r
22447</row>\r
22448<row>\r
22449<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/hamlet.sml"><literal>hamlet.sml</literal></ulink></simpara></entry>\r
22450<entry align="left" valign="top"><simpara>1,503,849</simpara></entry>\r
22451<entry align="left" valign="top"><simpara>2,280,691</simpara></entry>\r
22452<entry align="left" valign="top"><simpara>407,219</simpara></entry>\r
22453<entry align="left" valign="top"><simpara>2,249,504</simpara></entry>\r
22454<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22455</row>\r
22456<row>\r
22457<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/imp-for.sml"><literal>imp-for.sml</literal></ulink></simpara></entry>\r
22458<entry align="left" valign="top"><simpara>122,078</simpara></entry>\r
22459<entry align="left" valign="top"><simpara>89,346</simpara></entry>\r
22460<entry align="left" valign="top"><simpara>181,470</simpara></entry>\r
22461<entry align="left" valign="top"><simpara>106,088</simpara></entry>\r
22462<entry align="left" valign="top"><simpara>381,952</simpara></entry>\r
22463</row>\r
22464<row>\r
22465<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/knuth-bendix.sml"><literal>knuth-bendix.sml</literal></ulink></simpara></entry>\r
22466<entry align="left" valign="top"><simpara>193,145</simpara></entry>\r
22467<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22468<entry align="left" valign="top"><simpara>192,659</simpara></entry>\r
22469<entry align="left" valign="top"><simpara>161,080</simpara></entry>\r
22470<entry align="left" valign="top"><simpara>400,408</simpara></entry>\r
22471</row>\r
22472<row>\r
22473<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/lexgen.sml"><literal>lexgen.sml</literal></ulink></simpara></entry>\r
22474<entry align="left" valign="top"><simpara>308,296</simpara></entry>\r
22475<entry align="left" valign="top"><simpara>826,819</simpara></entry>\r
22476<entry align="left" valign="top"><simpara>213,128</simpara></entry>\r
22477<entry align="left" valign="top"><simpara>268,272</simpara></entry>\r
22478<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22479</row>\r
22480<row>\r
22481<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/life.sml"><literal>life.sml</literal></ulink></simpara></entry>\r
22482<entry align="left" valign="top"><simpara>141,862</simpara></entry>\r
22483<entry align="left" valign="top"><simpara>721,419</simpara></entry>\r
22484<entry align="left" valign="top"><simpara>186,463</simpara></entry>\r
22485<entry align="left" valign="top"><simpara>118,552</simpara></entry>\r
22486<entry align="left" valign="top"><simpara>384,024</simpara></entry>\r
22487</row>\r
22488<row>\r
22489<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/logic.sml"><literal>logic.sml</literal></ulink></simpara></entry>\r
22490<entry align="left" valign="top"><simpara>211,086</simpara></entry>\r
22491<entry align="left" valign="top"><simpara>782,667</simpara></entry>\r
22492<entry align="left" valign="top"><simpara>188,908</simpara></entry>\r
22493<entry align="left" valign="top"><simpara>198,408</simpara></entry>\r
22494<entry align="left" valign="top"><simpara>409,624</simpara></entry>\r
22495</row>\r
22496<row>\r
22497<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/mandelbrot.sml"><literal>mandelbrot.sml</literal></ulink></simpara></entry>\r
22498<entry align="left" valign="top"><simpara>122,086</simpara></entry>\r
22499<entry align="left" valign="top"><simpara>700,075</simpara></entry>\r
22500<entry align="left" valign="top"><simpara>183,037</simpara></entry>\r
22501<entry align="left" valign="top"><simpara>106,104</simpara></entry>\r
22502<entry align="left" valign="top"><simpara>386,048</simpara></entry>\r
22503</row>\r
22504<row>\r
22505<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/matrix-multiply.sml"><literal>matrix-multiply.sml</literal></ulink></simpara></entry>\r
22506<entry align="left" valign="top"><simpara>124,398</simpara></entry>\r
22507<entry align="left" valign="top"><simpara>280,006</simpara></entry>\r
22508<entry align="left" valign="top"><simpara>184,328</simpara></entry>\r
22509<entry align="left" valign="top"><simpara>110,232</simpara></entry>\r
22510<entry align="left" valign="top"><simpara>416,784</simpara></entry>\r
22511</row>\r
22512<row>\r
22513<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/md5.sml"><literal>md5.sml</literal></ulink></simpara></entry>\r
22514<entry align="left" valign="top"><simpara>150,497</simpara></entry>\r
22515<entry align="left" valign="top"><simpara>271,794</simpara></entry>\r
22516<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22517<entry align="left" valign="top"><simpara>122,624</simpara></entry>\r
22518<entry align="left" valign="top"><simpara>399,416</simpara></entry>\r
22519</row>\r
22520<row>\r
22521<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/merge.sml"><literal>merge.sml</literal></ulink></simpara></entry>\r
22522<entry align="left" valign="top"><simpara>123,846</simpara></entry>\r
22523<entry align="left" valign="top"><simpara>100,858</simpara></entry>\r
22524<entry align="left" valign="top"><simpara>181,542</simpara></entry>\r
22525<entry align="left" valign="top"><simpara>106,136</simpara></entry>\r
22526<entry align="left" valign="top"><simpara>381,960</simpara></entry>\r
22527</row>\r
22528<row>\r
22529<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/mlyacc.sml"><literal>mlyacc.sml</literal></ulink></simpara></entry>\r
22530<entry align="left" valign="top"><simpara>678,920</simpara></entry>\r
22531<entry align="left" valign="top"><simpara>1,233,587</simpara></entry>\r
22532<entry align="left" valign="top"><simpara>263,721</simpara></entry>\r
22533<entry align="left" valign="top"><simpara>576,728</simpara></entry>\r
22534<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22535</row>\r
22536<row>\r
22537<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/model-elimination.sml"><literal>model-elimination.sml</literal></ulink></simpara></entry>\r
22538<entry align="left" valign="top"><simpara>846,779</simpara></entry>\r
22539<entry align="left" valign="top"><simpara>1,432,283</simpara></entry>\r
22540<entry align="left" valign="top"><simpara>297,108</simpara></entry>\r
22541<entry align="left" valign="top"><simpara>777,664</simpara></entry>\r
22542<entry align="left" valign="top"><simpara>985,304</simpara></entry>\r
22543</row>\r
22544<row>\r
22545<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/mpuz.sml"><literal>mpuz.sml</literal></ulink></simpara></entry>\r
22546<entry align="left" valign="top"><simpara>124,126</simpara></entry>\r
22547<entry align="left" valign="top"><simpara>229,078</simpara></entry>\r
22548<entry align="left" valign="top"><simpara>184,440</simpara></entry>\r
22549<entry align="left" valign="top"><simpara>114,584</simpara></entry>\r
22550<entry align="left" valign="top"><simpara>392,232</simpara></entry>\r
22551</row>\r
22552<row>\r
22553<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/nucleic.sml"><literal>nucleic.sml</literal></ulink></simpara></entry>\r
22554<entry align="left" valign="top"><simpara>298,038</simpara></entry>\r
22555<entry align="left" valign="top"><simpara>507,186</simpara></entry>\r
22556<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22557<entry align="left" valign="top"><simpara>475,808</simpara></entry>\r
22558<entry align="left" valign="top"><simpara>456,744</simpara></entry>\r
22559</row>\r
22560<row>\r
22561<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/output1.sml"><literal>output1.sml</literal></ulink></simpara></entry>\r
22562<entry align="left" valign="top"><simpara>157,973</simpara></entry>\r
22563<entry align="left" valign="top"><simpara>699,003</simpara></entry>\r
22564<entry align="left" valign="top"><simpara>181,680</simpara></entry>\r
22565<entry align="left" valign="top"><simpara>118,800</simpara></entry>\r
22566<entry align="left" valign="top"><simpara>380,928</simpara></entry>\r
22567</row>\r
22568<row>\r
22569<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/peek.sml"><literal>peek.sml</literal></ulink></simpara></entry>\r
22570<entry align="left" valign="top"><simpara>156,401</simpara></entry>\r
22571<entry align="left" valign="top"><simpara>201,138</simpara></entry>\r
22572<entry align="left" valign="top"><simpara>183,438</simpara></entry>\r
22573<entry align="left" valign="top"><simpara>110,456</simpara></entry>\r
22574<entry align="left" valign="top"><simpara>385,072</simpara></entry>\r
22575</row>\r
22576<row>\r
22577<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/psdes-random.sml"><literal>psdes-random.sml</literal></ulink></simpara></entry>\r
22578<entry align="left" valign="top"><simpara>126,486</simpara></entry>\r
22579<entry align="left" valign="top"><simpara>106,166</simpara></entry>\r
22580<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22581<entry align="left" valign="top"><simpara>106,088</simpara></entry>\r
22582<entry align="left" valign="top"><simpara>393,256</simpara></entry>\r
22583</row>\r
22584<row>\r
22585<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/ratio-regions.sml"><literal>ratio-regions.sml</literal></ulink></simpara></entry>\r
22586<entry align="left" valign="top"><simpara>150,174</simpara></entry>\r
22587<entry align="left" valign="top"><simpara>265,694</simpara></entry>\r
22588<entry align="left" valign="top"><simpara>190,088</simpara></entry>\r
22589<entry align="left" valign="top"><simpara>184,536</simpara></entry>\r
22590<entry align="left" valign="top"><simpara>414,760</simpara></entry>\r
22591</row>\r
22592<row>\r
22593<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/ray.sml"><literal>ray.sml</literal></ulink></simpara></entry>\r
22594<entry align="left" valign="top"><simpara>260,863</simpara></entry>\r
22595<entry align="left" valign="top"><simpara>736,795</simpara></entry>\r
22596<entry align="left" valign="top"><simpara>195,064</simpara></entry>\r
22597<entry align="left" valign="top"><simpara>198,976</simpara></entry>\r
22598<entry align="left" valign="top"><simpara>512,160</simpara></entry>\r
22599</row>\r
22600<row>\r
22601<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/raytrace.sml"><literal>raytrace.sml</literal></ulink></simpara></entry>\r
22602<entry align="left" valign="top"><simpara>384,905</simpara></entry>\r
22603<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22604<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22605<entry align="left" valign="top"><simpara>446,424</simpara></entry>\r
22606<entry align="left" valign="top"><simpara>623,824</simpara></entry>\r
22607</row>\r
22608<row>\r
22609<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/simple.sml"><literal>simple.sml</literal></ulink></simpara></entry>\r
22610<entry align="left" valign="top"><simpara>365,578</simpara></entry>\r
22611<entry align="left" valign="top"><simpara>895,139</simpara></entry>\r
22612<entry align="left" valign="top"><simpara>197,765</simpara></entry>\r
22613<entry align="left" valign="top"><simpara>1,051,952</simpara></entry>\r
22614<entry align="left" valign="top"><simpara>708,696</simpara></entry>\r
22615</row>\r
22616<row>\r
22617<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/smith-normal-form.sml"><literal>smith-normal-form.sml</literal></ulink></simpara></entry>\r
22618<entry align="left" valign="top"><simpara>286,474</simpara></entry>\r
22619<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22620<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22621<entry align="left" valign="top"><simpara>262,616</simpara></entry>\r
22622<entry align="left" valign="top"><simpara>547,984</simpara></entry>\r
22623</row>\r
22624<row>\r
22625<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/string-concat.sml"><literal>string-concat.sml</literal></ulink></simpara></entry>\r
22626<entry align="left" valign="top"><simpara>119,102</simpara></entry>\r
22627<entry align="left" valign="top"><simpara>140,626</simpara></entry>\r
22628<entry align="left" valign="top"><simpara>183,249</simpara></entry>\r
22629<entry align="left" valign="top"><simpara>106,088</simpara></entry>\r
22630<entry align="left" valign="top"><simpara>390,160</simpara></entry>\r
22631</row>\r
22632<row>\r
22633<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/tailfib.sml"><literal>tailfib.sml</literal></ulink></simpara></entry>\r
22634<entry align="left" valign="top"><simpara>122,110</simpara></entry>\r
22635<entry align="left" valign="top"><simpara>87,890</simpara></entry>\r
22636<entry align="left" valign="top"><simpara>181,369</simpara></entry>\r
22637<entry align="left" valign="top"><simpara>106,072</simpara></entry>\r
22638<entry align="left" valign="top"><simpara>381,952</simpara></entry>\r
22639</row>\r
22640<row>\r
22641<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/tak.sml"><literal>tak.sml</literal></ulink></simpara></entry>\r
22642<entry align="left" valign="top"><simpara>122,246</simpara></entry>\r
22643<entry align="left" valign="top"><simpara>87,402</simpara></entry>\r
22644<entry align="left" valign="top"><simpara>181,349</simpara></entry>\r
22645<entry align="left" valign="top"><simpara>106,088</simpara></entry>\r
22646<entry align="left" valign="top"><simpara>376,832</simpara></entry>\r
22647</row>\r
22648<row>\r
22649<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/tensor.sml"><literal>tensor.sml</literal></ulink></simpara></entry>\r
22650<entry align="left" valign="top"><simpara>186,545</simpara></entry>\r
22651<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22652<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22653<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22654<entry align="left" valign="top"><simpara>421,984</simpara></entry>\r
22655</row>\r
22656<row>\r
22657<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/tsp.sml"><literal>tsp.sml</literal></ulink></simpara></entry>\r
22658<entry align="left" valign="top"><simpara>163,033</simpara></entry>\r
22659<entry align="left" valign="top"><simpara>722,571</simpara></entry>\r
22660<entry align="left" valign="top"><simpara>188,634</simpara></entry>\r
22661<entry align="left" valign="top"><simpara>126,984</simpara></entry>\r
22662<entry align="left" valign="top"><simpara>393,264</simpara></entry>\r
22663</row>\r
22664<row>\r
22665<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/tyan.sml"><literal>tyan.sml</literal></ulink></simpara></entry>\r
22666<entry align="left" valign="top"><simpara>235,449</simpara></entry>\r
22667<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22668<entry align="left" valign="top"><simpara>195,401</simpara></entry>\r
22669<entry align="left" valign="top"><simpara>184,816</simpara></entry>\r
22670<entry align="left" valign="top"><simpara>478,296</simpara></entry>\r
22671</row>\r
22672<row>\r
22673<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/vector32-concat.sml"><literal>vector32-concat.sml</literal></ulink></simpara></entry>\r
22674<entry align="left" valign="top"><simpara>123,790</simpara></entry>\r
22675<entry align="left" valign="top"><simpara>104,398</simpara></entry>\r
22676<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22677<entry align="left" valign="top"><simpara>106,200</simpara></entry>\r
22678<entry align="left" valign="top"><simpara>394,256</simpara></entry>\r
22679</row>\r
22680<row>\r
22681<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/vector64-concat.sml"><literal>vector64-concat.sml</literal></ulink></simpara></entry>\r
22682<entry align="left" valign="top"><simpara>123,846</simpara></entry>\r
22683<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22684<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22685<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22686<entry align="left" valign="top"><simpara>405,552</simpara></entry>\r
22687</row>\r
22688<row>\r
22689<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/vector-rev.sml"><literal>vector-rev.sml</literal></ulink></simpara></entry>\r
22690<entry align="left" valign="top"><simpara>122,982</simpara></entry>\r
22691<entry align="left" valign="top"><simpara>104,614</simpara></entry>\r
22692<entry align="left" valign="top"><simpara>181,534</simpara></entry>\r
22693<entry align="left" valign="top"><simpara>106,072</simpara></entry>\r
22694<entry align="left" valign="top"><simpara>394,256</simpara></entry>\r
22695</row>\r
22696<row>\r
22697<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/vliw.sml"><literal>vliw.sml</literal></ulink></simpara></entry>\r
22698<entry align="left" valign="top"><simpara>538,074</simpara></entry>\r
22699<entry align="left" valign="top"><simpara>1,182,851</simpara></entry>\r
22700<entry align="left" valign="top"><simpara>249,884</simpara></entry>\r
22701<entry align="left" valign="top"><simpara>580,792</simpara></entry>\r
22702<entry align="left" valign="top"><simpara>749,752</simpara></entry>\r
22703</row>\r
22704<row>\r
22705<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/wc-input1.sml"><literal>wc-input1.sml</literal></ulink></simpara></entry>\r
22706<entry align="left" valign="top"><simpara>186,152</simpara></entry>\r
22707<entry align="left" valign="top"><simpara>699,459</simpara></entry>\r
22708<entry align="left" valign="top"><simpara>191,347</simpara></entry>\r
22709<entry align="left" valign="top"><simpara>127,200</simpara></entry>\r
22710<entry align="left" valign="top"><simpara>386,048</simpara></entry>\r
22711</row>\r
22712<row>\r
22713<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/wc-scanStream.sml"><literal>wc-scanStream.sml</literal></ulink></simpara></entry>\r
22714<entry align="left" valign="top"><simpara>196,232</simpara></entry>\r
22715<entry align="left" valign="top"><simpara>700,131</simpara></entry>\r
22716<entry align="left" valign="top"><simpara>191,539</simpara></entry>\r
22717<entry align="left" valign="top"><simpara>127,232</simpara></entry>\r
22718<entry align="left" valign="top"><simpara>387,072</simpara></entry>\r
22719</row>\r
22720<row>\r
22721<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/zebra.sml"><literal>zebra.sml</literal></ulink></simpara></entry>\r
22722<entry align="left" valign="top"><simpara>230,433</simpara></entry>\r
22723<entry align="left" valign="top"><simpara>128,354</simpara></entry>\r
22724<entry align="left" valign="top"><simpara>186,322</simpara></entry>\r
22725<entry align="left" valign="top"><simpara>127,048</simpara></entry>\r
22726<entry align="left" valign="top"><simpara>390,184</simpara></entry>\r
22727</row>\r
22728<row>\r
22729<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/zern.sml"><literal>zern.sml</literal></ulink></simpara></entry>\r
22730<entry align="left" valign="top"><simpara>156,902</simpara></entry>\r
22731<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22732<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22733<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22734<entry align="left" valign="top"><simpara>453,768</simpara></entry>\r
22735</row>\r
22736</tbody>\r
22737</tgroup>\r
22738</informaltable>\r
22739</section>\r
22740<section id="_anchor_id_performance_compiletime_xreflabel_performance_compiletime_compile_time">\r
22741<title><anchor id="Performance_CompileTime" xreflabel="[Performance_CompileTime]"/>Compile time</title>\r
22742<simpara>The following table gives the compile time of each benchmark in\r
22743seconds. A * in an entry means that the compiler failed to compile\r
22744the benchmark.</simpara>\r
22745<informaltable\r
22746frame="all"\r
22747rowsep="1" colsep="1"\r
22748>\r
22749<tgroup cols="6">\r
22750<colspec colname="col_1" colwidth="28*"/>\r
22751<colspec colname="col_2" colwidth="14*"/>\r
22752<colspec colname="col_3" colwidth="14*"/>\r
22753<colspec colname="col_4" colwidth="14*"/>\r
22754<colspec colname="col_5" colwidth="14*"/>\r
22755<colspec colname="col_6" colwidth="14*"/>\r
22756<thead>\r
22757<row>\r
22758<entry align="left" valign="top">benchmark</entry>\r
22759<entry align="left" valign="top">MLton</entry>\r
22760<entry align="left" valign="top">ML-Kit</entry>\r
22761<entry align="left" valign="top">MosML</entry>\r
22762<entry align="left" valign="top">Poly/ML</entry>\r
22763<entry align="left" valign="top">SML/NJ</entry>\r
22764</row>\r
22765</thead>\r
22766<tbody>\r
22767<row>\r
22768<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/barnes-hut.sml"><literal>barnes-hut.sml</literal></ulink></simpara></entry>\r
22769<entry align="left" valign="top"><simpara>2.70</simpara></entry>\r
22770<entry align="left" valign="top"><simpara>0.89</simpara></entry>\r
22771<entry align="left" valign="top"><simpara>0.15</simpara></entry>\r
22772<entry align="left" valign="top"><simpara>0.29</simpara></entry>\r
22773<entry align="left" valign="top"><simpara>0.20</simpara></entry>\r
22774</row>\r
22775<row>\r
22776<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/boyer.sml"><literal>boyer.sml</literal></ulink></simpara></entry>\r
22777<entry align="left" valign="top"><simpara>2.87</simpara></entry>\r
22778<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22779<entry align="left" valign="top"><simpara>0.14</simpara></entry>\r
22780<entry align="left" valign="top"><simpara>0.20</simpara></entry>\r
22781<entry align="left" valign="top"><simpara>0.41</simpara></entry>\r
22782</row>\r
22783<row>\r
22784<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/checksum.sml"><literal>checksum.sml</literal></ulink></simpara></entry>\r
22785<entry align="left" valign="top"><simpara>2.21</simpara></entry>\r
22786<entry align="left" valign="top"><simpara>0.24</simpara></entry>\r
22787<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22788<entry align="left" valign="top"><simpara>0.07</simpara></entry>\r
22789<entry align="left" valign="top"><simpara>0.05</simpara></entry>\r
22790</row>\r
22791<row>\r
22792<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/count-graphs.sml"><literal>count-graphs.sml</literal></ulink></simpara></entry>\r
22793<entry align="left" valign="top"><simpara>2.28</simpara></entry>\r
22794<entry align="left" valign="top"><simpara>0.34</simpara></entry>\r
22795<entry align="left" valign="top"><simpara>0.04</simpara></entry>\r
22796<entry align="left" valign="top"><simpara>0.11</simpara></entry>\r
22797<entry align="left" valign="top"><simpara>0.21</simpara></entry>\r
22798</row>\r
22799<row>\r
22800<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/DLXSimulator.sml"><literal>DLXSimulator.sml</literal></ulink></simpara></entry>\r
22801<entry align="left" valign="top"><simpara>2.93</simpara></entry>\r
22802<entry align="left" valign="top"><simpara>1.01</simpara></entry>\r
22803<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22804<entry align="left" valign="top"><simpara>0.27</simpara></entry>\r
22805<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22806</row>\r
22807<row>\r
22808<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/even-odd.sml"><literal>even-odd.sml</literal></ulink></simpara></entry>\r
22809<entry align="left" valign="top"><simpara>2.23</simpara></entry>\r
22810<entry align="left" valign="top"><simpara>0.20</simpara></entry>\r
22811<entry align="left" valign="top"><simpara>0.01</simpara></entry>\r
22812<entry align="left" valign="top"><simpara>0.07</simpara></entry>\r
22813<entry align="left" valign="top"><simpara>0.04</simpara></entry>\r
22814</row>\r
22815<row>\r
22816<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/fft.sml"><literal>fft.sml</literal></ulink></simpara></entry>\r
22817<entry align="left" valign="top"><simpara>2.35</simpara></entry>\r
22818<entry align="left" valign="top"><simpara>0.28</simpara></entry>\r
22819<entry align="left" valign="top"><simpara>0.03</simpara></entry>\r
22820<entry align="left" valign="top"><simpara>0.09</simpara></entry>\r
22821<entry align="left" valign="top"><simpara>0.10</simpara></entry>\r
22822</row>\r
22823<row>\r
22824<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/fib.sml"><literal>fib.sml</literal></ulink></simpara></entry>\r
22825<entry align="left" valign="top"><simpara>2.16</simpara></entry>\r
22826<entry align="left" valign="top"><simpara>0.19</simpara></entry>\r
22827<entry align="left" valign="top"><simpara>0.01</simpara></entry>\r
22828<entry align="left" valign="top"><simpara>0.07</simpara></entry>\r
22829<entry align="left" valign="top"><simpara>0.04</simpara></entry>\r
22830</row>\r
22831<row>\r
22832<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/flat-array.sml"><literal>flat-array.sml</literal></ulink></simpara></entry>\r
22833<entry align="left" valign="top"><simpara>2.16</simpara></entry>\r
22834<entry align="left" valign="top"><simpara>0.20</simpara></entry>\r
22835<entry align="left" valign="top"><simpara>0.01</simpara></entry>\r
22836<entry align="left" valign="top"><simpara>0.07</simpara></entry>\r
22837<entry align="left" valign="top"><simpara>0.04</simpara></entry>\r
22838</row>\r
22839<row>\r
22840<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/hamlet.sml"><literal>hamlet.sml</literal></ulink></simpara></entry>\r
22841<entry align="left" valign="top"><simpara>12.28</simpara></entry>\r
22842<entry align="left" valign="top"><simpara>19.25</simpara></entry>\r
22843<entry align="left" valign="top"><simpara>23.75</simpara></entry>\r
22844<entry align="left" valign="top"><simpara>6.44</simpara></entry>\r
22845<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22846</row>\r
22847<row>\r
22848<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/imp-for.sml"><literal>imp-for.sml</literal></ulink></simpara></entry>\r
22849<entry align="left" valign="top"><simpara>2.14</simpara></entry>\r
22850<entry align="left" valign="top"><simpara>0.20</simpara></entry>\r
22851<entry align="left" valign="top"><simpara>0.01</simpara></entry>\r
22852<entry align="left" valign="top"><simpara>0.08</simpara></entry>\r
22853<entry align="left" valign="top"><simpara>0.04</simpara></entry>\r
22854</row>\r
22855<row>\r
22856<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/knuth-bendix.sml"><literal>knuth-bendix.sml</literal></ulink></simpara></entry>\r
22857<entry align="left" valign="top"><simpara>2.48</simpara></entry>\r
22858<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22859<entry align="left" valign="top"><simpara>0.08</simpara></entry>\r
22860<entry align="left" valign="top"><simpara>0.14</simpara></entry>\r
22861<entry align="left" valign="top"><simpara>0.23</simpara></entry>\r
22862</row>\r
22863<row>\r
22864<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/lexgen.sml"><literal>lexgen.sml</literal></ulink></simpara></entry>\r
22865<entry align="left" valign="top"><simpara>3.31</simpara></entry>\r
22866<entry align="left" valign="top"><simpara>0.75</simpara></entry>\r
22867<entry align="left" valign="top"><simpara>0.15</simpara></entry>\r
22868<entry align="left" valign="top"><simpara>0.22</simpara></entry>\r
22869<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22870</row>\r
22871<row>\r
22872<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/life.sml"><literal>life.sml</literal></ulink></simpara></entry>\r
22873<entry align="left" valign="top"><simpara>2.25</simpara></entry>\r
22874<entry align="left" valign="top"><simpara>0.32</simpara></entry>\r
22875<entry align="left" valign="top"><simpara>0.03</simpara></entry>\r
22876<entry align="left" valign="top"><simpara>0.09</simpara></entry>\r
22877<entry align="left" valign="top"><simpara>0.10</simpara></entry>\r
22878</row>\r
22879<row>\r
22880<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/logic.sml"><literal>logic.sml</literal></ulink></simpara></entry>\r
22881<entry align="left" valign="top"><simpara>2.72</simpara></entry>\r
22882<entry align="left" valign="top"><simpara>0.57</simpara></entry>\r
22883<entry align="left" valign="top"><simpara>0.07</simpara></entry>\r
22884<entry align="left" valign="top"><simpara>0.17</simpara></entry>\r
22885<entry align="left" valign="top"><simpara>0.21</simpara></entry>\r
22886</row>\r
22887<row>\r
22888<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/mandelbrot.sml"><literal>mandelbrot.sml</literal></ulink></simpara></entry>\r
22889<entry align="left" valign="top"><simpara>2.14</simpara></entry>\r
22890<entry align="left" valign="top"><simpara>0.24</simpara></entry>\r
22891<entry align="left" valign="top"><simpara>0.01</simpara></entry>\r
22892<entry align="left" valign="top"><simpara>0.07</simpara></entry>\r
22893<entry align="left" valign="top"><simpara>0.04</simpara></entry>\r
22894</row>\r
22895<row>\r
22896<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/matrix-multiply.sml"><literal>matrix-multiply.sml</literal></ulink></simpara></entry>\r
22897<entry align="left" valign="top"><simpara>2.14</simpara></entry>\r
22898<entry align="left" valign="top"><simpara>0.24</simpara></entry>\r
22899<entry align="left" valign="top"><simpara>0.01</simpara></entry>\r
22900<entry align="left" valign="top"><simpara>0.08</simpara></entry>\r
22901<entry align="left" valign="top"><simpara>0.05</simpara></entry>\r
22902</row>\r
22903<row>\r
22904<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/md5.sml"><literal>md5.sml</literal></ulink></simpara></entry>\r
22905<entry align="left" valign="top"><simpara>2.31</simpara></entry>\r
22906<entry align="left" valign="top"><simpara>0.39</simpara></entry>\r
22907<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22908<entry align="left" valign="top"><simpara>0.12</simpara></entry>\r
22909<entry align="left" valign="top"><simpara>0.27</simpara></entry>\r
22910</row>\r
22911<row>\r
22912<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/merge.sml"><literal>merge.sml</literal></ulink></simpara></entry>\r
22913<entry align="left" valign="top"><simpara>2.15</simpara></entry>\r
22914<entry align="left" valign="top"><simpara>0.21</simpara></entry>\r
22915<entry align="left" valign="top"><simpara>0.01</simpara></entry>\r
22916<entry align="left" valign="top"><simpara>0.07</simpara></entry>\r
22917<entry align="left" valign="top"><simpara>0.04</simpara></entry>\r
22918</row>\r
22919<row>\r
22920<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/mlyacc.sml"><literal>mlyacc.sml</literal></ulink></simpara></entry>\r
22921<entry align="left" valign="top"><simpara>7.07</simpara></entry>\r
22922<entry align="left" valign="top"><simpara>4.53</simpara></entry>\r
22923<entry align="left" valign="top"><simpara>2.05</simpara></entry>\r
22924<entry align="left" valign="top"><simpara>0.80</simpara></entry>\r
22925<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22926</row>\r
22927<row>\r
22928<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/model-elimination.sml"><literal>model-elimination.sml</literal></ulink></simpara></entry>\r
22929<entry align="left" valign="top"><simpara>6.78</simpara></entry>\r
22930<entry align="left" valign="top"><simpara>4.76</simpara></entry>\r
22931<entry align="left" valign="top"><simpara>1.20</simpara></entry>\r
22932<entry align="left" valign="top"><simpara>1.65</simpara></entry>\r
22933<entry align="left" valign="top"><simpara>4.78</simpara></entry>\r
22934</row>\r
22935<row>\r
22936<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/mpuz.sml"><literal>mpuz.sml</literal></ulink></simpara></entry>\r
22937<entry align="left" valign="top"><simpara>2.14</simpara></entry>\r
22938<entry align="left" valign="top"><simpara>0.28</simpara></entry>\r
22939<entry align="left" valign="top"><simpara>0.02</simpara></entry>\r
22940<entry align="left" valign="top"><simpara>0.08</simpara></entry>\r
22941<entry align="left" valign="top"><simpara>0.07</simpara></entry>\r
22942</row>\r
22943<row>\r
22944<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/nucleic.sml"><literal>nucleic.sml</literal></ulink></simpara></entry>\r
22945<entry align="left" valign="top"><simpara>3.96</simpara></entry>\r
22946<entry align="left" valign="top"><simpara>2.12</simpara></entry>\r
22947<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22948<entry align="left" valign="top"><simpara>0.37</simpara></entry>\r
22949<entry align="left" valign="top"><simpara>0.49</simpara></entry>\r
22950</row>\r
22951<row>\r
22952<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/output1.sml"><literal>output1.sml</literal></ulink></simpara></entry>\r
22953<entry align="left" valign="top"><simpara>2.30</simpara></entry>\r
22954<entry align="left" valign="top"><simpara>0.22</simpara></entry>\r
22955<entry align="left" valign="top"><simpara>0.01</simpara></entry>\r
22956<entry align="left" valign="top"><simpara>0.07</simpara></entry>\r
22957<entry align="left" valign="top"><simpara>0.04</simpara></entry>\r
22958</row>\r
22959<row>\r
22960<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/peek.sml"><literal>peek.sml</literal></ulink></simpara></entry>\r
22961<entry align="left" valign="top"><simpara>2.26</simpara></entry>\r
22962<entry align="left" valign="top"><simpara>0.20</simpara></entry>\r
22963<entry align="left" valign="top"><simpara>0.01</simpara></entry>\r
22964<entry align="left" valign="top"><simpara>0.07</simpara></entry>\r
22965<entry align="left" valign="top"><simpara>0.04</simpara></entry>\r
22966</row>\r
22967<row>\r
22968<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/psdes-random.sml"><literal>psdes-random.sml</literal></ulink></simpara></entry>\r
22969<entry align="left" valign="top"><simpara>2.12</simpara></entry>\r
22970<entry align="left" valign="top"><simpara>0.22</simpara></entry>\r
22971<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22972<entry align="left" valign="top"><simpara>9.83</simpara></entry>\r
22973<entry align="left" valign="top"><simpara>12.55</simpara></entry>\r
22974</row>\r
22975<row>\r
22976<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/ratio-regions.sml"><literal>ratio-regions.sml</literal></ulink></simpara></entry>\r
22977<entry align="left" valign="top"><simpara>2.59</simpara></entry>\r
22978<entry align="left" valign="top"><simpara>0.47</simpara></entry>\r
22979<entry align="left" valign="top"><simpara>0.07</simpara></entry>\r
22980<entry align="left" valign="top"><simpara>0.16</simpara></entry>\r
22981<entry align="left" valign="top"><simpara>0.24</simpara></entry>\r
22982</row>\r
22983<row>\r
22984<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/ray.sml"><literal>ray.sml</literal></ulink></simpara></entry>\r
22985<entry align="left" valign="top"><simpara>2.95</simpara></entry>\r
22986<entry align="left" valign="top"><simpara>0.46</simpara></entry>\r
22987<entry align="left" valign="top"><simpara>0.05</simpara></entry>\r
22988<entry align="left" valign="top"><simpara>0.17</simpara></entry>\r
22989<entry align="left" valign="top"><simpara>0.14</simpara></entry>\r
22990</row>\r
22991<row>\r
22992<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/raytrace.sml"><literal>raytrace.sml</literal></ulink></simpara></entry>\r
22993<entry align="left" valign="top"><simpara>3.93</simpara></entry>\r
22994<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22995<entry align="left" valign="top"><simpara>*</simpara></entry>\r
22996<entry align="left" valign="top"><simpara>0.45</simpara></entry>\r
22997<entry align="left" valign="top"><simpara>0.74</simpara></entry>\r
22998</row>\r
22999<row>\r
23000<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/simple.sml"><literal>simple.sml</literal></ulink></simpara></entry>\r
23001<entry align="left" valign="top"><simpara>3.42</simpara></entry>\r
23002<entry align="left" valign="top"><simpara>1.23</simpara></entry>\r
23003<entry align="left" valign="top"><simpara>0.30</simpara></entry>\r
23004<entry align="left" valign="top"><simpara>0.32</simpara></entry>\r
23005<entry align="left" valign="top"><simpara>0.53</simpara></entry>\r
23006</row>\r
23007<row>\r
23008<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/smith-normal-form.sml"><literal>smith-normal-form.sml</literal></ulink></simpara></entry>\r
23009<entry align="left" valign="top"><simpara>3.23</simpara></entry>\r
23010<entry align="left" valign="top"><simpara>*</simpara></entry>\r
23011<entry align="left" valign="top"><simpara>*</simpara></entry>\r
23012<entry align="left" valign="top"><simpara>0.15</simpara></entry>\r
23013<entry align="left" valign="top"><simpara>0.32</simpara></entry>\r
23014</row>\r
23015<row>\r
23016<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/string-concat.sml"><literal>string-concat.sml</literal></ulink></simpara></entry>\r
23017<entry align="left" valign="top"><simpara>2.25</simpara></entry>\r
23018<entry align="left" valign="top"><simpara>0.28</simpara></entry>\r
23019<entry align="left" valign="top"><simpara>0.01</simpara></entry>\r
23020<entry align="left" valign="top"><simpara>0.08</simpara></entry>\r
23021<entry align="left" valign="top"><simpara>0.05</simpara></entry>\r
23022</row>\r
23023<row>\r
23024<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/tailfib.sml"><literal>tailfib.sml</literal></ulink></simpara></entry>\r
23025<entry align="left" valign="top"><simpara>2.24</simpara></entry>\r
23026<entry align="left" valign="top"><simpara>0.21</simpara></entry>\r
23027<entry align="left" valign="top"><simpara>0.01</simpara></entry>\r
23028<entry align="left" valign="top"><simpara>0.08</simpara></entry>\r
23029<entry align="left" valign="top"><simpara>0.05</simpara></entry>\r
23030</row>\r
23031<row>\r
23032<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/tak.sml"><literal>tak.sml</literal></ulink></simpara></entry>\r
23033<entry align="left" valign="top"><simpara>2.23</simpara></entry>\r
23034<entry align="left" valign="top"><simpara>0.20</simpara></entry>\r
23035<entry align="left" valign="top"><simpara>0.01</simpara></entry>\r
23036<entry align="left" valign="top"><simpara>0.08</simpara></entry>\r
23037<entry align="left" valign="top"><simpara>0.05</simpara></entry>\r
23038</row>\r
23039<row>\r
23040<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/tensor.sml"><literal>tensor.sml</literal></ulink></simpara></entry>\r
23041<entry align="left" valign="top"><simpara>2.73</simpara></entry>\r
23042<entry align="left" valign="top"><simpara>*</simpara></entry>\r
23043<entry align="left" valign="top"><simpara>*</simpara></entry>\r
23044<entry align="left" valign="top"><simpara>*</simpara></entry>\r
23045<entry align="left" valign="top"><simpara>0.44</simpara></entry>\r
23046</row>\r
23047<row>\r
23048<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/tsp.sml"><literal>tsp.sml</literal></ulink></simpara></entry>\r
23049<entry align="left" valign="top"><simpara>2.42</simpara></entry>\r
23050<entry align="left" valign="top"><simpara>0.38</simpara></entry>\r
23051<entry align="left" valign="top"><simpara>0.05</simpara></entry>\r
23052<entry align="left" valign="top"><simpara>0.11</simpara></entry>\r
23053<entry align="left" valign="top"><simpara>0.11</simpara></entry>\r
23054</row>\r
23055<row>\r
23056<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/tyan.sml"><literal>tyan.sml</literal></ulink></simpara></entry>\r
23057<entry align="left" valign="top"><simpara>2.93</simpara></entry>\r
23058<entry align="left" valign="top"><simpara>*</simpara></entry>\r
23059<entry align="left" valign="top"><simpara>0.10</simpara></entry>\r
23060<entry align="left" valign="top"><simpara>0.27</simpara></entry>\r
23061<entry align="left" valign="top"><simpara>0.31</simpara></entry>\r
23062</row>\r
23063<row>\r
23064<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/vector32-concat.sml"><literal>vector32-concat.sml</literal></ulink></simpara></entry>\r
23065<entry align="left" valign="top"><simpara>2.23</simpara></entry>\r
23066<entry align="left" valign="top"><simpara>0.22</simpara></entry>\r
23067<entry align="left" valign="top"><simpara>*</simpara></entry>\r
23068<entry align="left" valign="top"><simpara>0.07</simpara></entry>\r
23069<entry align="left" valign="top"><simpara>0.04</simpara></entry>\r
23070</row>\r
23071<row>\r
23072<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/vector64-concat.sml"><literal>vector64-concat.sml</literal></ulink></simpara></entry>\r
23073<entry align="left" valign="top"><simpara>2.18</simpara></entry>\r
23074<entry align="left" valign="top"><simpara>*</simpara></entry>\r
23075<entry align="left" valign="top"><simpara>*</simpara></entry>\r
23076<entry align="left" valign="top"><simpara>*</simpara></entry>\r
23077<entry align="left" valign="top"><simpara>0.04</simpara></entry>\r
23078</row>\r
23079<row>\r
23080<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/vector-rev.sml"><literal>vector-rev.sml</literal></ulink></simpara></entry>\r
23081<entry align="left" valign="top"><simpara>2.23</simpara></entry>\r
23082<entry align="left" valign="top"><simpara>0.22</simpara></entry>\r
23083<entry align="left" valign="top"><simpara>0.01</simpara></entry>\r
23084<entry align="left" valign="top"><simpara>0.08</simpara></entry>\r
23085<entry align="left" valign="top"><simpara>0.05</simpara></entry>\r
23086</row>\r
23087<row>\r
23088<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/vliw.sml"><literal>vliw.sml</literal></ulink></simpara></entry>\r
23089<entry align="left" valign="top"><simpara>5.25</simpara></entry>\r
23090<entry align="left" valign="top"><simpara>2.93</simpara></entry>\r
23091<entry align="left" valign="top"><simpara>0.63</simpara></entry>\r
23092<entry align="left" valign="top"><simpara>0.94</simpara></entry>\r
23093<entry align="left" valign="top"><simpara>1.85</simpara></entry>\r
23094</row>\r
23095<row>\r
23096<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/wc-input1.sml"><literal>wc-input1.sml</literal></ulink></simpara></entry>\r
23097<entry align="left" valign="top"><simpara>2.46</simpara></entry>\r
23098<entry align="left" valign="top"><simpara>0.24</simpara></entry>\r
23099<entry align="left" valign="top"><simpara>0.01</simpara></entry>\r
23100<entry align="left" valign="top"><simpara>0.08</simpara></entry>\r
23101<entry align="left" valign="top"><simpara>0.05</simpara></entry>\r
23102</row>\r
23103<row>\r
23104<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/wc-scanStream.sml"><literal>wc-scanStream.sml</literal></ulink></simpara></entry>\r
23105<entry align="left" valign="top"><simpara>2.61</simpara></entry>\r
23106<entry align="left" valign="top"><simpara>0.25</simpara></entry>\r
23107<entry align="left" valign="top"><simpara>0.01</simpara></entry>\r
23108<entry align="left" valign="top"><simpara>0.08</simpara></entry>\r
23109<entry align="left" valign="top"><simpara>0.05</simpara></entry>\r
23110</row>\r
23111<row>\r
23112<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/zebra.sml"><literal>zebra.sml</literal></ulink></simpara></entry>\r
23113<entry align="left" valign="top"><simpara>2.99</simpara></entry>\r
23114<entry align="left" valign="top"><simpara>0.35</simpara></entry>\r
23115<entry align="left" valign="top"><simpara>0.03</simpara></entry>\r
23116<entry align="left" valign="top"><simpara>0.09</simpara></entry>\r
23117<entry align="left" valign="top"><simpara>0.11</simpara></entry>\r
23118</row>\r
23119<row>\r
23120<entry align="left" valign="top"><simpara><ulink url="https://raw.github.com/MLton/mlton/master/benchmark/tests/zern.sml"><literal>zern.sml</literal></ulink></simpara></entry>\r
23121<entry align="left" valign="top"><simpara>2.31</simpara></entry>\r
23122<entry align="left" valign="top"><simpara>*</simpara></entry>\r
23123<entry align="left" valign="top"><simpara>*</simpara></entry>\r
23124<entry align="left" valign="top"><simpara>*</simpara></entry>\r
23125<entry align="left" valign="top"><simpara>0.11</simpara></entry>\r
23126</row>\r
23127</tbody>\r
23128</tgroup>\r
23129</informaltable>\r
23130<simpara><?asciidoc-pagebreak?></simpara>\r
23131</section>\r
23132</section>\r
23133<section id="PhantomType">\r
23134<title>PhantomType</title>\r
23135<simpara>A phantom type is a type that has no run-time representation, but is\r
23136used to force the type checker to ensure invariants at compile time.\r
23137This is done by augmenting a type with additional arguments (phantom\r
23138type variables) and expressing constraints by choosing phantom types\r
23139to stand for the phantom types in the types of values.</simpara>\r
23140<section id="_also_see_20">\r
23141<title>Also see</title>\r
23142<itemizedlist>\r
23143<listitem>\r
23144<simpara>\r
23145<link linkend="References_Blume01">Blume01</link>\r
23146</simpara>\r
23147<itemizedlist>\r
23148<listitem>\r
23149<simpara>\r
23150dimensions\r
23151</simpara>\r
23152</listitem>\r
23153<listitem>\r
23154<simpara>\r
23155C type system\r
23156</simpara>\r
23157</listitem>\r
23158</itemizedlist>\r
23159</listitem>\r
23160<listitem>\r
23161<simpara>\r
23162<link linkend="References_FluetPucella06">FluetPucella06</link>\r
23163</simpara>\r
23164<itemizedlist>\r
23165<listitem>\r
23166<simpara>\r
23167subtyping\r
23168</simpara>\r
23169</listitem>\r
23170</itemizedlist>\r
23171</listitem>\r
23172<listitem>\r
23173<simpara>\r
23174socket module in <link linkend="BasisLibrary">Basis Library</link>\r
23175</simpara>\r
23176</listitem>\r
23177</itemizedlist>\r
23178<simpara><?asciidoc-pagebreak?></simpara>\r
23179</section>\r
23180</section>\r
23181<section id="PlatformSpecificNotes">\r
23182<title>PlatformSpecificNotes</title>\r
23183<simpara>Here are notes about using MLton on the following platforms.</simpara>\r
23184<section id="_operating_systems">\r
23185<title>Operating Systems</title>\r
23186<itemizedlist>\r
23187<listitem>\r
23188<simpara>\r
23189<link linkend="RunningOnAIX">AIX</link>\r
23190</simpara>\r
23191</listitem>\r
23192<listitem>\r
23193<simpara>\r
23194<link linkend="RunningOnCygwin">Cygwin</link>\r
23195</simpara>\r
23196</listitem>\r
23197<listitem>\r
23198<simpara>\r
23199<link linkend="RunningOnDarwin">Darwin</link>\r
23200</simpara>\r
23201</listitem>\r
23202<listitem>\r
23203<simpara>\r
23204<link linkend="RunningOnFreeBSD">FreeBSD</link>\r
23205</simpara>\r
23206</listitem>\r
23207<listitem>\r
23208<simpara>\r
23209<link linkend="RunningOnHPUX">HPUX</link>\r
23210</simpara>\r
23211</listitem>\r
23212<listitem>\r
23213<simpara>\r
23214<link linkend="RunningOnLinux">Linux</link>\r
23215</simpara>\r
23216</listitem>\r
23217<listitem>\r
23218<simpara>\r
23219<link linkend="RunningOnMinGW">MinGW</link>\r
23220</simpara>\r
23221</listitem>\r
23222<listitem>\r
23223<simpara>\r
23224<link linkend="RunningOnNetBSD">NetBSD</link>\r
23225</simpara>\r
23226</listitem>\r
23227<listitem>\r
23228<simpara>\r
23229<link linkend="RunningOnOpenBSD">OpenBSD</link>\r
23230</simpara>\r
23231</listitem>\r
23232<listitem>\r
23233<simpara>\r
23234<link linkend="RunningOnSolaris">Solaris</link>\r
23235</simpara>\r
23236</listitem>\r
23237</itemizedlist>\r
23238</section>\r
23239<section id="_architectures">\r
23240<title>Architectures</title>\r
23241<itemizedlist>\r
23242<listitem>\r
23243<simpara>\r
23244<link linkend="RunningOnAMD64">AMD64</link>\r
23245</simpara>\r
23246</listitem>\r
23247<listitem>\r
23248<simpara>\r
23249<link linkend="RunningOnHPPA">HPPA</link>\r
23250</simpara>\r
23251</listitem>\r
23252<listitem>\r
23253<simpara>\r
23254<link linkend="RunningOnPowerPC">PowerPC</link>\r
23255</simpara>\r
23256</listitem>\r
23257<listitem>\r
23258<simpara>\r
23259<link linkend="RunningOnPowerPC64">PowerPC64</link>\r
23260</simpara>\r
23261</listitem>\r
23262<listitem>\r
23263<simpara>\r
23264<link linkend="RunningOnSparc">Sparc</link>\r
23265</simpara>\r
23266</listitem>\r
23267<listitem>\r
23268<simpara>\r
23269<link linkend="RunningOnX86">X86</link>\r
23270</simpara>\r
23271</listitem>\r
23272</itemizedlist>\r
23273</section>\r
23274<section id="_also_see_21">\r
23275<title>Also see</title>\r
23276<itemizedlist>\r
23277<listitem>\r
23278<simpara>\r
23279<link linkend="PortingMLton">PortingMLton</link>\r
23280</simpara>\r
23281</listitem>\r
23282</itemizedlist>\r
23283<simpara><?asciidoc-pagebreak?></simpara>\r
23284</section>\r
23285</section>\r
23286<section id="PolyEqual">\r
23287<title>PolyEqual</title>\r
23288<simpara><link linkend="PolyEqual">PolyEqual</link> is an optimization pass for the <link linkend="SSA">SSA</link>\r
23289<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="SSASimplify">SSASimplify</link>.</simpara>\r
23290<section id="_description_42">\r
23291<title>Description</title>\r
23292<simpara>This pass implements polymorphic equality.</simpara>\r
23293</section>\r
23294<section id="_implementation_45">\r
23295<title>Implementation</title>\r
23296<itemizedlist>\r
23297<listitem>\r
23298<simpara>\r
23299<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/poly-equal.fun"><literal>poly-equal.fun</literal></ulink>\r
23300</simpara>\r
23301</listitem>\r
23302</itemizedlist>\r
23303</section>\r
23304<section id="_details_and_notes_45">\r
23305<title>Details and Notes</title>\r
23306<simpara>For each datatype, tycon, and vector type, it builds and equality\r
23307function and translates calls to <literal>MLton_equal</literal> into calls to that\r
23308function.</simpara>\r
23309<simpara>Also generates calls to <literal>Word_equal</literal>.</simpara>\r
23310<simpara>For tuples, it does the equality test inline; i.e., it does not create\r
23311a separate equality function for each tuple type.</simpara>\r
23312<simpara>All equality functions are created only if necessary, i.e., if\r
23313equality is actually used at a type.</simpara>\r
23314<simpara>Optimizations:</simpara>\r
23315<itemizedlist>\r
23316<listitem>\r
23317<simpara>\r
23318for datatypes that are enumerations, do not build a case dispatch,\r
23319just use <literal>MLton_eq</literal>, as the backend will represent these as ints\r
23320</simpara>\r
23321</listitem>\r
23322<listitem>\r
23323<simpara>\r
23324deep equality always does an <literal>MLton_eq</literal> test first\r
23325</simpara>\r
23326</listitem>\r
23327<listitem>\r
23328<simpara>\r
23329If one argument to <literal>=</literal> is a constant and the type will get\r
23330translated to an <literal>IntOrPointer</literal>, then just use <literal>eq</literal> instead of the\r
23331full equality. This is important for implementing code like the\r
23332following efficiently:\r
23333</simpara>\r
23334<screen>if x = 0 ... (* where x is of type IntInf.int *)</screen>\r
23335</listitem>\r
23336<listitem>\r
23337<simpara>\r
23338Also convert pointer equality on scalar types to type specific\r
23339primitives.\r
23340</simpara>\r
23341</listitem>\r
23342</itemizedlist>\r
23343<simpara><?asciidoc-pagebreak?></simpara>\r
23344</section>\r
23345</section>\r
23346<section id="PolyHash">\r
23347<title>PolyHash</title>\r
23348<simpara><link linkend="PolyHash">PolyHash</link> is an optimization pass for the <link linkend="SSA">SSA</link>\r
23349<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="SSASimplify">SSASimplify</link>.</simpara>\r
23350<section id="_description_43">\r
23351<title>Description</title>\r
23352<simpara>This pass implements polymorphic, structural hashing.</simpara>\r
23353</section>\r
23354<section id="_implementation_46">\r
23355<title>Implementation</title>\r
23356<itemizedlist>\r
23357<listitem>\r
23358<simpara>\r
23359<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/poly-hash.fun"><literal>poly-hash.fun</literal></ulink>\r
23360</simpara>\r
23361</listitem>\r
23362</itemizedlist>\r
23363</section>\r
23364<section id="_details_and_notes_46">\r
23365<title>Details and Notes</title>\r
23366<simpara>For each datatype, tycon, and vector type, it builds and equality\r
23367function and translates calls to <literal>MLton_hash</literal> into calls to that\r
23368function.</simpara>\r
23369<simpara>For tuples, it does the equality test inline; i.e., it does not create\r
23370a separate equality function for each tuple type.</simpara>\r
23371<simpara>All equality functions are created only if necessary, i.e., if\r
23372equality is actually used at a type.</simpara>\r
23373<simpara><?asciidoc-pagebreak?></simpara>\r
23374</section>\r
23375</section>\r
23376<section id="PolyML">\r
23377<title>PolyML</title>\r
23378<simpara><ulink url="http://www.polyml.org/">Poly/ML</ulink> is a\r
23379<link linkend="StandardMLImplementations">Standard ML implementation</link>.</simpara>\r
23380<section id="_also_see_22">\r
23381<title>Also see</title>\r
23382<itemizedlist>\r
23383<listitem>\r
23384<simpara>\r
23385<link linkend="References_Matthews95">Matthews95</link>\r
23386</simpara>\r
23387</listitem>\r
23388</itemizedlist>\r
23389<simpara><?asciidoc-pagebreak?></simpara>\r
23390</section>\r
23391</section>\r
23392<section id="PolymorphicEquality">\r
23393<title>PolymorphicEquality</title>\r
23394<simpara>Polymorphic equality is a built-in function in\r
23395<link linkend="StandardML">Standard ML</link> that compares two values of the same type\r
23396for equality. It is specified as</simpara>\r
23397<programlisting language="sml" linenumbering="unnumbered">val = : ''a * ''a -&gt; bool</programlisting>\r
23398<simpara>The <literal>''a</literal> in the specification are\r
23399<link linkend="EqualityTypeVariable">equality type variables</link>, and indicate that\r
23400polymorphic equality can only be applied to values of an\r
23401<link linkend="EqualityType">equality type</link>. It is not allowed in SML to rebind\r
23402<literal>=</literal>, so a programmer is guaranteed that <literal>=</literal> always denotes polymorphic\r
23403equality.</simpara>\r
23404<section id="_equality_of_ground_types">\r
23405<title>Equality of ground types</title>\r
23406<simpara>Ground types like <literal>char</literal>, <literal>int</literal>, and <literal>word</literal> may be compared (to values\r
23407of the same type). For example, <literal>13 = 14</literal> is type correct and yields\r
23408<literal>false</literal>.</simpara>\r
23409</section>\r
23410<section id="_equality_of_reals">\r
23411<title>Equality of reals</title>\r
23412<simpara>The one ground type that can not be compared is <literal>real</literal>. So,\r
23413<literal>13.0 = 14.0</literal> is not type correct. One can use <literal>Real.==</literal> to compare\r
23414reals for equality, but beware that this has different algebraic\r
23415properties than polymorphic equality.</simpara>\r
23416<simpara>See <ulink url="http://standardml.org/Basis/real.html">http://standardml.org/Basis/real.html</ulink> for a discussion of why\r
23417<literal>real</literal> is not an equality type.</simpara>\r
23418</section>\r
23419<section id="_equality_of_functions">\r
23420<title>Equality of functions</title>\r
23421<simpara>Comparison of functions is not allowed.</simpara>\r
23422</section>\r
23423<section id="_equality_of_immutable_types">\r
23424<title>Equality of immutable types</title>\r
23425<simpara>Polymorphic equality can be used on <link linkend="Immutable">immutable</link> values like\r
23426tuples, records, lists, and vectors. For example,</simpara>\r
23427<screen>(1, 2, 3) = (4, 5, 6)</screen>\r
23428<simpara>is a type-correct expression yielding <literal>false</literal>, while</simpara>\r
23429<screen>[1, 2, 3] = [1, 2, 3]</screen>\r
23430<simpara>is type correct and yields <literal>true</literal>.</simpara>\r
23431<simpara>Equality on immutable values is computed by structure, which means\r
23432that values are compared by recursively descending the data structure\r
23433until ground types are reached, at which point the ground types are\r
23434compared with primitive equality tests (like comparison of\r
23435characters). So, the expression</simpara>\r
23436<screen>[1, 2, 3] = [1, 1 + 1, 1 + 1 + 1]</screen>\r
23437<simpara>is guaranteed to yield <literal>true</literal>, even though the lists may occupy\r
23438different locations in memory.</simpara>\r
23439<simpara>Because of structural equality, immutable values can only be compared\r
23440if their components can be compared. For example, <literal>[1, 2, 3]</literal> can be\r
23441compared, but <literal>[1.0, 2.0, 3.0]</literal> can not. The SML type system uses\r
23442<link linkend="EqualityType">equality types</link> to ensure that structural equality is\r
23443only applied to valid values.</simpara>\r
23444</section>\r
23445<section id="_equality_of_mutable_values">\r
23446<title>Equality of mutable values</title>\r
23447<simpara>In contrast to immutable values, polymorphic equality of\r
23448<link linkend="Mutable">mutable</link> values (like ref cells and arrays) is performed by\r
23449pointer comparison, not by structure. So, the expression</simpara>\r
23450<screen>ref 13 = ref 13</screen>\r
23451<simpara>is guaranteed to yield <literal>false</literal>, even though the ref cells hold the\r
23452same contents.</simpara>\r
23453<simpara>Because equality of mutable values is not structural, arrays and refs\r
23454can be compared <emphasis>even if their components are not equality types</emphasis>.\r
23455Hence, the following expression is type correct (and yields true).</simpara>\r
23456<programlisting language="sml" linenumbering="unnumbered">let\r
23457 val r = ref 13.0\r
23458in\r
23459 r = r\r
23460end</programlisting>\r
23461</section>\r
23462<section id="_equality_of_datatypes">\r
23463<title>Equality of datatypes</title>\r
23464<simpara>Polymorphic equality of datatypes is structural. Two values of the\r
23465same datatype are equal if they are of the same <link linkend="Variant">variant</link> and\r
23466if the <link linkend="Variant">variant</link>'s arguments are equal (recursively). So,\r
23467with the datatype</simpara>\r
23468<programlisting language="sml" linenumbering="unnumbered">datatype t = A | B of t</programlisting>\r
23469<simpara>then <literal>B (B A) = B A</literal> is type correct and yields <literal>false</literal>, while <literal>A = A</literal>\r
23470and <literal>B A = B A</literal> yield <literal>true</literal>.</simpara>\r
23471<simpara>As polymorphic equality descends two values to compare them, it uses\r
23472pointer equality whenever it reaches a mutable value. So, with the\r
23473datatype</simpara>\r
23474<programlisting language="sml" linenumbering="unnumbered">datatype t = A of int ref | ...</programlisting>\r
23475<simpara>then <literal>A (ref 13) = A (ref 13)</literal> is type correct and yields <literal>false</literal>,\r
23476because the pointer equality on the two ref cells yields <literal>false</literal>.</simpara>\r
23477<simpara>One weakness of the SML type system is that datatypes do not inherit\r
23478the special property of the <literal>ref</literal> and <literal>array</literal> type constructors that\r
23479allows them to be compared regardless of their component type. For\r
23480example, after declaring</simpara>\r
23481<programlisting language="sml" linenumbering="unnumbered">datatype 'a t = A of 'a ref</programlisting>\r
23482<simpara>one might expect to be able to compare two values of type <literal>real t</literal>,\r
23483because pointer comparison on a ref cell would suffice.\r
23484Unfortunately, the type system can only express that a user-defined\r
23485datatype <link linkend="AdmitsEquality">admits equality</link> or not. In this case, <literal>t</literal>\r
23486admits equality, which means that <literal>int t</literal> can be compared but that\r
23487<literal>real t</literal> can not. We can confirm this with the program</simpara>\r
23488<programlisting language="sml" linenumbering="unnumbered">datatype 'a t = A of 'a ref\r
23489fun f (x: real t, y: real t) = x = y</programlisting>\r
23490<simpara>on which MLton reports the following error.</simpara>\r
23491<screen>Error: z.sml 2.32-2.36.\r
23492 Function applied to incorrect argument.\r
23493 expects: [&lt;equality&gt;] t * [&lt;equality&gt;] t\r
23494 but got: [real] t * [real] t\r
23495 in: = (x, y)</screen>\r
23496</section>\r
23497<section id="_implementation_47">\r
23498<title>Implementation</title>\r
23499<simpara>Polymorphic equality is implemented by recursively descending the two\r
23500values being compared, stopping as soon as they are determined to be\r
23501unequal, or exploring the entire values to determine that they are\r
23502equal. Hence, polymorphic equality can take time proportional to the\r
23503size of the smaller value.</simpara>\r
23504<simpara>MLton uses some optimizations to improve performance.</simpara>\r
23505<itemizedlist>\r
23506<listitem>\r
23507<simpara>\r
23508When computing structural equality, first do a pointer comparison.\r
23509If the comparison yields <literal>true</literal>, then stop and return <literal>true</literal>, since\r
23510the structural comparison is guaranteed to do so. If the pointer\r
23511comparison fails, then recursively descend the values.\r
23512</simpara>\r
23513</listitem>\r
23514<listitem>\r
23515<simpara>\r
23516If a datatype is an enum (e.g. <literal>datatype t = A | B | C</literal>), then a\r
23517single comparison suffices to compare values of the datatype. No case\r
23518dispatch is required to determine whether the two values are of the\r
23519same <link linkend="Variant">variant</link>.\r
23520</simpara>\r
23521</listitem>\r
23522<listitem>\r
23523<simpara>\r
23524When comparing a known constant non-value-carrying\r
23525<link linkend="Variant">variant</link>, use a single comparison. For example, the\r
23526following code will compile into a single comparison for <literal>A = x</literal>.\r
23527</simpara>\r
23528<programlisting language="sml" linenumbering="unnumbered">datatype t = A | B | C of ...\r
23529fun f x = ... if A = x then ...</programlisting>\r
23530</listitem>\r
23531<listitem>\r
23532<simpara>\r
23533When comparing a small constant <literal>IntInf.int</literal> to another\r
23534<literal>IntInf.int</literal>, use a single comparison against the constant. No case\r
23535dispatch is required.\r
23536</simpara>\r
23537</listitem>\r
23538</itemizedlist>\r
23539</section>\r
23540<section id="_also_see_23">\r
23541<title>Also see</title>\r
23542<itemizedlist>\r
23543<listitem>\r
23544<simpara>\r
23545<link linkend="AdmitsEquality">AdmitsEquality</link>\r
23546</simpara>\r
23547</listitem>\r
23548<listitem>\r
23549<simpara>\r
23550<link linkend="EqualityType">EqualityType</link>\r
23551</simpara>\r
23552</listitem>\r
23553<listitem>\r
23554<simpara>\r
23555<link linkend="EqualityTypeVariable">EqualityTypeVariable</link>\r
23556</simpara>\r
23557</listitem>\r
23558</itemizedlist>\r
23559<simpara><?asciidoc-pagebreak?></simpara>\r
23560</section>\r
23561</section>\r
23562<section id="Polyvariance">\r
23563<title>Polyvariance</title>\r
23564<simpara>Polyvariance is an optimization pass for the <link linkend="SXML">SXML</link>\r
23565<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="SXMLSimplify">SXMLSimplify</link>.</simpara>\r
23566<section id="_description_44">\r
23567<title>Description</title>\r
23568<simpara>This pass duplicates a higher-order, <literal>let</literal> bound function at each\r
23569variable reference, if the cost is smaller than some threshold.</simpara>\r
23570</section>\r
23571<section id="_implementation_48">\r
23572<title>Implementation</title>\r
23573<itemizedlist>\r
23574<listitem>\r
23575<simpara>\r
23576<ulink url="https://github.com/MLton/mlton/blob/master/mlton/xml/polyvariance.fun"><literal>polyvariance.fun</literal></ulink>\r
23577</simpara>\r
23578</listitem>\r
23579</itemizedlist>\r
23580</section>\r
23581<section id="_details_and_notes_47">\r
23582<title>Details and Notes</title>\r
23583<simpara></simpara>\r
23584<simpara><?asciidoc-pagebreak?></simpara>\r
23585</section>\r
23586</section>\r
23587<section id="Poplog">\r
23588<title>Poplog</title>\r
23589<simpara><ulink url="http://www.cs.bham.ac.uk/research/poplog/poplog.info.html">POPLOG</ulink> is a\r
23590development environment that includes implementations of a number of\r
23591languages, including <link linkend="StandardML">Standard ML</link>.</simpara>\r
23592<simpara>While POPLOG is actively developed, the <link linkend="ML">ML</link> support predates\r
23593<link linkend="DefinitionOfStandardML">SML&#8217;97</link>, and there is no support for the\r
23594<link linkend="BasisLibrary">Basis Library</link>\r
23595<ulink url="http://www.standardml.org/Basis">specification</ulink>.</simpara>\r
23596<section id="_also_see_24">\r
23597<title>Also see</title>\r
23598<itemizedlist>\r
23599<listitem>\r
23600<simpara>\r
23601<ulink url="http://www.cs.bham.ac.uk/research/poplog/doc/pmlhelp/mlinpop">Mixed-language programming in ML and Pop-11</ulink>.\r
23602</simpara>\r
23603</listitem>\r
23604</itemizedlist>\r
23605<simpara><?asciidoc-pagebreak?></simpara>\r
23606</section>\r
23607</section>\r
23608<section id="PortingMLton">\r
23609<title>PortingMLton</title>\r
23610<simpara>Porting MLton to a new target platform (architecture or OS) involves\r
23611the following steps.</simpara>\r
23612<orderedlist numeration="arabic">\r
23613<listitem>\r
23614<simpara>\r
23615Make the necessary changes to the scripts, runtime system,\r
23616<link linkend="BasisLibrary">Basis Library</link> implementation, and compiler.\r
23617</simpara>\r
23618</listitem>\r
23619<listitem>\r
23620<simpara>\r
23621Get the regressions working using a cross compiler.\r
23622</simpara>\r
23623</listitem>\r
23624<listitem>\r
23625<simpara>\r
23626<link linkend="CrossCompiling">Cross compile</link> MLton and bootstrap on the target.\r
23627</simpara>\r
23628</listitem>\r
23629</orderedlist>\r
23630<simpara>MLton has a native code generator only for AMD64 and X86, so, if you\r
23631are porting to another architecture, you must use the C code\r
23632generator. These notes do not cover building a new native code\r
23633generator.</simpara>\r
23634<simpara>Some of the following steps will not be necessary if MLton already\r
23635supports the architecture or operating system you are porting to.</simpara>\r
23636<section id="_what_code_to_change">\r
23637<title>What code to change</title>\r
23638<itemizedlist>\r
23639<listitem>\r
23640<simpara>\r
23641Scripts.\r
23642</simpara>\r
23643<itemizedlist>\r
23644<listitem>\r
23645<simpara>\r
23646In <literal>bin/platform</literal>, add new cases to define <literal>$HOST_OS</literal> and <literal>$HOST_ARCH</literal>.\r
23647</simpara>\r
23648</listitem>\r
23649</itemizedlist>\r
23650</listitem>\r
23651<listitem>\r
23652<simpara>\r
23653Runtime system.\r
23654</simpara>\r
23655<simpara>The goal of this step is to be able to successfully run <literal>make</literal> in the\r
23656<literal>runtime</literal> directory on the target machine.</simpara>\r
23657<itemizedlist>\r
23658<listitem>\r
23659<simpara>\r
23660In <literal>platform.h</literal>, add a new case to include <literal>platform/&lt;arch&gt;.h</literal> and <literal>platform/&lt;os&gt;.h</literal>.\r
23661</simpara>\r
23662</listitem>\r
23663<listitem>\r
23664<simpara>\r
23665In <literal>platform/&lt;arch&gt;.h</literal>:\r
23666</simpara>\r
23667<itemizedlist>\r
23668<listitem>\r
23669<simpara>\r
23670define <literal>MLton_Platform_Arch_host</literal>.\r
23671</simpara>\r
23672</listitem>\r
23673</itemizedlist>\r
23674</listitem>\r
23675<listitem>\r
23676<simpara>\r
23677In <literal>platform/&lt;os&gt;.h</literal>:\r
23678</simpara>\r
23679<itemizedlist>\r
23680<listitem>\r
23681<simpara>\r
23682include platform-specific includes.\r
23683</simpara>\r
23684</listitem>\r
23685<listitem>\r
23686<simpara>\r
23687define <literal>MLton_Platform_OS_host</literal>.\r
23688</simpara>\r
23689</listitem>\r
23690<listitem>\r
23691<simpara>\r
23692define all of the <literal>HAS_*</literal> macros.\r
23693</simpara>\r
23694</listitem>\r
23695</itemizedlist>\r
23696</listitem>\r
23697<listitem>\r
23698<simpara>\r
23699In <literal>platform/&lt;os&gt;.c</literal> implement any platform-dependent functions that the runtime needs.\r
23700</simpara>\r
23701</listitem>\r
23702<listitem>\r
23703<simpara>\r
23704Add rounding mode control to <literal>basis/Real/IEEEReal.c</literal> for the new arch (if not <literal>HAS_FEROUND</literal>)\r
23705</simpara>\r
23706</listitem>\r
23707<listitem>\r
23708<simpara>\r
23709Compile and install the <link linkend="GnuMP">GnuMP</link>. This varies from platform to platform. In <literal>platform/&lt;os&gt;.h</literal>, you need to include the appropriate <literal>gmp.h</literal>.\r
23710</simpara>\r
23711</listitem>\r
23712</itemizedlist>\r
23713</listitem>\r
23714<listitem>\r
23715<simpara>\r
23716Basis Library implementation (<literal>basis-library/*</literal>)\r
23717</simpara>\r
23718<itemizedlist>\r
23719<listitem>\r
23720<simpara>\r
23721In <literal>primitive/prim-mlton.sml</literal>:\r
23722</simpara>\r
23723<itemizedlist>\r
23724<listitem>\r
23725<simpara>\r
23726Add a new variant to the <literal>MLton.Platform.Arch.t</literal> datatype.\r
23727</simpara>\r
23728</listitem>\r
23729<listitem>\r
23730<simpara>\r
23731modify the constants that define <literal>MLton.Platform.Arch.host</literal> to match with <literal>MLton_Platform_Arch_host</literal>, as set in <literal>runtime/platform/&lt;arch&gt;.h</literal>.\r
23732</simpara>\r
23733</listitem>\r
23734<listitem>\r
23735<simpara>\r
23736Add a new variant to the <literal>MLton.Platform.OS.t</literal> datatype.\r
23737</simpara>\r
23738</listitem>\r
23739<listitem>\r
23740<simpara>\r
23741modify the constants that define <literal>MLton.Platform.OS.host</literal> to match with <literal>MLton_Platform_OS_host</literal>, as set in <literal>runtime/platform/&lt;os&gt;.h</literal>.\r
23742</simpara>\r
23743</listitem>\r
23744</itemizedlist>\r
23745</listitem>\r
23746<listitem>\r
23747<simpara>\r
23748In <literal>mlton/platform.{sig,sml}</literal> add a new variant.\r
23749</simpara>\r
23750</listitem>\r
23751<listitem>\r
23752<simpara>\r
23753In <literal>sml-nj/sml-nj.sml</literal>, modify <literal>getOSKind</literal>.\r
23754</simpara>\r
23755</listitem>\r
23756<listitem>\r
23757<simpara>\r
23758Look at all the uses of <literal>MLton.Platform</literal> in the Basis Library implementation and see if you need to do anything special. You might use the following command to see where to look.\r
23759</simpara>\r
23760<screen>find basis-library -type f | xargs grep 'MLton\.Platform'</screen>\r
23761<simpara>If in doubt, leave the code alone and wait to see what happens when you run the regression tests.</simpara>\r
23762</listitem>\r
23763</itemizedlist>\r
23764</listitem>\r
23765<listitem>\r
23766<simpara>\r
23767Compiler.\r
23768</simpara>\r
23769<itemizedlist>\r
23770<listitem>\r
23771<simpara>\r
23772In <literal>lib/stubs/mlton-stubs/platform.sig</literal> add any new variants, as was done in the Basis Library.\r
23773</simpara>\r
23774</listitem>\r
23775<listitem>\r
23776<simpara>\r
23777In <literal>lib/stubs/mlton-stubs/mlton.sml</literal> add any new variants in <literal>MLton.Platform</literal>, as was done in the Basis Library.\r
23778</simpara>\r
23779</listitem>\r
23780</itemizedlist>\r
23781</listitem>\r
23782</itemizedlist>\r
23783<simpara>The string used to identify a particular architecture or operating\r
23784system must be the same (except for possibly case of letters) in the\r
23785scripts, runtime, Basis Library implementation, and compiler (stubs).\r
23786In <literal>mlton/main/main.fun</literal>, MLton itself uses the conversions to and\r
23787from strings:</simpara>\r
23788<screen>MLton.Platform.{Arch,OS}.{from,to}String</screen>\r
23789<simpara>If the there is a mismatch, you may see the error message\r
23790<literal>strange arch</literal> or <literal>strange os</literal>.</simpara>\r
23791</section>\r
23792<section id="_running_the_regressions_with_a_cross_compiler">\r
23793<title>Running the regressions with a cross compiler</title>\r
23794<simpara>When porting to a new platform, it is always best to get all (or as\r
23795many as possible) of the regressions working before moving to a self\r
23796compile. It is easiest to do this by modifying and rebuilding the\r
23797compiler on a working machine and then running the regressions with a\r
23798cross compiler. It is not easy to build a gcc cross compiler, so we\r
23799recommend generating the C and assembly on a working machine (using\r
23800MLton&#8217;s <literal>-target</literal> and <literal>-stop g</literal> flags, copying the generated files to\r
23801the target machine, then compiling and linking there.</simpara>\r
23802<orderedlist numeration="arabic">\r
23803<listitem>\r
23804<simpara>\r
23805Remake the compiler on a working machine.\r
23806</simpara>\r
23807</listitem>\r
23808<listitem>\r
23809<simpara>\r
23810Use <literal>bin/add-cross</literal> to add support for the new target. In particular, this should create <literal>build/lib/mlton/targets/&lt;target&gt;/</literal> with the platform-specific necessary cross-compilation information.\r
23811</simpara>\r
23812</listitem>\r
23813<listitem>\r
23814<simpara>\r
23815Run the regression tests with the cross-compiler. To cross-compile all the tests, do\r
23816</simpara>\r
23817<screen>bin/regression -cross &lt;target&gt;</screen>\r
23818<simpara>This will create all the executables. Then, copy <literal>bin/regression</literal> and\r
23819the <literal>regression</literal> directory to the target machine, and do</simpara>\r
23820<screen>bin/regression -run-only &lt;target&gt;</screen>\r
23821<simpara>This should run all the tests.</simpara>\r
23822</listitem>\r
23823</orderedlist>\r
23824<simpara>Repeat this step, interleaved with appropriate compiler modifications,\r
23825until all the regressions pass.</simpara>\r
23826</section>\r
23827<section id="_bootstrap">\r
23828<title>Bootstrap</title>\r
23829<simpara>Once you&#8217;ve got all the regressions working, you can build MLton for\r
23830the new target. As with the regressions, the idea for bootstrapping\r
23831is to generate the C and assembly on a working machine, copy it to the\r
23832target machine, and then compile and link there. Here&#8217;s the sequence\r
23833of steps.</simpara>\r
23834<orderedlist numeration="arabic">\r
23835<listitem>\r
23836<simpara>\r
23837On a working machine, with the newly rebuilt compiler, in the <literal>mlton</literal> directory, do:\r
23838</simpara>\r
23839<screen>mlton -stop g -target &lt;target&gt; mlton.mlb</screen>\r
23840</listitem>\r
23841<listitem>\r
23842<simpara>\r
23843Copy to the target machine.\r
23844</simpara>\r
23845</listitem>\r
23846<listitem>\r
23847<simpara>\r
23848On the target machine, move the libraries to the right place. That is, in <literal>build/lib/mlton/targets</literal>, do:\r
23849</simpara>\r
23850<screen>rm -rf self\r
23851mv &lt;target&gt; self</screen>\r
23852<simpara>Also make sure you have all the header files in build/lib/mlton/include. You can copy them from a host machine that has run <literal>make runtime</literal>.</simpara>\r
23853</listitem>\r
23854<listitem>\r
23855<simpara>\r
23856On the target machine, compile and link MLton. That is, in the mlton directory, do something like:\r
23857</simpara>\r
23858<screen>gcc -c -Ibuild/lib/mlton/include -Ibuild/lib/mlton/targets/self/include -O1 -w mlton/mlton.*.[cs]\r
23859gcc -o build/lib/mlton/mlton-compile \\r
23860 -Lbuild/lib/mlton/targets/self \\r
23861 -L/usr/local/lib \\r
23862 mlton.*.o \\r
23863 -lmlton -lgmp -lgdtoa -lm</screen>\r
23864</listitem>\r
23865<listitem>\r
23866<simpara>\r
23867At this point, MLton should be working and you can finish the rest of a usual make on the target machine.\r
23868</simpara>\r
23869<screen>make basis-no-check script mlbpathmap constants libraries tools</screen>\r
23870</listitem>\r
23871<listitem>\r
23872<simpara>\r
23873Making the last tool, mlyacc, will fail, because mlyacc cannot bootstrap its own yacc.grm.* files. On the host machine, run <literal>make -C mlyacc src/yacc.grm.sml</literal>. Then copy both files to the target machine, and compile mlyacc, making sure to supply the path to your newly compile mllex: <literal>make -C mlyacc MLLEX=mllex/mllex</literal>.\r
23874</simpara>\r
23875</listitem>\r
23876</orderedlist>\r
23877<simpara>There are other details to get right, like making sure that the tools\r
23878directories were clean so that the tools are rebuilt on the new\r
23879platform, but hopefully this structure works. Once you&#8217;ve got a\r
23880compiler on the target machine, you should test it by running all the\r
23881regressions normally (i.e. without the <literal>-cross</literal> flag) and by running a\r
23882couple rounds of self compiles.</simpara>\r
23883</section>\r
23884<section id="_also_see_25">\r
23885<title>Also see</title>\r
23886<simpara>The above description is based on the following emails sent to the\r
23887MLton list.</simpara>\r
23888<itemizedlist>\r
23889<listitem>\r
23890<simpara>\r
23891<ulink url="http://www.mlton.org/pipermail/mlton/2002-October/013110.html">http://www.mlton.org/pipermail/mlton/2002-October/013110.html</ulink>\r
23892</simpara>\r
23893</listitem>\r
23894<listitem>\r
23895<simpara>\r
23896<ulink url="http://www.mlton.org/pipermail/mlton/2004-July/016029.html">http://www.mlton.org/pipermail/mlton/2004-July/016029.html</ulink>\r
23897</simpara>\r
23898</listitem>\r
23899</itemizedlist>\r
23900<simpara><?asciidoc-pagebreak?></simpara>\r
23901</section>\r
23902</section>\r
23903<section id="PrecedenceParse">\r
23904<title>PrecedenceParse</title>\r
23905<simpara><link linkend="PrecedenceParse">PrecedenceParse</link> is an analysis/rewrite pass for the <link linkend="AST">AST</link>\r
23906<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="Elaborate">Elaborate</link>.</simpara>\r
23907<section id="_description_45">\r
23908<title>Description</title>\r
23909<simpara>This pass rewrites <link linkend="AST">AST</link> function clauses, expressions, and patterns\r
23910to resolve <link linkend="OperatorPrecedence">OperatorPrecedence</link>.</simpara>\r
23911</section>\r
23912<section id="_implementation_49">\r
23913<title>Implementation</title>\r
23914<itemizedlist>\r
23915<listitem>\r
23916<simpara>\r
23917<ulink url="https://github.com/MLton/mlton/blob/master/mlton/elaborate/precedence-parse.sig"><literal>precedence-parse.sig</literal></ulink>\r
23918</simpara>\r
23919</listitem>\r
23920<listitem>\r
23921<simpara>\r
23922<ulink url="https://github.com/MLton/mlton/blob/master/mlton/elaborate/precedence-parse.fun"><literal>precedence-parse.fun</literal></ulink>\r
23923</simpara>\r
23924</listitem>\r
23925</itemizedlist>\r
23926</section>\r
23927<section id="_details_and_notes_48">\r
23928<title>Details and Notes</title>\r
23929<simpara></simpara>\r
23930<simpara><?asciidoc-pagebreak?></simpara>\r
23931</section>\r
23932</section>\r
23933<section id="Printf">\r
23934<title>Printf</title>\r
23935<simpara>Programmers coming from C or Java often ask if\r
23936<link linkend="StandardML">Standard ML</link> has a <literal>printf</literal> function. It does not.\r
23937However, it is possible to implement your own version with only a few\r
23938lines of code.</simpara>\r
23939<simpara>Here is a definition for <literal>printf</literal> and <literal>fprintf</literal>, along with format\r
23940specifiers for booleans, integers, and reals.</simpara>\r
23941<programlisting language="sml" linenumbering="unnumbered">structure Printf =\r
23942 struct\r
23943 fun $ (_, f) = f (fn p =&gt; p ()) ignore\r
23944 fun fprintf out f = f (out, id)\r
23945 val printf = fn z =&gt; fprintf TextIO.stdOut z\r
23946 fun one ((out, f), make) g =\r
23947 g (out, fn r =&gt;\r
23948 f (fn p =&gt;\r
23949 make (fn s =&gt;\r
23950 r (fn () =&gt; (p (); TextIO.output (out, s))))))\r
23951 fun ` x s = one (x, fn f =&gt; f s)\r
23952 fun spec to x = one (x, fn f =&gt; f o to)\r
23953 val B = fn z =&gt; spec Bool.toString z\r
23954 val I = fn z =&gt; spec Int.toString z\r
23955 val R = fn z =&gt; spec Real.toString z\r
23956 end</programlisting>\r
23957<simpara>Here&#8217;s an example use.</simpara>\r
23958<programlisting language="sml" linenumbering="unnumbered">val () = printf `"Int="I`" Bool="B`" Real="R`"\n" $ 1 false 2.0</programlisting>\r
23959<simpara>This prints the following.</simpara>\r
23960<screen>Int=1 Bool=false Real=2.0</screen>\r
23961<simpara>In general, a use of <literal>printf</literal> looks like</simpara>\r
23962<screen>printf &lt;spec1&gt; ... &lt;specn&gt; $ &lt;arg1&gt; ... &lt;argm&gt;</screen>\r
23963<simpara>where each <literal>&lt;speci&gt;</literal> is either a specifier like <literal>B</literal>, <literal>I</literal>, or <literal>R</literal>, or\r
23964is an inline string, like <literal>&grave;"foo"</literal>. A backtick (<literal>&grave;</literal>)\r
23965must precede each inline string. Each <literal>&lt;argi&gt;</literal> must be of the\r
23966appropriate type for the corresponding specifier.</simpara>\r
23967<simpara>SML <literal>printf</literal> is more powerful than its C counterpart in a number of\r
23968ways. In particular, the function produced by <literal>printf</literal> is a perfectly\r
23969ordinary SML function, and can be passed around, used multiple times,\r
23970etc. For example:</simpara>\r
23971<programlisting language="sml" linenumbering="unnumbered">val f: int -&gt; bool -&gt; unit = printf `"Int="I`" Bool="B`"\n" $\r
23972val () = f 1 true\r
23973val () = f 2 false</programlisting>\r
23974<simpara>The definition of <literal>printf</literal> is even careful to not print anything until\r
23975it is fully applied. So, examples like the following will work as\r
23976expected.</simpara>\r
23977<screen>val f: int -&gt; bool -&gt; unit = printf `"Int="I`" Bool="B`"\n" $ 13\r
23978val () = f true\r
23979val () = f false</screen>\r
23980<simpara>It is also easy to define new format specifiers. For example, suppose\r
23981we wanted format specifiers for characters and strings.</simpara>\r
23982<screen>val C = fn z =&gt; spec Char.toString z\r
23983val S = fn z =&gt; spec (fn s =&gt; s) z</screen>\r
23984<simpara>One can define format specifiers for more complex types, e.g. pairs of\r
23985integers.</simpara>\r
23986<screen>val I2 =\r
23987 fn z =&gt;\r
23988 spec (fn (i, j) =&gt;\r
23989 concat ["(", Int.toString i, ", ", Int.toString j, ")"])\r
23990 z</screen>\r
23991<simpara>Here&#8217;s an example use.</simpara>\r
23992<screen>val () = printf `"Test "I2`" a string "S`"\n" $ (1, 2) "hello"</screen>\r
23993<section id="_printf_via_link_linkend_fold_fold_link">\r
23994<title>Printf via <link linkend="Fold">Fold</link></title>\r
23995<simpara><literal>printf</literal> is best viewed as a special case of variable-argument\r
23996<link linkend="Fold">Fold</link> that inductively builds a function as it processes its\r
23997arguments. Here is the definition of a <literal>Printf</literal> structure in terms of\r
23998fold. The structure is equivalent to the above one, except that it\r
23999uses the standard <literal>$</literal> instead of a specialized one.</simpara>\r
24000<programlisting language="sml" linenumbering="unnumbered">structure Printf =\r
24001 struct\r
24002 fun fprintf out =\r
24003 Fold.fold ((out, id), fn (_, f) =&gt; f (fn p =&gt; p ()) ignore)\r
24004\r
24005 val printf = fn z =&gt; fprintf TextIO.stdOut z\r
24006\r
24007 fun one ((out, f), make) =\r
24008 (out, fn r =&gt;\r
24009 f (fn p =&gt;\r
24010 make (fn s =&gt;\r
24011 r (fn () =&gt; (p (); TextIO.output (out, s))))))\r
24012\r
24013 val ` =\r
24014 fn z =&gt; Fold.step1 (fn (s, x) =&gt; one (x, fn f =&gt; f s)) z\r
24015\r
24016 fun spec to = Fold.step0 (fn x =&gt; one (x, fn f =&gt; f o to))\r
24017\r
24018 val B = fn z =&gt; spec Bool.toString z\r
24019 val I = fn z =&gt; spec Int.toString z\r
24020 val R = fn z =&gt; spec Real.toString z\r
24021 end</programlisting>\r
24022<simpara>Viewing <literal>printf</literal> as a fold opens up a number of possibilities. For\r
24023example, one can name parts of format strings using the fold idiom for\r
24024naming sequences of steps.</simpara>\r
24025<screen>val IB = fn u =&gt; Fold.fold u `"Int="I`" Bool="B\r
24026val () = printf IB`" "IB`"\n" $ 1 true 3 false</screen>\r
24027<simpara>One can even parametrize over partial format strings.</simpara>\r
24028<screen>fun XB X = fn u =&gt; Fold.fold u `"X="X`" Bool="B\r
24029val () = printf (XB I)`" "(XB R)`"\n" $ 1 true 2.0 false</screen>\r
24030</section>\r
24031<section id="_also_see_26">\r
24032<title>Also see</title>\r
24033<itemizedlist>\r
24034<listitem>\r
24035<simpara>\r
24036<link linkend="PrintfGentle">PrintfGentle</link>\r
24037</simpara>\r
24038</listitem>\r
24039<listitem>\r
24040<simpara>\r
24041<link linkend="References_Danvy98">Functional Unparsing</link>\r
24042</simpara>\r
24043</listitem>\r
24044</itemizedlist>\r
24045<simpara><?asciidoc-pagebreak?></simpara>\r
24046</section>\r
24047</section>\r
24048<section id="PrintfGentle">\r
24049<title>PrintfGentle</title>\r
24050<simpara>This page provides a gentle introduction and derivation of <link linkend="Printf">Printf</link>,\r
24051with sections and arrangement more suitable to a talk.</simpara>\r
24052<section id="_introduction">\r
24053<title>Introduction</title>\r
24054<simpara>SML does not have <literal>printf</literal>. Could we define it ourselves?</simpara>\r
24055<programlisting language="sml" linenumbering="unnumbered">val () = printf ("here's an int %d and a real %f.\n", 13, 17.0)\r
24056val () = printf ("here's three values (%d, %f, %f).\n", 13, 17.0, 19.0)</programlisting>\r
24057<simpara>What could the type of <literal>printf</literal> be?</simpara>\r
24058<simpara>This obviously can&#8217;t work, because SML functions take a fixed number\r
24059of arguments. Actually they take one argument, but if that&#8217;s a tuple,\r
24060it can only have a fixed number of components.</simpara>\r
24061</section>\r
24062<section id="_from_tupling_to_currying">\r
24063<title>From tupling to currying</title>\r
24064<simpara>What about currying to get around the typing problem?</simpara>\r
24065<programlisting language="sml" linenumbering="unnumbered">val () = printf "here's an int %d and a real %f.\n" 13 17.0\r
24066val () = printf "here's three values (%d, %f, %f).\n" 13 17.0 19.0</programlisting>\r
24067<simpara>That fails for a similar reason. We need two types for <literal>printf</literal>.</simpara>\r
24068<screen>val printf: string -&gt; int -&gt; real -&gt; unit\r
24069val printf: string -&gt; int -&gt; real -&gt; real -&gt; unit</screen>\r
24070<simpara>This can&#8217;t work, because <literal>printf</literal> can only have one type. SML doesn&#8217;t\r
24071support programmer-defined overloading.</simpara>\r
24072</section>\r
24073<section id="_overloading_and_dependent_types">\r
24074<title>Overloading and dependent types</title>\r
24075<simpara>Even without worrying about number of arguments, there is another\r
24076problem. The type of <literal>printf</literal> depends on the format string.</simpara>\r
24077<programlisting language="sml" linenumbering="unnumbered">val () = printf "here's an int %d and a real %f.\n" 13 17.0\r
24078val () = printf "here's a real %f and an int %d.\n" 17.0 13</programlisting>\r
24079<simpara>Now we need</simpara>\r
24080<screen>val printf: string -&gt; int -&gt; real -&gt; unit\r
24081val printf: string -&gt; real -&gt; int -&gt; unit</screen>\r
24082<simpara>Again, this can&#8217;t possibly working because SML doesn&#8217;t have\r
24083overloading, and types can&#8217;t depend on values.</simpara>\r
24084</section>\r
24085<section id="_idea_express_type_information_in_the_format_string">\r
24086<title>Idea: express type information in the format string</title>\r
24087<simpara>If we express type information in the format string, then different\r
24088uses of <literal>printf</literal> can have different types.</simpara>\r
24089<programlisting language="sml" linenumbering="unnumbered">type 'a t (* the type of format strings *)\r
24090val printf: 'a t -&gt; 'a\r
24091infix D F\r
24092val fs1: (int -&gt; real -&gt; unit) t = "here's an int "D" and a real "F".\n"\r
24093val fs2: (int -&gt; real -&gt; real -&gt; unit) t =\r
24094 "here's three values ("D", "F", "F").\n"\r
24095val () = printf fs1 13 17.0\r
24096val () = printf fs2 13 17.0 19.0</programlisting>\r
24097<simpara>Now, our two calls to <literal>printf</literal> type check, because the format\r
24098string specializes <literal>printf</literal> to the appropriate type.</simpara>\r
24099</section>\r
24100<section id="_the_types_of_format_characters">\r
24101<title>The types of format characters</title>\r
24102<simpara>What should the type of format characters <literal>D</literal> and <literal>F</literal> be? Each format\r
24103character requires an additional argument of the appropriate type to\r
24104be supplied to <literal>printf</literal>.</simpara>\r
24105<simpara>Idea: guess the final type that will be needed for <literal>printf</literal> the format\r
24106string and verify it with each format character.</simpara>\r
24107<programlisting language="sml" linenumbering="unnumbered">type ('a, 'b) t (* 'a = rest of type to verify, 'b = final type *)\r
24108val ` : string -&gt; ('a, 'a) t (* guess the type, which must be verified *)\r
24109val D: (int -&gt; 'a, 'b) t * string -&gt; ('a, 'b) t (* consume an int *)\r
24110val F: (real -&gt; 'a, 'b) t * string -&gt; ('a, 'b) t (* consume a real *)\r
24111val printf: (unit, 'a) t -&gt; 'a</programlisting>\r
24112<simpara>Don&#8217;t worry. In the end, type inference will guess and verify for us.</simpara>\r
24113</section>\r
24114<section id="_understanding_guess_and_verify">\r
24115<title>Understanding guess and verify</title>\r
24116<simpara>Now, let&#8217;s build up a format string and a specialized <literal>printf</literal>.</simpara>\r
24117<programlisting language="sml" linenumbering="unnumbered">infix D F\r
24118val f0 = `"here's an int "\r
24119val f1 = f0 D " and a real "\r
24120val f2 = f1 F ".\n"\r
24121val p = printf f2</programlisting>\r
24122<simpara>These definitions yield the following types.</simpara>\r
24123<programlisting language="sml" linenumbering="unnumbered">val f0: (int -&gt; real -&gt; unit, int -&gt; real -&gt; unit) t\r
24124val f1: (real -&gt; unit, int -&gt; real -&gt; unit) t\r
24125val f2: (unit, int -&gt; real -&gt; unit) t\r
24126val p: int -&gt; real -&gt; unit</programlisting>\r
24127<simpara>So, <literal>p</literal> is a specialized <literal>printf</literal> function. We could use it as\r
24128follows</simpara>\r
24129<programlisting language="sml" linenumbering="unnumbered">val () = p 13 17.0\r
24130val () = p 14 19.0</programlisting>\r
24131</section>\r
24132<section id="_type_checking_this_using_a_functor">\r
24133<title>Type checking this using a functor</title>\r
24134<programlisting language="sml" linenumbering="unnumbered">signature PRINTF =\r
24135 sig\r
24136 type ('a, 'b) t\r
24137 val ` : string -&gt; ('a, 'a) t\r
24138 val D: (int -&gt; 'a, 'b) t * string -&gt; ('a, 'b) t\r
24139 val F: (real -&gt; 'a, 'b) t * string -&gt; ('a, 'b) t\r
24140 val printf: (unit, 'a) t -&gt; 'a\r
24141 end\r
24142\r
24143functor Test (P: PRINTF) =\r
24144 struct\r
24145 open P\r
24146 infix D F\r
24147\r
24148 val () = printf (`"here's an int "D" and a real "F".\n") 13 17.0\r
24149 val () = printf (`"here's three values ("D", "F ", "F").\n") 13 17.0 19.0\r
24150 end</programlisting>\r
24151</section>\r
24152<section id="_implementing_literal_printf_literal">\r
24153<title>Implementing <literal>Printf</literal></title>\r
24154<simpara>Think of a format character as a formatter transformer. It takes the\r
24155formatter for the part of the format string before it and transforms\r
24156it into a new formatter that first does the left hand bit, then does\r
24157its bit, then continues on with the rest of the format string.</simpara>\r
24158<programlisting language="sml" linenumbering="unnumbered">structure Printf: PRINTF =\r
24159 struct\r
24160 datatype ('a, 'b) t = T of (unit -&gt; 'a) -&gt; 'b\r
24161\r
24162 fun printf (T f) = f (fn () =&gt; ())\r
24163\r
24164 fun ` s = T (fn a =&gt; (print s; a ()))\r
24165\r
24166 fun D (T f, s) =\r
24167 T (fn g =&gt; f (fn () =&gt; fn i =&gt;\r
24168 (print (Int.toString i); print s; g ())))\r
24169\r
24170 fun F (T f, s) =\r
24171 T (fn g =&gt; f (fn () =&gt; fn i =&gt;\r
24172 (print (Real.toString i); print s; g ())))\r
24173 end</programlisting>\r
24174</section>\r
24175<section id="_testing_printf">\r
24176<title>Testing printf</title>\r
24177<programlisting language="sml" linenumbering="unnumbered">structure Z = Test (Printf)</programlisting>\r
24178</section>\r
24179<section id="_user_definable_formats">\r
24180<title>User-definable formats</title>\r
24181<simpara>The definition of the format characters is pretty much the same.\r
24182Within the <literal>Printf</literal> structure we can define a format character\r
24183generator.</simpara>\r
24184<programlisting language="sml" linenumbering="unnumbered">val newFormat: ('a -&gt; string) -&gt; ('a -&gt; 'b, 'c) t * string -&gt; ('b, 'c) t =\r
24185 fn toString =&gt; fn (T f, s) =&gt;\r
24186 T (fn th =&gt; f (fn () =&gt; fn a =&gt; (print (toString a); print s ; th ())))\r
24187val D = fn z =&gt; newFormat Int.toString z\r
24188val F = fn z =&gt; newFormat Real.toString z</programlisting>\r
24189</section>\r
24190<section id="_a_core_literal_printf_literal">\r
24191<title>A core <literal>Printf</literal></title>\r
24192<simpara>We can now have a very small <literal>PRINTF</literal> signature, and define all\r
24193the format strings externally to the core module.</simpara>\r
24194<programlisting language="sml" linenumbering="unnumbered">signature PRINTF =\r
24195 sig\r
24196 type ('a, 'b) t\r
24197 val ` : string -&gt; ('a, 'a) t\r
24198 val newFormat: ('a -&gt; string) -&gt; ('a -&gt; 'b, 'c) t * string -&gt; ('b, 'c) t\r
24199 val printf: (unit, 'a) t -&gt; 'a\r
24200 end\r
24201\r
24202structure Printf: PRINTF =\r
24203 struct\r
24204 datatype ('a, 'b) t = T of (unit -&gt; 'a) -&gt; 'b\r
24205\r
24206 fun printf (T f) = f (fn () =&gt; ())\r
24207\r
24208 fun ` s = T (fn a =&gt; (print s; a ()))\r
24209\r
24210 fun newFormat toString (T f, s) =\r
24211 T (fn th =&gt;\r
24212 f (fn () =&gt; fn a =&gt;\r
24213 (print (toString a)\r
24214 ; print s\r
24215 ; th ())))\r
24216 end</programlisting>\r
24217</section>\r
24218<section id="_extending_to_fprintf">\r
24219<title>Extending to fprintf</title>\r
24220<simpara>One can implement fprintf by threading the outstream through all the\r
24221transformers.</simpara>\r
24222<programlisting language="sml" linenumbering="unnumbered">signature PRINTF =\r
24223 sig\r
24224 type ('a, 'b) t\r
24225 val ` : string -&gt; ('a, 'a) t\r
24226 val fprintf: (unit, 'a) t * TextIO.outstream -&gt; 'a\r
24227 val newFormat: ('a -&gt; string) -&gt; ('a -&gt; 'b, 'c) t * string -&gt; ('b, 'c) t\r
24228 val printf: (unit, 'a) t -&gt; 'a\r
24229 end\r
24230\r
24231structure Printf: PRINTF =\r
24232 struct\r
24233 type out = TextIO.outstream\r
24234 val output = TextIO.output\r
24235\r
24236 datatype ('a, 'b) t = T of (out -&gt; 'a) -&gt; out -&gt; 'b\r
24237\r
24238 fun fprintf (T f, out) = f (fn _ =&gt; ()) out\r
24239\r
24240 fun printf t = fprintf (t, TextIO.stdOut)\r
24241\r
24242 fun ` s = T (fn a =&gt; fn out =&gt; (output (out, s); a out))\r
24243\r
24244 fun newFormat toString (T f, s) =\r
24245 T (fn g =&gt;\r
24246 f (fn out =&gt; fn a =&gt;\r
24247 (output (out, toString a)\r
24248 ; output (out, s)\r
24249 ; g out)))\r
24250 end</programlisting>\r
24251</section>\r
24252<section id="_notes_3">\r
24253<title>Notes</title>\r
24254<itemizedlist>\r
24255<listitem>\r
24256<simpara>\r
24257Lesson: instead of using dependent types for a function, express the\r
24258the dependency in the type of the argument.\r
24259</simpara>\r
24260</listitem>\r
24261<listitem>\r
24262<simpara>\r
24263If <literal>printf</literal> is partially applied, it will do the printing then and\r
24264there. Perhaps this could be fixed with some kind of terminator.\r
24265</simpara>\r
24266<simpara>A syntactic or argument terminator is not necessary. A formatter can\r
24267either be eager (as above) or lazy (as below). A lazy formatter\r
24268accumulates enough state to print the entire string. The simplest\r
24269lazy formatter concatenates the strings as they become available:</simpara>\r
24270<programlisting language="sml" linenumbering="unnumbered">structure PrintfLazyConcat: PRINTF =\r
24271 struct\r
24272 datatype ('a, 'b) t = T of (string -&gt; 'a) -&gt; string -&gt; 'b\r
24273\r
24274 fun printf (T f) = f print ""\r
24275\r
24276 fun ` s = T (fn th =&gt; fn s' =&gt; th (s' ^ s))\r
24277\r
24278 fun newFormat toString (T f, s) =\r
24279 T (fn th =&gt;\r
24280 f (fn s' =&gt; fn a =&gt;\r
24281 th (s' ^ toString a ^ s)))\r
24282 end</programlisting>\r
24283<simpara>It is somewhat more efficient to accumulate the strings as a list:</simpara>\r
24284<programlisting language="sml" linenumbering="unnumbered">structure PrintfLazyList: PRINTF =\r
24285 struct\r
24286 datatype ('a, 'b) t = T of (string list -&gt; 'a) -&gt; string list -&gt; 'b\r
24287\r
24288 fun printf (T f) = f (List.app print o List.rev) []\r
24289\r
24290 fun ` s = T (fn th =&gt; fn ss =&gt; th (s::ss))\r
24291\r
24292 fun newFormat toString (T f, s) =\r
24293 T (fn th =&gt;\r
24294 f (fn ss =&gt; fn a =&gt;\r
24295 th (s::toString a::ss)))\r
24296 end</programlisting>\r
24297</listitem>\r
24298</itemizedlist>\r
24299</section>\r
24300<section id="_also_see_27">\r
24301<title>Also see</title>\r
24302<itemizedlist>\r
24303<listitem>\r
24304<simpara>\r
24305<link linkend="Printf">Printf</link>\r
24306</simpara>\r
24307</listitem>\r
24308<listitem>\r
24309<simpara>\r
24310<link linkend="References_Danvy98">Functional Unparsing</link>\r
24311</simpara>\r
24312</listitem>\r
24313</itemizedlist>\r
24314<simpara><?asciidoc-pagebreak?></simpara>\r
24315</section>\r
24316</section>\r
24317<section id="ProductType">\r
24318<title>ProductType</title>\r
24319<simpara><link linkend="StandardML">Standard ML</link> has special syntax for products (tuples). A\r
24320product type is written as</simpara>\r
24321<programlisting language="sml" linenumbering="unnumbered">t1 * t2 * ... * tN</programlisting>\r
24322<simpara>and a product pattern is written as</simpara>\r
24323<programlisting language="sml" linenumbering="unnumbered">(p1, p2, ..., pN)</programlisting>\r
24324<simpara>In most situations the syntax is quite convenient. However, there are\r
24325situations where the syntax is cumbersome. There are also situations\r
24326in which it is useful to construct and destruct n-ary products\r
24327inductively, especially when using <link linkend="Fold">Fold</link>.</simpara>\r
24328<simpara>In such situations, it is useful to have a binary product datatype\r
24329with an infix constructor defined as follows.</simpara>\r
24330<programlisting language="sml" linenumbering="unnumbered">datatype ('a, 'b) product = &amp; of 'a * 'b\r
24331infix &amp;</programlisting>\r
24332<simpara>With these definitions, one can write an n-ary product as a nested\r
24333binary product quite conveniently.</simpara>\r
24334<programlisting language="sml" linenumbering="unnumbered">x1 &amp; x2 &amp; ... &amp; xn</programlisting>\r
24335<simpara>Because of left associativity, this is the same as</simpara>\r
24336<programlisting language="sml" linenumbering="unnumbered">(((x1 &amp; x2) &amp; ...) &amp; xn)</programlisting>\r
24337<simpara>Because <literal>&amp;</literal> is a constructor, the syntax can also be used for\r
24338patterns.</simpara>\r
24339<simpara>The symbol <literal>&amp;</literal> is inspired by the Curry-Howard isomorphism: the proof\r
24340of a conjunction <literal>(A &amp; B)</literal> is a pair of proofs <literal>(a, b)</literal>.</simpara>\r
24341<section id="_example_parser_combinators">\r
24342<title>Example: parser combinators</title>\r
24343<simpara>A typical parser combinator library provides a combinator that has a\r
24344type of the form.</simpara>\r
24345<programlisting language="sml" linenumbering="unnumbered">'a parser * 'b parser -&gt; ('a * 'b) parser</programlisting>\r
24346<simpara>and produces a parser for the concatenation of two parsers. When more\r
24347than two parsers are concatenated, the result of the resulting parser\r
24348is a nested structure of pairs</simpara>\r
24349<programlisting language="sml" linenumbering="unnumbered">(...((p1, p2), p3)..., pN)</programlisting>\r
24350<simpara>which is somewhat cumbersome.</simpara>\r
24351<simpara>By using a product type, the type of the concatenation combinator then\r
24352becomes</simpara>\r
24353<programlisting language="sml" linenumbering="unnumbered">'a parser * 'b parser -&gt; ('a, 'b) product parser</programlisting>\r
24354<simpara>While this doesn&#8217;t stop the nesting, it makes the pattern significantly\r
24355easier to write. Instead of</simpara>\r
24356<programlisting language="sml" linenumbering="unnumbered">(...((p1, p2), p3)..., pN)</programlisting>\r
24357<simpara>the pattern is written as</simpara>\r
24358<programlisting language="sml" linenumbering="unnumbered">p1 &amp; p2 &amp; p3 &amp; ... &amp; pN</programlisting>\r
24359<simpara>which is considerably more concise.</simpara>\r
24360</section>\r
24361<section id="_also_see_28">\r
24362<title>Also see</title>\r
24363<itemizedlist>\r
24364<listitem>\r
24365<simpara>\r
24366<link linkend="VariableArityPolymorphism">VariableArityPolymorphism</link>\r
24367</simpara>\r
24368</listitem>\r
24369<listitem>\r
24370<simpara>\r
24371<link linkend="Utilities">Utilities</link>\r
24372</simpara>\r
24373</listitem>\r
24374</itemizedlist>\r
24375<simpara><?asciidoc-pagebreak?></simpara>\r
24376</section>\r
24377</section>\r
24378<section id="Profiling">\r
24379<title>Profiling</title>\r
24380<simpara>With MLton and <literal>mlprof</literal>, you can profile your program to find out\r
24381bytes allocated, execution counts, or time spent in each function. To\r
24382profile you program, compile with <literal>-profile <emphasis>kind</emphasis></literal>, where <emphasis>kind</emphasis>\r
24383is one of <literal>alloc</literal>, <literal>count</literal>, or <literal>time</literal>. Then, run the executable,\r
24384which will write an <literal>mlmon.out</literal> file when it finishes. You can then\r
24385run <literal>mlprof</literal> on the executable and the <literal>mlmon.out</literal> file to see the\r
24386performance data.</simpara>\r
24387<simpara>Here are the three kinds of profiling that MLton supports.</simpara>\r
24388<itemizedlist>\r
24389<listitem>\r
24390<simpara>\r
24391<link linkend="ProfilingAllocation">ProfilingAllocation</link>\r
24392</simpara>\r
24393</listitem>\r
24394<listitem>\r
24395<simpara>\r
24396<link linkend="ProfilingCounts">ProfilingCounts</link>\r
24397</simpara>\r
24398</listitem>\r
24399<listitem>\r
24400<simpara>\r
24401<link linkend="ProfilingTime">ProfilingTime</link>\r
24402</simpara>\r
24403</listitem>\r
24404</itemizedlist>\r
24405<section id="_next_steps_6">\r
24406<title>Next steps</title>\r
24407<itemizedlist>\r
24408<listitem>\r
24409<simpara>\r
24410<link linkend="CallGraph">CallGraph</link>s to visualize profiling data.\r
24411</simpara>\r
24412</listitem>\r
24413<listitem>\r
24414<simpara>\r
24415<link linkend="HowProfilingWorks">HowProfilingWorks</link>\r
24416</simpara>\r
24417</listitem>\r
24418<listitem>\r
24419<simpara>\r
24420<link linkend="MLmon">MLmon</link>\r
24421</simpara>\r
24422</listitem>\r
24423<listitem>\r
24424<simpara>\r
24425<link linkend="MLtonProfile">MLtonProfile</link> to selectively profile parts of your program.\r
24426</simpara>\r
24427</listitem>\r
24428<listitem>\r
24429<simpara>\r
24430<link linkend="ProfilingTheStack">ProfilingTheStack</link>\r
24431</simpara>\r
24432</listitem>\r
24433<listitem>\r
24434<simpara>\r
24435<link linkend="ShowProf">ShowProf</link>\r
24436</simpara>\r
24437</listitem>\r
24438</itemizedlist>\r
24439<simpara><?asciidoc-pagebreak?></simpara>\r
24440</section>\r
24441</section>\r
24442<section id="ProfilingAllocation">\r
24443<title>ProfilingAllocation</title>\r
24444<simpara>With MLton and <literal>mlprof</literal>, you can <link linkend="Profiling">profile</link> your program to\r
24445find out how many bytes each function allocates. To do so, compile\r
24446your program with <literal>-profile alloc</literal>. For example, suppose that\r
24447<literal>list-rev.sml</literal> is the following.</simpara>\r
24448<programlisting language="sml" linenumbering="unnumbered">fun append (l1, l2) =\r
24449 case l1 of\r
24450 [] =&gt; l2\r
24451 | x :: l1 =&gt; x :: append (l1, l2)\r
24452\r
24453fun rev l =\r
24454 case l of\r
24455 [] =&gt; []\r
24456 | x :: l =&gt; append (rev l, [x])\r
24457\r
24458val l = List.tabulate (1000, fn i =&gt; i)\r
24459val _ = 1 + hd (rev l)</programlisting>\r
24460<simpara>Compile and run <literal>list-rev</literal> as follows.</simpara>\r
24461<screen>% mlton -profile alloc list-rev.sml\r
24462% ./list-rev\r
24463% mlprof -show-line true list-rev mlmon.out\r
244646,030,136 bytes allocated (108,336 bytes by GC)\r
24465 function cur\r
24466----------------------- -----\r
24467append list-rev.sml: 1 97.6%\r
24468&lt;gc&gt; 1.8%\r
24469&lt;main&gt; 0.4%\r
24470rev list-rev.sml: 6 0.2%</screen>\r
24471<simpara>The data shows that most of the allocation is done by the <literal>append</literal>\r
24472function defined on line 1 of <literal>list-rev.sml</literal>. The table also shows\r
24473how special functions like <literal>gc</literal> and <literal>main</literal> are handled: they are\r
24474printed with surrounding brackets. C functions are displayed\r
24475similarly. In this example, the allocation done by the garbage\r
24476collector is due to stack growth, which is usually the case.</simpara>\r
24477<simpara>The run-time performance impact of allocation profiling is noticeable,\r
24478because it inserts additional C calls for object allocation.</simpara>\r
24479<simpara>Compile with <literal>-profile alloc -profile-branch true</literal> to find out how\r
24480much allocation is done in each branch of a function; see\r
24481<link linkend="ProfilingCounts">ProfilingCounts</link> for more details on <literal>-profile-branch</literal>.</simpara>\r
24482<simpara><?asciidoc-pagebreak?></simpara>\r
24483</section>\r
24484<section id="ProfilingCounts">\r
24485<title>ProfilingCounts</title>\r
24486<simpara>With MLton and <literal>mlprof</literal>, you can <link linkend="Profiling">profile</link> your program to\r
24487find out how many times each function is called and how many times\r
24488each branch is taken. To do so, compile your program with\r
24489<literal>-profile count -profile-branch true</literal>. For example, suppose that\r
24490<literal>tak.sml</literal> contains the following.</simpara>\r
24491<programlisting language="sml" linenumbering="unnumbered">structure Tak =\r
24492 struct\r
24493 fun tak1 (x, y, z) =\r
24494 let\r
24495 fun tak2 (x, y, z) =\r
24496 if y &gt;= x\r
24497 then z\r
24498 else\r
24499 tak1 (tak2 (x - 1, y, z),\r
24500 tak2 (y - 1, z, x),\r
24501 tak2 (z - 1, x, y))\r
24502 in\r
24503 if y &gt;= x\r
24504 then z\r
24505 else\r
24506 tak1 (tak2 (x - 1, y, z),\r
24507 tak2 (y - 1, z, x),\r
24508 tak2 (z - 1, x, y))\r
24509 end\r
24510 end\r
24511\r
24512val rec f =\r
24513 fn 0 =&gt; ()\r
24514 | ~1 =&gt; print "this branch is not taken\n"\r
24515 | n =&gt; (Tak.tak1 (18, 12, 6) ; f (n-1))\r
24516\r
24517val _ = f 5000\r
24518\r
24519fun uncalled () = ()</programlisting>\r
24520<simpara>Compile with count profiling and run the program.</simpara>\r
24521<screen>% mlton -profile count -profile-branch true tak.sml\r
24522% ./tak</screen>\r
24523<simpara>Display the profiling data, along with raw counts and file positions.</simpara>\r
24524<screen>% mlprof -raw true -show-line true tak mlmon.out\r
24525623,610,002 ticks\r
24526 function cur raw\r
24527--------------------------------- ----- -------------\r
24528Tak.tak1.tak2 tak.sml: 5 38.2% (238,530,000)\r
24529Tak.tak1.tak2.&lt;true&gt; tak.sml: 7 27.5% (171,510,000)\r
24530Tak.tak1 tak.sml: 3 10.7% (67,025,000)\r
24531Tak.tak1.&lt;true&gt; tak.sml: 14 10.7% (67,025,000)\r
24532Tak.tak1.tak2.&lt;false&gt; tak.sml: 9 10.7% (67,020,000)\r
24533Tak.tak1.&lt;false&gt; tak.sml: 16 2.0% (12,490,000)\r
24534f tak.sml: 23 0.0% (5,001)\r
24535f.&lt;branch&gt; tak.sml: 25 0.0% (5,000)\r
24536f.&lt;branch&gt; tak.sml: 23 0.0% (1)\r
24537uncalled tak.sml: 29 0.0% (0)\r
24538f.&lt;branch&gt; tak.sml: 24 0.0% (0)</screen>\r
24539<simpara>Branches are displayed with lexical nesting followed by <literal>&lt;branch&gt;</literal>\r
24540where the function name would normally be, or <literal>&lt;true&gt;</literal> or <literal>&lt;false&gt;</literal>\r
24541for if-expressions. It is best to run <literal>mlprof</literal> with <literal>-show-line true</literal>\r
24542to help identify the branch.</simpara>\r
24543<simpara>One use of <literal>-profile count</literal> is as a code-coverage tool, to help find\r
24544code in your program that hasn&#8217;t been tested. For this reason,\r
24545<literal>mlprof</literal> displays functions and branches even if they have a count of\r
24546zero. As the above output shows, the branch on line 24 was never\r
24547taken and the function defined on line 29 was never called. To see\r
24548zero counts, it is best to run <literal>mlprof</literal> with <literal>-raw true</literal>, since some\r
24549code (e.g. the branch on line 23 above) will show up with <literal>0.0%</literal> but\r
24550may still have been executed and hence have a nonzero raw count.</simpara>\r
24551<simpara><?asciidoc-pagebreak?></simpara>\r
24552</section>\r
24553<section id="ProfilingTheStack">\r
24554<title>ProfilingTheStack</title>\r
24555<simpara>For all forms of <link linkend="Profiling">Profiling</link>, you can gather counts for all\r
24556functions on the stack, not just the currently executing function. To\r
24557do so, compile your program with <literal>-profile-stack true</literal>. For example,\r
24558suppose that <literal>list-rev.sml</literal> contains the following.</simpara>\r
24559<programlisting language="sml" linenumbering="unnumbered">fun append (l1, l2) =\r
24560 case l1 of\r
24561 [] =&gt; l2\r
24562 | x :: l1 =&gt; x :: append (l1, l2)\r
24563\r
24564fun rev l =\r
24565 case l of\r
24566 [] =&gt; []\r
24567 | x :: l =&gt; append (rev l, [x])\r
24568\r
24569val l = List.tabulate (1000, fn i =&gt; i)\r
24570val _ = 1 + hd (rev l)</programlisting>\r
24571<simpara>Compile with stack profiling and then run the program.</simpara>\r
24572<screen>% mlton -profile alloc -profile-stack true list-rev.sml\r
24573% ./list-rev</screen>\r
24574<simpara>Display the profiling data.</simpara>\r
24575<screen>% mlprof -show-line true list-rev mlmon.out\r
245766,030,136 bytes allocated (108,336 bytes by GC)\r
24577 function cur stack GC\r
24578----------------------- ----- ----- ----\r
24579append list-rev.sml: 1 97.6% 97.6% 1.4%\r
24580&lt;gc&gt; 1.8% 0.0% 1.8%\r
24581&lt;main&gt; 0.4% 98.2% 1.8%\r
24582rev list-rev.sml: 6 0.2% 97.6% 1.8%</screen>\r
24583<simpara>In the above table, we see that <literal>rev</literal>, defined on line 6 of\r
24584<literal>list-rev.sml</literal>, is only responsible for 0.2% of the allocation, but is\r
24585on the stack while 97.6% of the allocation is done by the user program\r
24586and while 1.8% of the allocation is done by the garbage collector.</simpara>\r
24587<simpara>The run-time performance impact of <literal>-profile-stack true</literal> can be\r
24588noticeable since there is some extra bookkeeping at every nontail call\r
24589and return.</simpara>\r
24590<simpara><?asciidoc-pagebreak?></simpara>\r
24591</section>\r
24592<section id="ProfilingTime">\r
24593<title>ProfilingTime</title>\r
24594<simpara>With MLton and <literal>mlprof</literal>, you can <link linkend="Profiling">profile</link> your program to\r
24595find out how much time is spent in each function over an entire run of\r
24596the program. To do so, compile your program with <literal>-profile time</literal>.\r
24597For example, suppose that <literal>tak.sml</literal> contains the following.</simpara>\r
24598<programlisting language="sml" linenumbering="unnumbered">structure Tak =\r
24599 struct\r
24600 fun tak1 (x, y, z) =\r
24601 let\r
24602 fun tak2 (x, y, z) =\r
24603 if y &gt;= x\r
24604 then z\r
24605 else\r
24606 tak1 (tak2 (x - 1, y, z),\r
24607 tak2 (y - 1, z, x),\r
24608 tak2 (z - 1, x, y))\r
24609 in\r
24610 if y &gt;= x\r
24611 then z\r
24612 else\r
24613 tak1 (tak2 (x - 1, y, z),\r
24614 tak2 (y - 1, z, x),\r
24615 tak2 (z - 1, x, y))\r
24616 end\r
24617 end\r
24618\r
24619val rec f =\r
24620 fn 0 =&gt; ()\r
24621 | ~1 =&gt; print "this branch is not taken\n"\r
24622 | n =&gt; (Tak.tak1 (18, 12, 6) ; f (n-1))\r
24623\r
24624val _ = f 5000\r
24625\r
24626fun uncalled () = ()</programlisting>\r
24627<simpara>Compile with time profiling and run the program.</simpara>\r
24628<screen>% mlton -profile time tak.sml\r
24629% ./tak</screen>\r
24630<simpara>Display the profiling data.</simpara>\r
24631<screen>% mlprof tak mlmon.out\r
246326.00 seconds of CPU time (0.00 seconds GC)\r
24633function cur\r
24634------------- -----\r
24635Tak.tak1.tak2 75.8%\r
24636Tak.tak1 24.2%</screen>\r
24637<simpara>This example shows how <literal>mlprof</literal> indicates lexical nesting: as a\r
24638sequence of period-separated names indicating the structures and\r
24639functions in which a function definition is nested. The profiling\r
24640data shows that roughly three-quarters of the time is spent in the\r
24641<literal>Tak.tak1.tak2</literal> function, while the rest is spent in <literal>Tak.tak1</literal>.</simpara>\r
24642<simpara>Display raw counts in addition to percentages with <literal>-raw true</literal>.</simpara>\r
24643<screen>% mlprof -raw true tak mlmon.out\r
246446.00 seconds of CPU time (0.00 seconds GC)\r
24645 function cur raw\r
24646------------- ----- -------\r
24647Tak.tak1.tak2 75.8% (4.55s)\r
24648Tak.tak1 24.2% (1.45s)</screen>\r
24649<simpara>Display the file name and line number for each function in addition to\r
24650its name with <literal>-show-line true</literal>.</simpara>\r
24651<screen>% mlprof -show-line true tak mlmon.out\r
246526.00 seconds of CPU time (0.00 seconds GC)\r
24653 function cur\r
24654------------------------- -----\r
24655Tak.tak1.tak2 tak.sml: 5 75.8%\r
24656Tak.tak1 tak.sml: 3 24.2%</screen>\r
24657<simpara>Time profiling is designed to have a very small performance impact.\r
24658However, in some cases there will be a run-time performance cost,\r
24659which may perturb the results. There is more likely to be an impact\r
24660with <literal>-codegen c</literal> than <literal>-codegen native</literal>.</simpara>\r
24661<simpara>You can also compile with <literal>-profile time -profile-branch true</literal> to find\r
24662out how much time is spent in each branch of a function; see\r
24663<link linkend="ProfilingCounts">ProfilingCounts</link> for more details on <literal>-profile-branch</literal>.</simpara>\r
24664<section id="_caveats_3">\r
24665<title>Caveats</title>\r
24666<simpara>With <literal>-profile time</literal>, use of the following in your program will cause\r
24667a run-time error, since they would interfere with the profiler signal\r
24668handler.</simpara>\r
24669<itemizedlist>\r
24670<listitem>\r
24671<simpara>\r
24672<literal>MLton.Itimer.set (MLton.Itimer.Prof, ...)</literal>\r
24673</simpara>\r
24674</listitem>\r
24675<listitem>\r
24676<simpara>\r
24677<literal>MLton.Signal.setHandler (MLton.Signal.prof, ...)</literal>\r
24678</simpara>\r
24679</listitem>\r
24680</itemizedlist>\r
24681<simpara>Also, because of the random sampling used to implement <literal>-profile\r
24682time</literal>, it is best to have a long running program (at least tens of\r
24683seconds) in order to get reasonable time</simpara>\r
24684<simpara><?asciidoc-pagebreak?></simpara>\r
24685</section>\r
24686</section>\r
24687<section id="Projects">\r
24688<title>Projects</title>\r
24689<simpara>We have lots of ideas for projects to improve MLton, many of which we\r
24690do not have time to implement, or at least haven&#8217;t started on yet.\r
24691Here is a list of some of those improvements, ranging from the easy (1\r
24692week) to the difficult (several months). If you have any interest in\r
24693working on one of these, or some other improvement to MLton not listed\r
24694here, please send mail to\r
24695<ulink url="mailto:MLton-devel@mlton.org"><literal>MLton-devel@mlton.org</literal></ulink>.</simpara>\r
24696<itemizedlist>\r
24697<listitem>\r
24698<simpara>\r
24699Port to new platform: Windows (native, not Cygwin or MinGW), &#8230;\r
24700</simpara>\r
24701</listitem>\r
24702<listitem>\r
24703<simpara>\r
24704Source-level debugger\r
24705</simpara>\r
24706</listitem>\r
24707<listitem>\r
24708<simpara>\r
24709Heap profiler\r
24710</simpara>\r
24711</listitem>\r
24712<listitem>\r
24713<simpara>\r
24714Interfaces to libraries: OpenGL, Gtk+, D-BUS, &#8230;\r
24715</simpara>\r
24716</listitem>\r
24717<listitem>\r
24718<simpara>\r
24719More libraries written in SML (see <ulink url="https://github.com/MLton/mltonlib"><literal>mltonlib</literal></ulink>)\r
24720</simpara>\r
24721</listitem>\r
24722<listitem>\r
24723<simpara>\r
24724Additional constant types: <literal>structure Real80: REAL</literal>, &#8230;\r
24725</simpara>\r
24726</listitem>\r
24727<listitem>\r
24728<simpara>\r
24729An IDE (possibly integrated with <link linkend="Eclipse">Eclipse</link>)\r
24730</simpara>\r
24731</listitem>\r
24732<listitem>\r
24733<simpara>\r
24734Port MLRISC and use for code generation\r
24735</simpara>\r
24736</listitem>\r
24737<listitem>\r
24738<simpara>\r
24739Optimizations\r
24740</simpara>\r
24741<itemizedlist>\r
24742<listitem>\r
24743<simpara>\r
24744Improved closure representation\r
24745</simpara>\r
24746<simpara>Right now, MLton&#8217;s closure conversion algorithm uses a simple flat closure to represent each function.</simpara>\r
24747<itemizedlist>\r
24748<listitem>\r
24749<simpara>\r
24750<ulink url="http://www.mlton.org/pipermail/mlton/2003-October/024570.html">http://www.mlton.org/pipermail/mlton/2003-October/024570.html</ulink>\r
24751</simpara>\r
24752</listitem>\r
24753<listitem>\r
24754<simpara>\r
24755<ulink url="http://www.mlton.org/pipermail/mlton-user/2007-July/001150.html">http://www.mlton.org/pipermail/mlton-user/2007-July/001150.html</ulink>\r
24756</simpara>\r
24757</listitem>\r
24758<listitem>\r
24759<simpara>\r
24760<link linkend="References_ShaoAppel94">ShaoAppel94</link>\r
24761</simpara>\r
24762</listitem>\r
24763</itemizedlist>\r
24764</listitem>\r
24765<listitem>\r
24766<simpara>\r
24767Elimination of array bounds checks in loops\r
24768</simpara>\r
24769</listitem>\r
24770<listitem>\r
24771<simpara>\r
24772Elimination of overflow checks on array index computations\r
24773</simpara>\r
24774</listitem>\r
24775<listitem>\r
24776<simpara>\r
24777Common-subexpression elimination of repeated array subscripts\r
24778</simpara>\r
24779</listitem>\r
24780<listitem>\r
24781<simpara>\r
24782Loop-invariant code motion, especially for tuple selects\r
24783</simpara>\r
24784</listitem>\r
24785<listitem>\r
24786<simpara>\r
24787Partial redundancy elimination\r
24788</simpara>\r
24789<itemizedlist>\r
24790<listitem>\r
24791<simpara>\r
24792<ulink url="http://www.mlton.org/pipermail/mlton/2006-April/028598.html">http://www.mlton.org/pipermail/mlton/2006-April/028598.html</ulink>\r
24793</simpara>\r
24794</listitem>\r
24795</itemizedlist>\r
24796</listitem>\r
24797<listitem>\r
24798<simpara>\r
24799Loop unrolling, especially for small loops\r
24800</simpara>\r
24801</listitem>\r
24802<listitem>\r
24803<simpara>\r
24804Auto-vectorization, for MMX/SSE/3DNow!/AltiVec (see the <ulink url="http://gcc.gnu.org/projects/tree-ssa/vectorization.html">work done on GCC</ulink>)\r
24805</simpara>\r
24806</listitem>\r
24807<listitem>\r
24808<simpara>\r
24809Optimize <literal>MLton_eq</literal>: pointer equality is necessarily false when one of the arguments is freshly allocated in the block\r
24810</simpara>\r
24811</listitem>\r
24812</itemizedlist>\r
24813</listitem>\r
24814<listitem>\r
24815<simpara>\r
24816Analyses\r
24817</simpara>\r
24818<itemizedlist>\r
24819<listitem>\r
24820<simpara>\r
24821Uncaught exception analysis\r
24822</simpara>\r
24823</listitem>\r
24824</itemizedlist>\r
24825</listitem>\r
24826</itemizedlist>\r
24827<simpara><?asciidoc-pagebreak?></simpara>\r
24828</section>\r
24829<section id="Pronounce">\r
24830<title>Pronounce</title>\r
24831<simpara>Here is <ulink url="guide/Pronounce.attachments/pronounce-mlton.mp3">how "MLton" sounds</ulink>.</simpara>\r
24832<simpara>"MLton" is pronounced in two syllables, with stress on the first\r
24833syllable. The first syllable sounds like the word <emphasis>mill</emphasis> (as in\r
24834"steel mill"), the second like the word <emphasis>tin</emphasis> (as in "cookie tin").</simpara>\r
24835<simpara><?asciidoc-pagebreak?></simpara>\r
24836</section>\r
24837<section id="PropertyList">\r
24838<title>PropertyList</title>\r
24839<simpara>A property list is a dictionary-like data structure into which\r
24840properties (name-value pairs) can be inserted and from which\r
24841properties can be looked up by name. The term comes from the Lisp\r
24842language, where every symbol has a property list for storing\r
24843information, and where the names are typically symbols and keys can be\r
24844any type of value.</simpara>\r
24845<simpara>Here is an SML signature for property lists such that for any type of\r
24846value a new property can be dynamically created to manipulate that\r
24847type of value in a property list.</simpara>\r
24848<programlisting language="sml" linenumbering="unnumbered">signature PROPERTY_LIST =\r
24849 sig\r
24850 type t\r
24851\r
24852 val new: unit -&gt; t\r
24853 val newProperty: unit -&gt; {add: t * 'a -&gt; unit,\r
24854 peek: t -&gt; 'a option}\r
24855 end</programlisting>\r
24856<simpara>Here is a functor demonstrating the use of property lists. It first\r
24857creates a property list, then two new properties (of different types),\r
24858and adds a value to the list for each property.</simpara>\r
24859<programlisting language="sml" linenumbering="unnumbered">functor Test (P: PROPERTY_LIST) =\r
24860 struct\r
24861 val pl = P.new ()\r
24862\r
24863 val {add = addInt: P.t * int -&gt; unit, peek = peekInt} = P.newProperty ()\r
24864 val {add = addReal: P.t * real -&gt; unit, peek = peekReal} = P.newProperty ()\r
24865\r
24866 val () = addInt (pl, 13)\r
24867 val () = addReal (pl, 17.0)\r
24868 val s1 = Int.toString (valOf (peekInt pl))\r
24869 val s2 = Real.toString (valOf (peekReal pl))\r
24870 val () = print (concat [s1, " ", s2, "\n"])\r
24871 end</programlisting>\r
24872<simpara>Applied to an appropriate implementation <literal>PROPERTY_LIST</literal>, the <literal>Test</literal>\r
24873functor will produce the following output.</simpara>\r
24874<screen>13 17.0</screen>\r
24875<section id="_implementation_50">\r
24876<title>Implementation</title>\r
24877<simpara>Because property lists can hold values of any type, their\r
24878implementation requires a <link linkend="UniversalType">UniversalType</link>. Given that, a property\r
24879list is simply a list of elements of the universal type. Adding a\r
24880property adds to the front of the list, and looking up a property\r
24881scans the list.</simpara>\r
24882<programlisting language="sml" linenumbering="unnumbered">functor PropertyList (U: UNIVERSAL_TYPE): PROPERTY_LIST =\r
24883 struct\r
24884 datatype t = T of U.t list ref\r
24885\r
24886 fun new () = T (ref [])\r
24887\r
24888 fun 'a newProperty () =\r
24889 let\r
24890 val (inject, out) = U.embed ()\r
24891 fun add (T r, a: 'a): unit = r := inject a :: (!r)\r
24892 fun peek (T r) =\r
24893 Option.map (valOf o out) (List.find (isSome o out) (!r))\r
24894 in\r
24895 {add = add, peek = peek}\r
24896 end\r
24897 end</programlisting>\r
24898<simpara>If <literal>U: UNIVERSAL_TYPE</literal>, then we can test our code as follows.</simpara>\r
24899<programlisting language="sml" linenumbering="unnumbered">structure Z = Test (PropertyList (U))</programlisting>\r
24900<simpara>Of course, a serious implementation of property lists would have to\r
24901handle duplicate insertions of the same property, as well as the\r
24902removal of elements in order to avoid space leaks.</simpara>\r
24903</section>\r
24904<section id="_also_see_29">\r
24905<title>Also see</title>\r
24906<itemizedlist>\r
24907<listitem>\r
24908<simpara>\r
24909MLton relies heavily on property lists for attaching information to\r
24910syntax tree nodes in its intermediate languages. See\r
24911<ulink url="https://github.com/MLton/mlton/blob/master/lib/mlton/basic/property-list.sig"><literal>property-list.sig</literal></ulink> and\r
24912<ulink url="https://github.com/MLton/mlton/blob/master/lib/mlton/basic/property-list.fun"><literal>property-list.fun</literal></ulink>.\r
24913</simpara>\r
24914</listitem>\r
24915<listitem>\r
24916<simpara>\r
24917The <link linkend="MLRISCLibrary">MLRISCLibrary</link> <link linkend="References_LeungGeorge99">uses property lists extensively</link>.\r
24918</simpara>\r
24919</listitem>\r
24920</itemizedlist>\r
24921<simpara><?asciidoc-pagebreak?></simpara>\r
24922</section>\r
24923</section>\r
24924<section id="Pygments">\r
24925<title>Pygments</title>\r
24926<simpara><ulink url="http://pygments.org/">Pygments</ulink> is a generic syntax highlighter. Here is a <emphasis>lexer</emphasis> for highlighting\r
24927<link linkend="StandardML">Standard ML</link>.</simpara>\r
24928<itemizedlist>\r
24929<listitem>\r
24930<simpara>\r
24931<ulink url="https://github.com/MLton/mlton/tree/master/ide/pygments/sml_lexer"><literal>sml_lexer</literal></ulink>&#8201;&#8212;&#8201;Provides highlighting of keywords, special constants, and (nested) comments.\r
24932</simpara>\r
24933</listitem>\r
24934</itemizedlist>\r
24935<section id="_install_and_use_2">\r
24936<title>Install and use</title>\r
24937<itemizedlist>\r
24938<listitem>\r
24939<simpara>\r
24940Checkout all files and install as a <ulink url="http://pygments.org/">Pygments</ulink> plugin.\r
24941</simpara>\r
24942<screen>$ git clone https://github.com/MLton/mlton.git mlton\r
24943$ cd mlton/ide/pygments\r
24944$ python setup.py install</screen>\r
24945</listitem>\r
24946<listitem>\r
24947<simpara>\r
24948Invoke <literal>pygmentize</literal> with <literal>-l sml</literal>.\r
24949</simpara>\r
24950</listitem>\r
24951</itemizedlist>\r
24952</section>\r
24953<section id="_feedback_2">\r
24954<title>Feedback</title>\r
24955<simpara>Comments and suggestions should be directed to <link linkend="MatthewFluet">MatthewFluet</link>.</simpara>\r
24956<simpara><?asciidoc-pagebreak?></simpara>\r
24957</section>\r
24958</section>\r
24959<section id="RayRacine">\r
24960<title>RayRacine</title>\r
24961<simpara>Using SML in some <emphasis>Semantic Web</emphasis> stuff. Anyone interested in\r
24962similar, please contact me. GreyLensman on #sml on IRC or rracine at\r
24963this domain adelphia with a dot here net.</simpara>\r
24964<simpara>Current areas of coding.</simpara>\r
24965<orderedlist numeration="arabic">\r
24966<listitem>\r
24967<simpara>\r
24968Pretty solid, high performance Rete implementation - base functionality is complete.\r
24969</simpara>\r
24970</listitem>\r
24971<listitem>\r
24972<simpara>\r
24973N3 parser - mostly complete\r
24974</simpara>\r
24975</listitem>\r
24976<listitem>\r
24977<simpara>\r
24978RDF parser based on fxg - not started.\r
24979</simpara>\r
24980</listitem>\r
24981<listitem>\r
24982<simpara>\r
24983Swerve HTTP server - 1/2 done.\r
24984</simpara>\r
24985</listitem>\r
24986<listitem>\r
24987<simpara>\r
24988SPARQL implementation - not started.\r
24989</simpara>\r
24990</listitem>\r
24991<listitem>\r
24992<simpara>\r
24993Persistent engine based on BerkelyDB - not started.\r
24994</simpara>\r
24995</listitem>\r
24996<listitem>\r
24997<simpara>\r
24998Native implementation of Postgresql protocol - underway, ways to go.\r
24999</simpara>\r
25000</listitem>\r
25001<listitem>\r
25002<simpara>\r
25003I also have a small change to the MLton compiler to add <literal>PackWord<emphasis>&lt;N&gt;</emphasis></literal> - changes compile but needs some more work, clean-up and unit tests.\r
25004</simpara>\r
25005</listitem>\r
25006</orderedlist>\r
25007<simpara><?asciidoc-pagebreak?></simpara>\r
25008</section>\r
25009<section id="Reachability">\r
25010<title>Reachability</title>\r
25011<simpara>Reachability is a notion dealing with the graph of heap objects\r
25012maintained at runtime. Nodes in the graph are heap objects and edges\r
25013correspond to the pointers between heap objects. As the program runs,\r
25014it allocates new objects (adds nodes to the graph), and those new\r
25015objects can contain pointers to other objects (new edges in the\r
25016graph). If the program uses mutable objects (refs or arrays), it can\r
25017also change edges in the graph.</simpara>\r
25018<simpara>At any time, the program has access to some finite set of <emphasis>root</emphasis>\r
25019nodes, and can only ever access nodes that are reachable by following\r
25020edges from these root nodes. Nodes that are <emphasis>unreachable</emphasis> can be\r
25021garbage collected.</simpara>\r
25022<section id="_also_see_30">\r
25023<title>Also see</title>\r
25024<itemizedlist>\r
25025<listitem>\r
25026<simpara>\r
25027<link linkend="MLtonFinalizable">MLtonFinalizable</link>\r
25028</simpara>\r
25029</listitem>\r
25030<listitem>\r
25031<simpara>\r
25032<link linkend="MLtonWeak">MLtonWeak</link>\r
25033</simpara>\r
25034</listitem>\r
25035</itemizedlist>\r
25036<simpara><?asciidoc-pagebreak?></simpara>\r
25037</section>\r
25038</section>\r
25039<section id="Redundant">\r
25040<title>Redundant</title>\r
25041<simpara><link linkend="Redundant">Redundant</link> is an optimization pass for the <link linkend="SSA">SSA</link>\r
25042<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="SSASimplify">SSASimplify</link>.</simpara>\r
25043<section id="_description_46">\r
25044<title>Description</title>\r
25045<simpara>The redundant SSA optimization eliminates redundant function and label\r
25046arguments; an argument of a function or label is redundant if it is\r
25047always the same as another argument of the same function or label.\r
25048The analysis finds an equivalence relation on the arguments of a\r
25049function or label, such that all arguments in an equivalence class are\r
25050redundant with respect to the other arguments in the equivalence\r
25051class; the transformation selects one representative of each\r
25052equivalence class and drops the binding occurrence of\r
25053non-representative variables and renames use occurrences of the\r
25054non-representative variables to the representative variable. The\r
25055analysis finds the equivalence classes via a fixed-point analysis.\r
25056Each vector of arguments to a function or label is initialized to\r
25057equivalence classes that equate all arguments of the same type; one\r
25058could start with an equivalence class that equates all arguments, but\r
25059arguments of different type cannot be redundant. Variables bound in\r
25060statements are initialized to singleton equivalence classes. The\r
25061fixed-point analysis repeatedly refines these equivalence classes on\r
25062the formals by the equivalence classes of the actuals.</simpara>\r
25063</section>\r
25064<section id="_implementation_51">\r
25065<title>Implementation</title>\r
25066<itemizedlist>\r
25067<listitem>\r
25068<simpara>\r
25069<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/redundant.fun"><literal>redundant.fun</literal></ulink>\r
25070</simpara>\r
25071</listitem>\r
25072</itemizedlist>\r
25073</section>\r
25074<section id="_details_and_notes_49">\r
25075<title>Details and Notes</title>\r
25076<simpara>The reason <link linkend="Redundant">Redundant</link> got put in was due to some output of the\r
25077<link linkend="ClosureConvert">ClosureConvert</link> pass converter where the environment record, or\r
25078components of it, were passed around in several places. That may have\r
25079been more relevant with polyvariant analyses (which are long gone).\r
25080But it still seems possibly relevant, especially with more aggressive\r
25081flattening, which should reveal some fields in nested closure records\r
25082that are redundant.</simpara>\r
25083<simpara><?asciidoc-pagebreak?></simpara>\r
25084</section>\r
25085</section>\r
25086<section id="RedundantTests">\r
25087<title>RedundantTests</title>\r
25088<simpara><link linkend="RedundantTests">RedundantTests</link> is an optimization pass for the <link linkend="SSA">SSA</link>\r
25089<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="SSASimplify">SSASimplify</link>.</simpara>\r
25090<section id="_description_47">\r
25091<title>Description</title>\r
25092<simpara>This pass simplifies conditionals whose results are implied by a\r
25093previous conditional test.</simpara>\r
25094</section>\r
25095<section id="_implementation_52">\r
25096<title>Implementation</title>\r
25097<itemizedlist>\r
25098<listitem>\r
25099<simpara>\r
25100<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/redundant-tests.fun"><literal>redundant-tests.fun</literal></ulink>\r
25101</simpara>\r
25102</listitem>\r
25103</itemizedlist>\r
25104</section>\r
25105<section id="_details_and_notes_50">\r
25106<title>Details and Notes</title>\r
25107<simpara>An additional test will sometimes eliminate the overflow test when\r
25108adding or subtracting 1. In particular, it will eliminate it in the\r
25109following cases:</simpara>\r
25110<programlisting language="sml" linenumbering="unnumbered">if x &lt; y\r
25111 then ... x + 1 ...\r
25112else ... y - 1 ...</programlisting>\r
25113<simpara><?asciidoc-pagebreak?></simpara>\r
25114</section>\r
25115</section>\r
25116<section id="References">\r
25117<title>References</title>\r
25118<simpara><link linkend="References_AAA">A</link>\r
25119<link linkend="References_BBB">B</link>\r
25120<link linkend="References_CCC">C</link>\r
25121<link linkend="References_DDD">D</link>\r
25122<link linkend="References_EEE">E</link>\r
25123<link linkend="References_FFF">F</link>\r
25124<link linkend="References_GGG">G</link>\r
25125<link linkend="References_HHH">H</link>\r
25126<link linkend="References_III">I</link>\r
25127<link linkend="References_JJJ">J</link>\r
25128<link linkend="References_KKK">K</link>\r
25129<link linkend="References_LLL">L</link>\r
25130<link linkend="References_MMM">M</link>\r
25131<link linkend="References_NNN">N</link>\r
25132<link linkend="References_OOO">O</link>\r
25133<link linkend="References_PPP">P</link>\r
25134<link linkend="References_QQQ">Q</link>\r
25135<link linkend="References_RRR">R</link>\r
25136<link linkend="References_SSS">S</link>\r
25137<link linkend="References_TTT">T</link>\r
25138<link linkend="References_UUU">U</link>\r
25139<link linkend="References_VVV">V</link>\r
25140<link linkend="References_WWW">W</link>\r
25141<link linkend="References_XXX">X</link>\r
25142<link linkend="References_YYY">Y</link>\r
25143<link linkend="References_ZZZ">Z</link></simpara>\r
25144<section id="_anchor_id_references_aaa_xreflabel_references_aaa_a">\r
25145<title><anchor id="References_AAA" xreflabel="[References_AAA]"/>A</title>\r
25146<itemizedlist>\r
25147<listitem>\r
25148<simpara>\r
25149<anchor id="References_AcarEtAl06" xreflabel="[References_AcarEtAl06]"/>\r
25150 <ulink url="http://www.umut-acar.org/publications/pldi2006.pdf">An Experimental Analysis of Self-Adjusting Computation</ulink>\r
25151 Umut Acar, Guy Blelloch, Matthias Blume, and Kanat Tangwongsan.\r
25152 <link linkend="References_PLDI">PLDI</link> 2006.\r
25153</simpara>\r
25154</listitem>\r
25155<listitem>\r
25156<simpara>\r
25157<anchor id="References_Appel92" xreflabel="[References_Appel92]"/>\r
25158 <ulink url="http://us.cambridge.org/titles/catalogue.asp?isbn=0521416957">Compiling with Continuations</ulink>\r
25159 (<ulink url="http://www.addall.com/New/submitNew.cgi?query=0-521-41695-7&amp;type=ISBN&amp;location=10000&amp;state=&amp;dispCurr=USD">addall</ulink>).\r
25160 ISBN 0521416957.\r
25161 Andrew W. Appel.\r
25162 Cambridge University Press, 1992.\r
25163</simpara>\r
25164</listitem>\r
25165<listitem>\r
25166<simpara>\r
25167<anchor id="References_Appel93" xreflabel="[References_Appel93]"/>\r
25168 <ulink url="http://www.cs.princeton.edu/research/techreps/TR-364-92">A Critique of Standard ML</ulink>.\r
25169 Andrew W. Appel.\r
25170 <link linkend="References_JFP">JFP</link> 1993.\r
25171</simpara>\r
25172</listitem>\r
25173<listitem>\r
25174<simpara>\r
25175<anchor id="References_Appel98" xreflabel="[References_Appel98]"/>\r
25176 <ulink url="http://us.cambridge.org/titles/catalogue.asp?isbn=0521582741">Modern Compiler Implementation in ML</ulink>\r
25177 (<ulink url="http://www.addall.com/New/submitNew.cgi?query=0-521-58274-1&amp;type=ISBN&amp;location=10000&amp;state=&amp;dispCurr=USD">addall</ulink>).\r
25178 ISBN 0521582741\r
25179 Andrew W. Appel.\r
25180 Cambridge University Press, 1998.\r
25181</simpara>\r
25182</listitem>\r
25183<listitem>\r
25184<simpara>\r
25185<anchor id="References_AppelJim97" xreflabel="[References_AppelJim97]"/>\r
25186 <ulink url="http://ncstrl.cs.princeton.edu/expand.php?id=TR-556-97">Shrinking Lambda Expressions in Linear Time</ulink>\r
25187 Andrew Appel and Trevor Jim.\r
25188 <link linkend="References_JFP">JFP</link> 1997.\r
25189</simpara>\r
25190</listitem>\r
25191<listitem>\r
25192<simpara>\r
25193<anchor id="References_AppelEtAl94" xreflabel="[References_AppelEtAl94]"/>\r
25194 <ulink url="http://www.smlnj.org/doc/ML-Lex/manual.html">A lexical analyzer generator for Standard ML. Version 1.6.0</ulink>\r
25195 Andrew W. Appel, James S. Mattson, and David R. Tarditi. 1994\r
25196</simpara>\r
25197</listitem>\r
25198</itemizedlist>\r
25199</section>\r
25200<section id="_anchor_id_references_bbb_xreflabel_references_bbb_b">\r
25201<title><anchor id="References_BBB" xreflabel="[References_BBB]"/>B</title>\r
25202<itemizedlist>\r
25203<listitem>\r
25204<simpara>\r
25205<anchor id="References_BaudinetMacQueen85" xreflabel="[References_BaudinetMacQueen85]"/>\r
25206 <ulink url="http://www.classes.cs.uchicago.edu/archive/2011/spring/22620-1/papers/macqueen-baudinet85.pdf">Tree Pattern Matching for ML</ulink>.\r
25207 Marianne Baudinet, David MacQueen. 1985.\r
25208</simpara>\r
25209<blockquote>\r
25210<simpara>Describes the match compiler used in an early version of\r
25211<link linkend="SMLNJ">SML/NJ</link>.</simpara>\r
25212</blockquote>\r
25213</listitem>\r
25214<listitem>\r
25215<simpara>\r
25216<anchor id="References_BentonEtAl98" xreflabel="[References_BentonEtAl98]"/>\r
25217 <ulink url="http://research.microsoft.com/en-us/um/people/nick/icfp98.pdf">Compiling Standard ML to Java Bytecodes</ulink>.\r
25218 Nick Benton, Andrew Kennedy, and George Russell.\r
25219 <link linkend="References_ICFP">ICFP</link> 1998.\r
25220</simpara>\r
25221</listitem>\r
25222<listitem>\r
25223<simpara>\r
25224<anchor id="References_BentonKennedy99" xreflabel="[References_BentonKennedy99]"/>\r
25225 <ulink url="http://research.microsoft.com/en-us/um/people/nick/SMLJavaInterop.pdf">Interlanguage Working Without Tears: Blending SML with Java</ulink>.\r
25226 Nick Benton and Andrew Kennedy.\r
25227 <link linkend="References_ICFP">ICFP</link> 1999.\r
25228</simpara>\r
25229</listitem>\r
25230<listitem>\r
25231<simpara>\r
25232<anchor id="References_BentonKennedy01" xreflabel="[References_BentonKennedy01]"/>\r
25233 <ulink url="http://research.microsoft.com/en-us/um/people/akenn/sml/ExceptionalSyntax.pdf">Exceptional Syntax</ulink>.\r
25234 Nick Benton and Andrew Kennedy.\r
25235 <link linkend="References_JFP">JFP</link> 2001.\r
25236</simpara>\r
25237</listitem>\r
25238<listitem>\r
25239<simpara>\r
25240<anchor id="References_BentonEtAl04" xreflabel="[References_BentonEtAl04]"/>\r
25241 <ulink url="http://research.microsoft.com/en-us/um/people/nick/p53-Benton.pdf">Adventures in Interoperability: The SML.NET Experience</ulink>.\r
25242 Nick Benton, Andrew Kennedy, and Claudio Russo.\r
25243 <link linkend="References_PPDP">PPDP</link> 2004.\r
25244</simpara>\r
25245</listitem>\r
25246<listitem>\r
25247<simpara>\r
25248<anchor id="References_BentonEtAl04_2" xreflabel="[References_BentonEtAl04_2]"/>\r
25249 <ulink url="http://research.microsoft.com/en-us/um/people/nick/shrinking.pdf">Shrinking Reductions in SML.NET</ulink>.\r
25250 Nick Benton, Andrew Kennedy, Sam Lindley and Claudio Russo.\r
25251 <link linkend="References_IFL">IFL</link> 2004.\r
25252</simpara>\r
25253<blockquote>\r
25254<simpara>Describes a linear-time implementation of an\r
25255<link linkend="References_AppelJim97">Appel-Jim shrinker</link>, using a mutable IL, and shows\r
25256that it yields nice speedups in SML.NET&#8217;s compile times. There are\r
25257also benchmarks showing that SML.NET when compiled by MLton runs\r
25258roughly five times faster than when compiled by SML/NJ.</simpara>\r
25259</blockquote>\r
25260</listitem>\r
25261<listitem>\r
25262<simpara>\r
25263<anchor id="References_Benton05" xreflabel="[References_Benton05]"/>\r
25264 <ulink url="http://research.microsoft.com/en-us/um/people/nick/benton03.pdf">Embedded Interpreters</ulink>.\r
25265 Nick Benton.\r
25266 <link linkend="References_JFP">JFP</link> 2005.\r
25267</simpara>\r
25268</listitem>\r
25269<listitem>\r
25270<simpara>\r
25271<anchor id="References_Berry91" xreflabel="[References_Berry91]"/>\r
25272 <ulink url="http://www.lfcs.inf.ed.ac.uk/reports/91/ECS-LFCS-91-148/ECS-LFCS-91-148.pdf">The Edinburgh SML Library</ulink>.\r
25273 Dave Berry.\r
25274 University of Edinburgh Technical Report ECS-LFCS-91-148, 1991.\r
25275</simpara>\r
25276</listitem>\r
25277<listitem>\r
25278<simpara>\r
25279<anchor id="References_BerryEtAl93" xreflabel="[References_BerryEtAl93]"/>\r
25280 <ulink url="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.36.7958&amp;rep=rep1&amp;type=ps">A semantics for ML concurrency primitives</ulink>.\r
25281 Dave Berry, Robin Milner, and David N. Turner.\r
25282 <link linkend="References_POPL">POPL</link> 1992.\r
25283</simpara>\r
25284</listitem>\r
25285<listitem>\r
25286<simpara>\r
25287<anchor id="References_Berry93" xreflabel="[References_Berry93]"/>\r
25288 <ulink url="http://journals.cambridge.org/abstract_S0956796800000873">Lessons From the Design of a Standard ML Library</ulink>.\r
25289 Dave Berry.\r
25290 <link linkend="References_JFP">JFP</link> 1993.\r
25291</simpara>\r
25292</listitem>\r
25293<listitem>\r
25294<simpara>\r
25295<anchor id="References_Bertelsen98" xreflabel="[References_Bertelsen98]"/>\r
25296 <ulink url="http://www.petermb.dk/sml2jvm.ps.gz">Compiling SML to Java Bytecode</ulink>.\r
25297 Peter Bertelsen.\r
25298 Master&#8217;s Thesis, 1998.\r
25299</simpara>\r
25300</listitem>\r
25301<listitem>\r
25302<simpara>\r
25303<anchor id="References_Berthomieu00" xreflabel="[References_Berthomieu00]"/>\r
25304 <ulink url="http://homepages.laas.fr/bernard/oo/ooml.html">OO Programming styles in ML</ulink>.\r
25305 Bernard Berthomieu.\r
25306 LAAS Report #2000111, 2000.\r
25307</simpara>\r
25308</listitem>\r
25309<listitem>\r
25310<simpara>\r
25311<anchor id="References_Blume01" xreflabel="[References_Blume01]"/>\r
25312 <ulink url="http://people.cs.uchicago.edu/~blume/papers/nlffi-entcs.pdf">No-Longer-Foreign: Teaching an ML compiler to speak C "natively"</ulink>.\r
25313 Matthias Blume.\r
25314 <link linkend="References_BABEL">BABEL</link> 2001.\r
25315</simpara>\r
25316</listitem>\r
25317<listitem>\r
25318<simpara>\r
25319<anchor id="References_Blume01_02" xreflabel="[References_Blume01_02]"/>\r
25320 <ulink url="http://people.cs.uchicago.edu/~blume/pgraph/proposal.pdf">Portable library descriptions for Standard ML</ulink>.\r
25321 Matthias Blume. 2001.\r
25322</simpara>\r
25323</listitem>\r
25324<listitem>\r
25325<simpara>\r
25326<anchor id="References_Boehm03" xreflabel="[References_Boehm03]"/>\r
25327 <ulink url="http://www.hpl.hp.com/techreports/2002/HPL-2002-335.html">Destructors, Finalizers, and Synchronization</ulink>.\r
25328 Hans Boehm.\r
25329 <link linkend="References_POPL">POPL</link> 2003.\r
25330</simpara>\r
25331<blockquote>\r
25332<simpara>Discusses a number of issues in the design of finalizers. Many of the\r
25333design choices are consistent with <link linkend="MLtonFinalizable">MLtonFinalizable</link>.</simpara>\r
25334</blockquote>\r
25335</listitem>\r
25336</itemizedlist>\r
25337</section>\r
25338<section id="_anchor_id_references_ccc_xreflabel_references_ccc_c">\r
25339<title><anchor id="References_CCC" xreflabel="[References_CCC]"/>C</title>\r
25340<itemizedlist>\r
25341<listitem>\r
25342<simpara>\r
25343<anchor id="References_CejtinEtAl00" xreflabel="[References_CejtinEtAl00]"/>\r
25344 <ulink url="http://www.cs.purdue.edu/homes/suresh/papers/icfp99.ps.gz">Flow-directed Closure Conversion for Typed Languages</ulink>.\r
25345 Henry Cejtin, Suresh Jagannathan, and Stephen Weeks.\r
25346 <link linkend="References_ESOP">ESOP</link> 2000.\r
25347</simpara>\r
25348<blockquote>\r
25349<simpara>Describes MLton&#8217;s closure-conversion algorithm, which translates from\r
25350its simply-typed higher-order intermediate language to its\r
25351simply-typed first-order intermediate language.</simpara>\r
25352</blockquote>\r
25353</listitem>\r
25354<listitem>\r
25355<simpara>\r
25356<anchor id="References_ChengBlelloch01" xreflabel="[References_ChengBlelloch01]"/>\r
25357 <ulink url="http://www.cs.cmu.edu/afs/cs/project/pscico/pscico/papers/gc01/pldi-final.pdf">A Parallel, Real-Time Garbage Collector</ulink>.\r
25358 Perry Cheng and Guy E. Blelloch.\r
25359 <link linkend="References_PLDI">PLDI</link> 2001.\r
25360</simpara>\r
25361</listitem>\r
25362<listitem>\r
25363<simpara>\r
25364<anchor id="References_Claessen00" xreflabel="[References_Claessen00]"/>\r
25365 <ulink url="http://users.eecs.northwestern.edu/~robby/courses/395-495-2009-fall/quick.pdf">QuickCheck: A Lightweight Tool for Random Testing of Haskell Programs</ulink>.\r
25366 Koen Claessen and John Hughes.\r
25367 <link linkend="References_ICFP">ICFP</link> 2000.\r
25368</simpara>\r
25369</listitem>\r
25370<listitem>\r
25371<simpara>\r
25372<anchor id="References_Clinger98" xreflabel="[References_Clinger98]"/>\r
25373 <ulink url="http://www.cesura17.net/~will/Professional/Research/Papers/tail.pdf">Proper Tail Recursion and Space Efficiency</ulink>.\r
25374 William D. Clinger.\r
25375 <link linkend="References_PLDI">PLDI</link> 1998.\r
25376</simpara>\r
25377</listitem>\r
25378<listitem>\r
25379<simpara>\r
25380<anchor id="References_CooperMorrisett90" xreflabel="[References_CooperMorrisett90]"/>\r
25381 <ulink url="http://www.eecs.harvard.edu/~greg/papers/jgmorris-mlthreads.ps">Adding Threads to Standard ML</ulink>.\r
25382 Eric C. Cooper and J. Gregory Morrisett.\r
25383 CMU Technical Report CMU-CS-90-186, 1990.\r
25384</simpara>\r
25385</listitem>\r
25386<listitem>\r
25387<simpara>\r
25388<anchor id="References_CouttsEtAl07" xreflabel="[References_CouttsEtAl07]"/>\r
25389 <ulink url="http://metagraph.org/papers/stream_fusion.pdf">Stream Fusion: From Lists to Streams to Nothing at All</ulink>.\r
25390 Duncan Coutts, Roman Leshchinskiy, and Don Stewart.\r
25391 Submitted for publication. April 2007.\r
25392</simpara>\r
25393</listitem>\r
25394</itemizedlist>\r
25395</section>\r
25396<section id="_anchor_id_references_ddd_xreflabel_references_ddd_d">\r
25397<title><anchor id="References_DDD" xreflabel="[References_DDD]"/>D</title>\r
25398<itemizedlist>\r
25399<listitem>\r
25400<simpara>\r
25401<anchor id="References_DamasMilner82" xreflabel="[References_DamasMilner82]"/>\r
25402 <ulink url="http://groups.csail.mit.edu/pag/6.883/readings/p207-damas.pdf">Principal Type-Schemes for Functional Programs</ulink>.\r
25403 Luis Damas and Robin Milner.\r
25404 <link linkend="References_POPL">POPL</link> 1982.\r
25405</simpara>\r
25406</listitem>\r
25407<listitem>\r
25408<simpara>\r
25409<anchor id="References_Danvy98" xreflabel="[References_Danvy98]"/>\r
25410 <ulink url="http://www.brics.dk/RS/98/12">Functional Unparsing</ulink>.\r
25411 Olivier Danvy.\r
25412 BRICS Technical Report RS 98-12, 1998.\r
25413</simpara>\r
25414</listitem>\r
25415<listitem>\r
25416<simpara>\r
25417<anchor id="References_Deboer05" xreflabel="[References_Deboer05]"/>\r
25418 <ulink url="http://alleystoughton.us/eXene/dusty-thesis.pdf">Exhancements to eXene</ulink>.\r
25419 Dustin B. deBoer.\r
25420 Master of Science Thesis, 2005.\r
25421</simpara>\r
25422<blockquote>\r
25423<simpara>Describes ways to improve widget concurrency, handling of input focus,\r
25424X resources and selections.</simpara>\r
25425</blockquote>\r
25426</listitem>\r
25427<listitem>\r
25428<simpara>\r
25429<anchor id="References_DoligezLeroy93" xreflabel="[References_DoligezLeroy93]"/>\r
25430 <ulink url="http://cristal.inria.fr/~doligez/publications/doligez-leroy-popl-1993.pdf">A Concurrent, Generational Garbage Collector for a Multithreaded Implementation of ML</ulink>.\r
25431 Damien Doligez and Xavier Leroy.\r
25432 <link linkend="References_POPL">POPL</link> 1993.\r
25433</simpara>\r
25434</listitem>\r
25435<listitem>\r
25436<simpara>\r
25437<anchor id="References_Dreyer07" xreflabel="[References_Dreyer07]"/>\r
25438 <ulink url="http://www.mpi-sws.org/~dreyer/papers/mtc/main-long.pdf">Modular Type Classes</ulink>.\r
25439 Derek Dreyer, Robert Harper, Manuel M.T. Chakravarty, Gabriele Keller.\r
25440 University of Chicago Technical Report TR-2007-02, 2006.\r
25441</simpara>\r
25442</listitem>\r
25443<listitem>\r
25444<simpara>\r
25445<anchor id="References_DreyerBlume07" xreflabel="[References_DreyerBlume07]"/>\r
25446 <ulink url="http://www.mpi-sws.org/~dreyer/papers/infmod/main-long.pdf">Principal Type Schemes for Modular Programs</ulink>.\r
25447 Derek Dreyer and Matthias Blume.\r
25448 <link linkend="References_ESOP">ESOP</link> 2007.\r
25449</simpara>\r
25450</listitem>\r
25451<listitem>\r
25452<simpara>\r
25453<anchor id="References_Dubois95" xreflabel="[References_Dubois95]"/>\r
25454 <ulink url="ftp://ftp.inria.fr/INRIA/Projects/cristal/Francois.Rouaix/generics.dvi.Z">Extensional Polymorphism</ulink>.\r
25455 Catherin Dubois, Francois Rouaix, and Pierre Weis.\r
25456 <link linkend="References_POPL">POPL</link> 1995.\r
25457</simpara>\r
25458<blockquote>\r
25459<simpara>An extension of ML that allows the definition of ad-hoc polymorphic\r
25460functions by inspecting the type of their argument.</simpara>\r
25461</blockquote>\r
25462</listitem>\r
25463</itemizedlist>\r
25464</section>\r
25465<section id="_anchor_id_references_eee_xreflabel_references_eee_e">\r
25466<title><anchor id="References_EEE" xreflabel="[References_EEE]"/>E</title>\r
25467<itemizedlist>\r
25468<listitem>\r
25469<simpara>\r
25470<anchor id="References_Elsman03" xreflabel="[References_Elsman03]"/>\r
25471 <ulink url="http://www.elsman.com/tldi03.pdf">Garbage Collection Safety for Region-based Memory Management</ulink>.\r
25472 Martin Elsman.\r
25473 <link linkend="References_TLDI">TLDI</link> 2003.\r
25474</simpara>\r
25475</listitem>\r
25476<listitem>\r
25477<simpara>\r
25478<anchor id="References_Elsman04" xreflabel="[References_Elsman04]"/>\r
25479 <ulink url="http://www.elsman.com/ITU-TR-2004-43.pdf">Type-Specialized Serialization with Sharing</ulink>.\r
25480 Martin Elsman. University of Copenhagen. IT University Technical\r
25481 Report TR-2004-43, 2004.\r
25482</simpara>\r
25483</listitem>\r
25484</itemizedlist>\r
25485</section>\r
25486<section id="_anchor_id_references_fff_xreflabel_references_fff_f">\r
25487<title><anchor id="References_FFF" xreflabel="[References_FFF]"/>F</title>\r
25488<itemizedlist>\r
25489<listitem>\r
25490<simpara>\r
25491<anchor id="References_FelleisenFreidman98" xreflabel="[References_FelleisenFreidman98]"/>\r
25492 <ulink url="http://mitpress.mit.edu/catalog/item/default.asp?ttype=2&amp;tid=4787">The Little MLer</ulink>\r
25493 (<ulink url="http://www3.addall.com/New/submitNew.cgi?query=026256114X&amp;type=ISBN">addall</ulink>).\r
25494 ISBN 026256114X.\r
25495 Matthias Felleisen and Dan Freidman.\r
25496 The MIT Press, 1998.\r
25497</simpara>\r
25498</listitem>\r
25499<listitem>\r
25500<simpara>\r
25501<anchor id="References_FlattFindler04" xreflabel="[References_FlattFindler04]"/>\r
25502 <ulink url="http://www.cs.utah.edu/plt/kill-safe/">Kill-Safe Synchronization Abstractions</ulink>.\r
25503 Matthew Flatt and Robert Bruce Findler.\r
25504 <link linkend="References_PLDI">PLDI</link> 2004.\r
25505</simpara>\r
25506</listitem>\r
25507<listitem>\r
25508<simpara>\r
25509<anchor id="References_FluetWeeks01" xreflabel="[References_FluetWeeks01]"/>\r
25510 <ulink url="http://www.cs.rit.edu/~mtf/research/contification">Contification Using Dominators</ulink>.\r
25511 Matthew Fluet and Stephen Weeks.\r
25512 <link linkend="References_ICFP">ICFP</link> 2001.\r
25513</simpara>\r
25514<blockquote>\r
25515<simpara>Describes contification, a generalization of tail-recursion\r
25516elimination that is an optimization operating on MLton&#8217;s static single\r
25517assignment (SSA) intermediate language.</simpara>\r
25518</blockquote>\r
25519</listitem>\r
25520<listitem>\r
25521<simpara>\r
25522<anchor id="References_FluetPucella06" xreflabel="[References_FluetPucella06]"/>\r
25523 <ulink url="http://www.cs.rit.edu/~mtf/research/phantom-subtyping/jfp06/jfp06.pdf">Phantom Types and Subtyping</ulink>.\r
25524 Matthew Fluet and Riccardo Pucella.\r
25525 <link linkend="References_JFP">JFP</link> 2006.\r
25526</simpara>\r
25527</listitem>\r
25528<listitem>\r
25529<simpara>\r
25530<anchor id="References_Furuse01" xreflabel="[References_Furuse01]"/>\r
25531 <ulink url="http://jfla.inria.fr/2001/actes/07-furuse.ps">Generic Polymorphism in ML</ulink>.\r
25532 J. Furuse.\r
25533 <link linkend="References_JFLA">JFLA</link> 2001.\r
25534</simpara>\r
25535<blockquote>\r
25536<simpara>The formalism behind G&#8217;CAML, which has an approach to ad-hoc\r
25537polymorphism based on <link linkend="References_Dubois95">Dubois95</link>, the differences being in how\r
25538type checking works an an improved compilation approach for typecase\r
25539that does the matching at compile time, not run time.</simpara>\r
25540</blockquote>\r
25541</listitem>\r
25542</itemizedlist>\r
25543</section>\r
25544<section id="_anchor_id_references_ggg_xreflabel_references_ggg_g">\r
25545<title><anchor id="References_GGG" xreflabel="[References_GGG]"/>G</title>\r
25546<itemizedlist>\r
25547<listitem>\r
25548<simpara>\r
25549<anchor id="References_GansnerReppy93" xreflabel="[References_GansnerReppy93]"/>\r
25550 <ulink url="http://alleystoughton.us/eXene/1993-trends.pdf">A Multi-Threaded Higher-order User Interface Toolkit</ulink>.\r
25551 Emden R. Gansner and John H. Reppy.\r
25552 User Interface Software, 1993.\r
25553</simpara>\r
25554</listitem>\r
25555<listitem>\r
25556<simpara>\r
25557<anchor id="References_GansnerReppy04" xreflabel="[References_GansnerReppy04]"/>\r
25558<ulink url="http://www.cambridge.org/gb/academic/subjects/computer-science/programming-languages-and-applied-logic/standard-ml-basis-library">The Standard ML Basis Library</ulink>.\r
25559 (<ulink url="http://www3.addall.com/New/submitNew.cgi?query=9780521794787&amp;type=ISBN">addall</ulink>)\r
25560 ISBN 9780521794787.\r
25561 Emden R. Gansner and John H. Reppy.\r
25562 Cambridge University Press, 2004.\r
25563</simpara>\r
25564<blockquote>\r
25565<simpara>An introduction and overview of the <link linkend="BasisLibrary">Basis Library</link>,\r
25566followed by a detailed description of each module. The module\r
25567descriptions are also available\r
25568<ulink url="http://www.standardml.org/Basis">online</ulink>.</simpara>\r
25569</blockquote>\r
25570</listitem>\r
25571<listitem>\r
25572<simpara>\r
25573<anchor id="References_GrossmanEtAl02" xreflabel="[References_GrossmanEtAl02]"/>\r
25574 <ulink url="http://www.cs.umd.edu/projects/cyclone/papers/cyclone-regions.pdf">Region-based Memory Management in Cyclone</ulink>.\r
25575 Dan Grossman, Greg Morrisett, Trevor Jim, Michael Hicks, Yanling\r
25576 Wang, and James Cheney.\r
25577 <link linkend="References_PLDI">PLDI</link> 2002.\r
25578</simpara>\r
25579</listitem>\r
25580</itemizedlist>\r
25581</section>\r
25582<section id="_anchor_id_references_hhh_xreflabel_references_hhh_h">\r
25583<title><anchor id="References_HHH" xreflabel="[References_HHH]"/>H</title>\r
25584<itemizedlist>\r
25585<listitem>\r
25586<simpara>\r
25587<anchor id="References_HallenbergEtAl02" xreflabel="[References_HallenbergEtAl02]"/>\r
25588 <ulink url="http://www.itu.dk/people/tofte/publ/pldi2002.pdf">Combining Region Inference and Garbage Collection</ulink>.\r
25589 Niels Hallenberg, Martin Elsman, and Mads Tofte.\r
25590 <link linkend="References_PLDI">PLDI</link> 2002.\r
25591</simpara>\r
25592</listitem>\r
25593<listitem>\r
25594<simpara>\r
25595<anchor id="References_HansenRichel99" xreflabel="[References_HansenRichel99]"/>\r
25596 <ulink url="http://www.it.dtu.dk/introSML">Introduction to Programming Using SML</ulink>\r
25597 (<ulink url="http://www3.addall.com/New/submitNew.cgi?query=0201398206&amp;type=ISBN">addall</ulink>).\r
25598 ISBN 0201398206.\r
25599 Michael R. Hansen, Hans Rischel.\r
25600 Addison-Wesley, 1999.\r
25601</simpara>\r
25602</listitem>\r
25603<listitem>\r
25604<simpara>\r
25605<anchor id="References_Harper11" xreflabel="[References_Harper11]"/>\r
25606 <ulink url="http://www.cs.cmu.edu/~rwh/smlbook/book.pdf">Programming in Standard ML</ulink>.\r
25607 Robert Harper.\r
25608</simpara>\r
25609</listitem>\r
25610<listitem>\r
25611<simpara>\r
25612<anchor id="References_HarperEtAl93" xreflabel="[References_HarperEtAl93]"/>\r
25613 <ulink url="http://www.cs.cmu.edu/~rwh/papers/callcc/jfp.pdf">Typing First-Class Continuations in ML</ulink>.\r
25614 Robert Harper, Bruce F. Duba, and David MacQueen.\r
25615 <link linkend="References_JFP">JFP</link> 1993.\r
25616</simpara>\r
25617</listitem>\r
25618<listitem>\r
25619<simpara>\r
25620<anchor id="References_HarperMitchell92" xreflabel="[References_HarperMitchell92]"/>\r
25621 <ulink url="http://www.cs.cmu.edu/~rwh/papers/xml/toplas93.pdf">On the Type Structure of Standard ML</ulink>.\r
25622 Robert Harper and John C. Mitchell.\r
25623 <link linkend="References_TOPLAS">TOPLAS</link> 1992.\r
25624</simpara>\r
25625</listitem>\r
25626<listitem>\r
25627<simpara>\r
25628<anchor id="References_HauserBenson04" xreflabel="[References_HauserBenson04]"/>\r
25629 <ulink url="http://doi.ieeecomputersociety.org/10.1109/CSD.2004.1309122">On the Practicality and Desirability of Highly-concurrent, Mostly-functional Programming</ulink>.\r
25630 Carl H. Hauser and David B. Benson.\r
25631 <link linkend="References_ACSD">ACSD</link> 2004.\r
25632</simpara>\r
25633<blockquote>\r
25634<simpara>Describes the use of <link linkend="ConcurrentML">Concurrent ML</link> in implementing\r
25635the Ped text editor. Argues that using large numbers of threads and\r
25636message passing style is a practical and effective way of\r
25637modularizing a program.</simpara>\r
25638</blockquote>\r
25639</listitem>\r
25640<listitem>\r
25641<simpara>\r
25642<anchor id="References_HeckmanWilhelm97" xreflabel="[References_HeckmanWilhelm97]"/>\r
25643 <ulink url="http://rw4.cs.uni-sb.de/~heckmann/abstracts/neuform.html">A Functional Description of TeX&#8217;s Formula Layout</ulink>.\r
25644 Reinhold Heckmann and Reinhard Wilhelm.\r
25645 <link linkend="References_JFP">JFP</link> 1997.\r
25646</simpara>\r
25647</listitem>\r
25648<listitem>\r
25649<simpara>\r
25650<anchor id="References_HicksEtAl03" xreflabel="[References_HicksEtAl03]"/>\r
25651 <ulink url="http://wwwold.cs.umd.edu/Library/TRs/CS-TR-4514/CS-TR-4514.pdf">Safe and Flexible Memory Management in Cyclone</ulink>.\r
25652 Mike Hicks, Greg Morrisett, Dan Grossman, and Trevor Jim.\r
25653 University of Maryland Technical Report CS-TR-4514, 2003.\r
25654</simpara>\r
25655</listitem>\r
25656<listitem>\r
25657<simpara>\r
25658<anchor id="References_Hurd04" xreflabel="[References_Hurd04]"/>\r
25659 <ulink url="http://www.gilith.com/research/talks/tphols2004.pdf">Compiling HOL4 to Native Code</ulink>.\r
25660 Joe Hurd.\r
25661 <link linkend="References_TPHOLs">TPHOLs</link> 2004.\r
25662</simpara>\r
25663<blockquote>\r
25664<simpara>Describes a port of HOL from Moscow ML to MLton, the difficulties\r
25665encountered in compiling large programs, and the speedups achieved\r
25666(roughly 10x).</simpara>\r
25667</blockquote>\r
25668</listitem>\r
25669</itemizedlist>\r
25670</section>\r
25671<section id="_anchor_id_references_iii_xreflabel_references_iii_i">\r
25672<title><anchor id="References_III" xreflabel="[References_III]"/>I</title>\r
25673<simpara></simpara>\r
25674</section>\r
25675<section id="_anchor_id_references_jjj_xreflabel_references_jjj_j">\r
25676<title><anchor id="References_JJJ" xreflabel="[References_JJJ]"/>J</title>\r
25677<itemizedlist>\r
25678<listitem>\r
25679<simpara>\r
25680<anchor id="References_Jones99" xreflabel="[References_Jones99]"/>\r
25681 <ulink url="http://www.cs.kent.ac.uk/people/staff/rej/gcbook">Garbage Collection: Algorithms for Automatic Memory Management</ulink>\r
25682 (<ulink url="http://www3.addall.com/New/submitNew.cgi?query=0471941484&amp;type=ISBN">addall</ulink>).\r
25683 ISBN 0471941484.\r
25684 Richard Jones.\r
25685 John Wiley &amp; Sons, 1999.\r
25686</simpara>\r
25687</listitem>\r
25688</itemizedlist>\r
25689</section>\r
25690<section id="_anchor_id_references_kkk_xreflabel_references_kkk_k">\r
25691<title><anchor id="References_KKK" xreflabel="[References_KKK]"/>K</title>\r
25692<itemizedlist>\r
25693<listitem>\r
25694<simpara>\r
25695<anchor id="References_Kahrs93" xreflabel="[References_Kahrs93]"/>\r
25696 <ulink url="http://kar.kent.ac.uk/21122/">Mistakes and Ambiguities in the Definition of Standard ML</ulink>.\r
25697 Stefan Kahrs.\r
25698 University of Edinburgh Technical Report ECS-LFCS-93-257, 1993.\r
25699</simpara>\r
25700<blockquote>\r
25701<simpara>Describes a number of problems with the\r
25702<link linkend="References_MilnerEtAl90">1990 Definition</link>, many of which were fixed in the\r
25703<link linkend="References_MilnerEtAl97">1997 Definition</link>.</simpara>\r
25704<simpara>Also see the <ulink url="http://www.cs.kent.ac.uk/~smk/errors-new.ps.Z">addenda</ulink>\r
25705published in 1996.</simpara>\r
25706</blockquote>\r
25707</listitem>\r
25708<listitem>\r
25709<simpara>\r
25710<anchor id="References_Karvonen07" xreflabel="[References_Karvonen07]"/>\r
25711 <ulink url="http://dl.acm.org/citation.cfm?doid=1292535.1292547">Generics for the Working ML&#8217;er</ulink>.\r
25712 Vesa Karvonen.\r
25713 <link linkend="References_ML">ML</link> 2007. <ulink url="http://research.microsoft.com/~crusso/ml2007/slides/ml08rp-karvonen-slides.pdf">Slides</ulink> from the presentation are also available.\r
25714</simpara>\r
25715</listitem>\r
25716<listitem>\r
25717<simpara>\r
25718<anchor id="References_Kennedy04" xreflabel="[References_Kennedy04]"/>\r
25719 <ulink url="http://research.microsoft.com/~akenn/fun/picklercombinators.pdf">Pickler Combinators</ulink>.\r
25720 Andrew Kennedy.\r
25721 <link linkend="References_JFP">JFP</link> 2004.\r
25722</simpara>\r
25723</listitem>\r
25724<listitem>\r
25725<simpara>\r
25726<anchor id="References_KoserEtAl03" xreflabel="[References_KoserEtAl03]"/>\r
25727 <ulink url="http://www.litech.org/~vaughan/pdf/dpcool2003.pdf">sml2java: A Source To Source Translator</ulink>.\r
25728 Justin Koser, Haakon Larsen, Jeffrey A. Vaughan.\r
25729 <link linkend="References_DPCOOL">DPCOOL</link> 2003.\r
25730</simpara>\r
25731</listitem>\r
25732</itemizedlist>\r
25733</section>\r
25734<section id="_anchor_id_references_lll_xreflabel_references_lll_l">\r
25735<title><anchor id="References_LLL" xreflabel="[References_LLL]"/>L</title>\r
25736<itemizedlist>\r
25737<listitem>\r
25738<simpara>\r
25739<anchor id="References_Lang99" xreflabel="[References_Lang99]"/>\r
25740 <ulink url="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.29.7130&amp;rep=rep1&amp;type=ps">Faster Algorithms for Finding Minimal Consistent DFAs</ulink>.\r
25741 Kevin Lang. 1999.\r
25742</simpara>\r
25743</listitem>\r
25744<listitem>\r
25745<simpara>\r
25746<anchor id="References_LarsenNiss04" xreflabel="[References_LarsenNiss04]"/>\r
25747 <ulink url="http://usenix.org/publications/library/proceedings/usenix04/tech/freenix/full_papers/larsen/larsen.pdf">mGTK: An SML binding of Gtk+</ulink>.\r
25748 Ken Larsen and Henning Niss.\r
25749 USENIX Annual Technical Conference, 2004.\r
25750</simpara>\r
25751</listitem>\r
25752<listitem>\r
25753<simpara>\r
25754<anchor id="References_Leibig13" xreflabel="[References_Leibig13]"/>\r
25755 <ulink url="http://www.cs.rit.edu/~bal6053/msproject/">An LLVM Back-end for MLton</ulink>.\r
25756 Brian Leibig.\r
25757 MS Project Report, 2013.\r
25758</simpara>\r
25759<blockquote>\r
25760<simpara>Describes MLton&#8217;s <link linkend="LLVMCodegen">LLVMCodegen</link>.</simpara>\r
25761</blockquote>\r
25762</listitem>\r
25763<listitem>\r
25764<simpara>\r
25765<anchor id="References_Leroy90" xreflabel="[References_Leroy90]"/>\r
25766 <ulink url="http://pauillac.inria.fr/~xleroy/bibrefs/Leroy-ZINC.html">The ZINC Experiment: an Economical Implementation of the ML Language</ulink>.\r
25767 Xavier Leroy.\r
25768 Technical report 117, INRIA, 1990.\r
25769</simpara>\r
25770<blockquote>\r
25771<simpara>A detailed explanation of the design and implementation of a bytecode\r
25772compiler and interpreter for ML with a machine model aimed at\r
25773efficient implementation.</simpara>\r
25774</blockquote>\r
25775</listitem>\r
25776<listitem>\r
25777<simpara>\r
25778<anchor id="References_Leroy93" xreflabel="[References_Leroy93]"/>\r
25779 <ulink url="http://pauillac.inria.fr/~xleroy/bibrefs/Leroy-poly-par-nom.html">Polymorphism by Name for References and Continuations</ulink>.\r
25780 Xavier Leroy.\r
25781 <link linkend="References_POPL">POPL</link> 1993.\r
25782</simpara>\r
25783</listitem>\r
25784<listitem>\r
25785<simpara>\r
25786<anchor id="References_LeungGeorge99" xreflabel="[References_LeungGeorge99]"/>\r
25787 <ulink url="http://www.cs.nyu.edu/leunga/my-papers/annotations.ps">MLRISC Annotations</ulink>.\r
25788 Allen Leung and Lal George. 1999.\r
25789</simpara>\r
25790</listitem>\r
25791</itemizedlist>\r
25792</section>\r
25793<section id="_anchor_id_references_mmm_xreflabel_references_mmm_m">\r
25794<title><anchor id="References_MMM" xreflabel="[References_MMM]"/>M</title>\r
25795<itemizedlist>\r
25796<listitem>\r
25797<simpara>\r
25798<anchor id="References_MarlowEtAl01" xreflabel="[References_MarlowEtAl01]"/>\r
25799 <ulink url="http://community.haskell.org/~simonmar/papers/async.pdf">Asynchronous Exceptions in Haskell</ulink>.\r
25800 Simon Marlow, Simon Peyton Jones, Andy Moran and John Reppy.\r
25801 <link linkend="References_PLDI">PLDI</link> 2001.\r
25802</simpara>\r
25803<blockquote>\r
25804<simpara>An asynchronous exception is a signal that one thread can send to\r
25805another, and is useful for the receiving thread to treat as an\r
25806exception so that it can clean up locks or other state relevant to its\r
25807current context.</simpara>\r
25808</blockquote>\r
25809</listitem>\r
25810<listitem>\r
25811<simpara>\r
25812<anchor id="References_MacQueenEtAl84" xreflabel="[References_MacQueenEtAl84]"/>\r
25813 <ulink url="http://homepages.inf.ed.ac.uk/gdp/publications/Ideal_model.pdf">An Ideal Model for Recursive Polymorphic Types</ulink>.\r
25814 David MacQueen, Gordon Plotkin, Ravi Sethi.\r
25815 <link linkend="References_POPL">POPL</link> 1984.\r
25816</simpara>\r
25817</listitem>\r
25818<listitem>\r
25819<simpara>\r
25820<anchor id="References_Matthews91" xreflabel="[References_Matthews91]"/>\r
25821 <ulink url="http://www.lfcs.inf.ed.ac.uk/reports/91/ECS-LFCS-91-174">A Distributed Concurrent Implementation of Standard ML</ulink>.\r
25822 David Matthews.\r
25823 University of Edinburgh Technical Report ECS-LFCS-91-174, 1991.\r
25824</simpara>\r
25825</listitem>\r
25826<listitem>\r
25827<simpara>\r
25828<anchor id="References_Matthews95" xreflabel="[References_Matthews95]"/>\r
25829 <ulink url="http://www.lfcs.inf.ed.ac.uk/reports/95/ECS-LFCS-95-335">Papers on Poly/ML</ulink>.\r
25830 David C. J. Matthews.\r
25831 University of Edinburgh Technical Report ECS-LFCS-95-335, 1995.\r
25832</simpara>\r
25833</listitem>\r
25834<listitem>\r
25835<simpara>\r
25836<ulink url="http://www.lfcs.inf.ed.ac.uk/reports/97/ECS-LFCS-97-375">That About Wraps it Up: Using FIX to Handle Errors Without Exceptions, and Other Programming Tricks</ulink>.\r
25837 Bruce J. McAdam.\r
25838 University of Edinburgh Technical Report ECS-LFCS-97-375, 1997.\r
25839</simpara>\r
25840</listitem>\r
25841<listitem>\r
25842<simpara>\r
25843<anchor id="References_MeierNorgaard93" xreflabel="[References_MeierNorgaard93]"/>\r
25844 A Just-In-Time Backend for Moscow ML 2.00 in SML.\r
25845 Bjarke Meier, Kristian Nørgaard.\r
25846 Masters Thesis, 2003.\r
25847</simpara>\r
25848<blockquote>\r
25849<simpara>A just-in-time compiler using GNU Lightning, showing a speedup of up\r
25850to four times over Moscow ML&#8217;s usual bytecode interpreter.</simpara>\r
25851<simpara>The full report is only available in\r
25852<ulink url="http://www.itu.dk/stud/speciale/bmkn/fundanemt/download/report">Danish</ulink>.</simpara>\r
25853</blockquote>\r
25854</listitem>\r
25855<listitem>\r
25856<simpara>\r
25857<anchor id="References_Milner78" xreflabel="[References_Milner78]"/>\r
25858 <ulink url="http://courses.engr.illinois.edu/cs421/sp2013/project/milner-polymorphism.pdf">A Theory of Type Polymorphism in Programming</ulink>.\r
25859 Robin Milner.\r
25860 Journal of Computer and System Sciences, 1978.\r
25861</simpara>\r
25862</listitem>\r
25863<listitem>\r
25864<simpara>\r
25865<anchor id="References_Milner82" xreflabel="[References_Milner82]"/>\r
25866 <ulink url="http://homepages.inf.ed.ac.uk/dts/fps/papers/evolved.dvi.gz">How ML Evolved</ulink>.\r
25867 Robin Milner.\r
25868 Polymorphism&#8212;The ML/LCF/Hope Newsletter, 1983.\r
25869</simpara>\r
25870</listitem>\r
25871<listitem>\r
25872<simpara>\r
25873<anchor id="References_MilnerTofte91" xreflabel="[References_MilnerTofte91]"/>\r
25874 <ulink url="http://www.itu.dk/people/tofte/publ/1990sml/1990sml.html">Commentary on Standard ML</ulink>\r
25875 (<ulink url="http://www3.addall.com/New/submitNew.cgi?query=0262631377&amp;type=ISBN">addall</ulink>)\r
25876 ISBN 0262631377.\r
25877 Robin Milner and Mads Tofte.\r
25878 The MIT Press, 1991.\r
25879</simpara>\r
25880<blockquote>\r
25881<simpara>Introduces and explains the notation and approach used in\r
25882<link linkend="References_MilnerEtAl90">The Definition of Standard ML</link>.</simpara>\r
25883</blockquote>\r
25884</listitem>\r
25885<listitem>\r
25886<simpara>\r
25887<anchor id="References_MilnerEtAl90" xreflabel="[References_MilnerEtAl90]"/>\r
25888 <ulink url="http://www.itu.dk/people/tofte/publ/1990sml/1990sml.html">The Definition of Standard ML</ulink>.\r
25889 (<ulink url="http://www3.addall.com/New/submitNew.cgi?query=0262631326&amp;type=ISBN">addall</ulink>)\r
25890 ISBN 0262631326.\r
25891 Robin Milner, Mads Tofte, and Robert Harper.\r
25892 The MIT Press, 1990.\r
25893</simpara>\r
25894<blockquote>\r
25895<simpara>Superseded by <link linkend="References_MilnerEtAl97">The Definition of Standard ML (Revised)</link>.\r
25896Accompanied by the <link linkend="References_MilnerTofte91">Commentary on Standard ML</link>.</simpara>\r
25897</blockquote>\r
25898</listitem>\r
25899<listitem>\r
25900<simpara>\r
25901<anchor id="References_MilnerEtAl97" xreflabel="[References_MilnerEtAl97]"/>\r
25902 <ulink url="http://mitpress.mit.edu/books/definition-standard-ml">The Definition of Standard ML (Revised)</ulink>.\r
25903 (<ulink url="http://www3.addall.com/New/submitNew.cgi?query=0262631814&amp;type=ISBN">addall</ulink>)\r
25904 ISBN 0262631814.\r
25905 Robin Milner, Mads Tofte, Robert Harper, and David MacQueen.\r
25906 The MIT Press, 1997.\r
25907</simpara>\r
25908<blockquote>\r
25909<simpara>A terse and formal specification of Standard ML&#8217;s syntax and\r
25910semantics. Supersedes <link linkend="References_MilnerEtAl90">The Definition of Standard ML</link>.</simpara>\r
25911</blockquote>\r
25912</listitem>\r
25913<listitem>\r
25914<simpara>\r
25915<anchor id="References_ML2000" xreflabel="[References_ML2000]"/>\r
25916 <ulink url="http://flint.cs.yale.edu/flint/publications/ml2000.html">Principles and a Preliminary Design for ML2000</ulink>.\r
25917 The ML2000 working group, 1999.\r
25918</simpara>\r
25919</listitem>\r
25920<listitem>\r
25921<simpara>\r
25922<anchor id="References_Morentsen99" xreflabel="[References_Morentsen99]"/>\r
25923 <ulink url="http://daimi.au.dk/CPnets/workshop99/papers/Mortensen.pdf">Automatic Code Generation from Coloured Petri Nets for an Access Control System</ulink>.\r
25924 Kjeld H. Mortensen.\r
25925 Workshop on Practical Use of Coloured Petri Nets and Design/CPN, 1999.\r
25926</simpara>\r
25927</listitem>\r
25928<listitem>\r
25929<simpara>\r
25930<anchor id="References_MorrisettTolmach93" xreflabel="[References_MorrisettTolmach93]"/>\r
25931 <ulink url="http://web.cecs.pdx.edu/~apt/ppopp93.ps">Procs and Locks: a Portable Multiprocessing Platform for Standard ML of New Jersey</ulink>.\r
25932 J. Gregory Morrisett and Andrew Tolmach.\r
25933 <link linkend="References_PPoPP">PPoPP</link> 1993.\r
25934</simpara>\r
25935</listitem>\r
25936<listitem>\r
25937<simpara>\r
25938<anchor id="References_Murphy06" xreflabel="[References_Murphy06]"/>\r
25939 <ulink url="http://www.cs.cmu.edu/~tom7/papers/grid-ml06.pdf">ML Grid Programming with ConCert</ulink>.\r
25940 Tom Murphy VII.\r
25941 <link linkend="References_ML">ML</link> 2006.\r
25942</simpara>\r
25943</listitem>\r
25944</itemizedlist>\r
25945</section>\r
25946<section id="_anchor_id_references_nnn_xreflabel_references_nnn_n">\r
25947<title><anchor id="References_NNN" xreflabel="[References_NNN]"/>N</title>\r
25948<itemizedlist>\r
25949<listitem>\r
25950<simpara>\r
25951<anchor id="References_Neumann99" xreflabel="[References_Neumann99]"/>\r
25952 <ulink url="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.25.9485&amp;rep=rep1&amp;type=ps">fxp - Processing Structured Documents in SML</ulink>.\r
25953 Andreas Neumann.\r
25954 Scottish Functional Programming Workshop, 1999.\r
25955</simpara>\r
25956<blockquote>\r
25957<simpara>Describes <ulink url="http://atseidl2.informatik.tu-muenchen.de/~berlea/Fxp">fxp</ulink>,\r
25958an XML parser implemented in Standard ML.</simpara>\r
25959</blockquote>\r
25960</listitem>\r
25961<listitem>\r
25962<simpara>\r
25963<anchor id="References_Neumann99Thesis" xreflabel="[References_Neumann99Thesis]"/>\r
25964 <ulink url="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.25.8108&amp;rep=rep1&amp;type=ps">Parsing and Querying XML Documents in SML</ulink>.\r
25965 Andreas Neumann.\r
25966 Doctoral Thesis, 1999.\r
25967</simpara>\r
25968</listitem>\r
25969<listitem>\r
25970<simpara>\r
25971<anchor id="References_NguyenOhori06" xreflabel="[References_NguyenOhori06]"/>\r
25972 <ulink url="http://www.pllab.riec.tohoku.ac.jp/~ohori/research/NguyenOhoriPPDP06.pdf">Compiling ML Polymorphism with Explicit Layout Bitmap</ulink>.\r
25973 Huu-Duc Nguyen and Atsushi Ohori.\r
25974 <link linkend="References_PPDP">PPDP</link> 2006.\r
25975</simpara>\r
25976</listitem>\r
25977</itemizedlist>\r
25978</section>\r
25979<section id="_anchor_id_references_ooo_xreflabel_references_ooo_o">\r
25980<title><anchor id="References_OOO" xreflabel="[References_OOO]"/>O</title>\r
25981<itemizedlist>\r
25982<listitem>\r
25983<simpara>\r
25984<anchor id="References_Okasaki99" xreflabel="[References_Okasaki99]"/>\r
25985<ulink url="http://www.cambridge.org/gb/academic/subjects/computer-science/programming-languages-and-applied-logic/purely-functional-data-structures">Purely Functional Data Structures</ulink>.\r
25986 ISBN 9780521663502.\r
25987 Chris Okasaki.\r
25988 Cambridge University Press, 1999.\r
25989</simpara>\r
25990</listitem>\r
25991<listitem>\r
25992<simpara>\r
25993<anchor id="References_Ohori89" xreflabel="[References_Ohori89]"/>\r
25994 <ulink url="http://www.pllab.riec.tohoku.ac.jp/~ohori/research/fpca89.pdf">A Simple Semantics for ML Polymorphism</ulink>.\r
25995 Atsushi Ohori.\r
25996 <link linkend="References_FPCA">FPCA</link> 1989.\r
25997</simpara>\r
25998</listitem>\r
25999<listitem>\r
26000<simpara>\r
26001<anchor id="References_Ohori95" xreflabel="[References_Ohori95]"/>\r
26002 <ulink url="http://www.pllab.riec.tohoku.ac.jp/~ohori/research/toplas95.pdf">A Polymorphic Record Calculus and Its Compilation</ulink>.\r
26003 Atsushi Ohori.\r
26004 <link linkend="References_TOPLAS">TOPLAS</link> 1995.\r
26005</simpara>\r
26006</listitem>\r
26007<listitem>\r
26008<simpara>\r
26009<anchor id="References_OhoriTakamizawa97" xreflabel="[References_OhoriTakamizawa97]"/>\r
26010 <ulink url="http://www.pllab.riec.tohoku.ac.jp/~ohori/research/jlsc97.pdf">An Unboxed Operational Semantics for ML Polymorphism</ulink>.\r
26011 Atsushi Ohori and Tomonobu Takamizawa.\r
26012 <link linkend="References_LASC">LASC</link> 1997.\r
26013</simpara>\r
26014</listitem>\r
26015<listitem>\r
26016<simpara>\r
26017<anchor id="References_Ohori99" xreflabel="[References_Ohori99]"/>\r
26018 <ulink url="http://www.pllab.riec.tohoku.ac.jp/~ohori/research/ic98.pdf">Type-Directed Specialization of Polymorphism</ulink>.\r
26019 Atsushi Ohori.\r
26020 <link linkend="References_IC">IC</link> 1999.\r
26021</simpara>\r
26022</listitem>\r
26023<listitem>\r
26024<simpara>\r
26025<anchor id="References_OwensEtAl09" xreflabel="[References_OwensEtAl09]"/>\r
26026 <ulink url="http://www.mpi-sws.org/~turon/re-deriv.pdf">Regular-expression derivatives reexamined</ulink>.\r
26027 Scott Owens, John Reppy, and Aaron Turon.\r
26028 <link linkend="References_JFP">JFP</link> 2009.\r
26029</simpara>\r
26030</listitem>\r
26031</itemizedlist>\r
26032</section>\r
26033<section id="_anchor_id_references_ppp_xreflabel_references_ppp_p">\r
26034<title><anchor id="References_PPP" xreflabel="[References_PPP]"/>P</title>\r
26035<itemizedlist>\r
26036<listitem>\r
26037<simpara>\r
26038<anchor id="References_Paulson96" xreflabel="[References_Paulson96]"/>\r
26039 <ulink url="http://www.cambridge.org/co/academic/subjects/computer-science/programming-languages-and-applied-logic/ml-working-programmer-2nd-edition">ML For the Working Programmer</ulink>\r
26040 (<ulink url="http://www3.addall.com/New/submitNew.cgi?query=052156543X&amp;type=ISBN">addall</ulink>)\r
26041 ISBN 052156543X.\r
26042 Larry C. Paulson.\r
26043 Cambridge University Press, 1996.\r
26044</simpara>\r
26045</listitem>\r
26046<listitem>\r
26047<simpara>\r
26048<anchor id="References_PetterssonEtAl02" xreflabel="[References_PetterssonEtAl02]"/>\r
26049 <ulink url="http://user.it.uu.se/~kostis/Papers/flops02_22.ps.gz">The HiPE/x86 Erlang Compiler: System Description and Performance Evaluation</ulink>.\r
26050 Mikael Pettersson, Konstantinos Sagonas, and Erik Johansson.\r
26051 <link linkend="References_FLOPS">FLOPS</link> 2002.\r
26052</simpara>\r
26053<blockquote>\r
26054<simpara>Describes a native x86 Erlang compiler and a comparison of many\r
26055different native x86 compilers (including MLton) and their register\r
26056usage and call stack implementations.</simpara>\r
26057</blockquote>\r
26058</listitem>\r
26059<listitem>\r
26060<simpara>\r
26061<anchor id="References_Price09" xreflabel="[References_Price09]"/>\r
26062 <ulink url="http://rogerprice.org/#UG">User&#8217;s Guide to ML-Lex and ML-Yacc</ulink>\r
26063 Roger Price. 2009.\r
26064</simpara>\r
26065</listitem>\r
26066<listitem>\r
26067<simpara>\r
26068<anchor id="References_Pucella98" xreflabel="[References_Pucella98]"/>\r
26069 <ulink url="http://arxiv.org/abs/cs.PL/0405080">Reactive Programming in Standard ML</ulink>.\r
26070 Riccardo R. Puccella. 1998.\r
26071 <link linkend="References_ICCL">ICCL</link> 1998.\r
26072</simpara>\r
26073</listitem>\r
26074</itemizedlist>\r
26075</section>\r
26076<section id="_anchor_id_references_qqq_xreflabel_references_qqq_q">\r
26077<title><anchor id="References_QQQ" xreflabel="[References_QQQ]"/>Q</title>\r
26078<simpara></simpara>\r
26079</section>\r
26080<section id="_anchor_id_references_rrr_xreflabel_references_rrr_r">\r
26081<title><anchor id="References_RRR" xreflabel="[References_RRR]"/>R</title>\r
26082<itemizedlist>\r
26083<listitem>\r
26084<simpara>\r
26085<anchor id="References_Ramsey90" xreflabel="[References_Ramsey90]"/>\r
26086 <ulink url="https://www.cs.princeton.edu/research/techreps/TR-262-90">Concurrent Programming in ML</ulink>.\r
26087 Norman Ramsey.\r
26088 Princeton University Technical Report CS-TR-262-90, 1990.\r
26089</simpara>\r
26090</listitem>\r
26091<listitem>\r
26092<simpara>\r
26093<anchor id="References_Ramsey11" xreflabel="[References_Ramsey11]"/>\r
26094 <ulink url="http://www.cs.tufts.edu/~nr/pubs/embedj-abstract.html">Embedding an Interpreted Language Using Higher-Order Functions and Types</ulink>.\r
26095 Norman Ramsey.\r
26096 <link linkend="References_JFP">JFP</link> 2011.\r
26097</simpara>\r
26098</listitem>\r
26099<listitem>\r
26100<simpara>\r
26101<anchor id="References_RamseyFisherGovereau05" xreflabel="[References_RamseyFisherGovereau05]"/>\r
26102 <ulink url="http://www.cs.tufts.edu/~nr/pubs/els-abstract.html">An Expressive Language of Signatures</ulink>.\r
26103 Norman Ramsey, Kathleen Fisher, and Paul Govereau.\r
26104 <link linkend="References_ICFP">ICFP</link> 2005.\r
26105</simpara>\r
26106</listitem>\r
26107<listitem>\r
26108<simpara>\r
26109<anchor id="References_RedwineRamsey04" xreflabel="[References_RedwineRamsey04]"/>\r
26110 <ulink url="http://www.cs.tufts.edu/~nr/pubs/widen-abstract.html">Widening Integer Arithmetic</ulink>.\r
26111 Kevin Redwine and Norman Ramsey.\r
26112 <link linkend="References_CC">CC</link> 2004.\r
26113</simpara>\r
26114<blockquote>\r
26115<simpara>Describes a method to implement numeric types and operations (like\r
26116<literal>Int31</literal> or <literal>Word17</literal>) for sizes smaller than that provided by the\r
26117processor.</simpara>\r
26118</blockquote>\r
26119</listitem>\r
26120<listitem>\r
26121<simpara>\r
26122<anchor id="References_Reppy88" xreflabel="[References_Reppy88]"/>\r
26123 Synchronous Operations as First-Class Values.\r
26124 John Reppy.\r
26125 <link linkend="References_PLDI">PLDI</link> 1988.\r
26126</simpara>\r
26127</listitem>\r
26128<listitem>\r
26129<simpara>\r
26130<anchor id="References_Reppy07" xreflabel="[References_Reppy07]"/>\r
26131 <ulink url="http://www.cambridge.org/co/academic/subjects/computer-science/distributed-networked-and-mobile-computing/concurrent-programming-ml">Concurrent Programming in ML</ulink>\r
26132 (<ulink url="http://www3.addall.com/New/submitNew.cgi?query=9780521714723&amp;type=ISBN">addall</ulink>).\r
26133 ISBN 9780521714723.\r
26134 John Reppy.\r
26135 Cambridge University Press, 2007.\r
26136</simpara>\r
26137<blockquote>\r
26138<simpara>Describes <link linkend="ConcurrentML">ConcurrentML</link>.</simpara>\r
26139</blockquote>\r
26140</listitem>\r
26141<listitem>\r
26142<simpara>\r
26143<anchor id="References_Reynolds98" xreflabel="[References_Reynolds98]"/>\r
26144 <ulink url="https://users-cs.au.dk/hosc/local/HOSC-11-4-pp355-361.pdf">Definitional Interpreters Revisited</ulink>.\r
26145 John C. Reynolds.\r
26146 <link linkend="References_HOSC">HOSC</link> 1998.\r
26147</simpara>\r
26148</listitem>\r
26149<listitem>\r
26150<simpara>\r
26151<anchor id="References_Reynolds98_2" xreflabel="[References_Reynolds98_2]"/>\r
26152 <ulink url="https://users-cs.au.dk/hosc/local/HOSC-11-4-pp363-397.pdf">Definitional Interpreters for Higher-Order Programming Languages</ulink>\r
26153 John C. Reynolds.\r
26154 <link linkend="References_HOSC">HOSC</link> 1998.\r
26155</simpara>\r
26156</listitem>\r
26157<listitem>\r
26158<simpara>\r
26159<anchor id="References_Rossberg01" xreflabel="[References_Rossberg01]"/>\r
26160 <ulink url="http://www.mpi-sws.org/~rossberg/papers/Rossberg%20-%20Defects%20in%20the%20Revised%20Definition%20of%20Standard%20ML%20%5B2007-01-22%20Update%5D.pdf">Defects in the Revised Definition of Standard ML</ulink>.\r
26161 Andreas Rossberg. 2001.\r
26162</simpara>\r
26163</listitem>\r
26164</itemizedlist>\r
26165</section>\r
26166<section id="_anchor_id_references_sss_xreflabel_references_sss_s">\r
26167<title><anchor id="References_SSS" xreflabel="[References_SSS]"/>S</title>\r
26168<itemizedlist>\r
26169<listitem>\r
26170<simpara>\r
26171<anchor id="References_Sansom91" xreflabel="[References_Sansom91]"/>\r
26172 <ulink url="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.24.1020&amp;rep=rep1&amp;type=ps">Dual-Mode Garbage Collection</ulink>.\r
26173 Patrick M. Sansom.\r
26174 Workshop on the Parallel Implementation of Functional Languages, 1991.\r
26175</simpara>\r
26176</listitem>\r
26177<listitem>\r
26178<simpara>\r
26179<anchor id="References_ScottRamsey00" xreflabel="[References_ScottRamsey00]"/>\r
26180 <ulink url="http://www.cs.tufts.edu/~nr/pubs/match-abstract.html">When Do Match-Compilation Heuristics Matter</ulink>.\r
26181 Kevin Scott and Norman Ramsey.\r
26182 University of Virginia Technical Report CS-2000-13, 2000.\r
26183</simpara>\r
26184<blockquote>\r
26185<simpara>Modified SML/NJ to experimentally compare a number of\r
26186match-compilation heuristics and showed that choice of heuristic\r
26187usually does not significantly affect code size or run time.</simpara>\r
26188</blockquote>\r
26189</listitem>\r
26190<listitem>\r
26191<simpara>\r
26192<anchor id="References_Sestoft96" xreflabel="[References_Sestoft96]"/>\r
26193 <ulink url="http://www.itu.dk/~sestoft/papers/match.ps.gz">ML Pattern Match Compilation and Partial Evaluation</ulink>.\r
26194 Peter Sestoft.\r
26195 Partial Evaluation, 1996.\r
26196</simpara>\r
26197<blockquote>\r
26198<simpara>Describes the derivation of the match compiler used in\r
26199<link linkend="MoscowML">Moscow ML</link>.</simpara>\r
26200</blockquote>\r
26201</listitem>\r
26202<listitem>\r
26203<simpara>\r
26204<anchor id="References_ShaoAppel94" xreflabel="[References_ShaoAppel94]"/>\r
26205 <ulink url="http://flint.cs.yale.edu/flint/publications/closure.html">Space-Efficient Closure Representations</ulink>.\r
26206 Zhong Shao and Andrew W. Appel.\r
26207 <link linkend="References_LFP">LFP</link> 1994.\r
26208</simpara>\r
26209</listitem>\r
26210<listitem>\r
26211<simpara>\r
26212<anchor id="References_Shipman02" xreflabel="[References_Shipman02]"/>\r
26213 <ulink url="guide/References.attachments/Shipman02.pdf">Unix System Programming with Standard ML</ulink>.\r
26214 Anthony L. Shipman.\r
26215 2002.\r
26216</simpara>\r
26217<blockquote>\r
26218<simpara>Includes a description of the <link linkend="Swerve">Swerve</link> HTTP server written in SML.</simpara>\r
26219</blockquote>\r
26220</listitem>\r
26221<listitem>\r
26222<simpara>\r
26223<anchor id="References_Signoles03" xreflabel="[References_Signoles03]"/>\r
26224 Calcul Statique des Applications de Modules Parametres.\r
26225 Julien Signoles.\r
26226 <link linkend="References_JFLA">JFLA</link> 2003.\r
26227</simpara>\r
26228<blockquote>\r
26229<simpara>Describes a <ulink url="http://caml.inria.fr/cgi-bin/hump.en.cgi?contrib=382">defunctorizer</ulink>\r
26230for OCaml, and compares it to existing defunctorizers, including MLton.</simpara>\r
26231</blockquote>\r
26232</listitem>\r
26233<listitem>\r
26234<simpara>\r
26235<anchor id="References_SittampalamEtAl04" xreflabel="[References_SittampalamEtAl04]"/>\r
26236 <ulink url="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.4.1349&amp;rep=rep1&amp;type=ps">Incremental Execution of Transformation Specifications</ulink>.\r
26237 Ganesh Sittampalam, Oege de Moor, and Ken Friis Larsen.\r
26238 <link linkend="References_POPL">POPL</link> 2004.\r
26239</simpara>\r
26240<blockquote>\r
26241<simpara>Mentions a port from Moscow ML to MLton of\r
26242<ulink url="http://www.itu.dk/research/muddy/">MuDDY</ulink>, an SML wrapper around the\r
26243<ulink url="http://sourceforge.net/projects/buddy">BuDDY</ulink> BDD package.</simpara>\r
26244</blockquote>\r
26245</listitem>\r
26246<listitem>\r
26247<simpara>\r
26248<anchor id="References_SwaseyEtAl06" xreflabel="[References_SwaseyEtAl06]"/>\r
26249 <ulink url="http://www.cs.cmu.edu/~tom7/papers/smlsc2-ml06.pdf">A Separate Compilation Extension to Standard ML</ulink>.\r
26250 David Swasey, Tom Murphy VII, Karl Crary and Robert Harper.\r
26251 <link linkend="References_ML">ML</link> 2006.\r
26252</simpara>\r
26253</listitem>\r
26254</itemizedlist>\r
26255</section>\r
26256<section id="_anchor_id_references_ttt_xreflabel_references_ttt_t">\r
26257<title><anchor id="References_TTT" xreflabel="[References_TTT]"/>T</title>\r
26258<itemizedlist>\r
26259<listitem>\r
26260<simpara>\r
26261<anchor id="References_TarditiAppel00" xreflabel="[References_TarditiAppel00]"/>\r
26262 <ulink url="http://www.smlnj.org/doc/ML-Yacc/index.html">ML-Yacc User&#8217;s Manual. Version 2.4</ulink>\r
26263 David R. Tarditi and Andrew W. Appel. 2000.\r
26264</simpara>\r
26265</listitem>\r
26266<listitem>\r
26267<simpara>\r
26268<anchor id="References_TarditiEtAl90" xreflabel="[References_TarditiEtAl90]"/>\r
26269 <ulink url="http://research.microsoft.com/pubs/68738/loplas-sml2c.ps">No Assembly Required: Compiling Standard ML to C</ulink>.\r
26270 David Tarditi, Peter Lee, and Anurag Acharya. 1990.\r
26271</simpara>\r
26272</listitem>\r
26273<listitem>\r
26274<simpara>\r
26275<anchor id="References_ThorupTofte94" xreflabel="[References_ThorupTofte94]"/>\r
26276 <ulink url="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.53.5372&amp;rep=rep1&amp;type=ps">Object-oriented programming and Standard ML</ulink>.\r
26277 Lars Thorup and Mads Tofte.\r
26278 <link linkend="References_ML">ML</link>, 1994.\r
26279</simpara>\r
26280</listitem>\r
26281<listitem>\r
26282<simpara>\r
26283<anchor id="References_Tofte90" xreflabel="[References_Tofte90]"/>\r
26284 Type Inference for Polymorphic References.\r
26285 Mads Tofte.\r
26286 <link linkend="References_IC">IC</link> 1990.\r
26287</simpara>\r
26288</listitem>\r
26289<listitem>\r
26290<simpara>\r
26291<anchor id="References_Tofte96" xreflabel="[References_Tofte96]"/>\r
26292 <ulink url="http://www.itu.dk/courses/FDP/E2004/Tofte-1996-Essentials_of_SML_Modules.pdf">Essentials of Standard ML Modules</ulink>.\r
26293 Mads Tofte.\r
26294</simpara>\r
26295</listitem>\r
26296<listitem>\r
26297<simpara>\r
26298<anchor id="References_Tofte09" xreflabel="[References_Tofte09]"/>\r
26299 <ulink url="http://www.itu.dk/people/tofte/publ/tips.pdf">Tips for Computer Scientists on Standard ML (Revised)</ulink>.\r
26300 Mads Tofte.\r
26301</simpara>\r
26302</listitem>\r
26303<listitem>\r
26304<simpara>\r
26305<anchor id="References_TolmachAppel95" xreflabel="[References_TolmachAppel95]"/>\r
26306 <ulink url="http://web.cecs.pdx.edu/~apt/jfp95.ps">A Debugger for Standard ML</ulink>.\r
26307 Andrew Tolmach and Andrew W. Appel.\r
26308 <link linkend="References_JFP">JFP</link> 1995.\r
26309</simpara>\r
26310</listitem>\r
26311<listitem>\r
26312<simpara>\r
26313<anchor id="References_Tolmach97" xreflabel="[References_Tolmach97]"/>\r
26314 <ulink url="http://web.cecs.pdx.edu/~apt/tic97.ps">Combining Closure Conversion with Closure Analysis using Algebraic Types</ulink>.\r
26315 Andrew Tolmach.\r
26316 <link linkend="References_TIC">TIC</link> 1997.\r
26317</simpara>\r
26318<blockquote>\r
26319<simpara>Describes a closure-conversion algorithm for a monomorphic IL. The\r
26320algorithm uses a unification-based flow analysis followed by\r
26321defunctionalization and is similar to the approach used in MLton\r
26322(<link linkend="References_CejtinEtAl00">CejtinEtAl00</link>).</simpara>\r
26323</blockquote>\r
26324</listitem>\r
26325<listitem>\r
26326<simpara>\r
26327<anchor id="References_TolmachOliva98" xreflabel="[References_TolmachOliva98]"/>\r
26328 <ulink url="http://web.cecs.pdx.edu/~apt/jfp98.ps">From ML to Ada: Strongly-typed Language Interoperability via Source Translation</ulink>.\r
26329 Andrew Tolmach and Dino Oliva.\r
26330 <link linkend="References_JFP">JFP</link> 1998.\r
26331</simpara>\r
26332<blockquote>\r
26333<simpara>Describes a compiler for RML, a core SML-like language. The compiler\r
26334is similar in structure to MLton, using monomorphisation,\r
26335defunctionalization, and optimization on a first-order IL.</simpara>\r
26336</blockquote>\r
26337</listitem>\r
26338</itemizedlist>\r
26339</section>\r
26340<section id="_anchor_id_references_uuu_xreflabel_references_uuu_u">\r
26341<title><anchor id="References_UUU" xreflabel="[References_UUU]"/>U</title>\r
26342<itemizedlist>\r
26343<listitem>\r
26344<simpara>\r
26345<anchor id="References_Ullman98" xreflabel="[References_Ullman98]"/>\r
26346 <ulink url="http://www-db.stanford.edu/~ullman/emlp.html">Elements of ML Programming</ulink>\r
26347 (<ulink url="http://www3.addall.com/New/submitNew.cgi?query=0137903871&amp;type=ISBN">addall</ulink>).\r
26348 ISBN 0137903871.\r
26349 Jeffrey D. Ullman.\r
26350 Prentice-Hall, 1998.\r
26351</simpara>\r
26352</listitem>\r
26353</itemizedlist>\r
26354</section>\r
26355<section id="_anchor_id_references_vvv_xreflabel_references_vvv_v">\r
26356<title><anchor id="References_VVV" xreflabel="[References_VVV]"/>V</title>\r
26357<simpara></simpara>\r
26358</section>\r
26359<section id="_anchor_id_references_www_xreflabel_references_www_w">\r
26360<title><anchor id="References_WWW" xreflabel="[References_WWW]"/>W</title>\r
26361<itemizedlist>\r
26362<listitem>\r
26363<simpara>\r
26364<anchor id="References_Wand84" xreflabel="[References_Wand84]"/>\r
26365 <ulink url="http://portal.acm.org/citation.cfm?id=800527">A Types-as-Sets Semantics for Milner-Style Polymorphism</ulink>.\r
26366 Mitchell Wand.\r
26367 <link linkend="References_POPL">POPL</link> 1984.\r
26368</simpara>\r
26369</listitem>\r
26370<listitem>\r
26371<simpara>\r
26372<anchor id="References_Wang01" xreflabel="[References_Wang01]"/>\r
26373 <ulink url="http://ncstrl.cs.princeton.edu/expand.php?id=TR-640-01">Managing Memory with Types</ulink>.\r
26374 Daniel C. Wang.\r
26375 PhD Thesis.\r
26376</simpara>\r
26377<blockquote>\r
26378<simpara>Chapter 6 describes an implementation of a type-preserving garbage\r
26379collector for MLton.</simpara>\r
26380</blockquote>\r
26381</listitem>\r
26382<listitem>\r
26383<simpara>\r
26384<anchor id="References_WangAppel01" xreflabel="[References_WangAppel01]"/>\r
26385 <ulink url="http://www.cs.princeton.edu/~appel/papers/typegc.pdf">Type-Preserving Garbage Collectors</ulink>.\r
26386 Daniel C. Wang and Andrew W. Appel.\r
26387 <link linkend="References_POPL">POPL</link> 2001.\r
26388</simpara>\r
26389<blockquote>\r
26390<simpara>Shows how to modify MLton to generate a strongly-typed garbage\r
26391collector as part of a program.</simpara>\r
26392</blockquote>\r
26393</listitem>\r
26394<listitem>\r
26395<simpara>\r
26396<anchor id="References_WangMurphy02" xreflabel="[References_WangMurphy02]"/>\r
26397 <ulink url="http://www.cs.cmu.edu/~tom7/papers/wang-murphy-recursion.pdf">Programming With Recursion Schemes</ulink>.\r
26398 Daniel C. Wang and Tom Murphy VII.\r
26399</simpara>\r
26400<blockquote>\r
26401<simpara>Describes a programming technique for data abstraction, along with\r
26402benchmarks of MLton and other SML compilers.</simpara>\r
26403</blockquote>\r
26404</listitem>\r
26405<listitem>\r
26406<simpara>\r
26407<anchor id="References_Weeks06" xreflabel="[References_Weeks06]"/>\r
26408 <ulink url="guide/References.attachments/060916-mlton.pdf">Whole-Program Compilation in MLton</ulink>.\r
26409 Stephen Weeks.\r
26410 <link linkend="References_ML">ML</link> 2006.\r
26411</simpara>\r
26412</listitem>\r
26413<listitem>\r
26414<simpara>\r
26415<anchor id="References_Wright95" xreflabel="[References_Wright95]"/>\r
26416 <ulink url="http://homepages.inf.ed.ac.uk/dts/fps/papers/wright.ps.gz">Simple Imperative Polymorphism</ulink>.\r
26417 Andrew Wright.\r
26418 <link linkend="References_LASC">LASC</link>, 8(4):343-355, 1995.\r
26419</simpara>\r
26420<blockquote>\r
26421<simpara>The origin of the <link linkend="ValueRestriction">ValueRestriction</link>.</simpara>\r
26422</blockquote>\r
26423</listitem>\r
26424</itemizedlist>\r
26425</section>\r
26426<section id="_anchor_id_references_xxx_xreflabel_references_xxx_x">\r
26427<title><anchor id="References_XXX" xreflabel="[References_XXX]"/>X</title>\r
26428<simpara></simpara>\r
26429</section>\r
26430<section id="_anchor_id_references_yyy_xreflabel_references_yyy_y">\r
26431<title><anchor id="References_YYY" xreflabel="[References_YYY]"/>Y</title>\r
26432<itemizedlist>\r
26433<listitem>\r
26434<simpara>\r
26435<anchor id="References_Yang98" xreflabel="[References_Yang98]"/>\r
26436 <ulink url="http://cs.nyu.edu/zheyang/papers/YangZ--ICFP98.html">Encoding Types in ML-like Languages</ulink>.\r
26437 Zhe Yang.\r
26438 <link linkend="References_ICFP">ICFP</link> 1998.\r
26439</simpara>\r
26440</listitem>\r
26441</itemizedlist>\r
26442</section>\r
26443<section id="_anchor_id_references_zzz_xreflabel_references_zzz_z">\r
26444<title><anchor id="References_ZZZ" xreflabel="[References_ZZZ]"/>Z</title>\r
26445<itemizedlist>\r
26446<listitem>\r
26447<simpara>\r
26448<anchor id="References_ZiarekEtAl06" xreflabel="[References_ZiarekEtAl06]"/>\r
26449 <ulink url="http://www.cs.purdue.edu/homes/lziarek/icfp06.pdf">Stabilizers: A Modular Checkpointing Abstraction for Concurrent Functional Programs</ulink>.\r
26450 Lukasz Ziarek, Philip Schatz, and Suresh Jagannathan.\r
26451 <link linkend="References_ICFP">ICFP</link> 2006.\r
26452</simpara>\r
26453</listitem>\r
26454<listitem>\r
26455<simpara>\r
26456<anchor id="References_ZiarekEtAl08" xreflabel="[References_ZiarekEtAl08]"/>\r
26457 <ulink url="http://www.cse.buffalo.edu/~lziarek/hosc.pdf">Flattening tuples in an SSA intermediate representation</ulink>.\r
26458 Lukasz Ziarek, Stephen Weeks, and Suresh Jagannathan.\r
26459 <link linkend="References_HOSC">HOSC</link> 2008.\r
26460</simpara>\r
26461</listitem>\r
26462</itemizedlist>\r
26463</section>\r
26464<section id="_abbreviations">\r
26465<title>Abbreviations</title>\r
26466<itemizedlist>\r
26467<listitem>\r
26468<simpara>\r
26469<anchor id="References_ACSD" xreflabel="[References_ACSD]"/> ACSD = International Conference on Application of Concurrency to System Design\r
26470</simpara>\r
26471</listitem>\r
26472<listitem>\r
26473<simpara>\r
26474<anchor id="References_BABEL" xreflabel="[References_BABEL]"/> BABEL = Workshop on multi-language infrastructure and interoperability\r
26475</simpara>\r
26476</listitem>\r
26477<listitem>\r
26478<simpara>\r
26479<anchor id="References_CC" xreflabel="[References_CC]"/> CC = International Conference on Compiler Construction\r
26480</simpara>\r
26481</listitem>\r
26482<listitem>\r
26483<simpara>\r
26484<anchor id="References_DPCOOL" xreflabel="[References_DPCOOL]"/> DPCOOL = Workshop on Declarative Programming in the Context of OO Languages\r
26485</simpara>\r
26486</listitem>\r
26487<listitem>\r
26488<simpara>\r
26489<anchor id="References_ESOP" xreflabel="[References_ESOP]"/> ESOP = European Symposium on Programming\r
26490</simpara>\r
26491</listitem>\r
26492<listitem>\r
26493<simpara>\r
26494<anchor id="References_FLOPS" xreflabel="[References_FLOPS]"/> FLOPS = Symposium on Functional and Logic Programming\r
26495</simpara>\r
26496</listitem>\r
26497<listitem>\r
26498<simpara>\r
26499<anchor id="References_FPCA" xreflabel="[References_FPCA]"/> FPCA = Conference on Functional Programming Languages and Computer Architecture\r
26500</simpara>\r
26501</listitem>\r
26502<listitem>\r
26503<simpara>\r
26504<anchor id="References_HOSC" xreflabel="[References_HOSC]"/> HOSC = Higher-Order and Symbolic Computation\r
26505</simpara>\r
26506</listitem>\r
26507<listitem>\r
26508<simpara>\r
26509<anchor id="References_IC" xreflabel="[References_IC]"/> IC = Information and Computation\r
26510</simpara>\r
26511</listitem>\r
26512<listitem>\r
26513<simpara>\r
26514<anchor id="References_ICCL" xreflabel="[References_ICCL]"/> ICCL = IEEE International Conference on Computer Languages\r
26515</simpara>\r
26516</listitem>\r
26517<listitem>\r
26518<simpara>\r
26519<anchor id="References_ICFP" xreflabel="[References_ICFP]"/> ICFP = International Conference on Functional Programming\r
26520</simpara>\r
26521</listitem>\r
26522<listitem>\r
26523<simpara>\r
26524<anchor id="References_IFL" xreflabel="[References_IFL]"/> IFL = International Workshop on Implementation and Application of Functional Languages\r
26525</simpara>\r
26526</listitem>\r
26527<listitem>\r
26528<simpara>\r
26529<anchor id="References_IVME" xreflabel="[References_IVME]"/> IVME = Workshop on Interpreters, Virtual Machines and Emulators\r
26530</simpara>\r
26531</listitem>\r
26532<listitem>\r
26533<simpara>\r
26534<anchor id="References_JFLA" xreflabel="[References_JFLA]"/> JFLA = Journees Francophones des Langages Applicatifs\r
26535</simpara>\r
26536</listitem>\r
26537<listitem>\r
26538<simpara>\r
26539<anchor id="References_JFP" xreflabel="[References_JFP]"/> JFP = Journal of Functional Programming\r
26540</simpara>\r
26541</listitem>\r
26542<listitem>\r
26543<simpara>\r
26544<anchor id="References_LASC" xreflabel="[References_LASC]"/> LASC = Lisp and Symbolic Computation\r
26545</simpara>\r
26546</listitem>\r
26547<listitem>\r
26548<simpara>\r
26549<anchor id="References_LFP" xreflabel="[References_LFP]"/> LFP = Lisp and Functional Programming\r
26550</simpara>\r
26551</listitem>\r
26552<listitem>\r
26553<simpara>\r
26554<anchor id="References_ML" xreflabel="[References_ML]"/> ML = Workshop on ML\r
26555</simpara>\r
26556</listitem>\r
26557<listitem>\r
26558<simpara>\r
26559<anchor id="References_PLDI" xreflabel="[References_PLDI]"/> PLDI = Conference on Programming Language Design and Implementation\r
26560</simpara>\r
26561</listitem>\r
26562<listitem>\r
26563<simpara>\r
26564<anchor id="References_POPL" xreflabel="[References_POPL]"/> POPL = Symposium on Principles of Programming Languages\r
26565</simpara>\r
26566</listitem>\r
26567<listitem>\r
26568<simpara>\r
26569<anchor id="References_PPDP" xreflabel="[References_PPDP]"/> PPDP = International Conference on Principles and Practice of Declarative Programming\r
26570</simpara>\r
26571</listitem>\r
26572<listitem>\r
26573<simpara>\r
26574<anchor id="References_PPoPP" xreflabel="[References_PPoPP]"/> PPoPP = Principles and Practice of Parallel Programming\r
26575</simpara>\r
26576</listitem>\r
26577<listitem>\r
26578<simpara>\r
26579<anchor id="References_TCS" xreflabel="[References_TCS]"/> TCS = IFIP International Conference on Theoretical Computer Science\r
26580</simpara>\r
26581</listitem>\r
26582<listitem>\r
26583<simpara>\r
26584<anchor id="References_TIC" xreflabel="[References_TIC]"/> TIC = Types in Compilation\r
26585</simpara>\r
26586</listitem>\r
26587<listitem>\r
26588<simpara>\r
26589<anchor id="References_TLDI" xreflabel="[References_TLDI]"/> TLDI = Workshop on Types in Language Design and Implementation\r
26590</simpara>\r
26591</listitem>\r
26592<listitem>\r
26593<simpara>\r
26594<anchor id="References_TOPLAS" xreflabel="[References_TOPLAS]"/> TOPLAS = Transactions on Programming Languages and Systems\r
26595</simpara>\r
26596</listitem>\r
26597<listitem>\r
26598<simpara>\r
26599<anchor id="References_TPHOLs" xreflabel="[References_TPHOLs]"/> TPHOLs = International Conference on Theorem Proving in Higher Order Logics\r
26600</simpara>\r
26601</listitem>\r
26602</itemizedlist>\r
26603<simpara><?asciidoc-pagebreak?></simpara>\r
26604</section>\r
26605</section>\r
26606<section id="RefFlatten">\r
26607<title>RefFlatten</title>\r
26608<simpara><link linkend="RefFlatten">RefFlatten</link> is an optimization pass for the <link linkend="SSA2">SSA2</link>\r
26609<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="SSA2Simplify">SSA2Simplify</link>.</simpara>\r
26610<section id="_description_48">\r
26611<title>Description</title>\r
26612<simpara>This pass flattens a <literal>ref</literal> cell into its containing object.\r
26613The idea is to replace, where possible, a type like</simpara>\r
26614<screen>(int ref * real)</screen>\r
26615<simpara>with a type like</simpara>\r
26616<screen>(int[m] * real)</screen>\r
26617<simpara>where the <literal>[m]</literal> indicates a mutable field of a tuple.</simpara>\r
26618</section>\r
26619<section id="_implementation_53">\r
26620<title>Implementation</title>\r
26621<itemizedlist>\r
26622<listitem>\r
26623<simpara>\r
26624<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/ref-flatten.fun"><literal>ref-flatten.fun</literal></ulink>\r
26625</simpara>\r
26626</listitem>\r
26627</itemizedlist>\r
26628</section>\r
26629<section id="_details_and_notes_51">\r
26630<title>Details and Notes</title>\r
26631<simpara>The savings is obvious, I hope. We avoid an extra heap-allocated\r
26632object for the <literal>ref</literal>, which in the above case saves two words. We\r
26633also save the time and code for the extra indirection at each get and\r
26634set. There are lots of useful data structures (singly-linked and\r
26635doubly-linked lists, union-find, Fibonacci heaps, &#8230;) that I believe\r
26636we are paying through the nose right now because of the absence of ref\r
26637flattening.</simpara>\r
26638<simpara>The idea is to compute for each occurrence of a <literal>ref</literal> type in the\r
26639program whether or not that <literal>ref</literal> can be represented as an offset of\r
26640some object (constructor or tuple). As before, a unification-based\r
26641whole-program with deep abstract values makes sure the analysis is\r
26642consistent.</simpara>\r
26643<simpara>The only syntactic part of the analysis that remains is the part that\r
26644checks that for a variable bound to a value constructed by <literal>Ref_ref</literal>:</simpara>\r
26645<itemizedlist>\r
26646<listitem>\r
26647<simpara>\r
26648the object allocation is in the same block. This is pretty\r
26649draconian, and it would be nice to generalize it some day to allow\r
26650flattening as long as the <literal>ref</literal> allocation and object allocation "line\r
26651up one-to-one" in the same loop-free chunk of code.\r
26652</simpara>\r
26653</listitem>\r
26654<listitem>\r
26655<simpara>\r
26656updates occur in the same block (and hence it is safe-for-space\r
26657because the containing object is still alive). It would be nice to\r
26658relax this to allow updates as long as it can be provedthat the\r
26659container is live.\r
26660</simpara>\r
26661</listitem>\r
26662</itemizedlist>\r
26663<simpara>Prevent flattening of <literal>unit ref</literal>-s.</simpara>\r
26664<simpara><link linkend="RefFlatten">RefFlatten</link> is safe for space. The idea is to prevent a <literal>ref</literal>\r
26665being flattened into an object that has a component of unbounded size\r
26666(other than possibly the <literal>ref</literal> itself) unless we can prove that at\r
26667each point the <literal>ref</literal> is live, then the containing object is live too.\r
26668I used a pretty simple approximation to liveness.</simpara>\r
26669<simpara><?asciidoc-pagebreak?></simpara>\r
26670</section>\r
26671</section>\r
26672<section id="Regions">\r
26673<title>Regions</title>\r
26674<simpara>In region-based memory management, the heap is divided into a\r
26675collection of regions into which objects are allocated. At compile\r
26676time, either in the source program or through automatic inference,\r
26677allocation points are annotated with the region in which the\r
26678allocation will occur. Typically, although not always, the regions\r
26679are allocated and deallocated according to a stack discipline.</simpara>\r
26680<simpara>MLton does not use region-based memory management; it uses traditional\r
26681<link linkend="GarbageCollection">GarbageCollection</link>. We have considered integrating regions with\r
26682MLton, but in our opinion it is far from clear that regions would\r
26683provide MLton with improved performance, while they would certainly\r
26684add a lot of complexity to the compiler and complicate reasoning about\r
26685and achieving <link linkend="SpaceSafety">SpaceSafety</link>. Region-based memory management and\r
26686garbage collection have different strengths and weaknesses; it&#8217;s\r
26687pretty easy to come up with programs that do significantly better\r
26688under regions than under GC, and vice versa. We believe that it is\r
26689the case that common SML idioms tend to work better under GC than\r
26690under regions.</simpara>\r
26691<simpara>One common argument for regions is that the region operations can all\r
26692be done in (approximately) constant time; therefore, you eliminate GC\r
26693pause times, leading to a real-time GC. However, because of space\r
26694safety concerns (see below), we believe that region-based memory\r
26695management for SML must also include a traditional garbage collector.\r
26696Hence, to achieve real-time memory management for MLton/SML, we\r
26697believe that it would be both easier and more efficient to implement a\r
26698traditional real-time garbage collector than it would be to implement\r
26699a region system.</simpara>\r
26700<section id="_regions_the_ml_kit_and_space_safety">\r
26701<title>Regions, the ML Kit, and space safety</title>\r
26702<simpara>The <link linkend="MLKit">ML Kit</link> pioneered the use of regions for compiling\r
26703Standard ML. The ML Kit maintains a stack of regions at run time. At\r
26704compile time, it uses region inference to decide when data can be\r
26705allocated in a stack-like manner, assigning it to an appropriate\r
26706region. The ML Kit has put a lot of effort into improving the\r
26707supporting analyses and representations of regions, which are all\r
26708necessary to improve the performance.</simpara>\r
26709<simpara>Unfortunately, under a pure stack-based region system, space leaks are\r
26710inevitable in theory, and costly in practice. Data for which region\r
26711inference can not determine the lifetime is moved into the "global\r
26712region" whose lifetime is the entire program. There are two ways in\r
26713which region inference will place an object to the global region.</simpara>\r
26714<itemizedlist>\r
26715<listitem>\r
26716<simpara>\r
26717When the inference is too conservative, that is, when the data is\r
26718used in a stack-like manner but the region inference can&#8217;t figure it\r
26719out.\r
26720</simpara>\r
26721</listitem>\r
26722<listitem>\r
26723<simpara>\r
26724When data is not used in a stack-like manner. In this case,\r
26725correctness requires region inference to place the object\r
26726</simpara>\r
26727</listitem>\r
26728</itemizedlist>\r
26729<simpara>This global region is a source of space leaks. No matter what region\r
26730system you use, there are some programs such that the global region\r
26731must exist, and its size will grow to an unbounded multiple of the\r
26732live data size. For these programs one must have a GC to achieve\r
26733space safety.</simpara>\r
26734<simpara>To solve this problem, the ML Kit has undergone work to combine\r
26735garbage collection with region-based memory management.\r
26736<link linkend="References_HallenbergEtAl02">HallenbergEtAl02</link> and <link linkend="References_Elsman03">Elsman03</link> describe the addition\r
26737of a garbage collector to the ML Kit&#8217;s region-based system. These\r
26738papers provide convincing evidence for space leaks in the global\r
26739region. They show a number of benchmarks where the memory usage of\r
26740the program running with just regions is a large multiple (2, 10, 50,\r
26741even 150) of the program running with regions plus GC.</simpara>\r
26742<simpara>These papers also give some numbers to show the ML Kit with just\r
26743regions does better than either a system with just GC or a combined\r
26744system. Unfortunately, a pure region system isn&#8217;t practical because\r
26745of the lack of space safety. And the other performance numbers are\r
26746not so convincing, because they compare to an old version of SML/NJ\r
26747and not at all with MLton. It would be interesting to see a\r
26748comparison with a more serious collector.</simpara>\r
26749</section>\r
26750<section id="_regions_garbage_collection_and_cyclone">\r
26751<title>Regions, Garbage Collection, and Cyclone</title>\r
26752<simpara>One possibility is to take Cyclone&#8217;s approach, and provide both\r
26753region-based memory management and garbage collection, but at the\r
26754programmer&#8217;s option (<link linkend="References_GrossmanEtAl02">GrossmanEtAl02</link>, <link linkend="References_HicksEtAl03">HicksEtAl03</link>).</simpara>\r
26755<simpara>One might ask whether we might do the same thing&#8201;&#8212;&#8201;i.e., provide a\r
26756<literal>MLton.Regions</literal> structure with explicit region based memory\r
26757management operations, so that the programmer could use them when\r
26758appropriate. <link linkend="MatthewFluet">MatthewFluet</link> has thought about this question</simpara>\r
26759<itemizedlist>\r
26760<listitem>\r
26761<simpara>\r
26762<ulink url="http://www.cs.cornell.edu/People/fluet/rgn-monad/index.html">http://www.cs.cornell.edu/People/fluet/rgn-monad/index.html</ulink>\r
26763</simpara>\r
26764</listitem>\r
26765</itemizedlist>\r
26766<simpara>Unfortunately, his conclusion is that the SML type system is too weak\r
26767to support this option, although there might be a "poor-man&#8217;s" version\r
26768with dynamic checks.</simpara>\r
26769<simpara><?asciidoc-pagebreak?></simpara>\r
26770</section>\r
26771</section>\r
26772<section id="Release20041109">\r
26773<title>Release20041109</title>\r
26774<simpara>This is an archived public release of MLton, version 20041109.</simpara>\r
26775<section id="_changes_since_the_last_public_release">\r
26776<title>Changes since the last public release</title>\r
26777<itemizedlist>\r
26778<listitem>\r
26779<simpara>\r
26780New platforms:\r
26781</simpara>\r
26782<itemizedlist>\r
26783<listitem>\r
26784<simpara>\r
26785x86: FreeBSD 5.x, OpenBSD\r
26786</simpara>\r
26787</listitem>\r
26788<listitem>\r
26789<simpara>\r
26790PowerPC: Darwin (MacOSX)\r
26791</simpara>\r
26792</listitem>\r
26793</itemizedlist>\r
26794</listitem>\r
26795<listitem>\r
26796<simpara>\r
26797Support for the <link linkend="MLBasis">ML Basis system</link>, a new mechanism supporting programming in the very large, separate delivery of library sources, and more.\r
26798</simpara>\r
26799</listitem>\r
26800<listitem>\r
26801<simpara>\r
26802Support for dynamic libraries.\r
26803</simpara>\r
26804</listitem>\r
26805<listitem>\r
26806<simpara>\r
26807Support for <link linkend="ConcurrentML">ConcurrentML</link> (CML).\r
26808</simpara>\r
26809</listitem>\r
26810<listitem>\r
26811<simpara>\r
26812New structures: <literal>Int2</literal>, <literal>Int3</literal>, &#8230;, <literal>Int31</literal> and <literal>Word2</literal>, <literal>Word3</literal>, &#8230;, <literal>Word31</literal>.\r
26813</simpara>\r
26814</listitem>\r
26815<listitem>\r
26816<simpara>\r
26817Front-end bug fixes and improvements.\r
26818</simpara>\r
26819</listitem>\r
26820<listitem>\r
26821<simpara>\r
26822A new form of profiling with <literal>-profile count</literal>, which can be used to test code coverage.\r
26823</simpara>\r
26824</listitem>\r
26825<listitem>\r
26826<simpara>\r
26827A bytecode generator, available via <literal>-codegen bytecode</literal>.\r
26828</simpara>\r
26829</listitem>\r
26830<listitem>\r
26831<simpara>\r
26832Representation improvements:\r
26833</simpara>\r
26834<itemizedlist>\r
26835<listitem>\r
26836<simpara>\r
26837Tuples and datatypes are packed to decrease space usage.\r
26838</simpara>\r
26839</listitem>\r
26840<listitem>\r
26841<simpara>\r
26842Ref cells may be unboxed into their containing object.\r
26843</simpara>\r
26844</listitem>\r
26845<listitem>\r
26846<simpara>\r
26847Arrays of tuples may represent the tuples unboxed.\r
26848</simpara>\r
26849</listitem>\r
26850</itemizedlist>\r
26851</listitem>\r
26852</itemizedlist>\r
26853<simpara>For a complete list of changes and bug fixes since 20040227, see the\r
26854<ulink url="https://raw.github.com/MLton/mlton/on-20041109-release/doc/changelog"><literal>changelog</literal></ulink>.</simpara>\r
26855</section>\r
26856<section id="_also_see_31">\r
26857<title>Also see</title>\r
26858<itemizedlist>\r
26859<listitem>\r
26860<simpara>\r
26861<link linkend="Bugs20041109">Bugs20041109</link>\r
26862</simpara>\r
26863</listitem>\r
26864</itemizedlist>\r
26865<simpara><?asciidoc-pagebreak?></simpara>\r
26866</section>\r
26867</section>\r
26868<section id="Release20051202">\r
26869<title>Release20051202</title>\r
26870<simpara>This is an archived public release of MLton, version 20051202.</simpara>\r
26871<section id="_changes_since_the_last_public_release_2">\r
26872<title>Changes since the last public release</title>\r
26873<itemizedlist>\r
26874<listitem>\r
26875<simpara>\r
26876The <link linkend="License">MLton license</link> is now BSD-style instead of the GPL.\r
26877</simpara>\r
26878</listitem>\r
26879<listitem>\r
26880<simpara>\r
26881New platforms: <link linkend="RunningOnMinGW">X86/MinGW</link> and HPPA/Linux.\r
26882</simpara>\r
26883</listitem>\r
26884<listitem>\r
26885<simpara>\r
26886Improved and expanded documentation, based on the MLton wiki.\r
26887</simpara>\r
26888</listitem>\r
26889<listitem>\r
26890<simpara>\r
26891Compiler.\r
26892</simpara>\r
26893<itemizedlist>\r
26894<listitem>\r
26895<simpara>\r
26896improved exception history.\r
26897</simpara>\r
26898</listitem>\r
26899<listitem>\r
26900<simpara>\r
26901<link linkend="CompileTimeOptions">Command-line switches</link>.\r
26902</simpara>\r
26903<itemizedlist>\r
26904<listitem>\r
26905<simpara>\r
26906Added: <literal>-as-opt</literal>, <literal>-mlb-path-map</literal>, <literal>-target-as-opt</literal>, <literal>-target-cc-opt</literal>.\r
26907</simpara>\r
26908</listitem>\r
26909<listitem>\r
26910<simpara>\r
26911Removed: <literal>-native</literal>, <literal>-sequence-unit</literal>, <literal>-warn-match</literal>, <literal>-warn-unused</literal>.\r
26912</simpara>\r
26913</listitem>\r
26914</itemizedlist>\r
26915</listitem>\r
26916</itemizedlist>\r
26917</listitem>\r
26918<listitem>\r
26919<simpara>\r
26920Language.\r
26921</simpara>\r
26922<itemizedlist>\r
26923<listitem>\r
26924<simpara>\r
26925<link linkend="ForeignFunctionInterface">FFI</link> syntax changes and extensions.\r
26926</simpara>\r
26927<itemizedlist>\r
26928<listitem>\r
26929<simpara>\r
26930Added: <literal>_symbol</literal>.\r
26931</simpara>\r
26932</listitem>\r
26933<listitem>\r
26934<simpara>\r
26935Changed: <literal>_export</literal>, <literal>_import</literal>.\r
26936</simpara>\r
26937</listitem>\r
26938<listitem>\r
26939<simpara>\r
26940Removed: <literal>_ffi</literal>.\r
26941</simpara>\r
26942</listitem>\r
26943</itemizedlist>\r
26944</listitem>\r
26945<listitem>\r
26946<simpara>\r
26947<link linkend="MLBasisAnnotations">ML Basis annotations</link>.\r
26948</simpara>\r
26949<itemizedlist>\r
26950<listitem>\r
26951<simpara>\r
26952Added: <literal>allowFFI</literal>, <literal>nonexhaustiveExnMatch</literal>, <literal>nonexhaustiveMatch</literal>, <literal>redundantMatch</literal>, <literal>sequenceNonUnit</literal>.\r
26953</simpara>\r
26954</listitem>\r
26955<listitem>\r
26956<simpara>\r
26957Deprecated: <literal>allowExport</literal>, <literal>allowImport</literal>, <literal>sequenceUnit</literal>, <literal>warnMatch</literal>.\r
26958</simpara>\r
26959</listitem>\r
26960</itemizedlist>\r
26961</listitem>\r
26962</itemizedlist>\r
26963</listitem>\r
26964<listitem>\r
26965<simpara>\r
26966Libraries.\r
26967</simpara>\r
26968<itemizedlist>\r
26969<listitem>\r
26970<simpara>\r
26971Basis Library.\r
26972</simpara>\r
26973<itemizedlist>\r
26974<listitem>\r
26975<simpara>\r
26976Added: <literal>Int1</literal>, <literal>Word1</literal>.\r
26977</simpara>\r
26978</listitem>\r
26979</itemizedlist>\r
26980</listitem>\r
26981<listitem>\r
26982<simpara>\r
26983<link linkend="MLtonStructure">MLton structure</link>.\r
26984</simpara>\r
26985<itemizedlist>\r
26986<listitem>\r
26987<simpara>\r
26988Added: <literal>Process.create</literal>, <literal>ProcEnv.setgroups</literal>, <literal>Rusage.measureGC</literal>, <literal>Socket.fdToSock</literal>, <literal>Socket.Ctl.getError</literal>.\r
26989</simpara>\r
26990</listitem>\r
26991<listitem>\r
26992<simpara>\r
26993Changed: <literal>MLton.Platform.Arch</literal>.\r
26994</simpara>\r
26995</listitem>\r
26996</itemizedlist>\r
26997</listitem>\r
26998<listitem>\r
26999<simpara>\r
27000Other libraries.\r
27001</simpara>\r
27002<itemizedlist>\r
27003<listitem>\r
27004<simpara>\r
27005Added: <link linkend="CKitLibrary">ckit</link>, <link linkend="MLNLFFI">ML-NLFFI library</link>, <link linkend="SMLNJLibrary">SML/NJ library</link>.\r
27006</simpara>\r
27007</listitem>\r
27008</itemizedlist>\r
27009</listitem>\r
27010</itemizedlist>\r
27011</listitem>\r
27012<listitem>\r
27013<simpara>\r
27014Tools.\r
27015</simpara>\r
27016<itemizedlist>\r
27017<listitem>\r
27018<simpara>\r
27019Updates of <literal>mllex</literal> and <literal>mlyacc</literal> from SML/NJ.\r
27020</simpara>\r
27021</listitem>\r
27022<listitem>\r
27023<simpara>\r
27024Added <link linkend="MLNLFFI">mlnlffigen</link>.\r
27025</simpara>\r
27026</listitem>\r
27027<listitem>\r
27028<simpara>\r
27029<link linkend="Profiling">Profiling</link> supports better inclusion/exclusion of code.\r
27030</simpara>\r
27031</listitem>\r
27032</itemizedlist>\r
27033</listitem>\r
27034</itemizedlist>\r
27035<simpara>For a complete list of changes and bug fixes since\r
27036<link linkend="Release20041109">Release20041109</link>, see the\r
27037<ulink url="https://raw.github.com/MLton/mlton/on-20051202-release/doc/changelog"><literal>changelog</literal></ulink> and\r
27038<link linkend="Bugs20041109">Bugs20041109</link>.</simpara>\r
27039</section>\r
27040<section id="_20051202_binary_packages">\r
27041<title>20051202 binary packages</title>\r
27042<itemizedlist>\r
27043<listitem>\r
27044<simpara>\r
27045x86\r
27046</simpara>\r
27047<itemizedlist>\r
27048<listitem>\r
27049<simpara>\r
27050<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20051202/mlton-20051202-1.i386-cygwin.tgz">Cygwin</ulink> 1.5.18-1\r
27051</simpara>\r
27052</listitem>\r
27053<listitem>\r
27054<simpara>\r
27055<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20051202/mlton-20051202-1.i386-freebsd.tbz">FreeBSD</ulink> 5.4\r
27056</simpara>\r
27057</listitem>\r
27058<listitem>\r
27059<simpara>\r
27060Linux\r
27061</simpara>\r
27062<itemizedlist>\r
27063<listitem>\r
27064<simpara>\r
27065<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20051202/mlton_20051202-1_i386.deb">Debian</ulink> sid\r
27066</simpara>\r
27067</listitem>\r
27068<listitem>\r
27069<simpara>\r
27070<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20051202/mlton_20051202-1_i386.stable.deb">Debian</ulink> stable (Sarge)\r
27071</simpara>\r
27072</listitem>\r
27073<listitem>\r
27074<simpara>\r
27075<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20051202/mlton-20051202-1.i386.rpm">RedHat</ulink> 7.1-9.3 FC1-FC4\r
27076</simpara>\r
27077</listitem>\r
27078<listitem>\r
27079<simpara>\r
27080<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20051202/mlton-20051202-1.i386-linux.tgz">tgz</ulink> for other distributions (glibc 2.3)\r
27081</simpara>\r
27082</listitem>\r
27083</itemizedlist>\r
27084</listitem>\r
27085<listitem>\r
27086<simpara>\r
27087<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20051202/mlton-20051202-1.i386-mingw.tgz">MinGW</ulink>\r
27088</simpara>\r
27089</listitem>\r
27090<listitem>\r
27091<simpara>\r
27092<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20051202/mlton-20051202-1.i386-netbsd.tgz">NetBSD</ulink> 2.0.2\r
27093</simpara>\r
27094</listitem>\r
27095<listitem>\r
27096<simpara>\r
27097<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20051202/mlton-20051202-1.i386-openbsd.tgz">OpenBSD</ulink> 3.7\r
27098</simpara>\r
27099</listitem>\r
27100</itemizedlist>\r
27101</listitem>\r
27102<listitem>\r
27103<simpara>\r
27104PowerPC\r
27105</simpara>\r
27106<itemizedlist>\r
27107<listitem>\r
27108<simpara>\r
27109<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20051202/mlton-20051202-1.powerpc-darwin.tgz">Darwin</ulink> 7.9.0 (Mac OS X)\r
27110</simpara>\r
27111</listitem>\r
27112</itemizedlist>\r
27113</listitem>\r
27114<listitem>\r
27115<simpara>\r
27116Sparc\r
27117</simpara>\r
27118<itemizedlist>\r
27119<listitem>\r
27120<simpara>\r
27121<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20051202/mlton-20051202-1.sparc-solaris.tgz">Solaris</ulink> 8\r
27122</simpara>\r
27123</listitem>\r
27124</itemizedlist>\r
27125</listitem>\r
27126</itemizedlist>\r
27127</section>\r
27128<section id="_20051202_source_packages">\r
27129<title>20051202 source packages</title>\r
27130<itemizedlist>\r
27131<listitem>\r
27132<simpara>\r
27133<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20051202/mlton-20051202-1.src.tgz">source tgz</ulink>\r
27134</simpara>\r
27135</listitem>\r
27136<listitem>\r
27137<simpara>\r
27138Debian <ulink url="http://sourceforge.net/projects/mlton/files/mlton/20051202/mlton_20051202-1.dsc">dsc</ulink>, <ulink url="http://sourceforge.net/projects/mlton/files/mlton/20051202/mlton_20051202-1.diff.gz">diff.gz</ulink>, <ulink url="http://sourceforge.net/projects/mlton/files/mlton/20051202/mlton_20051202.orig.tar.gz">orig.tar.gz</ulink>\r
27139</simpara>\r
27140</listitem>\r
27141<listitem>\r
27142<simpara>\r
27143RedHat <ulink url="http://sourceforge.net/projects/mlton/files/mlton/20051202/mlton-20051202-1.src.rpm">source rpm</ulink>\r
27144</simpara>\r
27145</listitem>\r
27146</itemizedlist>\r
27147</section>\r
27148<section id="_packages_available_at_other_sites">\r
27149<title>Packages available at other sites</title>\r
27150<itemizedlist>\r
27151<listitem>\r
27152<simpara>\r
27153<ulink url="http://packages.debian.org/cgi-bin/search_packages.pl?searchon=names&amp;version=all&amp;exact=1&amp;keywords=mlton">Debian</ulink>\r
27154</simpara>\r
27155</listitem>\r
27156<listitem>\r
27157<simpara>\r
27158<ulink url="http://www.freebsd.org/cgi/ports.cgi?query=mlton&amp;stype=all">FreeBSD</ulink>\r
27159</simpara>\r
27160</listitem>\r
27161<listitem>\r
27162<simpara>\r
27163Fedora Core <ulink url="http://fedoraproject.org/extras/4/i386/repodata/repoview/mlton-0-20051202-8.fc4.html">4</ulink> <ulink url="http://fedoraproject.org/extras/5/i386/repodata/repoview/mlton-0-20051202-8.fc5.html">5</ulink>\r
27164</simpara>\r
27165</listitem>\r
27166<listitem>\r
27167<simpara>\r
27168<ulink url="http://packages.ubuntu.com/dapper/devel/mlton">Ubuntu</ulink>\r
27169</simpara>\r
27170</listitem>\r
27171</itemizedlist>\r
27172</section>\r
27173<section id="_also_see_32">\r
27174<title>Also see</title>\r
27175<itemizedlist>\r
27176<listitem>\r
27177<simpara>\r
27178<link linkend="Bugs20051202">Bugs20051202</link>\r
27179</simpara>\r
27180</listitem>\r
27181<listitem>\r
27182<simpara>\r
27183<ulink url="http://www.mlton.org/guide/20051202/">MLton Guide (20051202)</ulink>.\r
27184</simpara>\r
27185<simpara>A snapshot of the MLton wiki at the time of release.</simpara>\r
27186</listitem>\r
27187</itemizedlist>\r
27188<simpara><?asciidoc-pagebreak?></simpara>\r
27189</section>\r
27190</section>\r
27191<section id="Release20070826">\r
27192<title>Release20070826</title>\r
27193<simpara>This is an archived public release of MLton, version 20070826.</simpara>\r
27194<section id="_changes_since_the_last_public_release_3">\r
27195<title>Changes since the last public release</title>\r
27196<itemizedlist>\r
27197<listitem>\r
27198<simpara>\r
27199New platforms:\r
27200</simpara>\r
27201<itemizedlist>\r
27202<listitem>\r
27203<simpara>\r
27204<link linkend="RunningOnAMD64">AMD64</link>/<link linkend="RunningOnLinux">Linux</link>, <link linkend="RunningOnAMD64">AMD64</link>/<link linkend="RunningOnFreeBSD">FreeBSD</link>\r
27205</simpara>\r
27206</listitem>\r
27207<listitem>\r
27208<simpara>\r
27209<link linkend="RunningOnHPPA">HPPA</link>/<link linkend="RunningOnHPUX">HPUX</link>\r
27210</simpara>\r
27211</listitem>\r
27212<listitem>\r
27213<simpara>\r
27214<link linkend="RunningOnPowerPC">PowerPC</link>/<link linkend="RunningOnAIX">AIX</link>\r
27215</simpara>\r
27216</listitem>\r
27217<listitem>\r
27218<simpara>\r
27219<link linkend="RunningOnX86">X86</link>/<link linkend="RunningOnDarwin">Darwin (Mac OS X)</link>\r
27220</simpara>\r
27221</listitem>\r
27222</itemizedlist>\r
27223</listitem>\r
27224<listitem>\r
27225<simpara>\r
27226Compiler.\r
27227</simpara>\r
27228<itemizedlist>\r
27229<listitem>\r
27230<simpara>\r
27231Support for 64-bit platforms.\r
27232</simpara>\r
27233<itemizedlist>\r
27234<listitem>\r
27235<simpara>\r
27236Native amd64 codegen.\r
27237</simpara>\r
27238</listitem>\r
27239</itemizedlist>\r
27240</listitem>\r
27241<listitem>\r
27242<simpara>\r
27243<link linkend="CompileTimeOptions">Compile-time options</link>.\r
27244</simpara>\r
27245<itemizedlist>\r
27246<listitem>\r
27247<simpara>\r
27248Added: <literal>-codegen amd64</literal>, <literal>-codegen x86</literal>, <literal>-default-type <emphasis>type</emphasis></literal>, <literal>-profile-val {false|true}</literal>.\r
27249</simpara>\r
27250</listitem>\r
27251<listitem>\r
27252<simpara>\r
27253Changed: <literal>-stop f</literal> (file listing now includes <literal>.mlb</literal> files).\r
27254</simpara>\r
27255</listitem>\r
27256</itemizedlist>\r
27257</listitem>\r
27258<listitem>\r
27259<simpara>\r
27260Bytecode codegen.\r
27261</simpara>\r
27262<itemizedlist>\r
27263<listitem>\r
27264<simpara>\r
27265Support for exception history.\r
27266</simpara>\r
27267</listitem>\r
27268<listitem>\r
27269<simpara>\r
27270Support for profiling.\r
27271</simpara>\r
27272</listitem>\r
27273</itemizedlist>\r
27274</listitem>\r
27275</itemizedlist>\r
27276</listitem>\r
27277<listitem>\r
27278<simpara>\r
27279Language.\r
27280</simpara>\r
27281<itemizedlist>\r
27282<listitem>\r
27283<simpara>\r
27284<link linkend="MLBasisAnnotations">ML Basis annotations</link>.\r
27285</simpara>\r
27286<itemizedlist>\r
27287<listitem>\r
27288<simpara>\r
27289Removed: <literal>allowExport</literal>, <literal>allowImport</literal>, <literal>sequenceUnit</literal>, <literal>warnMatch</literal>.\r
27290</simpara>\r
27291</listitem>\r
27292</itemizedlist>\r
27293</listitem>\r
27294</itemizedlist>\r
27295</listitem>\r
27296<listitem>\r
27297<simpara>\r
27298Libraries.\r
27299</simpara>\r
27300<itemizedlist>\r
27301<listitem>\r
27302<simpara>\r
27303<link linkend="BasisLibrary">Basis Library</link>.\r
27304</simpara>\r
27305<itemizedlist>\r
27306<listitem>\r
27307<simpara>\r
27308Added: <literal>PackWord16Big</literal>, <literal>PackWord16Little</literal>, <literal>PackWord64Big</literal>, <literal>PackWord64Little</literal>.\r
27309</simpara>\r
27310</listitem>\r
27311<listitem>\r
27312<simpara>\r
27313Bug fixes: see <ulink url="https://raw.github.com/MLton/mlton/on-20070826-release/doc/changelog"><literal>changelog</literal></ulink>.\r
27314</simpara>\r
27315</listitem>\r
27316</itemizedlist>\r
27317</listitem>\r
27318<listitem>\r
27319<simpara>\r
27320<link linkend="MLtonStructure">MLton structure</link>.\r
27321</simpara>\r
27322<itemizedlist>\r
27323<listitem>\r
27324<simpara>\r
27325Added: <literal>MLTON_MONO_ARRAY</literal>, <literal>MLTON_MONO_VECTOR</literal>, <literal>MLTON_REAL</literal>, <literal>MLton.BinIO.tempPrefix</literal>, <literal>MLton.CharArray</literal>, <literal>MLton.CharVector</literal>, <literal>MLton.Exn.defaultTopLevelHandler</literal>, <literal>MLton.Exn.getTopLevelHandler</literal>, <literal>MLton.Exn.setTopLevelHandler</literal>, <literal>MLton.IntInf.BigWord</literal>, <literal>Mlton.IntInf.SmallInt</literal>, <literal>MLton.LargeReal</literal>, <literal>MLton.LargeWord</literal>, <literal>MLton.Real</literal>, <literal>MLton.Real32</literal>, <literal>MLton.Real64</literal>, <literal>MLton.Rlimit.Rlim</literal>, <literal>MLton.TextIO.tempPrefix</literal>, <literal>MLton.Vector.create</literal>, <literal>MLton.Word.bswap</literal>, <literal>MLton.Word8.bswap</literal>, <literal>MLton.Word16</literal>, <literal>MLton.Word32</literal>, <literal>MLton.Word64</literal>, <literal>MLton.Word8Array</literal>, <literal>MLton.Word8Vector</literal>.\r
27326</simpara>\r
27327</listitem>\r
27328<listitem>\r
27329<simpara>\r
27330Changed: <literal>MLton.Array.unfoldi</literal>, <literal>MLton.IntInf.rep</literal>, <literal>MLton.Rlimit</literal>, <literal>MLton.Vector.unfoldi</literal>.\r
27331</simpara>\r
27332</listitem>\r
27333<listitem>\r
27334<simpara>\r
27335Deprecated: <literal>MLton.Socket</literal>.\r
27336</simpara>\r
27337</listitem>\r
27338</itemizedlist>\r
27339</listitem>\r
27340<listitem>\r
27341<simpara>\r
27342Other libraries.\r
27343</simpara>\r
27344<itemizedlist>\r
27345<listitem>\r
27346<simpara>\r
27347Added: <link linkend="MLRISCLibrary">MLRISC library</link>.\r
27348</simpara>\r
27349</listitem>\r
27350<listitem>\r
27351<simpara>\r
27352Updated: <link linkend="CKitLibrary">ckit library</link>, <link linkend="SMLNJLibrary">SML/NJ library</link>.\r
27353</simpara>\r
27354</listitem>\r
27355</itemizedlist>\r
27356</listitem>\r
27357</itemizedlist>\r
27358</listitem>\r
27359<listitem>\r
27360<simpara>\r
27361Tools.\r
27362</simpara>\r
27363</listitem>\r
27364</itemizedlist>\r
27365<simpara>For a complete list of changes and bug fixes since\r
27366<link linkend="Release20051202">Release20051202</link>, see the\r
27367<ulink url="https://raw.github.com/MLton/mlton/on-20070826-release/doc/changelog"><literal>changelog</literal></ulink> and\r
27368<link linkend="Bugs20051202">Bugs20051202</link>.</simpara>\r
27369</section>\r
27370<section id="_20070826_binary_packages">\r
27371<title>20070826 binary packages</title>\r
27372<itemizedlist>\r
27373<listitem>\r
27374<simpara>\r
27375AMD64\r
27376</simpara>\r
27377<itemizedlist>\r
27378<listitem>\r
27379<simpara>\r
27380<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20070826/mlton-20070826-1.amd64-linux.tgz">Linux</ulink>, glibc 2.3\r
27381</simpara>\r
27382</listitem>\r
27383</itemizedlist>\r
27384</listitem>\r
27385<listitem>\r
27386<simpara>\r
27387HPPA\r
27388</simpara>\r
27389<itemizedlist>\r
27390<listitem>\r
27391<simpara>\r
27392<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20070826/mlton-20070826-1.hppa-hpux1100.tgz">HPUX</ulink> 11.00 and above, statically linked against <link linkend="GnuMP">GnuMP</link>\r
27393</simpara>\r
27394</listitem>\r
27395</itemizedlist>\r
27396</listitem>\r
27397<listitem>\r
27398<simpara>\r
27399PowerPC\r
27400</simpara>\r
27401<itemizedlist>\r
27402<listitem>\r
27403<simpara>\r
27404<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20070826/mlton-20070826-1.powerpc-aix51.tgz">AIX</ulink> 5.1 and above, statically linked against <link linkend="GnuMP">GnuMP</link>\r
27405</simpara>\r
27406</listitem>\r
27407<listitem>\r
27408<simpara>\r
27409<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20070826/mlton-20070826-1.powerpc-darwin.gmp-static.tgz">Darwin</ulink> 8.10 (Mac OS X), statically linked against <link linkend="GnuMP">GnuMP</link>\r
27410</simpara>\r
27411</listitem>\r
27412<listitem>\r
27413<simpara>\r
27414<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20070826/mlton-20070826-1.powerpc-darwin.gmp-macports.tgz">Darwin</ulink> 8.10 (Mac OS X), dynamically linked against <link linkend="GnuMP">GnuMP</link> in <literal>/opt/local/lib</literal> (suitable for <ulink url="http://macports.org">MacPorts</ulink> install of <link linkend="GnuMP">GnuMP</link>)\r
27415</simpara>\r
27416</listitem>\r
27417</itemizedlist>\r
27418</listitem>\r
27419<listitem>\r
27420<simpara>\r
27421Sparc\r
27422</simpara>\r
27423<itemizedlist>\r
27424<listitem>\r
27425<simpara>\r
27426<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20070826/mlton-20070826-1.sparc-solaris8.tgz">Solaris</ulink> 8 and above, statically linked against <link linkend="GnuMP">GnuMP</link>\r
27427</simpara>\r
27428</listitem>\r
27429</itemizedlist>\r
27430</listitem>\r
27431<listitem>\r
27432<simpara>\r
27433X86\r
27434</simpara>\r
27435<itemizedlist>\r
27436<listitem>\r
27437<simpara>\r
27438<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20070826/mlton-20070826-1.x86-cygwin.tgz">Cygwin</ulink> 1.5.24-2\r
27439</simpara>\r
27440</listitem>\r
27441<listitem>\r
27442<simpara>\r
27443<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20070826/mlton-20070826-1.x86-darwin.gmp-macports.tgz">Darwin (.tgz)</ulink> 8.10 (Mac OS X), dynamically linked against <link linkend="GnuMP">GnuMP</link> in <literal>/opt/local/lib</literal> (suitable for <ulink url="http://macports.org">MacPorts</ulink> install of <link linkend="GnuMP">GnuMP</link>)\r
27444</simpara>\r
27445</listitem>\r
27446<listitem>\r
27447<simpara>\r
27448<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20070826/mlton-20070826-1.x86-darwin.gmp-macports.dmg">Darwin (.dmg)</ulink> 8.10 (Mac OS X), dynamically linked against <link linkend="GnuMP">GnuMP</link> in <literal>/opt/local/lib</literal> (suitable for <ulink url="http://macports.org">MacPorts</ulink> install of <link linkend="GnuMP">GnuMP</link>)\r
27449</simpara>\r
27450</listitem>\r
27451<listitem>\r
27452<simpara>\r
27453<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20070826/mlton-20070826-1.x86-darwin.gmp-static.tgz">Darwin (.tgz)</ulink> 8.10 (Mac OS X), statically linked against <link linkend="GnuMP">GnuMP</link>\r
27454</simpara>\r
27455</listitem>\r
27456<listitem>\r
27457<simpara>\r
27458<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20070826/mlton-20070826-1.x86-darwin.gmp-static.dmg">Darwin (.dmg)</ulink> 8.10 (Mac OS X), statically linked against <link linkend="GnuMP">GnuMP</link>\r
27459</simpara>\r
27460</listitem>\r
27461<listitem>\r
27462<simpara>\r
27463<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20070826/mlton-20070826-1.x86-freebsd.tgz">FreeBSD</ulink>\r
27464</simpara>\r
27465</listitem>\r
27466<listitem>\r
27467<simpara>\r
27468<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20070826/mlton-20070826-1.x86-linux.tgz">Linux</ulink>, glibc 2.3\r
27469</simpara>\r
27470</listitem>\r
27471<listitem>\r
27472<simpara>\r
27473<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20070826/mlton-20070826-1.x86-linux.glibc213.gmp-static.tgz">Linux</ulink>, glibc 2.1, statically linked against <link linkend="GnuMP">GnuMP</link>\r
27474</simpara>\r
27475</listitem>\r
27476<listitem>\r
27477<simpara>\r
27478<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20070826/mlton-20070826-1.x86-mingw.gmp-dll.tgz">MinGW</ulink>, dynamically linked against <link linkend="GnuMP">GnuMP</link> (requires <literal>libgmp-3.dll</literal>)\r
27479</simpara>\r
27480</listitem>\r
27481<listitem>\r
27482<simpara>\r
27483<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20070826/mlton-20070826-1.x86-mingw.gmp-static.tgz">MinGW</ulink>, statically linked against <link linkend="GnuMP">GnuMP</link>\r
27484</simpara>\r
27485</listitem>\r
27486</itemizedlist>\r
27487</listitem>\r
27488</itemizedlist>\r
27489</section>\r
27490<section id="_20070826_source_packages">\r
27491<title>20070826 source packages</title>\r
27492<itemizedlist>\r
27493<listitem>\r
27494<simpara>\r
27495<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20070826/mlton-20070826-1.src.tgz">source tgz</ulink>\r
27496</simpara>\r
27497</listitem>\r
27498<listitem>\r
27499<simpara>\r
27500Debian <ulink url="http://sourceforge.net/projects/mlton/files/mlton/20070826/mlton_20070826-1.dsc">dsc</ulink>,\r
27501 <ulink url="http://sourceforge.net/projects/mlton/files/mlton/20070826/mlton_20070826-1.diff.gz">diff.gz</ulink>,\r
27502 <ulink url="http://sourceforge.net/projects/mlton/files/mlton/20070826/mlton_20070826.orig.tar.gz">orig.tar.gz</ulink>\r
27503</simpara>\r
27504</listitem>\r
27505</itemizedlist>\r
27506</section>\r
27507<section id="_packages_available_at_other_sites_2">\r
27508<title>Packages available at other sites</title>\r
27509<itemizedlist>\r
27510<listitem>\r
27511<simpara>\r
27512<ulink url="http://packages.debian.org/search?keywords=mlton&amp;searchon=names&amp;suite=all&amp;section=all">Debian</ulink>\r
27513</simpara>\r
27514</listitem>\r
27515<listitem>\r
27516<simpara>\r
27517<ulink url="http://www.freebsd.org/cgi/ports.cgi?query=mlton&amp;stype=all">FreeBSD</ulink>\r
27518</simpara>\r
27519</listitem>\r
27520<listitem>\r
27521<simpara>\r
27522<ulink url="https://admin.fedoraproject.org/pkgdb/packages/name/mlton">Fedora</ulink>\r
27523</simpara>\r
27524</listitem>\r
27525<listitem>\r
27526<simpara>\r
27527<ulink url="http://packages.ubuntu.com/cgi-bin/search_packages.pl?keywords=mlton&amp;searchon=names&amp;version=all&amp;release=all">Ubuntu</ulink>\r
27528</simpara>\r
27529</listitem>\r
27530</itemizedlist>\r
27531</section>\r
27532<section id="_also_see_33">\r
27533<title>Also see</title>\r
27534<itemizedlist>\r
27535<listitem>\r
27536<simpara>\r
27537<link linkend="Bugs20070826">Bugs20070826</link>\r
27538</simpara>\r
27539</listitem>\r
27540<listitem>\r
27541<simpara>\r
27542<ulink url="http://www.mlton.org/guide/20070826/">MLton Guide (20070826)</ulink>.\r
27543</simpara>\r
27544<simpara>A snapshot of the MLton wiki at the time of release.</simpara>\r
27545</listitem>\r
27546</itemizedlist>\r
27547<simpara><?asciidoc-pagebreak?></simpara>\r
27548</section>\r
27549</section>\r
27550<section id="Release20100608">\r
27551<title>Release20100608</title>\r
27552<simpara>This is an archived public release of MLton, version 20100608.</simpara>\r
27553<section id="_changes_since_the_last_public_release_4">\r
27554<title>Changes since the last public release</title>\r
27555<itemizedlist>\r
27556<listitem>\r
27557<simpara>\r
27558New platforms.\r
27559</simpara>\r
27560<itemizedlist>\r
27561<listitem>\r
27562<simpara>\r
27563<link linkend="RunningOnAMD64">AMD64</link>/<link linkend="RunningOnDarwin">Darwin</link> (Mac OS X Snow Leopard)\r
27564</simpara>\r
27565</listitem>\r
27566<listitem>\r
27567<simpara>\r
27568<link linkend="RunningOnIA64">IA64</link>/<link linkend="RunningOnHPUX">HPUX</link>\r
27569</simpara>\r
27570</listitem>\r
27571<listitem>\r
27572<simpara>\r
27573<link linkend="RunningOnPowerPC64">PowerPC64</link>/<link linkend="RunningOnAIX">AIX</link>\r
27574</simpara>\r
27575</listitem>\r
27576</itemizedlist>\r
27577</listitem>\r
27578<listitem>\r
27579<simpara>\r
27580Compiler.\r
27581</simpara>\r
27582<itemizedlist>\r
27583<listitem>\r
27584<simpara>\r
27585<link linkend="CompileTimeOptions">Command-line switches</link>.\r
27586</simpara>\r
27587<itemizedlist>\r
27588<listitem>\r
27589<simpara>\r
27590Added: <literal>-mlb-path-var <emphasis>&lt;name&gt; &lt;value&gt;</emphasis></literal>\r
27591</simpara>\r
27592</listitem>\r
27593<listitem>\r
27594<simpara>\r
27595Removed: <literal>-keep sml</literal>, <literal>-stop sml</literal>\r
27596</simpara>\r
27597</listitem>\r
27598</itemizedlist>\r
27599</listitem>\r
27600<listitem>\r
27601<simpara>\r
27602Improved constant folding of floating-point operations.\r
27603</simpara>\r
27604</listitem>\r
27605<listitem>\r
27606<simpara>\r
27607Experimental: Support for compiling to a C library; see <link linkend="LibrarySupport">documentation</link>.\r
27608</simpara>\r
27609</listitem>\r
27610<listitem>\r
27611<simpara>\r
27612Extended <literal>-show-def-use <emphasis>output</emphasis></literal> to include types of variable definitions.\r
27613</simpara>\r
27614</listitem>\r
27615<listitem>\r
27616<simpara>\r
27617Deprecated features (to be removed in a future release)\r
27618</simpara>\r
27619<itemizedlist>\r
27620<listitem>\r
27621<simpara>\r
27622Bytecode codegen: The bytecode codegen has not seen significant use and it is not well understood by any of the active developers.\r
27623</simpara>\r
27624</listitem>\r
27625<listitem>\r
27626<simpara>\r
27627Support for <literal>.cm</literal> files as input: The ML Basis system provides much better infrastructure for "programming in the very large" than the (very) limited support for CM. The <literal>cm2mlb</literal> tool (available in the source distribution) can be used to convert CM projects to MLB projects, preserving the CM scoping of module identifiers.\r
27628</simpara>\r
27629</listitem>\r
27630</itemizedlist>\r
27631</listitem>\r
27632<listitem>\r
27633<simpara>\r
27634Bug fixes: see <ulink url="https://raw.github.com/MLton/mlton/on-20100608-release/doc/changelog"><literal>changelog</literal></ulink>\r
27635</simpara>\r
27636</listitem>\r
27637</itemizedlist>\r
27638</listitem>\r
27639<listitem>\r
27640<simpara>\r
27641Runtime.\r
27642</simpara>\r
27643<itemizedlist>\r
27644<listitem>\r
27645<simpara>\r
27646<link linkend="RunTimeOptions">@MLton switches</link>.\r
27647</simpara>\r
27648<itemizedlist>\r
27649<listitem>\r
27650<simpara>\r
27651Added: <literal>may-page-heap {false|true}</literal>\r
27652</simpara>\r
27653</listitem>\r
27654</itemizedlist>\r
27655</listitem>\r
27656<listitem>\r
27657<simpara>\r
27658<literal>may-page-heap</literal>: By default, MLton will not page the heap to disk when unable to grow the heap to accommodate an allocation. (Previously, this behavior was the default, with no means to disable, with security an least-surprise issues.)\r
27659</simpara>\r
27660</listitem>\r
27661<listitem>\r
27662<simpara>\r
27663Bug fixes: see <ulink url="https://raw.github.com/MLton/mlton/on-20100608-release/doc/changelog"><literal>changelog</literal></ulink>\r
27664</simpara>\r
27665</listitem>\r
27666</itemizedlist>\r
27667</listitem>\r
27668<listitem>\r
27669<simpara>\r
27670Language.\r
27671</simpara>\r
27672<itemizedlist>\r
27673<listitem>\r
27674<simpara>\r
27675Allow numeric characters in <link linkend="MLBasis">ML Basis</link> path variables.\r
27676</simpara>\r
27677</listitem>\r
27678</itemizedlist>\r
27679</listitem>\r
27680<listitem>\r
27681<simpara>\r
27682Libraries.\r
27683</simpara>\r
27684<itemizedlist>\r
27685<listitem>\r
27686<simpara>\r
27687<link linkend="BasisLibrary">Basis Library</link>.\r
27688</simpara>\r
27689<itemizedlist>\r
27690<listitem>\r
27691<simpara>\r
27692Bug fixes: see <ulink url="https://raw.github.com/MLton/mlton/on-20100608-release/doc/changelog"><literal>changelog</literal></ulink>\r
27693</simpara>\r
27694</listitem>\r
27695</itemizedlist>\r
27696</listitem>\r
27697<listitem>\r
27698<simpara>\r
27699<link linkend="MLtonStructure">MLton structure</link>.\r
27700</simpara>\r
27701<itemizedlist>\r
27702<listitem>\r
27703<simpara>\r
27704Added: <literal>MLton.equal</literal>, <literal>MLton.hash</literal>, <literal>MLton.Cont.isolate</literal>, <literal>MLton.GC.Statistics</literal>, <literal>MLton.Pointer.sizeofPointer</literal>, <literal>MLton.Socket.Address.toVector</literal>\r
27705</simpara>\r
27706</listitem>\r
27707<listitem>\r
27708<simpara>\r
27709Changed:\r
27710</simpara>\r
27711</listitem>\r
27712<listitem>\r
27713<simpara>\r
27714Deprecated: <literal>MLton.Socket</literal>\r
27715</simpara>\r
27716</listitem>\r
27717</itemizedlist>\r
27718</listitem>\r
27719<listitem>\r
27720<simpara>\r
27721<link linkend="UnsafeStructure">Unsafe structure</link>.\r
27722</simpara>\r
27723<itemizedlist>\r
27724<listitem>\r
27725<simpara>\r
27726Added versions of all of the monomorphic array and vector structures.\r
27727</simpara>\r
27728</listitem>\r
27729</itemizedlist>\r
27730</listitem>\r
27731<listitem>\r
27732<simpara>\r
27733Other libraries.\r
27734</simpara>\r
27735<itemizedlist>\r
27736<listitem>\r
27737<simpara>\r
27738Updated: <link linkend="CKitLibrary">ckit library</link>, <link linkend="MLRISCLibrary">MLRISC library</link>, <link linkend="SMLNJLibrary">SML/NJ library</link>.\r
27739</simpara>\r
27740</listitem>\r
27741</itemizedlist>\r
27742</listitem>\r
27743</itemizedlist>\r
27744</listitem>\r
27745<listitem>\r
27746<simpara>\r
27747Tools.\r
27748</simpara>\r
27749<itemizedlist>\r
27750<listitem>\r
27751<simpara>\r
27752<literal>mllex</literal>\r
27753</simpara>\r
27754<itemizedlist>\r
27755<listitem>\r
27756<simpara>\r
27757Eliminated top-level <literal>type int = Int.int</literal> in output.\r
27758</simpara>\r
27759</listitem>\r
27760<listitem>\r
27761<simpara>\r
27762Include <literal>(*#line line:col "file.lex" *)</literal> directives in output.\r
27763</simpara>\r
27764</listitem>\r
27765<listitem>\r
27766<simpara>\r
27767Added <literal>%posint</literal> command, to set the <literal>yypos</literal> type and allow the lexing of multi-gigabyte files.\r
27768</simpara>\r
27769</listitem>\r
27770</itemizedlist>\r
27771</listitem>\r
27772<listitem>\r
27773<simpara>\r
27774<literal>mlnlffigen</literal>\r
27775</simpara>\r
27776<itemizedlist>\r
27777<listitem>\r
27778<simpara>\r
27779Added command-line switches <literal>-linkage archive</literal> and <literal>-linkage shared</literal>.\r
27780</simpara>\r
27781</listitem>\r
27782<listitem>\r
27783<simpara>\r
27784Deprecated command-line switch <literal>-linkage static</literal>.\r
27785</simpara>\r
27786</listitem>\r
27787<listitem>\r
27788<simpara>\r
27789Added support for <link linkend="RunningOnIA64">IA64</link> and <link linkend="RunningOnHPPA">HPPA</link> targets.\r
27790</simpara>\r
27791</listitem>\r
27792</itemizedlist>\r
27793</listitem>\r
27794<listitem>\r
27795<simpara>\r
27796<literal>mlyacc</literal>\r
27797</simpara>\r
27798<itemizedlist>\r
27799<listitem>\r
27800<simpara>\r
27801Eliminated top-level <literal>type int = Int.int</literal> in output.\r
27802</simpara>\r
27803</listitem>\r
27804<listitem>\r
27805<simpara>\r
27806Include <literal>(*#line line:col "file.grm" *)</literal> directives in output.\r
27807</simpara>\r
27808</listitem>\r
27809</itemizedlist>\r
27810</listitem>\r
27811</itemizedlist>\r
27812</listitem>\r
27813</itemizedlist>\r
27814<simpara>For a complete list of changes and bug fixes since <link linkend="Release20070826">Release20070826</link>, see the\r
27815<ulink url="https://raw.github.com/MLton/mlton/on-20100608-release/doc/changelog"><literal>changelog</literal></ulink>\r
27816and <link linkend="Bugs20070826">Bugs20070826</link>.</simpara>\r
27817</section>\r
27818<section id="_20100608_binary_packages">\r
27819<title>20100608 binary packages</title>\r
27820<itemizedlist>\r
27821<listitem>\r
27822<simpara>\r
27823AMD64 (aka "x86-64" or "x64")\r
27824</simpara>\r
27825<itemizedlist>\r
27826<listitem>\r
27827<simpara>\r
27828<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20100608/mlton-20100608-1.amd64-darwin.gmp-macports.tgz">Darwin (.tgz)</ulink> 10.3 (Mac OS X Snow Leopard), dynamically linked against <link linkend="GnuMP">GnuMP</link> in <literal>/opt/local/lib</literal> (suitable for <ulink url="http://macports.org">MacPorts</ulink> install of <link linkend="GnuMP">GnuMP</link>)\r
27829</simpara>\r
27830</listitem>\r
27831<listitem>\r
27832<simpara>\r
27833<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20100608/mlton-20100608-1.amd64-darwin.gmp-static.tgz">Darwin (.tgz)</ulink> 10.3 (Mac OS X Snow Leopard), statically linked against <link linkend="GnuMP">GnuMP</link> (but requires <link linkend="GnuMP">GnuMP</link> for generated executables)\r
27834</simpara>\r
27835</listitem>\r
27836<listitem>\r
27837<simpara>\r
27838<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20100608/mlton-20100608-1.amd64-linux.tgz">Linux</ulink>, glibc 2.11\r
27839</simpara>\r
27840</listitem>\r
27841<listitem>\r
27842<simpara>\r
27843<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20100608/mlton-20100608-1.amd64-linux.static.tgz">Linux</ulink>, statically linked\r
27844</simpara>\r
27845</listitem>\r
27846<listitem>\r
27847<simpara>\r
27848Windows MinGW 32/64 <ulink url="http://sourceforge.net/projects/mlton/files/mlton/20100608/MLton-20100608-1.exe">self-extracting</ulink> (28MB) or <ulink url="http://sourceforge.net/projects/mlton/files/mlton/20100608/MLton-20100608-1.msi">MSI</ulink> (61MB) installer\r
27849</simpara>\r
27850</listitem>\r
27851</itemizedlist>\r
27852</listitem>\r
27853<listitem>\r
27854<simpara>\r
27855X86\r
27856</simpara>\r
27857<itemizedlist>\r
27858<listitem>\r
27859<simpara>\r
27860<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20100608/mlton-20100608-1.x86-cygwin.tgz">Cygwin</ulink> 1.7.5\r
27861</simpara>\r
27862</listitem>\r
27863<listitem>\r
27864<simpara>\r
27865<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20100608/mlton-20100608-1.x86-darwin.gmp-macports.tgz">Darwin (.tgz)</ulink> 9.8 (Mac OS X Leopard), dynamically linked against <link linkend="GnuMP">GnuMP</link> in <literal>/opt/local/lib</literal> (suitable for <ulink url="http://macports.org">MacPorts</ulink> install of <link linkend="GnuMP">GnuMP</link>)\r
27866</simpara>\r
27867</listitem>\r
27868<listitem>\r
27869<simpara>\r
27870<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20100608/mlton-20100608-1.x86-darwin.gmp-static.tgz">Darwin (.tgz)</ulink> 9.8 (Mac OS X Leopard), statically linked against <link linkend="GnuMP">GnuMP</link> (but requires <link linkend="GnuMP">GnuMP</link> for generated executables)\r
27871</simpara>\r
27872</listitem>\r
27873<listitem>\r
27874<simpara>\r
27875<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20100608/mlton-20100608-1.x86-linux.tgz">Linux</ulink>, glibc 2.11\r
27876</simpara>\r
27877</listitem>\r
27878<listitem>\r
27879<simpara>\r
27880<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20100608/mlton-20100608-1.x86-linux.static.tgz">Linux</ulink>, statically linked\r
27881</simpara>\r
27882</listitem>\r
27883<listitem>\r
27884<simpara>\r
27885Windows MinGW 32/64 <ulink url="http://sourceforge.net/projects/mlton/files/mlton/20100608/MLton-20100608-1.exe">self-extracting</ulink> (28MB) or <ulink url="http://sourceforge.net/projects/mlton/files/mlton/20100608/MLton-20100608-1.msi">MSI</ulink> (61MB) installer\r
27886</simpara>\r
27887</listitem>\r
27888</itemizedlist>\r
27889</listitem>\r
27890</itemizedlist>\r
27891</section>\r
27892<section id="_20100608_source_packages">\r
27893<title>20100608 source packages</title>\r
27894<itemizedlist>\r
27895<listitem>\r
27896<simpara>\r
27897<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20100608/mlton-20100608.src.tgz">mlton-20100608.src.tgz</ulink>\r
27898</simpara>\r
27899</listitem>\r
27900</itemizedlist>\r
27901</section>\r
27902<section id="_packages_available_at_other_sites_3">\r
27903<title>Packages available at other sites</title>\r
27904<itemizedlist>\r
27905<listitem>\r
27906<simpara>\r
27907<ulink url="http://packages.debian.org/search?keywords=mlton&amp;searchon=names&amp;suite=all&amp;section=all">Debian</ulink>\r
27908</simpara>\r
27909</listitem>\r
27910<listitem>\r
27911<simpara>\r
27912<ulink url="http://www.freebsd.org/cgi/ports.cgi?query=mlton&amp;stype=all">FreeBSD</ulink>\r
27913</simpara>\r
27914</listitem>\r
27915<listitem>\r
27916<simpara>\r
27917<ulink url="https://admin.fedoraproject.org/pkgdb/acls/name/mlton">Fedora</ulink>\r
27918</simpara>\r
27919</listitem>\r
27920<listitem>\r
27921<simpara>\r
27922<ulink url="http://packages.ubuntu.com/search?suite=default&amp;section=all&amp;arch=any&amp;searchon=names&amp;keywords=mlton">Ubuntu</ulink>\r
27923</simpara>\r
27924</listitem>\r
27925</itemizedlist>\r
27926</section>\r
27927<section id="_also_see_34">\r
27928<title>Also see</title>\r
27929<itemizedlist>\r
27930<listitem>\r
27931<simpara>\r
27932<link linkend="Bugs20100608">Bugs20100608</link>\r
27933</simpara>\r
27934</listitem>\r
27935<listitem>\r
27936<simpara>\r
27937<ulink url="http://www.mlton.org/guide/20100608/">MLton Guide (20100608)</ulink>.\r
27938</simpara>\r
27939<simpara>A snapshot of the MLton wiki at the time of release.</simpara>\r
27940</listitem>\r
27941</itemizedlist>\r
27942<simpara><?asciidoc-pagebreak?></simpara>\r
27943</section>\r
27944</section>\r
27945<section id="Release20130715">\r
27946<title>Release20130715</title>\r
27947<simpara>This is an archived public release of MLton, version 20130715.</simpara>\r
27948<section id="_changes_since_the_last_public_release_5">\r
27949<title>Changes since the last public release</title>\r
27950<itemizedlist>\r
27951<listitem>\r
27952<simpara>\r
27953Compiler.\r
27954</simpara>\r
27955<itemizedlist>\r
27956<listitem>\r
27957<simpara>\r
27958Cosmetic improvements to type-error messages.\r
27959</simpara>\r
27960</listitem>\r
27961<listitem>\r
27962<simpara>\r
27963Removed features:\r
27964</simpara>\r
27965<itemizedlist>\r
27966<listitem>\r
27967<simpara>\r
27968Bytecode codegen: The bytecode codegen had not seen significant use and it was not well understood by any of the active developers.\r
27969</simpara>\r
27970</listitem>\r
27971<listitem>\r
27972<simpara>\r
27973Support for <literal>.cm</literal> files as input: The <link linkend="MLBasis">ML Basis system</link> provides much better infrastructure for "programming in the very large" than the (very) limited support for CM. The <literal>cm2mlb</literal> tool (available in the source distribution) can be used to convert CM projects to MLB projects, preserving the CM scoping of module identifiers.\r
27974</simpara>\r
27975</listitem>\r
27976</itemizedlist>\r
27977</listitem>\r
27978<listitem>\r
27979<simpara>\r
27980Bug fixes: see <ulink url="https://raw.github.com/MLton/mlton/on-20130715-release/doc/changelog"><literal>changelog</literal></ulink>\r
27981</simpara>\r
27982</listitem>\r
27983</itemizedlist>\r
27984</listitem>\r
27985<listitem>\r
27986<simpara>\r
27987Runtime.\r
27988</simpara>\r
27989<itemizedlist>\r
27990<listitem>\r
27991<simpara>\r
27992Bug fixes: see <ulink url="https://raw.github.com/MLton/mlton/on-20130715-release/doc/changelog"><literal>changelog</literal></ulink>\r
27993</simpara>\r
27994</listitem>\r
27995</itemizedlist>\r
27996</listitem>\r
27997<listitem>\r
27998<simpara>\r
27999Language.\r
28000</simpara>\r
28001<itemizedlist>\r
28002<listitem>\r
28003<simpara>\r
28004Interpret <literal>(*#line line:col "file" *)</literal> directives as relative file names.\r
28005</simpara>\r
28006</listitem>\r
28007<listitem>\r
28008<simpara>\r
28009<link linkend="MLBasisAnnotations">ML Basis annotations</link>.\r
28010</simpara>\r
28011<itemizedlist>\r
28012<listitem>\r
28013<simpara>\r
28014Added: <literal>resolveScope</literal>\r
28015</simpara>\r
28016</listitem>\r
28017</itemizedlist>\r
28018</listitem>\r
28019</itemizedlist>\r
28020</listitem>\r
28021<listitem>\r
28022<simpara>\r
28023Libraries.\r
28024</simpara>\r
28025<itemizedlist>\r
28026<listitem>\r
28027<simpara>\r
28028<link linkend="BasisLibrary">Basis Library</link>.\r
28029</simpara>\r
28030<itemizedlist>\r
28031<listitem>\r
28032<simpara>\r
28033Improved performance of <literal>String.concatWith</literal>.\r
28034</simpara>\r
28035</listitem>\r
28036<listitem>\r
28037<simpara>\r
28038Use bit operations for <literal>REAL.class</literal> and other low-level operations.\r
28039</simpara>\r
28040</listitem>\r
28041<listitem>\r
28042<simpara>\r
28043Support additional variables with <literal>Posix.ProcEnv.sysconf</literal>.\r
28044</simpara>\r
28045</listitem>\r
28046<listitem>\r
28047<simpara>\r
28048Bug fixes: see <ulink url="https://raw.github.com/MLton/mlton/on-20130715-release/doc/changelog"><literal>changelog</literal></ulink>\r
28049</simpara>\r
28050</listitem>\r
28051</itemizedlist>\r
28052</listitem>\r
28053<listitem>\r
28054<simpara>\r
28055<link linkend="MLtonStructure">MLton structure</link>.\r
28056</simpara>\r
28057<itemizedlist>\r
28058<listitem>\r
28059<simpara>\r
28060Removed: <literal>MLton.Socket</literal>\r
28061</simpara>\r
28062</listitem>\r
28063</itemizedlist>\r
28064</listitem>\r
28065<listitem>\r
28066<simpara>\r
28067Other libraries.\r
28068</simpara>\r
28069<itemizedlist>\r
28070<listitem>\r
28071<simpara>\r
28072Updated: <link linkend="CKitLibrary">ckit library</link>, <link linkend="MLRISCLibrary">MLRISC library</link>, <link linkend="SMLNJLibrary">SML/NJ library</link>\r
28073</simpara>\r
28074</listitem>\r
28075<listitem>\r
28076<simpara>\r
28077Added: <link linkend="MLLPTLibrary">MLLPT library</link>\r
28078</simpara>\r
28079</listitem>\r
28080</itemizedlist>\r
28081</listitem>\r
28082</itemizedlist>\r
28083</listitem>\r
28084<listitem>\r
28085<simpara>\r
28086Tools.\r
28087</simpara>\r
28088<itemizedlist>\r
28089<listitem>\r
28090<simpara>\r
28091<literal>mllex</literal>\r
28092</simpara>\r
28093<itemizedlist>\r
28094<listitem>\r
28095<simpara>\r
28096Generate <literal>(*#line line:col "file.lex" *)</literal> directives with simple (relative) file names, rather than absolute paths.\r
28097</simpara>\r
28098</listitem>\r
28099</itemizedlist>\r
28100</listitem>\r
28101<listitem>\r
28102<simpara>\r
28103<literal>mlyacc</literal>\r
28104</simpara>\r
28105<itemizedlist>\r
28106<listitem>\r
28107<simpara>\r
28108Generate <literal>(*#line line:col "file.grm" *)</literal> directives with simple (relative) file names, rather than absolute paths.\r
28109</simpara>\r
28110</listitem>\r
28111<listitem>\r
28112<simpara>\r
28113Fixed bug in comment-handling in lexer.\r
28114</simpara>\r
28115</listitem>\r
28116</itemizedlist>\r
28117</listitem>\r
28118</itemizedlist>\r
28119</listitem>\r
28120</itemizedlist>\r
28121<simpara>For a complete list of changes and bug fixes since\r
28122<link linkend="Release20100608">Release20100608</link>, see the\r
28123<ulink url="https://raw.github.com/MLton/mlton/on-20130715-release/doc/changelog"><literal>changelog</literal></ulink> and\r
28124<link linkend="Bugs20100608">Bugs20100608</link>.</simpara>\r
28125</section>\r
28126<section id="_20130715_binary_packages">\r
28127<title>20130715 binary packages</title>\r
28128<itemizedlist>\r
28129<listitem>\r
28130<simpara>\r
28131AMD64 (aka "x86-64" or "x64")\r
28132</simpara>\r
28133<itemizedlist>\r
28134<listitem>\r
28135<simpara>\r
28136<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20130715/mlton-20130715-1.amd64-darwin.gmp-macports.tgz">Darwin (.tgz)</ulink> 11.4 (Mac OS X Lion), dynamically linked against <link linkend="GnuMP">GnuMP</link> in <literal>/opt/local/lib</literal> (suitable for <ulink url="http://macports.org">MacPorts</ulink> install of <link linkend="GnuMP">GnuMP</link>)\r
28137</simpara>\r
28138</listitem>\r
28139<listitem>\r
28140<simpara>\r
28141<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20130715/mlton-20130715-1.amd64-darwin.gmp-static.tgz">Darwin (.tgz)</ulink> 11.4 (Mac OS X Lion), statically linked against <link linkend="GnuMP">GnuMP</link> (but requires <link linkend="GnuMP">GnuMP</link> for generated executables)\r
28142</simpara>\r
28143</listitem>\r
28144<listitem>\r
28145<simpara>\r
28146<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20130715/mlton-20130715-1.amd64-linux.tgz">Linux</ulink>, glibc 2.15\r
28147\r
28148</simpara>\r
28149</listitem>\r
28150</itemizedlist>\r
28151</listitem>\r
28152<listitem>\r
28153<simpara>\r
28154X86\r
28155</simpara>\r
28156<itemizedlist>\r
28157<listitem>\r
28158<simpara>\r
28159<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20130715/mlton-20130715-1.x86-linux.tgz">Linux</ulink>, glibc 2.15\r
28160\r
28161</simpara>\r
28162</listitem>\r
28163</itemizedlist>\r
28164</listitem>\r
28165</itemizedlist>\r
28166</section>\r
28167<section id="_20130715_source_packages">\r
28168<title>20130715 source packages</title>\r
28169<itemizedlist>\r
28170<listitem>\r
28171<simpara>\r
28172<ulink url="http://sourceforge.net/projects/mlton/files/mlton/20130715/mlton-20130715.src.tgz">mlton-20130715.src.tgz</ulink>\r
28173</simpara>\r
28174</listitem>\r
28175</itemizedlist>\r
28176</section>\r
28177<section id="_downstream_packages">\r
28178<title>Downstream packages</title>\r
28179<itemizedlist>\r
28180<listitem>\r
28181<simpara>\r
28182<ulink url="http://packages.debian.org/search?keywords=mlton&amp;searchon=names&amp;suite=all&amp;section=all">Debian</ulink>\r
28183</simpara>\r
28184</listitem>\r
28185<listitem>\r
28186<simpara>\r
28187<ulink url="http://www.freebsd.org/cgi/ports.cgi?query=mlton&amp;stype=all">FreeBSD</ulink>\r
28188</simpara>\r
28189</listitem>\r
28190<listitem>\r
28191<simpara>\r
28192<ulink url="https://admin.fedoraproject.org/pkgdb/acls/name/mlton">Fedora</ulink>\r
28193</simpara>\r
28194</listitem>\r
28195<listitem>\r
28196<simpara>\r
28197<ulink url="http://packages.ubuntu.com/search?suite=default&amp;section=all&amp;arch=any&amp;searchon=names&amp;keywords=mlton">Ubuntu</ulink>\r
28198</simpara>\r
28199</listitem>\r
28200</itemizedlist>\r
28201</section>\r
28202<section id="_also_see_35">\r
28203<title>Also see</title>\r
28204<itemizedlist>\r
28205<listitem>\r
28206<simpara>\r
28207<link linkend="Bugs20130715">Bugs20130715</link>\r
28208</simpara>\r
28209</listitem>\r
28210<listitem>\r
28211<simpara>\r
28212<ulink url="http://www.mlton.org/guide/20130715/">MLton Guide (20130715)</ulink>.\r
28213</simpara>\r
28214<simpara>A snapshot of the MLton website at the time of release.</simpara>\r
28215</listitem>\r
28216</itemizedlist>\r
28217<simpara><?asciidoc-pagebreak?></simpara>\r
28218</section>\r
28219</section>\r
28220<section id="Release20180207">\r
28221<title>Release20180207</title>\r
28222<simpara>Here you can download the latest public release of MLton, version 20180207.</simpara>\r
28223<section id="_changes_since_the_last_public_release_6">\r
28224<title>Changes since the last public release</title>\r
28225<itemizedlist>\r
28226<listitem>\r
28227<simpara>\r
28228Compiler.\r
28229</simpara>\r
28230<itemizedlist>\r
28231<listitem>\r
28232<simpara>\r
28233Added an experimental LLVM codegen (<literal>-codegen llvm</literal>); requires LLVM tools\r
28234 (<literal>llvm-as</literal>, <literal>opt</literal>, <literal>llc</literal>) version &ge; 3.7.\r
28235</simpara>\r
28236</listitem>\r
28237<listitem>\r
28238<simpara>\r
28239Made many substantial cosmetic improvements to front-end diagnostic\r
28240 messages, especially with respect to source location regions, type inference\r
28241 for <literal>fun</literal> and <literal>val rec</literal> declarations, signature constraints applied to a\r
28242 structure, <literal>sharing type</literal> specifications and <literal>where type</literal> signature\r
28243 expressions, type constructor or type variable escaping scope, and\r
28244 nonexhaustive pattern matching.\r
28245</simpara>\r
28246</listitem>\r
28247<listitem>\r
28248<simpara>\r
28249Fixed minor bugs with exception replication, precedence parsing of function\r
28250 clauses, and simultaneous <literal>sharing</literal> of multiple structures.\r
28251</simpara>\r
28252</listitem>\r
28253<listitem>\r
28254<simpara>\r
28255Made compilation deterministic (eliminate output executable name from\r
28256 compile-time specified <literal>@MLton</literal> runtime arguments; deterministically generate\r
28257 magic constant for executable).\r
28258</simpara>\r
28259</listitem>\r
28260<listitem>\r
28261<simpara>\r
28262Updated <literal>-show-basis</literal> (recursively expand structures in environments,\r
28263 displaying components with long identifiers; append <literal>(* @ region *)</literal>\r
28264 annotations to items shown in environment).\r
28265</simpara>\r
28266</listitem>\r
28267<listitem>\r
28268<simpara>\r
28269Forced amd64 codegen to generate PIC on amd64-linux targets.\r
28270</simpara>\r
28271</listitem>\r
28272</itemizedlist>\r
28273</listitem>\r
28274<listitem>\r
28275<simpara>\r
28276Runtime.\r
28277</simpara>\r
28278<itemizedlist>\r
28279<listitem>\r
28280<simpara>\r
28281Added <literal>gc-summary-file file</literal> runtime option.\r
28282</simpara>\r
28283</listitem>\r
28284<listitem>\r
28285<simpara>\r
28286Reorganized runtime support for <literal>IntInf</literal> operations so that programs that\r
28287 do not use <literal>IntInf</literal> compile to executables with no residual dependency on GMP.\r
28288</simpara>\r
28289</listitem>\r
28290<listitem>\r
28291<simpara>\r
28292Changed heap representation to store forwarding pointer for an object in\r
28293 the object header (rather than in the object data and setting the header to a\r
28294 sentinel value).\r
28295</simpara>\r
28296</listitem>\r
28297</itemizedlist>\r
28298</listitem>\r
28299<listitem>\r
28300<simpara>\r
28301Language.\r
28302</simpara>\r
28303<itemizedlist>\r
28304<listitem>\r
28305<simpara>\r
28306Added support for selected SuccessorML features; see\r
28307 <ulink url="http://mlton.org/SuccessorML">http://mlton.org/SuccessorML</ulink> for details.\r
28308</simpara>\r
28309</listitem>\r
28310<listitem>\r
28311<simpara>\r
28312Added <literal>(*#showBasis "file" *)</literal> directive; see\r
28313 <ulink url="http://mlton.org/ShowBasisDirective">http://mlton.org/ShowBasisDirective</ulink> for details.\r
28314</simpara>\r
28315</listitem>\r
28316<listitem>\r
28317<simpara>\r
28318FFI:\r
28319</simpara>\r
28320<itemizedlist>\r
28321<listitem>\r
28322<simpara>\r
28323Added <literal>pure</literal>, <literal>impure</literal>, and <literal>reentrant</literal> attributes to <literal>_import</literal>. An\r
28324 unattributed <literal>_import</literal> is treated as <literal>impure</literal>. A <literal>pure</literal> <literal>_import</literal> may be\r
28325 subject to more aggressive optimizations (common subexpression elimination,\r
28326 dead-code elimination). An <literal>_import</literal>-ed C function that (directly or\r
28327 indirectly) calls an <literal>_export</literal>-ed SML function should be attributed\r
28328 <literal>reentrant</literal>.\r
28329</simpara>\r
28330</listitem>\r
28331</itemizedlist>\r
28332</listitem>\r
28333<listitem>\r
28334<simpara>\r
28335ML Basis annotations.\r
28336</simpara>\r
28337<itemizedlist>\r
28338<listitem>\r
28339<simpara>\r
28340Added <literal>allowSuccessorML {false|true}</literal> to enable all SuccessorML features\r
28341 and other annotations to enable specific SuccessorML features; see\r
28342 <ulink url="http://mlton.org/SuccessorML">http://mlton.org/SuccessorML</ulink> for details.\r
28343</simpara>\r
28344</listitem>\r
28345<listitem>\r
28346<simpara>\r
28347Split <literal>nonexhaustiveMatch {warn|error|igore}</literal> and <literal>redundantMatch\r
28348 {warn|error|ignore}</literal> into <literal>nonexhaustiveMatch</literal> and <literal>redundantMatch</literal>\r
28349 (controls diagnostics for <literal>case</literal> expressions, <literal>fn</literal> expressions, and <literal>fun</literal>\r
28350 declarations (which may raise <literal>Match</literal> on failure)) and <literal>nonexhaustiveBind</literal>\r
28351 and <literal>redundantBind</literal> (controls diagnostics for <literal>val</literal> declarations (which may\r
28352 raise <literal>Bind</literal> on failure)).\r
28353</simpara>\r
28354</listitem>\r
28355<listitem>\r
28356<simpara>\r
28357Added <literal>valrecConstr {warn|error|ignore}</literal> to report when a <literal>val rec</literal> (or\r
28358 <literal>fun</literal>) declaration redefines an identifier that previously had constructor\r
28359 status.\r
28360</simpara>\r
28361</listitem>\r
28362</itemizedlist>\r
28363</listitem>\r
28364</itemizedlist>\r
28365</listitem>\r
28366<listitem>\r
28367<simpara>\r
28368Libraries.\r
28369</simpara>\r
28370<itemizedlist>\r
28371<listitem>\r
28372<simpara>\r
28373Basis Library.\r
28374</simpara>\r
28375<itemizedlist>\r
28376<listitem>\r
28377<simpara>\r
28378Improved performance of <literal>Array.copy</literal>, <literal>Array.copyVec</literal>, <literal>Vector.append</literal>,\r
28379 <literal>String.^</literal>, <literal>String.concat</literal>, <literal>String.concatWith</literal>, and other related\r
28380 functions by using <literal>memmove</literal> rather than element-by-element constructions.\r
28381</simpara>\r
28382</listitem>\r
28383</itemizedlist>\r
28384</listitem>\r
28385<listitem>\r
28386<simpara>\r
28387<literal>Unsafe</literal> structure.\r
28388</simpara>\r
28389<itemizedlist>\r
28390<listitem>\r
28391<simpara>\r
28392Added unsafe operations for array uninitialization and raw arrays; see\r
28393 <ulink url="https://github.com/MLton/mlton/pull/207">https://github.com/MLton/mlton/pull/207</ulink> for details.\r
28394</simpara>\r
28395</listitem>\r
28396</itemizedlist>\r
28397</listitem>\r
28398<listitem>\r
28399<simpara>\r
28400Other libraries.\r
28401</simpara>\r
28402<itemizedlist>\r
28403<listitem>\r
28404<simpara>\r
28405Updated: ckit library, MLLPT library, MLRISC library, SML/NJ library\r
28406</simpara>\r
28407</listitem>\r
28408</itemizedlist>\r
28409</listitem>\r
28410</itemizedlist>\r
28411</listitem>\r
28412<listitem>\r
28413<simpara>\r
28414Tools.\r
28415</simpara>\r
28416<itemizedlist>\r
28417<listitem>\r
28418<simpara>\r
28419mlnlffigen\r
28420</simpara>\r
28421<itemizedlist>\r
28422<listitem>\r
28423<simpara>\r
28424Updated to warn and skip (rather than abort) when encountering functions\r
28425 with <literal>struct</literal>/<literal>union</literal> argument or return type.\r
28426</simpara>\r
28427</listitem>\r
28428</itemizedlist>\r
28429</listitem>\r
28430</itemizedlist>\r
28431</listitem>\r
28432</itemizedlist>\r
28433<simpara>For a complete list of changes and bug fixes since\r
28434<link linkend="Release20130715">Release20130715</link>, see the\r
28435<ulink url="https://github.com/MLton/mlton/blob/on-20180207-release/CHANGELOG.adoc"><literal>CHANGELOG.adoc</literal></ulink> and\r
28436<link linkend="Bugs20130715">Bugs20130715</link>.</simpara>\r
28437</section>\r
28438<section id="_20180207_binary_packages">\r
28439<title>20180207 binary packages</title>\r
28440<itemizedlist>\r
28441<listitem>\r
28442<simpara>\r
28443AMD64 (aka "x86-64" or "x64")\r
28444</simpara>\r
28445<itemizedlist>\r
28446<listitem>\r
28447<simpara>\r
28448<ulink url="https://sourceforge.net/projects/mlton/files/mlton/20180207/mlton-20180207-1.amd64-darwin.gmp-homebrew.tgz">Darwin (.tgz)</ulink> 16.7 (Mac OS X Sierra), dynamically linked against <link linkend="GnuMP">GnuMP</link> in <literal>/usr/local/lib</literal> (suitable for <ulink url="https://brew.sh/">Homebrew</ulink> install of <link linkend="GnuMP">GnuMP</link>)\r
28449</simpara>\r
28450</listitem>\r
28451<listitem>\r
28452<simpara>\r
28453<ulink url="https://sourceforge.net/projects/mlton/files/mlton/20180207/mlton-20180207-1.amd64-darwin.gmp-static.tgz">Darwin (.tgz)</ulink> 16.7 (Mac OS X Sierra), statically linked against <link linkend="GnuMP">GnuMP</link> (but requires <link linkend="GnuMP">GnuMP</link> for generated executables)\r
28454</simpara>\r
28455</listitem>\r
28456<listitem>\r
28457<simpara>\r
28458<ulink url="https://sourceforge.net/projects/mlton/files/mlton/20180207/mlton-20180207-1.amd64-linux.tgz">Linux</ulink>, glibc 2.23\r
28459\r
28460\r
28461\r
28462\r
28463\r
28464</simpara>\r
28465</listitem>\r
28466</itemizedlist>\r
28467</listitem>\r
28468</itemizedlist>\r
28469</section>\r
28470<section id="_20180207_source_packages">\r
28471<title>20180207 source packages</title>\r
28472<itemizedlist>\r
28473<listitem>\r
28474<simpara>\r
28475<ulink url="https://sourceforge.net/projects/mlton/files/mlton/20180207/mlton-20180207.src.tgz">mlton-20180207.src.tgz</ulink>\r
28476</simpara>\r
28477</listitem>\r
28478</itemizedlist>\r
28479</section>\r
28480<section id="_also_see_36">\r
28481<title>Also see</title>\r
28482<itemizedlist>\r
28483<listitem>\r
28484<simpara>\r
28485<link linkend="Bugs20180207">Bugs20180207</link>\r
28486</simpara>\r
28487</listitem>\r
28488<listitem>\r
28489<simpara>\r
28490<ulink url="http://www.mlton.org/guide/20180207/">MLton Guide (20180207)</ulink>.\r
28491</simpara>\r
28492<simpara>A snapshot of the MLton website at the time of release.</simpara>\r
28493</listitem>\r
28494</itemizedlist>\r
28495<simpara><?asciidoc-pagebreak?></simpara>\r
28496</section>\r
28497</section>\r
28498<section id="ReleaseChecklist">\r
28499<title>ReleaseChecklist</title>\r
28500<section id="_advance_preparation_for_release">\r
28501<title>Advance preparation for release</title>\r
28502<itemizedlist>\r
28503<listitem>\r
28504<simpara>\r
28505Update <literal>./CHANGELOG.adoc</literal>.\r
28506</simpara>\r
28507<itemizedlist>\r
28508<listitem>\r
28509<simpara>\r
28510Write entries for missing notable commits.\r
28511</simpara>\r
28512</listitem>\r
28513<listitem>\r
28514<simpara>\r
28515Write summary of changes from previous release.\r
28516</simpara>\r
28517</listitem>\r
28518<listitem>\r
28519<simpara>\r
28520Update with estimated release date.\r
28521</simpara>\r
28522</listitem>\r
28523</itemizedlist>\r
28524</listitem>\r
28525<listitem>\r
28526<simpara>\r
28527Update <literal>./README.adoc</literal>.\r
28528</simpara>\r
28529<itemizedlist>\r
28530<listitem>\r
28531<simpara>\r
28532Check features and description.\r
28533</simpara>\r
28534</listitem>\r
28535</itemizedlist>\r
28536</listitem>\r
28537<listitem>\r
28538<simpara>\r
28539Update <literal>man/{mlton,mlprof}.1</literal>.\r
28540</simpara>\r
28541<itemizedlist>\r
28542<listitem>\r
28543<simpara>\r
28544Check compile-time and run-time options in <literal>man/mlton.1</literal>.\r
28545</simpara>\r
28546</listitem>\r
28547<listitem>\r
28548<simpara>\r
28549Check options in <literal>man/mlprof.1</literal>.\r
28550</simpara>\r
28551</listitem>\r
28552<listitem>\r
28553<simpara>\r
28554Update with estimated release date.\r
28555</simpara>\r
28556</listitem>\r
28557</itemizedlist>\r
28558</listitem>\r
28559<listitem>\r
28560<simpara>\r
28561Update <literal>doc/guide</literal>.\r
28562</simpara>\r
28563<itemizedlist>\r
28564<listitem>\r
28565<simpara>\r
28566Synchronize <link linkend="Features">Features</link> page with <literal>./README.adoc</literal>.\r
28567</simpara>\r
28568</listitem>\r
28569<listitem>\r
28570<simpara>\r
28571Update <link linkend="Credits">Credits</link> page with acknowledgements.\r
28572</simpara>\r
28573</listitem>\r
28574<listitem>\r
28575<simpara>\r
28576Create <emphasis role="strong">ReleaseYYYYMM??</emphasis> page (i.e., forthcoming release) based on <emphasis role="strong">ReleaseXXXXLLCC</emphasis> (i.e., previous release).\r
28577</simpara>\r
28578<itemizedlist>\r
28579<listitem>\r
28580<simpara>\r
28581Update summary from <literal>./CHANGELOG.adoc</literal>.\r
28582</simpara>\r
28583</listitem>\r
28584<listitem>\r
28585<simpara>\r
28586Update links to estimated release date.\r
28587</simpara>\r
28588</listitem>\r
28589</itemizedlist>\r
28590</listitem>\r
28591<listitem>\r
28592<simpara>\r
28593Create <emphasis role="strong">BugsYYYYMM??</emphasis> page based on <emphasis role="strong">BugsXXXXLLCC</emphasis>.\r
28594</simpara>\r
28595<itemizedlist>\r
28596<listitem>\r
28597<simpara>\r
28598Update links to estimated release date.\r
28599</simpara>\r
28600</listitem>\r
28601</itemizedlist>\r
28602</listitem>\r
28603<listitem>\r
28604<simpara>\r
28605Spell check pages.\r
28606</simpara>\r
28607</listitem>\r
28608</itemizedlist>\r
28609</listitem>\r
28610<listitem>\r
28611<simpara>\r
28612Ensure that all updates are pushed to <literal>master</literal> branch of <ulink url="https://github.com/MLton/mlton"><literal>mlton</literal></ulink>.\r
28613</simpara>\r
28614</listitem>\r
28615</itemizedlist>\r
28616</section>\r
28617<section id="_prepare_sources_for_tagging">\r
28618<title>Prepare sources for tagging</title>\r
28619<itemizedlist>\r
28620<listitem>\r
28621<simpara>\r
28622Update <literal>./CHANGELOG.adoc</literal>.\r
28623</simpara>\r
28624<itemizedlist>\r
28625<listitem>\r
28626<simpara>\r
28627Update with proper release date.\r
28628</simpara>\r
28629</listitem>\r
28630</itemizedlist>\r
28631</listitem>\r
28632<listitem>\r
28633<simpara>\r
28634Update <literal>man/{mlton,mlprof}.1</literal>.\r
28635</simpara>\r
28636<itemizedlist>\r
28637<listitem>\r
28638<simpara>\r
28639Update with proper release date.\r
28640</simpara>\r
28641</listitem>\r
28642</itemizedlist>\r
28643</listitem>\r
28644<listitem>\r
28645<simpara>\r
28646Update <literal>doc/guide</literal>.\r
28647</simpara>\r
28648<itemizedlist>\r
28649<listitem>\r
28650<simpara>\r
28651Rename <emphasis role="strong">ReleaseYYYYMM??</emphasis> to <emphasis role="strong">ReleaseYYYYMMDD</emphasis> with proper release date.\r
28652</simpara>\r
28653<itemizedlist>\r
28654<listitem>\r
28655<simpara>\r
28656Update links with proper release date.\r
28657</simpara>\r
28658</listitem>\r
28659</itemizedlist>\r
28660</listitem>\r
28661<listitem>\r
28662<simpara>\r
28663Rename <emphasis role="strong">BugsYYYYMM??</emphasis> to <emphasis role="strong">BugsYYYYMMDD</emphasis> with proper release date.\r
28664</simpara>\r
28665<itemizedlist>\r
28666<listitem>\r
28667<simpara>\r
28668Update links with proper release date.\r
28669</simpara>\r
28670</listitem>\r
28671</itemizedlist>\r
28672</listitem>\r
28673<listitem>\r
28674<simpara>\r
28675Update <emphasis role="strong">ReleaseXXXXLLCC</emphasis>.\r
28676</simpara>\r
28677<itemizedlist>\r
28678<listitem>\r
28679<simpara>\r
28680Change intro to "<literal>This is an archived public release of MLton, version XXXXLLCC.</literal>"\r
28681</simpara>\r
28682</listitem>\r
28683</itemizedlist>\r
28684</listitem>\r
28685<listitem>\r
28686<simpara>\r
28687Update <link linkend="Home">Home</link> with note of new release.\r
28688</simpara>\r
28689<itemizedlist>\r
28690<listitem>\r
28691<simpara>\r
28692Change <literal>What's new?</literal> text to <literal>Please try out our new release, &lt;:ReleaseYYYYMMDD:MLton YYYYMMDD&gt;</literal>.\r
28693</simpara>\r
28694</listitem>\r
28695<listitem>\r
28696<simpara>\r
28697Update <literal>Download</literal> link with proper release date.\r
28698</simpara>\r
28699</listitem>\r
28700</itemizedlist>\r
28701</listitem>\r
28702<listitem>\r
28703<simpara>\r
28704Update <link linkend="Releases">Releases</link> with new release.\r
28705</simpara>\r
28706</listitem>\r
28707</itemizedlist>\r
28708</listitem>\r
28709<listitem>\r
28710<simpara>\r
28711Ensure that all updates are pushed to <literal>master</literal> branch of <ulink url="https://github.com/MLton/mlton"><literal>mlton</literal></ulink>.\r
28712</simpara>\r
28713</listitem>\r
28714</itemizedlist>\r
28715</section>\r
28716<section id="_tag_sources">\r
28717<title>Tag sources</title>\r
28718<itemizedlist>\r
28719<listitem>\r
28720<simpara>\r
28721Shell commands:\r
28722</simpara>\r
28723<screen>git clone http://github.com/MLton/mlton mlton.git\r
28724cd mlton.git\r
28725git checkout master\r
28726git tag -a -m "Tagging YYYYMMDD release" on-YYYYMMDD-release master\r
28727git push origin on-YYYYMMDD-release</screen>\r
28728</listitem>\r
28729</itemizedlist>\r
28730</section>\r
28731<section id="_packaging">\r
28732<title>Packaging</title>\r
28733<section id="_sourceforge_frs">\r
28734<title>SourceForge FRS</title>\r
28735<itemizedlist>\r
28736<listitem>\r
28737<simpara>\r
28738Create <emphasis role="strong">YYYYMMDD</emphasis> directory:\r
28739</simpara>\r
28740<screen>sftp user@frs.sourceforge.net:/home/frs/project/mlton/mlton\r
28741sftp&gt; mkdir YYYYMMDD\r
28742sftp&gt; quit</screen>\r
28743</listitem>\r
28744</itemizedlist>\r
28745</section>\r
28746<section id="_source_release">\r
28747<title>Source release</title>\r
28748<itemizedlist>\r
28749<listitem>\r
28750<simpara>\r
28751Create <literal>mlton-YYYYMMDD.src.tgz</literal>:\r
28752</simpara>\r
28753<screen>git clone http://github.com/MLton/mlton mlton\r
28754cd mlton\r
28755git checkout on-YYYYMMDD-release\r
28756make MLTON_VERSION=YYYYMMDD source-release\r
28757cd ..</screen>\r
28758<simpara>or</simpara>\r
28759<screen>wget https://github.com/MLton/mlton/archive/on-YYYYMMDD-release.tar.gz\r
28760tar xzvf on-YYYYMMDD-release.tar.gz\r
28761cd mlton-on-YYYYMMDD-release\r
28762make MLTON_VERSION=YYYYMMDD source-release\r
28763cd ..</screen>\r
28764</listitem>\r
28765<listitem>\r
28766<simpara>\r
28767Upload <literal>mlton-YYYYMMDD.src.tgz</literal>:\r
28768</simpara>\r
28769<screen>scp mlton-YYYYMMDD.src.tgz user@frs.sourceforge.net:/home/frs/project/mlton/mlton/YYYYMMDD/</screen>\r
28770</listitem>\r
28771<listitem>\r
28772<simpara>\r
28773Update <emphasis role="strong">ReleaseYYYYMMDD</emphasis> with <literal>mlton-YYYYMMDD.src.tgz</literal> link.\r
28774</simpara>\r
28775</listitem>\r
28776</itemizedlist>\r
28777</section>\r
28778<section id="_binary_releases">\r
28779<title>Binary releases</title>\r
28780<itemizedlist>\r
28781<listitem>\r
28782<simpara>\r
28783Build and create <literal>mlton-YYYYMMDD-1.ARCH-OS.tgz</literal>:\r
28784</simpara>\r
28785<screen>wget http://sourceforge.net/projects/mlton/files/mlton/YYYYMMDD/mlton-YYYYMMDD.src.tgz\r
28786tar xzvf mlton-YYYYMMDD.src.tgz\r
28787cd mlton-YYYYMMDD\r
28788make binary-release\r
28789cd ..</screen>\r
28790</listitem>\r
28791<listitem>\r
28792<simpara>\r
28793Upload <literal>mlton-YYYYMMDD-1.ARCH-OS.tgz</literal>:\r
28794</simpara>\r
28795<screen>scp mlton-YYYYMMDD-1.ARCH-OS.tgz user@frs.sourceforge.net:/home/frs/project/mlton/mlton/YYYYMMDD/</screen>\r
28796</listitem>\r
28797<listitem>\r
28798<simpara>\r
28799Update <emphasis role="strong">ReleaseYYYYMMDD</emphasis> with <literal>mlton-YYYYMMDD-1.ARCH-OS.tgz</literal> link.\r
28800</simpara>\r
28801</listitem>\r
28802</itemizedlist>\r
28803</section>\r
28804</section>\r
28805<section id="_website">\r
28806<title>Website</title>\r
28807<itemizedlist>\r
28808<listitem>\r
28809<simpara>\r
28810<literal>guide/YYYYMMDD</literal> gets a copy of <literal>doc/guide/localhost</literal>.\r
28811</simpara>\r
28812</listitem>\r
28813<listitem>\r
28814<simpara>\r
28815Shell commands:\r
28816</simpara>\r
28817<screen>wget http://sourceforge.net/projects/mlton/files/mlton/YYYYMMDD/mlton-YYYYMMDD.src.tgz\r
28818tar xzvf mlton-YYYYMMDD.src.tgz\r
28819cd mlton-YYYYMMDD\r
28820cd doc/guide\r
28821cp -prf localhost YYYYMMDD\r
28822tar czvf guide-YYYYMMDD.tgz YYYYMMDD\r
28823rsync -avzP --delete -e ssh YYYYMMDD user@web.sourceforge.net:/home/project-web/mlton/htdocs/guide/\r
28824rsync -avzP --delete -e ssh guide-YYYYMMDD.tgz user@web.sourceforge.net:/home/project-web/mlton/htdocs/guide/</screen>\r
28825</listitem>\r
28826</itemizedlist>\r
28827</section>\r
28828<section id="_announce_release">\r
28829<title>Announce release</title>\r
28830<itemizedlist>\r
28831<listitem>\r
28832<simpara>\r
28833Mail announcement to:\r
28834</simpara>\r
28835<itemizedlist>\r
28836<listitem>\r
28837<simpara>\r
28838<ulink url="mailto:MLton-devel@mlton.org"><literal>MLton-devel@mlton.org</literal></ulink>\r
28839</simpara>\r
28840</listitem>\r
28841<listitem>\r
28842<simpara>\r
28843<ulink url="mailto:MLton-user@mlton.org"><literal>MLton-user@mlton.org</literal></ulink>\r
28844</simpara>\r
28845</listitem>\r
28846</itemizedlist>\r
28847</listitem>\r
28848</itemizedlist>\r
28849</section>\r
28850<section id="_misc">\r
28851<title>Misc.</title>\r
28852<itemizedlist>\r
28853<listitem>\r
28854<simpara>\r
28855Generate new <link linkend="Performance">Performance</link> numbers.\r
28856</simpara>\r
28857</listitem>\r
28858</itemizedlist>\r
28859<simpara><?asciidoc-pagebreak?></simpara>\r
28860</section>\r
28861</section>\r
28862<section id="Releases">\r
28863<title>Releases</title>\r
28864<simpara>Public releases of MLton:</simpara>\r
28865<itemizedlist>\r
28866<listitem>\r
28867<simpara>\r
28868<link linkend="Release20180207">Release20180207</link>\r
28869</simpara>\r
28870</listitem>\r
28871<listitem>\r
28872<simpara>\r
28873<link linkend="Release20130715">Release20130715</link>\r
28874</simpara>\r
28875</listitem>\r
28876<listitem>\r
28877<simpara>\r
28878<link linkend="Release20100608">Release20100608</link>\r
28879</simpara>\r
28880</listitem>\r
28881<listitem>\r
28882<simpara>\r
28883<link linkend="Release20070826">Release20070826</link>\r
28884</simpara>\r
28885</listitem>\r
28886<listitem>\r
28887<simpara>\r
28888<link linkend="Release20051202">Release20051202</link>\r
28889</simpara>\r
28890</listitem>\r
28891<listitem>\r
28892<simpara>\r
28893<link linkend="Release20041109">Release20041109</link>\r
28894</simpara>\r
28895</listitem>\r
28896<listitem>\r
28897<simpara>\r
28898Release20040227\r
28899</simpara>\r
28900</listitem>\r
28901<listitem>\r
28902<simpara>\r
28903Release20030716\r
28904</simpara>\r
28905</listitem>\r
28906<listitem>\r
28907<simpara>\r
28908Release20030711\r
28909</simpara>\r
28910</listitem>\r
28911<listitem>\r
28912<simpara>\r
28913Release20030312\r
28914</simpara>\r
28915</listitem>\r
28916<listitem>\r
28917<simpara>\r
28918Release20020923\r
28919</simpara>\r
28920</listitem>\r
28921<listitem>\r
28922<simpara>\r
28923Release20020410\r
28924</simpara>\r
28925</listitem>\r
28926<listitem>\r
28927<simpara>\r
28928Release20011006\r
28929</simpara>\r
28930</listitem>\r
28931<listitem>\r
28932<simpara>\r
28933Release20010806\r
28934</simpara>\r
28935</listitem>\r
28936<listitem>\r
28937<simpara>\r
28938Release20010706\r
28939</simpara>\r
28940</listitem>\r
28941<listitem>\r
28942<simpara>\r
28943Release20000906\r
28944</simpara>\r
28945</listitem>\r
28946<listitem>\r
28947<simpara>\r
28948Release20000712\r
28949</simpara>\r
28950</listitem>\r
28951<listitem>\r
28952<simpara>\r
28953Release19990712\r
28954</simpara>\r
28955</listitem>\r
28956<listitem>\r
28957<simpara>\r
28958Release19990319\r
28959</simpara>\r
28960</listitem>\r
28961<listitem>\r
28962<simpara>\r
28963Release19980826\r
28964</simpara>\r
28965</listitem>\r
28966</itemizedlist>\r
28967<simpara><?asciidoc-pagebreak?></simpara>\r
28968</section>\r
28969<section id="RemoveUnused">\r
28970<title>RemoveUnused</title>\r
28971<simpara><link linkend="RemoveUnused">RemoveUnused</link> is an optimization pass for both the <link linkend="SSA">SSA</link> and\r
28972<link linkend="SSA2">SSA2</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link>s, invoked from <link linkend="SSASimplify">SSASimplify</link> and\r
28973<link linkend="SSA2Simplify">SSA2Simplify</link>.</simpara>\r
28974<section id="_description_49">\r
28975<title>Description</title>\r
28976<simpara>This pass aggressively removes unused:</simpara>\r
28977<itemizedlist>\r
28978<listitem>\r
28979<simpara>\r
28980datatypes\r
28981</simpara>\r
28982</listitem>\r
28983<listitem>\r
28984<simpara>\r
28985datatype constructors\r
28986</simpara>\r
28987</listitem>\r
28988<listitem>\r
28989<simpara>\r
28990datatype constructor arguments\r
28991</simpara>\r
28992</listitem>\r
28993<listitem>\r
28994<simpara>\r
28995functions\r
28996</simpara>\r
28997</listitem>\r
28998<listitem>\r
28999<simpara>\r
29000function arguments\r
29001</simpara>\r
29002</listitem>\r
29003<listitem>\r
29004<simpara>\r
29005function returns\r
29006</simpara>\r
29007</listitem>\r
29008<listitem>\r
29009<simpara>\r
29010blocks\r
29011</simpara>\r
29012</listitem>\r
29013<listitem>\r
29014<simpara>\r
29015block arguments\r
29016</simpara>\r
29017</listitem>\r
29018<listitem>\r
29019<simpara>\r
29020statements (variable bindings)\r
29021</simpara>\r
29022</listitem>\r
29023<listitem>\r
29024<simpara>\r
29025handlers from non-tail calls (mayRaise analysis)\r
29026</simpara>\r
29027</listitem>\r
29028<listitem>\r
29029<simpara>\r
29030continuations from non-tail calls (mayReturn analysis)\r
29031</simpara>\r
29032</listitem>\r
29033</itemizedlist>\r
29034</section>\r
29035<section id="_implementation_54">\r
29036<title>Implementation</title>\r
29037<itemizedlist>\r
29038<listitem>\r
29039<simpara>\r
29040<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/remove-unused.fun"><literal>remove-unused.fun</literal></ulink>\r
29041</simpara>\r
29042</listitem>\r
29043<listitem>\r
29044<simpara>\r
29045<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/remove-unused2.fun"><literal>remove-unused2.fun</literal></ulink>\r
29046</simpara>\r
29047</listitem>\r
29048</itemizedlist>\r
29049</section>\r
29050<section id="_details_and_notes_52">\r
29051<title>Details and Notes</title>\r
29052<simpara></simpara>\r
29053<simpara><?asciidoc-pagebreak?></simpara>\r
29054</section>\r
29055</section>\r
29056<section id="Restore">\r
29057<title>Restore</title>\r
29058<simpara><link linkend="Restore">Restore</link> is a rewrite pass for the <link linkend="SSA">SSA</link> and <link linkend="SSA2">SSA2</link>\r
29059<link linkend="IntermediateLanguage">IntermediateLanguage</link>s, invoked from <link linkend="KnownCase">KnownCase</link> and\r
29060<link linkend="LocalRef">LocalRef</link>.</simpara>\r
29061<section id="_description_50">\r
29062<title>Description</title>\r
29063<simpara>This pass restores the SSA condition for a violating <link linkend="SSA">SSA</link> or\r
29064<link linkend="SSA2">SSA2</link> program; the program must satisfy:</simpara>\r
29065<blockquote>\r
29066<simpara>Every path from the root to a use of a variable (excluding globals)\r
29067passes through a def of that variable.</simpara>\r
29068</blockquote>\r
29069</section>\r
29070<section id="_implementation_55">\r
29071<title>Implementation</title>\r
29072<itemizedlist>\r
29073<listitem>\r
29074<simpara>\r
29075<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/restore.sig"><literal>restore.sig</literal></ulink>\r
29076</simpara>\r
29077</listitem>\r
29078<listitem>\r
29079<simpara>\r
29080<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/restore.fun"><literal>restore.fun</literal></ulink>\r
29081</simpara>\r
29082</listitem>\r
29083<listitem>\r
29084<simpara>\r
29085<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/restore2.sig"><literal>restore2.sig</literal></ulink>\r
29086</simpara>\r
29087</listitem>\r
29088<listitem>\r
29089<simpara>\r
29090<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/restore2.fun"><literal>restore2.fun</literal></ulink>\r
29091</simpara>\r
29092</listitem>\r
29093</itemizedlist>\r
29094</section>\r
29095<section id="_details_and_notes_53">\r
29096<title>Details and Notes</title>\r
29097<simpara>Based primarily on Section 19.1 of <link linkend="References_Appel98">Modern Compiler Implementation in ML</link>.</simpara>\r
29098<simpara>The main deviation is the calculation of liveness of the violating\r
29099variables, which is used to predicate the insertion of phi arguments.\r
29100This is due to the algorithm&#8217;s bias towards imperative languages, for\r
29101which it makes the assumption that all variables are defined in the\r
29102start block and all variables are "used" at exit.</simpara>\r
29103<simpara>This is "optimized" for restoration of functions with small numbers of\r
29104violating variables&#8201;&#8212;&#8201;use bool vectors to represent sets of violating\r
29105variables.</simpara>\r
29106<simpara>Also, we use a <literal>Promise.t</literal> to suspend part of the dominance frontier\r
29107computation.</simpara>\r
29108<simpara><?asciidoc-pagebreak?></simpara>\r
29109</section>\r
29110</section>\r
29111<section id="ReturnStatement">\r
29112<title>ReturnStatement</title>\r
29113<simpara>Programmers coming from languages that have a <literal>return</literal> statement, such\r
29114as C, Java, and Python, often ask how one can translate functions that\r
29115return early into SML. This page briefly describes a number of ways\r
29116to translate uses of <literal>return</literal> to SML.</simpara>\r
29117<section id="_conditional_iterator_function">\r
29118<title>Conditional iterator function</title>\r
29119<simpara>A conditional iterator function, such as\r
29120<ulink url="http://www.standardml.org/Basis/list.html#SIG:LIST.find:VAL"><literal>List.find</literal></ulink>,\r
29121<ulink url="http://www.standardml.org/Basis/list.html#SIG:LIST.exists:VAL"><literal>List.exists</literal></ulink>,\r
29122or\r
29123<ulink url="http://www.standardml.org/Basis/list.html#SIG:LIST.all:VAL"><literal>List.all</literal></ulink>\r
29124is probably what you want in most cases. Unfortunately, it might be\r
29125the case that the particular conditional iteration pattern that you\r
29126want isn&#8217;t provided for your data structure. Usually the best\r
29127alternative in such a case is to implement the desired iteration\r
29128pattern as a higher-order function. For example, to implement a\r
29129<literal>find</literal> function for arrays (which already exists as\r
29130<ulink url="http://www.standardml.org/Basis/array.html#SIG:ARRAY.findi:VAL"><literal>Array.find</literal></ulink>)\r
29131one could write</simpara>\r
29132<programlisting language="sml" linenumbering="unnumbered">fun find predicate array = let\r
29133 fun loop i =\r
29134 if i = Array.length array then\r
29135 NONE\r
29136 else if predicate (Array.sub (array, i)) then\r
29137 SOME (Array.sub (array, i))\r
29138 else\r
29139 loop (i+1)\r
29140in\r
29141 loop 0\r
29142end</programlisting>\r
29143<simpara>Of course, this technique, while probably the most common case in\r
29144practice, applies only if you are essentially iterating over some data\r
29145structure.</simpara>\r
29146</section>\r
29147<section id="_escape_handler">\r
29148<title>Escape handler</title>\r
29149<simpara>Probably the most direct way to translate code using <literal>return</literal>\r
29150statements is to basically implement <literal>return</literal> using exception\r
29151handling. The mechanism can be packaged into a reusable module with\r
29152the signature\r
29153(<ulink url="https://github.com/MLton/mltonlib/blob/master/com/ssh/extended-basis/unstable/public/control/exit.sig"><literal>exit.sig</literal></ulink>):</simpara>\r
29154<programlisting language="sml" linenumbering="unnumbered">(**\r
29155 * Signature for exit (or escape) handlers.\r
29156 *\r
29157 * Note that the implementation necessarily uses exception handling. This\r
29158 * is to make proper resource handling possible. Exceptions raised by the\r
29159 * implementation can be caught by wildcard exception handlers. Wildcard\r
29160 * exception handlers should generally reraise exceptions after performing\r
29161 * their effects.\r
29162 *)\r
29163signature EXIT = sig\r
29164 type 'a t\r
29165 (** The type of exits. *)\r
29166\r
29167 val within : ('a t, 'a) CPS.t\r
29168 (**\r
29169 * Sets up an exit and passes it to the given function. The function\r
29170 * may then return normally or by calling {to} with the exit and a\r
29171 * return value. For example,\r
29172 *\r
29173 *&gt; Exit.within\r
29174 *&gt; (fn l =&gt;\r
29175 *&gt; if condition then\r
29176 *&gt; Exit.to l 1\r
29177 *&gt; else\r
29178 *&gt; 2)\r
29179 *\r
29180 * evaluates either to {1} or to {2} depending on the {condition}.\r
29181 *\r
29182 * Note that the function receiving the exit is called from a non-tail\r
29183 * position.\r
29184 *)\r
29185\r
29186 val to : 'a t -&gt; 'a -&gt; 'b\r
29187 (**\r
29188 * {to l v} returns from the {within} invocation that introduced the\r
29189 * exit {l} with the value {v}. Evaluating {to l v} outside of the\r
29190 * {within} invocation that introduced {l} is a programming error and\r
29191 * raises an exception.\r
29192 *\r
29193 * Note that the type variable {'b} only appears as the return type.\r
29194 * This means that {to} doesn't return normally to the caller and can\r
29195 * be called from a context of any type.\r
29196 *)\r
29197\r
29198 val call : ('a -&gt; 'b, 'a) CPS.t\r
29199 (**\r
29200 * Simpler, but less flexibly typed, interface to {within} and {to}.\r
29201 * Specifically, {call f} is equivalent to {within (f o to)}.\r
29202 *)\r
29203end</programlisting>\r
29204<simpara>(<link linkend="References_HarperEtAl93">Typing First-Class Continuations in ML</link>\r
29205discusses the typing of a related construct.) The implementation\r
29206(<ulink url="https://github.com/MLton/mltonlib/blob/master/com/ssh/extended-basis/unstable/detail/control/exit.sml"><literal>exit.sml</literal></ulink>)\r
29207is straightforward:</simpara>\r
29208<programlisting language="sml" linenumbering="unnumbered">structure Exit :&gt; EXIT = struct\r
29209 type 'a t = 'a -&gt; exn\r
29210\r
29211 fun within block = let\r
29212 exception EscapedExit of 'a\r
29213 in\r
29214 block EscapedExit\r
29215 handle EscapedExit value =&gt; value\r
29216 end\r
29217\r
29218 fun to exit value = raise exit value\r
29219\r
29220 fun call block = within (block o to)\r
29221end</programlisting>\r
29222<simpara>Here is an example of how one could implement a <literal>find</literal> function given\r
29223an <literal>app</literal> function:</simpara>\r
29224<programlisting language="sml" linenumbering="unnumbered">fun appToFind (app : ('a -&gt; unit) -&gt; 'b -&gt; unit)\r
29225 (predicate : 'a -&gt; bool)\r
29226 (data : 'b) =\r
29227 Exit.call\r
29228 (fn return =&gt;\r
29229 (app (fn x =&gt;\r
29230 if predicate x then\r
29231 return (SOME x)\r
29232 else\r
29233 ())\r
29234 data\r
29235 ; NONE))</programlisting>\r
29236<simpara>In the above, as soon as the expression <literal>predicate x</literal> evaluates to\r
29237<literal>true</literal> the <literal>app</literal> invocation is terminated.</simpara>\r
29238</section>\r
29239<section id="_continuation_passing_style_cps">\r
29240<title>Continuation-passing Style (CPS)</title>\r
29241<simpara>A general way to implement complex control patterns is to use\r
29242<ulink url="http://en.wikipedia.org/wiki/Continuation-passing_style">CPS</ulink>. In CPS,\r
29243instead of returning normally, functions invoke a function passed as\r
29244an argument. In general, multiple continuation functions may be\r
29245passed as arguments and the ordinary return continuation may also be\r
29246used. As an example, here is a function that finds the leftmost\r
29247element of a binary tree satisfying a given predicate:</simpara>\r
29248<programlisting language="sml" linenumbering="unnumbered">datatype 'a tree = LEAF | BRANCH of 'a tree * 'a * 'a tree\r
29249\r
29250fun find predicate = let\r
29251 fun recurse continue =\r
29252 fn LEAF =&gt;\r
29253 continue ()\r
29254 | BRANCH (lhs, elem, rhs) =&gt;\r
29255 recurse\r
29256 (fn () =&gt;\r
29257 if predicate elem then\r
29258 SOME elem\r
29259 else\r
29260 recurse continue rhs)\r
29261 lhs\r
29262in\r
29263 recurse (fn () =&gt; NONE)\r
29264end</programlisting>\r
29265<simpara>Note that the above function returns as soon as the leftmost element\r
29266satisfying the predicate is found.</simpara>\r
29267<simpara><?asciidoc-pagebreak?></simpara>\r
29268</section>\r
29269</section>\r
29270<section id="RSSA">\r
29271<title>RSSA</title>\r
29272<simpara><link linkend="RSSA">RSSA</link> is an <link linkend="IntermediateLanguage">IntermediateLanguage</link>, translated from <link linkend="SSA2">SSA2</link> by\r
29273<link linkend="ToRSSA">ToRSSA</link>, optimized by <link linkend="RSSASimplify">RSSASimplify</link>, and translated by\r
29274<link linkend="ToMachine">ToMachine</link> to <link linkend="Machine">Machine</link>.</simpara>\r
29275<section id="_description_51">\r
29276<title>Description</title>\r
29277<simpara><link linkend="RSSA">RSSA</link> is a <link linkend="IntermediateLanguage">IntermediateLanguage</link> that makes representation\r
29278decisions explicit.</simpara>\r
29279</section>\r
29280<section id="_implementation_56">\r
29281<title>Implementation</title>\r
29282<itemizedlist>\r
29283<listitem>\r
29284<simpara>\r
29285<ulink url="https://github.com/MLton/mlton/blob/master/mlton/backend/rssa.sig"><literal>rssa.sig</literal></ulink>\r
29286</simpara>\r
29287</listitem>\r
29288<listitem>\r
29289<simpara>\r
29290<ulink url="https://github.com/MLton/mlton/blob/master/mlton/backend/rssa.fun"><literal>rssa.fun</literal></ulink>\r
29291</simpara>\r
29292</listitem>\r
29293</itemizedlist>\r
29294</section>\r
29295<section id="_type_checking_4">\r
29296<title>Type Checking</title>\r
29297<simpara>The new type language is aimed at expressing bit-level control over\r
29298layout and associated packing of data representations. There are\r
29299singleton types that denote constants, other atomic types for things\r
29300like integers and reals, and arbitrary sum types and sequence (tuple)\r
29301types. The big change to the type system is that type checking is now\r
29302based on subtyping, not type equality. So, for example, the singleton\r
29303type <literal>0xFFFFEEBB</literal> whose only inhabitant is the eponymous constant is a\r
29304subtype of the type <literal>Word32</literal>.</simpara>\r
29305</section>\r
29306<section id="_details_and_notes_54">\r
29307<title>Details and Notes</title>\r
29308<simpara>SSA is an abbreviation for Static Single Assignment. The <link linkend="RSSA">RSSA</link>\r
29309<link linkend="IntermediateLanguage">IntermediateLanguage</link> is a variant of SSA.</simpara>\r
29310<simpara><?asciidoc-pagebreak?></simpara>\r
29311</section>\r
29312</section>\r
29313<section id="RSSAShrink">\r
29314<title>RSSAShrink</title>\r
29315<simpara><link linkend="RSSAShrink">RSSAShrink</link> is an optimization pass for the <link linkend="RSSA">RSSA</link>\r
29316<link linkend="IntermediateLanguage">IntermediateLanguage</link>.</simpara>\r
29317<section id="_description_52">\r
29318<title>Description</title>\r
29319<simpara>This pass implements a whole family of compile-time reductions, like:</simpara>\r
29320<itemizedlist>\r
29321<listitem>\r
29322<simpara>\r
29323constant folding, copy propagation\r
29324</simpara>\r
29325</listitem>\r
29326<listitem>\r
29327<simpara>\r
29328inline the <literal>Goto</literal> to a block with a unique predecessor\r
29329</simpara>\r
29330</listitem>\r
29331</itemizedlist>\r
29332</section>\r
29333<section id="_implementation_57">\r
29334<title>Implementation</title>\r
29335<itemizedlist>\r
29336<listitem>\r
29337<simpara>\r
29338<ulink url="https://github.com/MLton/mlton/blob/master/mlton/backend/rssa.fun"><literal>rssa.fun</literal></ulink>\r
29339</simpara>\r
29340</listitem>\r
29341</itemizedlist>\r
29342</section>\r
29343<section id="_details_and_notes_55">\r
29344<title>Details and Notes</title>\r
29345<simpara></simpara>\r
29346<simpara><?asciidoc-pagebreak?></simpara>\r
29347</section>\r
29348</section>\r
29349<section id="RSSASimplify">\r
29350<title>RSSASimplify</title>\r
29351<simpara>The optimization passes for the <link linkend="RSSA">RSSA</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link> are\r
29352collected and controlled by the <literal>Backend</literal> functor\r
29353(<ulink url="https://github.com/MLton/mlton/blob/master/mlton/backend/backend.sig"><literal>backend.sig</literal></ulink>,\r
29354<ulink url="https://github.com/MLton/mlton/blob/master/mlton/backend/backend.fun"><literal>backend.fun</literal></ulink>).</simpara>\r
29355<simpara>The following optimization pass is implemented:</simpara>\r
29356<itemizedlist>\r
29357<listitem>\r
29358<simpara>\r
29359<link linkend="RSSAShrink">RSSAShrink</link>\r
29360</simpara>\r
29361</listitem>\r
29362</itemizedlist>\r
29363<simpara>The following implementation passes are implemented:</simpara>\r
29364<itemizedlist>\r
29365<listitem>\r
29366<simpara>\r
29367<link linkend="ImplementHandlers">ImplementHandlers</link>\r
29368</simpara>\r
29369</listitem>\r
29370<listitem>\r
29371<simpara>\r
29372<link linkend="ImplementProfiling">ImplementProfiling</link>\r
29373</simpara>\r
29374</listitem>\r
29375<listitem>\r
29376<simpara>\r
29377<link linkend="InsertLimitChecks">InsertLimitChecks</link>\r
29378</simpara>\r
29379</listitem>\r
29380<listitem>\r
29381<simpara>\r
29382<link linkend="InsertSignalChecks">InsertSignalChecks</link>\r
29383</simpara>\r
29384</listitem>\r
29385</itemizedlist>\r
29386<simpara>The optimization passes can be controlled from the command-line by the options</simpara>\r
29387<itemizedlist>\r
29388<listitem>\r
29389<simpara>\r
29390<literal>-diag-pass &lt;pass&gt;</literal>&#8201;&#8212;&#8201;keep diagnostic info for pass\r
29391</simpara>\r
29392</listitem>\r
29393<listitem>\r
29394<simpara>\r
29395<literal>-drop-pass &lt;pass&gt;</literal>&#8201;&#8212;&#8201;omit optimization pass\r
29396</simpara>\r
29397</listitem>\r
29398<listitem>\r
29399<simpara>\r
29400<literal>-keep-pass &lt;pass&gt;</literal>&#8201;&#8212;&#8201;keep the results of pass\r
29401</simpara>\r
29402</listitem>\r
29403</itemizedlist>\r
29404<simpara><?asciidoc-pagebreak?></simpara>\r
29405</section>\r
29406<section id="RunningOnAIX">\r
29407<title>RunningOnAIX</title>\r
29408<simpara>MLton runs fine on AIX.</simpara>\r
29409<section id="_also_see_37">\r
29410<title>Also see</title>\r
29411<itemizedlist>\r
29412<listitem>\r
29413<simpara>\r
29414<link linkend="RunningOnPowerPC">RunningOnPowerPC</link>\r
29415</simpara>\r
29416</listitem>\r
29417<listitem>\r
29418<simpara>\r
29419<link linkend="RunningOnPowerPC64">RunningOnPowerPC64</link>\r
29420</simpara>\r
29421</listitem>\r
29422</itemizedlist>\r
29423<simpara><?asciidoc-pagebreak?></simpara>\r
29424</section>\r
29425</section>\r
29426<section id="RunningOnAlpha">\r
29427<title>RunningOnAlpha</title>\r
29428<simpara>MLton runs fine on the Alpha architecture.</simpara>\r
29429<section id="_notes_4">\r
29430<title>Notes</title>\r
29431<itemizedlist>\r
29432<listitem>\r
29433<simpara>\r
29434When compiling for Alpha, MLton doesn&#8217;t support native code\r
29435generation (<literal>-codegen native</literal>). Hence, performance is not as good as\r
29436it might be and compile times are longer. Also, the quality of code\r
29437generated by <literal>gcc</literal> is important. By default, MLton calls <literal>gcc -O1</literal>.\r
29438You can change this by calling MLton with <literal>-cc-opt -O2</literal>.\r
29439</simpara>\r
29440</listitem>\r
29441<listitem>\r
29442<simpara>\r
29443When compiling for Alpha, MLton uses <literal>-align 8</literal> by default.\r
29444</simpara>\r
29445</listitem>\r
29446</itemizedlist>\r
29447<simpara><?asciidoc-pagebreak?></simpara>\r
29448</section>\r
29449</section>\r
29450<section id="RunningOnAMD64">\r
29451<title>RunningOnAMD64</title>\r
29452<simpara>MLton runs fine on the AMD64 (aka "x86-64" or "x64") architecture.</simpara>\r
29453<section id="_notes_5">\r
29454<title>Notes</title>\r
29455<itemizedlist>\r
29456<listitem>\r
29457<simpara>\r
29458When compiling for AMD64, MLton targets the 64-bit ABI.\r
29459</simpara>\r
29460</listitem>\r
29461<listitem>\r
29462<simpara>\r
29463On AMD64, MLton supports native code generation (<literal>-codegen native</literal> or <literal>-codegen amd64</literal>).\r
29464</simpara>\r
29465</listitem>\r
29466<listitem>\r
29467<simpara>\r
29468When compiling for AMD64, MLton uses <literal>-align 8</literal> by default. Using\r
29469<literal>-align 4</literal> may be incompatible with optimized builds of the <link linkend="GnuMP">GnuMP</link>\r
29470library, which assume 8-byte alignment. (See the thread at\r
29471<ulink url="http://www.mlton.org/pipermail/mlton/2009-October/030674.html">http://www.mlton.org/pipermail/mlton/2009-October/030674.html</ulink> for more\r
29472details.)\r
29473</simpara>\r
29474</listitem>\r
29475</itemizedlist>\r
29476<simpara><?asciidoc-pagebreak?></simpara>\r
29477</section>\r
29478</section>\r
29479<section id="RunningOnARM">\r
29480<title>RunningOnARM</title>\r
29481<simpara>MLton runs fine on the ARM architecture.</simpara>\r
29482<section id="_notes_6">\r
29483<title>Notes</title>\r
29484<itemizedlist>\r
29485<listitem>\r
29486<simpara>\r
29487When compiling for ARM, MLton doesn&#8217;t support native code generation\r
29488(<literal>-codegen native</literal>). Hence, performance is not as good as it might be\r
29489and compile times are longer. Also, the quality of code generated by\r
29490<literal>gcc</literal> is important. By default, MLton calls <literal>gcc -O1</literal>. You can\r
29491change this by calling MLton with <literal>-cc-opt -O2</literal>.\r
29492</simpara>\r
29493</listitem>\r
29494</itemizedlist>\r
29495<simpara><?asciidoc-pagebreak?></simpara>\r
29496</section>\r
29497</section>\r
29498<section id="RunningOnCygwin">\r
29499<title>RunningOnCygwin</title>\r
29500<simpara>MLton runs on the <ulink url="http://www.cygwin.com/">Cygwin</ulink> emulation layer,\r
29501which provides a Posix-like environment while running on Windows. To\r
29502run MLton with Cygwin, you must first install Cygwin on your Windows\r
29503machine. To do this, visit the Cygwin site from your Windows machine\r
29504and run their <literal>setup.exe</literal> script. Then, you can unpack the MLton\r
29505binary <literal>tgz</literal> in your Cygwin environment.</simpara>\r
29506<simpara>To run MLton cross-compiled executables on Windows, you must install\r
29507the Cygwin <literal>dll</literal> on the Windows machine.</simpara>\r
29508<section id="_known_issues_2">\r
29509<title>Known issues</title>\r
29510<itemizedlist>\r
29511<listitem>\r
29512<simpara>\r
29513Time profiling is disabled.\r
29514</simpara>\r
29515</listitem>\r
29516<listitem>\r
29517<simpara>\r
29518Cygwin&#8217;s <literal>mmap</literal> emulation is less than perfect. Sometimes it\r
29519interacts badly with <literal>Posix.Process.fork</literal>.\r
29520</simpara>\r
29521</listitem>\r
29522<listitem>\r
29523<simpara>\r
29524The <ulink url="https://raw.github.com/MLton/mlton/master/regression/socket.sml"><literal>socket.sml</literal></ulink> regression\r
29525test fails. We suspect this is not a bug and is simply due to our\r
29526test relying on a certain behavior when connecting to a socket that\r
29527has not yet accepted, which is handled differently on Cygwin than\r
29528other platforms. Any help in understanding and resolving this issue\r
29529is appreciated.\r
29530</simpara>\r
29531</listitem>\r
29532</itemizedlist>\r
29533</section>\r
29534<section id="_also_see_38">\r
29535<title>Also see</title>\r
29536<itemizedlist>\r
29537<listitem>\r
29538<simpara>\r
29539<link linkend="RunningOnMinGW">RunningOnMinGW</link>\r
29540</simpara>\r
29541</listitem>\r
29542</itemizedlist>\r
29543<simpara><?asciidoc-pagebreak?></simpara>\r
29544</section>\r
29545</section>\r
29546<section id="RunningOnDarwin">\r
29547<title>RunningOnDarwin</title>\r
29548<simpara>MLton runs fine on Darwin (and on Mac OS X).</simpara>\r
29549<section id="_notes_7">\r
29550<title>Notes</title>\r
29551<itemizedlist>\r
29552<listitem>\r
29553<simpara>\r
29554MLton requires the <link linkend="GnuMP">GnuMP</link> library, which is available via\r
29555<ulink url="http://www.finkproject.org">Fink</ulink>, <ulink url="http://www.macports.com">MacPorts</ulink>,\r
29556<ulink url="http://mxcl.github.io/homebrew/">Homebrew</ulink>.\r
29557</simpara>\r
29558</listitem>\r
29559<listitem>\r
29560<simpara>\r
29561For Intel-based Macs, MLton targets the <link linkend="RunningOnAMD64">AMD64 architecture</link> on Darwin 10 (Mac OS X Snow Leopard) and higher and\r
29562targets the <link linkend="RunningOnX86">x86 architecture</link> on Darwin 8 (Mac OS X\r
29563Tiger) and Darwin 9 (Mac OS X Leopard).\r
29564</simpara>\r
29565</listitem>\r
29566</itemizedlist>\r
29567</section>\r
29568<section id="_known_issues_3">\r
29569<title>Known issues</title>\r
29570<itemizedlist>\r
29571<listitem>\r
29572<simpara>\r
29573Executables that save and load worlds on Darwin 11 (Mac OS X Lion)\r
29574and higher should be compiled with <literal>-link-opt -fno-PIE</literal> ; see\r
29575<link linkend="MLtonWorld">MLtonWorld</link> for more details.\r
29576</simpara>\r
29577</listitem>\r
29578<listitem>\r
29579<simpara>\r
29580<link linkend="ProfilingTime">ProfilingTime</link> may give inaccurate results on multi-processor\r
29581machines. The <literal>SIGPROF</literal> signal, used to sample the profiled program,\r
29582is supposed to be delivered 100 times a second (i.e., at 10000us\r
29583intervals), but there can be delays of over 1 minute between the\r
29584delivery of consecutive <literal>SIGPROF</literal> signals. A more complete\r
29585description may be found\r
29586<ulink url="http://lists.apple.com/archives/Unix-porting/2007/Aug/msg00000.html">here</ulink>\r
29587and\r
29588<ulink url="http://lists.apple.com/archives/Darwin-dev/2007/Aug/msg00045.html">here</ulink>.\r
29589</simpara>\r
29590</listitem>\r
29591</itemizedlist>\r
29592</section>\r
29593<section id="_also_see_39">\r
29594<title>Also see</title>\r
29595<itemizedlist>\r
29596<listitem>\r
29597<simpara>\r
29598<link linkend="RunningOnAMD64">RunningOnAMD64</link>\r
29599</simpara>\r
29600</listitem>\r
29601<listitem>\r
29602<simpara>\r
29603<link linkend="RunningOnPowerPC">RunningOnPowerPC</link>\r
29604</simpara>\r
29605</listitem>\r
29606<listitem>\r
29607<simpara>\r
29608<link linkend="RunningOnX86">RunningOnX86</link>\r
29609</simpara>\r
29610</listitem>\r
29611</itemizedlist>\r
29612<simpara><?asciidoc-pagebreak?></simpara>\r
29613</section>\r
29614</section>\r
29615<section id="RunningOnFreeBSD">\r
29616<title>RunningOnFreeBSD</title>\r
29617<simpara>MLton runs fine on <ulink url="http://www.freebsd.org/">FreeBSD</ulink>.</simpara>\r
29618<section id="_notes_8">\r
29619<title>Notes</title>\r
29620<itemizedlist>\r
29621<listitem>\r
29622<simpara>\r
29623MLton is available as a <ulink url="http://www.freebsd.org/">FreeBSD</ulink>\r
29624<ulink url="http://www.freebsd.org/cgi/ports.cgi?query=mlton&amp;stype=all">port</ulink>.\r
29625</simpara>\r
29626</listitem>\r
29627</itemizedlist>\r
29628</section>\r
29629<section id="_known_issues_4">\r
29630<title>Known issues</title>\r
29631<itemizedlist>\r
29632<listitem>\r
29633<simpara>\r
29634Executables often run more slowly than on a comparable Linux\r
29635machine. We conjecture that part of this is due to costs due to heap\r
29636resizing and kernel zeroing of pages. Any help in solving the problem\r
29637would be appreciated.\r
29638</simpara>\r
29639</listitem>\r
29640<listitem>\r
29641<simpara>\r
29642FreeBSD defaults to a datasize limit of 512M, even if you have more\r
29643than that amount of memory in the computer. Hence, your MLton process\r
29644will be limited in the amount of memory it has. To fix this problem,\r
29645turn up the datasize and the default datasize available to a process:\r
29646Edit <literal>/boot/loader.conf</literal> to set the limits. For example, the setting\r
29647</simpara>\r
29648<screen> kern.maxdsiz="671088640"\r
29649 kern.dfldsiz="671088640"\r
29650 kern.maxssiz="134217728"</screen>\r
29651<simpara>will give a process 640M of datasize memory, default to 640M available\r
29652and set 128M of stack size memory.</simpara>\r
29653</listitem>\r
29654</itemizedlist>\r
29655<simpara><?asciidoc-pagebreak?></simpara>\r
29656</section>\r
29657</section>\r
29658<section id="RunningOnHPPA">\r
29659<title>RunningOnHPPA</title>\r
29660<simpara>MLton runs fine on the HPPA architecture.</simpara>\r
29661<section id="_notes_9">\r
29662<title>Notes</title>\r
29663<itemizedlist>\r
29664<listitem>\r
29665<simpara>\r
29666When compiling for HPPA, MLton targets the 32-bit HPPA architecture.\r
29667</simpara>\r
29668</listitem>\r
29669<listitem>\r
29670<simpara>\r
29671When compiling for HPPA, MLton doesn&#8217;t support native code\r
29672generation (<literal>-codegen native</literal>). Hence, performance is not as good as\r
29673it might be and compile times are longer. Also, the quality of code\r
29674generated by <literal>gcc</literal> is important. By default, MLton calls <literal>gcc -O1</literal>.\r
29675You can change this by calling MLton with <literal>-cc-opt -O2</literal>.\r
29676</simpara>\r
29677</listitem>\r
29678<listitem>\r
29679<simpara>\r
29680When compiling for HPPA, MLton uses <literal>-align 8</literal> by default. While\r
29681this speeds up reals, it also may increase object sizes. If your\r
29682program does not make significant use of reals, you might see a\r
29683speedup with <literal>-align 4</literal>.\r
29684</simpara>\r
29685</listitem>\r
29686</itemizedlist>\r
29687<simpara><?asciidoc-pagebreak?></simpara>\r
29688</section>\r
29689</section>\r
29690<section id="RunningOnHPUX">\r
29691<title>RunningOnHPUX</title>\r
29692<simpara>MLton runs fine on HPUX.</simpara>\r
29693<section id="_also_see_40">\r
29694<title>Also see</title>\r
29695<itemizedlist>\r
29696<listitem>\r
29697<simpara>\r
29698<link linkend="RunningOnHPPA">RunningOnHPPA</link>\r
29699</simpara>\r
29700</listitem>\r
29701</itemizedlist>\r
29702<simpara><?asciidoc-pagebreak?></simpara>\r
29703</section>\r
29704</section>\r
29705<section id="RunningOnIA64">\r
29706<title>RunningOnIA64</title>\r
29707<simpara>MLton runs fine on the IA64 architecture.</simpara>\r
29708<section id="_notes_10">\r
29709<title>Notes</title>\r
29710<itemizedlist>\r
29711<listitem>\r
29712<simpara>\r
29713When compiling for IA64, MLton targets the 64-bit ABI.\r
29714</simpara>\r
29715</listitem>\r
29716<listitem>\r
29717<simpara>\r
29718When compiling for IA64, MLton doesn&#8217;t support native code\r
29719generation (<literal>-codegen native</literal>). Hence, performance is not as good as\r
29720it might be and compile times are longer. Also, the quality of code\r
29721generated by <literal>gcc</literal> is important. By default, MLton calls <literal>gcc -O1</literal>.\r
29722You can change this by calling MLton with <literal>-cc-opt -O2</literal>.\r
29723</simpara>\r
29724</listitem>\r
29725<listitem>\r
29726<simpara>\r
29727When compiling for IA64, MLton uses <literal>-align 8</literal> by default.\r
29728</simpara>\r
29729</listitem>\r
29730<listitem>\r
29731<simpara>\r
29732On the IA64, the <link linkend="GnuMP">GnuMP</link> library supports multiple ABIs. See the\r
29733<link linkend="GnuMP">GnuMP</link> page for more details.\r
29734</simpara>\r
29735</listitem>\r
29736</itemizedlist>\r
29737<simpara><?asciidoc-pagebreak?></simpara>\r
29738</section>\r
29739</section>\r
29740<section id="RunningOnLinux">\r
29741<title>RunningOnLinux</title>\r
29742<simpara>MLton runs fine on Linux.</simpara>\r
29743<simpara><?asciidoc-pagebreak?></simpara>\r
29744</section>\r
29745<section id="RunningOnMinGW">\r
29746<title>RunningOnMinGW</title>\r
29747<simpara>MLton runs on <ulink url="http://mingw.org">MinGW</ulink>, a library for porting Unix\r
29748applications to Windows. Some library functionality is missing or\r
29749changed.</simpara>\r
29750<section id="_notes_11">\r
29751<title>Notes</title>\r
29752<itemizedlist>\r
29753<listitem>\r
29754<simpara>\r
29755To compile MLton on MinGW:\r
29756</simpara>\r
29757<itemizedlist>\r
29758<listitem>\r
29759<simpara>\r
29760The <link linkend="GnuMP">GnuMP</link> library is required.\r
29761</simpara>\r
29762</listitem>\r
29763<listitem>\r
29764<simpara>\r
29765The Bash shell is required. If you are using a prebuilt MSYS, you\r
29766probably want to symlink <literal>bash</literal> to <literal>sh</literal>.\r
29767</simpara>\r
29768</listitem>\r
29769</itemizedlist>\r
29770</listitem>\r
29771</itemizedlist>\r
29772</section>\r
29773<section id="_known_issues_5">\r
29774<title>Known issues</title>\r
29775<itemizedlist>\r
29776<listitem>\r
29777<simpara>\r
29778Many functions are unimplemented and will <literal>raise SysErr</literal>.\r
29779</simpara>\r
29780<itemizedlist>\r
29781<listitem>\r
29782<simpara>\r
29783<literal>MLton.Itimer.set</literal>\r
29784</simpara>\r
29785</listitem>\r
29786<listitem>\r
29787<simpara>\r
29788<literal>MLton.ProcEnv.setgroups</literal>\r
29789</simpara>\r
29790</listitem>\r
29791<listitem>\r
29792<simpara>\r
29793<literal>MLton.Process.kill</literal>\r
29794</simpara>\r
29795</listitem>\r
29796<listitem>\r
29797<simpara>\r
29798<literal>MLton.Process.reap</literal>\r
29799</simpara>\r
29800</listitem>\r
29801<listitem>\r
29802<simpara>\r
29803<literal>MLton.World.load</literal>\r
29804</simpara>\r
29805</listitem>\r
29806<listitem>\r
29807<simpara>\r
29808<literal>OS.FileSys.readLink</literal>\r
29809</simpara>\r
29810</listitem>\r
29811<listitem>\r
29812<simpara>\r
29813<literal>OS.IO.poll</literal>\r
29814</simpara>\r
29815</listitem>\r
29816<listitem>\r
29817<simpara>\r
29818<literal>OS.Process.terminate</literal>\r
29819</simpara>\r
29820</listitem>\r
29821<listitem>\r
29822<simpara>\r
29823<literal>Posix.FileSys.chown</literal>\r
29824</simpara>\r
29825</listitem>\r
29826<listitem>\r
29827<simpara>\r
29828<literal>Posix.FileSys.fchown</literal>\r
29829</simpara>\r
29830</listitem>\r
29831<listitem>\r
29832<simpara>\r
29833<literal>Posix.FileSys.fpathconf</literal>\r
29834</simpara>\r
29835</listitem>\r
29836<listitem>\r
29837<simpara>\r
29838<literal>Posix.FileSys.link</literal>\r
29839</simpara>\r
29840</listitem>\r
29841<listitem>\r
29842<simpara>\r
29843<literal>Posix.FileSys.mkfifo</literal>\r
29844</simpara>\r
29845</listitem>\r
29846<listitem>\r
29847<simpara>\r
29848<literal>Posix.FileSys.pathconf</literal>\r
29849</simpara>\r
29850</listitem>\r
29851<listitem>\r
29852<simpara>\r
29853<literal>Posix.FileSys.readlink</literal>\r
29854</simpara>\r
29855</listitem>\r
29856<listitem>\r
29857<simpara>\r
29858<literal>Posix.FileSys.symlink</literal>\r
29859</simpara>\r
29860</listitem>\r
29861<listitem>\r
29862<simpara>\r
29863<literal>Posix.IO.dupfd</literal>\r
29864</simpara>\r
29865</listitem>\r
29866<listitem>\r
29867<simpara>\r
29868<literal>Posix.IO.getfd</literal>\r
29869</simpara>\r
29870</listitem>\r
29871<listitem>\r
29872<simpara>\r
29873<literal>Posix.IO.getfl</literal>\r
29874</simpara>\r
29875</listitem>\r
29876<listitem>\r
29877<simpara>\r
29878<literal>Posix.IO.getlk</literal>\r
29879</simpara>\r
29880</listitem>\r
29881<listitem>\r
29882<simpara>\r
29883<literal>Posix.IO.setfd</literal>\r
29884</simpara>\r
29885</listitem>\r
29886<listitem>\r
29887<simpara>\r
29888<literal>Posix.IO.setfl</literal>\r
29889</simpara>\r
29890</listitem>\r
29891<listitem>\r
29892<simpara>\r
29893<literal>Posix.IO.setlkw</literal>\r
29894</simpara>\r
29895</listitem>\r
29896<listitem>\r
29897<simpara>\r
29898<literal>Posix.IO.setlk</literal>\r
29899</simpara>\r
29900</listitem>\r
29901<listitem>\r
29902<simpara>\r
29903<literal>Posix.ProcEnv.ctermid</literal>\r
29904</simpara>\r
29905</listitem>\r
29906<listitem>\r
29907<simpara>\r
29908<literal>Posix.ProcEnv.getegid</literal>\r
29909</simpara>\r
29910</listitem>\r
29911<listitem>\r
29912<simpara>\r
29913<literal>Posix.ProcEnv.geteuid</literal>\r
29914</simpara>\r
29915</listitem>\r
29916<listitem>\r
29917<simpara>\r
29918<literal>Posix.ProcEnv.getgid</literal>\r
29919</simpara>\r
29920</listitem>\r
29921<listitem>\r
29922<simpara>\r
29923<literal>Posix.ProcEnv.getgroups</literal>\r
29924</simpara>\r
29925</listitem>\r
29926<listitem>\r
29927<simpara>\r
29928<literal>Posix.ProcEnv.getlogin</literal>\r
29929</simpara>\r
29930</listitem>\r
29931<listitem>\r
29932<simpara>\r
29933<literal>Posix.ProcEnv.getpgrp</literal>\r
29934</simpara>\r
29935</listitem>\r
29936<listitem>\r
29937<simpara>\r
29938<literal>Posix.ProcEnv.getpid</literal>\r
29939</simpara>\r
29940</listitem>\r
29941<listitem>\r
29942<simpara>\r
29943<literal>Posix.ProcEnv.getppid</literal>\r
29944</simpara>\r
29945</listitem>\r
29946<listitem>\r
29947<simpara>\r
29948<literal>Posix.ProcEnv.getuid</literal>\r
29949</simpara>\r
29950</listitem>\r
29951<listitem>\r
29952<simpara>\r
29953<literal>Posix.ProcEnv.setgid</literal>\r
29954</simpara>\r
29955</listitem>\r
29956<listitem>\r
29957<simpara>\r
29958<literal>Posix.ProcEnv.setpgid</literal>\r
29959</simpara>\r
29960</listitem>\r
29961<listitem>\r
29962<simpara>\r
29963<literal>Posix.ProcEnv.setsid</literal>\r
29964</simpara>\r
29965</listitem>\r
29966<listitem>\r
29967<simpara>\r
29968<literal>Posix.ProcEnv.setuid</literal>\r
29969</simpara>\r
29970</listitem>\r
29971<listitem>\r
29972<simpara>\r
29973<literal>Posix.ProcEnv.sysconf</literal>\r
29974</simpara>\r
29975</listitem>\r
29976<listitem>\r
29977<simpara>\r
29978<literal>Posix.ProcEnv.times</literal>\r
29979</simpara>\r
29980</listitem>\r
29981<listitem>\r
29982<simpara>\r
29983<literal>Posix.ProcEnv.ttyname</literal>\r
29984</simpara>\r
29985</listitem>\r
29986<listitem>\r
29987<simpara>\r
29988<literal>Posix.Process.exece</literal>\r
29989</simpara>\r
29990</listitem>\r
29991<listitem>\r
29992<simpara>\r
29993<literal>Posix.Process.execp</literal>\r
29994</simpara>\r
29995</listitem>\r
29996<listitem>\r
29997<simpara>\r
29998<literal>Posix.Process.exit</literal>\r
29999</simpara>\r
30000</listitem>\r
30001<listitem>\r
30002<simpara>\r
30003<literal>Posix.Process.fork</literal>\r
30004</simpara>\r
30005</listitem>\r
30006<listitem>\r
30007<simpara>\r
30008<literal>Posix.Process.kill</literal>\r
30009</simpara>\r
30010</listitem>\r
30011<listitem>\r
30012<simpara>\r
30013<literal>Posix.Process.pause</literal>\r
30014</simpara>\r
30015</listitem>\r
30016<listitem>\r
30017<simpara>\r
30018<literal>Posix.Process.waitpid_nh</literal>\r
30019</simpara>\r
30020</listitem>\r
30021<listitem>\r
30022<simpara>\r
30023<literal>Posix.Process.waitpid</literal>\r
30024</simpara>\r
30025</listitem>\r
30026<listitem>\r
30027<simpara>\r
30028<literal>Posix.SysDB.getgrgid</literal>\r
30029</simpara>\r
30030</listitem>\r
30031<listitem>\r
30032<simpara>\r
30033<literal>Posix.SysDB.getgrnam</literal>\r
30034</simpara>\r
30035</listitem>\r
30036<listitem>\r
30037<simpara>\r
30038<literal>Posix.SysDB.getpwuid</literal>\r
30039</simpara>\r
30040</listitem>\r
30041<listitem>\r
30042<simpara>\r
30043<literal>Posix.TTY.TC.drain</literal>\r
30044</simpara>\r
30045</listitem>\r
30046<listitem>\r
30047<simpara>\r
30048<literal>Posix.TTY.TC.flow</literal>\r
30049</simpara>\r
30050</listitem>\r
30051<listitem>\r
30052<simpara>\r
30053<literal>Posix.TTY.TC.flush</literal>\r
30054</simpara>\r
30055</listitem>\r
30056<listitem>\r
30057<simpara>\r
30058<literal>Posix.TTY.TC.getattr</literal>\r
30059</simpara>\r
30060</listitem>\r
30061<listitem>\r
30062<simpara>\r
30063<literal>Posix.TTY.TC.getpgrp</literal>\r
30064</simpara>\r
30065</listitem>\r
30066<listitem>\r
30067<simpara>\r
30068<literal>Posix.TTY.TC.sendbreak</literal>\r
30069</simpara>\r
30070</listitem>\r
30071<listitem>\r
30072<simpara>\r
30073<literal>Posix.TTY.TC.setattr</literal>\r
30074</simpara>\r
30075</listitem>\r
30076<listitem>\r
30077<simpara>\r
30078<literal>Posix.TTY.TC.setpgrp</literal>\r
30079</simpara>\r
30080</listitem>\r
30081<listitem>\r
30082<simpara>\r
30083<literal>Unix.kill</literal>\r
30084</simpara>\r
30085</listitem>\r
30086<listitem>\r
30087<simpara>\r
30088<literal>Unix.reap</literal>\r
30089</simpara>\r
30090</listitem>\r
30091<listitem>\r
30092<simpara>\r
30093<literal>UnixSock.fromAddr</literal>\r
30094</simpara>\r
30095</listitem>\r
30096<listitem>\r
30097<simpara>\r
30098<literal>UnixSock.toAddr</literal>\r
30099</simpara>\r
30100</listitem>\r
30101</itemizedlist>\r
30102</listitem>\r
30103</itemizedlist>\r
30104<simpara><?asciidoc-pagebreak?></simpara>\r
30105</section>\r
30106</section>\r
30107<section id="RunningOnNetBSD">\r
30108<title>RunningOnNetBSD</title>\r
30109<simpara>MLton runs fine on <ulink url="http://www.netbsd.org/">NetBSD</ulink>.</simpara>\r
30110<section id="_installing_the_correct_packages_for_netbsd">\r
30111<title>Installing the correct packages for NetBSD</title>\r
30112<simpara>The NetBSD system installs 3rd party packages by a mechanism known as\r
30113pkgsrc. This is a tree of Makefiles which when invoked downloads the\r
30114source code, builds a package and installs it on the system. In order\r
30115to run MLton on NetBSD, you will have to install several packages for\r
30116it to work:</simpara>\r
30117<itemizedlist>\r
30118<listitem>\r
30119<simpara>\r
30120<literal>shells/bash</literal>\r
30121</simpara>\r
30122</listitem>\r
30123<listitem>\r
30124<simpara>\r
30125<literal>devel/gmp</literal>\r
30126</simpara>\r
30127</listitem>\r
30128<listitem>\r
30129<simpara>\r
30130<literal>devel/gmake</literal>\r
30131</simpara>\r
30132</listitem>\r
30133</itemizedlist>\r
30134<simpara>In order to get graphical call-graphs of profiling information, you\r
30135will need the additional package</simpara>\r
30136<itemizedlist>\r
30137<listitem>\r
30138<simpara>\r
30139<literal>graphics/graphviz</literal>\r
30140</simpara>\r
30141</listitem>\r
30142</itemizedlist>\r
30143<simpara>To build the documentation for MLton, you will need the addtional\r
30144package</simpara>\r
30145<itemizedlist>\r
30146<listitem>\r
30147<simpara>\r
30148<literal>textproc/asciidoc</literal>.\r
30149</simpara>\r
30150</listitem>\r
30151</itemizedlist>\r
30152</section>\r
30153<section id="_tips_for_compiling_and_using_mlton_on_netbsd">\r
30154<title>Tips for compiling and using MLton on NetBSD</title>\r
30155<simpara>MLton can be a memory-hog on computers with little memory. While\r
30156640Mb of RAM ought to be enough to self-compile MLton one might want\r
30157to do some tuning to the NetBSD VM subsystem in order to succeed. The\r
30158notes presented here is what <link linkend="JesperLouisAndersen">JesperLouisAndersen</link> uses for\r
30159compiling MLton on his laptop.</simpara>\r
30160<section id="_the_netbsd_vm_subsystem">\r
30161<title>The NetBSD VM subsystem</title>\r
30162<simpara>NetBSD uses a VM subsystem named\r
30163<ulink url="http://www.ccrc.wustl.edu/pub/chuck/tech/uvm/">UVM</ulink>.\r
30164<ulink url="http://www.selonen.org/arto/netbsd/vm_tune.html">Tuning the VM system</ulink>\r
30165can be done via the <literal>sysctl(8)</literal>-interface with the "VM" MIB set.</simpara>\r
30166</section>\r
30167<section id="_tuning_the_netbsd_vm_subsystem_for_mlton">\r
30168<title>Tuning the NetBSD VM subsystem for MLton</title>\r
30169<simpara>MLton uses a lot of anonymous pages when it is running. Thus, we will\r
30170need to tune up the default of 80 for anonymous pages. Setting</simpara>\r
30171<screen>sysctl -w vm.anonmax=95\r
30172sysctl -w vm.anonmin=50\r
30173sysctl -w vm.filemin=2\r
30174sysctl -w vm.execmin=2\r
30175sysctl -w vm.filemax=4\r
30176sysctl -w vm.execmax=4</screen>\r
30177<simpara>makes it less likely for the VM system to swap out anonymous pages.\r
30178For a full explanation of the above flags, see the documentation.</simpara>\r
30179<simpara>The result is that my laptop goes from a MLton compile where it swaps\r
30180a lot to a MLton compile with no swapping.</simpara>\r
30181<simpara><?asciidoc-pagebreak?></simpara>\r
30182</section>\r
30183</section>\r
30184</section>\r
30185<section id="RunningOnOpenBSD">\r
30186<title>RunningOnOpenBSD</title>\r
30187<simpara>MLton runs fine on <ulink url="http://www.openbsd.org/">OpenBSD</ulink>.</simpara>\r
30188<section id="_known_issues_6">\r
30189<title>Known issues</title>\r
30190<itemizedlist>\r
30191<listitem>\r
30192<simpara>\r
30193The <ulink url="https://raw.github.com/MLton/mlton/master/regression/socket.sml"><literal>socket.sml</literal></ulink> regression\r
30194test fails. We suspect this is not a bug and is simply due to our\r
30195test relying on a certain behavior when connecting to a socket that\r
30196has not yet accepted, which is handled differently on OpenBSD than\r
30197other platforms. Any help in understanding and resolving this issue\r
30198is appreciated.\r
30199</simpara>\r
30200</listitem>\r
30201</itemizedlist>\r
30202<simpara><?asciidoc-pagebreak?></simpara>\r
30203</section>\r
30204</section>\r
30205<section id="RunningOnPowerPC">\r
30206<title>RunningOnPowerPC</title>\r
30207<simpara>MLton runs fine on the PowerPC architecture.</simpara>\r
30208<section id="_notes_12">\r
30209<title>Notes</title>\r
30210<itemizedlist>\r
30211<listitem>\r
30212<simpara>\r
30213When compiling for PowerPC, MLton targets the 32-bit PowerPC\r
30214architecture.\r
30215</simpara>\r
30216</listitem>\r
30217<listitem>\r
30218<simpara>\r
30219When compiling for PowerPC, MLton doesn&#8217;t support native code\r
30220generation (<literal>-codegen native</literal>). Hence, performance is not as good as\r
30221it might be and compile times are longer. Also, the quality of code\r
30222generated by <literal>gcc</literal> is important. By default, MLton calls <literal>gcc -O1</literal>.\r
30223You can change this by calling MLton with <literal>-cc-opt -O2</literal>.\r
30224</simpara>\r
30225</listitem>\r
30226<listitem>\r
30227<simpara>\r
30228On the PowerPC, the <link linkend="GnuMP">GnuMP</link> library supports multiple ABIs. See\r
30229the <link linkend="GnuMP">GnuMP</link> page for more details.\r
30230</simpara>\r
30231</listitem>\r
30232</itemizedlist>\r
30233<simpara><?asciidoc-pagebreak?></simpara>\r
30234</section>\r
30235</section>\r
30236<section id="RunningOnPowerPC64">\r
30237<title>RunningOnPowerPC64</title>\r
30238<simpara>MLton runs fine on the PowerPC64 architecture.</simpara>\r
30239<section id="_notes_13">\r
30240<title>Notes</title>\r
30241<itemizedlist>\r
30242<listitem>\r
30243<simpara>\r
30244When compiling for PowerPC64, MLton targets the 64-bit PowerPC\r
30245architecture.\r
30246</simpara>\r
30247</listitem>\r
30248<listitem>\r
30249<simpara>\r
30250When compiling for PowerPC64, MLton doesn&#8217;t support native code\r
30251generation (<literal>-codegen native</literal>). Hence, performance is not as good as\r
30252it might be and compile times are longer. Also, the quality of code\r
30253generated by <literal>gcc</literal> is important. By default, MLton calls <literal>gcc -O1</literal>.\r
30254You can change this by calling MLton with <literal>-cc-opt -O2</literal>.\r
30255</simpara>\r
30256</listitem>\r
30257<listitem>\r
30258<simpara>\r
30259On the PowerPC64, the <link linkend="GnuMP">GnuMP</link> library supports multiple ABIs. See\r
30260the <link linkend="GnuMP">GnuMP</link> page for more details.\r
30261</simpara>\r
30262</listitem>\r
30263</itemizedlist>\r
30264<simpara><?asciidoc-pagebreak?></simpara>\r
30265</section>\r
30266</section>\r
30267<section id="RunningOnS390">\r
30268<title>RunningOnS390</title>\r
30269<simpara>MLton runs fine on the S390 architecture.</simpara>\r
30270<section id="_notes_14">\r
30271<title>Notes</title>\r
30272<itemizedlist>\r
30273<listitem>\r
30274<simpara>\r
30275When compiling for S390, MLton doesn&#8217;t support native code\r
30276generation (<literal>-codegen native</literal>). Hence, performance is not as good as\r
30277it might be and compile times are longer. Also, the quality of code\r
30278generated by <literal>gcc</literal> is important. By default, MLton calls <literal>gcc -O1</literal>.\r
30279You can change this by calling MLton with <literal>-cc-opt -O2</literal>.\r
30280</simpara>\r
30281</listitem>\r
30282</itemizedlist>\r
30283<simpara><?asciidoc-pagebreak?></simpara>\r
30284</section>\r
30285</section>\r
30286<section id="RunningOnSolaris">\r
30287<title>RunningOnSolaris</title>\r
30288<simpara>MLton runs fine on Solaris.</simpara>\r
30289<section id="_notes_15">\r
30290<title>Notes</title>\r
30291<itemizedlist>\r
30292<listitem>\r
30293<simpara>\r
30294You must install the <literal>binutils</literal>, <literal>gcc</literal>, and <literal>make</literal> packages. You\r
30295can find out how to get these at\r
30296<ulink url="http://www.sunfreeware.com">sunfreeware.com</ulink>.\r
30297</simpara>\r
30298</listitem>\r
30299<listitem>\r
30300<simpara>\r
30301Making the documentation requires that you install <literal>latex</literal> and\r
30302<literal>dvips</literal>, which are available in the <literal>tetex</literal> package.\r
30303</simpara>\r
30304</listitem>\r
30305</itemizedlist>\r
30306</section>\r
30307<section id="_known_issues_7">\r
30308<title>Known issues</title>\r
30309<itemizedlist>\r
30310<listitem>\r
30311<simpara>\r
30312Bootstrapping on the <link linkend="RunningOnSparc">Sparc architecture</link> is so slow\r
30313as to be impractical (many hours on a 500MHz UltraSparc). For this\r
30314reason, we strongly recommend building with a\r
30315<link linkend="CrossCompiling">cross compiler</link>.\r
30316</simpara>\r
30317</listitem>\r
30318</itemizedlist>\r
30319</section>\r
30320<section id="_also_see_41">\r
30321<title>Also see</title>\r
30322<itemizedlist>\r
30323<listitem>\r
30324<simpara>\r
30325<link linkend="RunningOnAMD64">RunningOnAMD64</link>\r
30326</simpara>\r
30327</listitem>\r
30328<listitem>\r
30329<simpara>\r
30330<link linkend="RunningOnSparc">RunningOnSparc</link>\r
30331</simpara>\r
30332</listitem>\r
30333<listitem>\r
30334<simpara>\r
30335<link linkend="RunningOnX86">RunningOnX86</link>\r
30336</simpara>\r
30337</listitem>\r
30338</itemizedlist>\r
30339<simpara><?asciidoc-pagebreak?></simpara>\r
30340</section>\r
30341</section>\r
30342<section id="RunningOnSparc">\r
30343<title>RunningOnSparc</title>\r
30344<simpara>MLton runs fine on the Sparc architecture.</simpara>\r
30345<section id="_notes_16">\r
30346<title>Notes</title>\r
30347<itemizedlist>\r
30348<listitem>\r
30349<simpara>\r
30350When compiling for Sparc, MLton targets the 32-bit Sparc\r
30351architecture (i.e., Sparc V8).\r
30352</simpara>\r
30353</listitem>\r
30354<listitem>\r
30355<simpara>\r
30356When compiling for Sparc, MLton doesn&#8217;t support native code\r
30357generation (<literal>-codegen native</literal>). Hence, performance is not as good as\r
30358it might be and compile times are longer. Also, the quality of code\r
30359generated by <literal>gcc</literal> is important. By default, MLton calls <literal>gcc -O1</literal>.\r
30360You can change this by calling MLton with <literal>-cc-opt -O2</literal>. We have seen\r
30361this speed up some programs by as much as 30%, especially those\r
30362involving floating point; however, it can also more than double\r
30363compile times.\r
30364</simpara>\r
30365</listitem>\r
30366<listitem>\r
30367<simpara>\r
30368When compiling for Sparc, MLton uses <literal>-align 8</literal> by default. While\r
30369this speeds up reals, it also may increase object sizes. If your\r
30370program does not make significant use of reals, you might see a\r
30371speedup with <literal>-align 4</literal>.\r
30372</simpara>\r
30373</listitem>\r
30374</itemizedlist>\r
30375</section>\r
30376<section id="_known_issues_8">\r
30377<title>Known issues</title>\r
30378<itemizedlist>\r
30379<listitem>\r
30380<simpara>\r
30381Bootstrapping on the <link linkend="RunningOnSparc">Sparc architecture</link> is so slow\r
30382as to be impractical (many hours on a 500MHz UltraSparc). For this\r
30383reason, we strongly recommend building with a\r
30384<link linkend="CrossCompiling">cross compiler</link>.\r
30385</simpara>\r
30386</listitem>\r
30387</itemizedlist>\r
30388</section>\r
30389<section id="_also_see_42">\r
30390<title>Also see</title>\r
30391<itemizedlist>\r
30392<listitem>\r
30393<simpara>\r
30394<link linkend="RunningOnSolaris">RunningOnSolaris</link>\r
30395</simpara>\r
30396</listitem>\r
30397</itemizedlist>\r
30398<simpara><?asciidoc-pagebreak?></simpara>\r
30399</section>\r
30400</section>\r
30401<section id="RunningOnX86">\r
30402<title>RunningOnX86</title>\r
30403<simpara>MLton runs fine on the x86 architecture.</simpara>\r
30404<section id="_notes_17">\r
30405<title>Notes</title>\r
30406<itemizedlist>\r
30407<listitem>\r
30408<simpara>\r
30409On x86, MLton supports native code generation (<literal>-codegen native</literal> or\r
30410<literal>-codegen x86</literal>).\r
30411</simpara>\r
30412</listitem>\r
30413</itemizedlist>\r
30414<simpara><?asciidoc-pagebreak?></simpara>\r
30415</section>\r
30416</section>\r
30417<section id="RunTimeOptions">\r
30418<title>RunTimeOptions</title>\r
30419<simpara>Executables produced by MLton take command line arguments that control\r
30420the runtime system. These arguments are optional, and occur before\r
30421the executable&#8217;s usual arguments. To use these options, the first\r
30422argument to the executable must be <literal>@MLton</literal>. The optional arguments\r
30423then follow, must be terminated by <literal>--</literal>, and are followed by any\r
30424arguments to the program. The optional arguments are <emphasis>not</emphasis> made\r
30425available to the SML program via <literal>CommandLine.arguments</literal>. For\r
30426example, a valid call to <literal>hello-world</literal> is:</simpara>\r
30427<screen>hello-world @MLton gc-summary fixed-heap 10k -- a b c</screen>\r
30428<simpara>In the above example,\r
30429<literal>CommandLine.arguments () = ["a", "b", "c"]</literal>.</simpara>\r
30430<simpara>It is allowed to have a sequence of <literal>@MLton</literal> arguments, as in:</simpara>\r
30431<screen>hello-world @MLton gc-summary -- @MLton fixed-heap 10k -- a b c</screen>\r
30432<simpara>Run-time options can also control MLton, as in</simpara>\r
30433<screen>mlton @MLton fixed-heap 0.5g -- foo.sml</screen>\r
30434<section id="_options_2">\r
30435<title>Options</title>\r
30436<itemizedlist>\r
30437<listitem>\r
30438<simpara>\r
30439<literal>fixed-heap <emphasis>x</emphasis>{k|K|m|M|g|G}</literal>\r
30440</simpara>\r
30441<simpara>Use a fixed size heap of size <emphasis>x</emphasis>, where <emphasis>x</emphasis> is a real number and the\r
30442trailing letter indicates its units.</simpara>\r
30443<informaltable\r
30444frame="all"\r
30445rowsep="1" colsep="1"\r
30446>\r
30447<tgroup cols="2">\r
30448<colspec colname="col_1" colwidth="25*"/>\r
30449<colspec colname="col_2" colwidth="75*"/>\r
30450<tbody>\r
30451<row>\r
30452<entry align="center" valign="top"><simpara><literal>k</literal> or <literal>K</literal></simpara></entry>\r
30453<entry align="left" valign="top"><simpara>1024</simpara></entry>\r
30454</row>\r
30455<row>\r
30456<entry align="center" valign="top"><simpara><literal>m</literal> or <literal>M</literal></simpara></entry>\r
30457<entry align="left" valign="top"><simpara>1,048,576</simpara></entry>\r
30458</row>\r
30459<row>\r
30460<entry align="center" valign="top"><simpara><literal>g</literal> or <literal>G</literal></simpara></entry>\r
30461<entry align="left" valign="top"><simpara>1,073,741,824</simpara></entry>\r
30462</row>\r
30463</tbody>\r
30464</tgroup>\r
30465</informaltable>\r
30466<simpara>A value of <literal>0</literal> means to use almost all the RAM present on the machine.</simpara>\r
30467<simpara>The heap size used by <literal>fixed-heap</literal> includes all memory allocated by\r
30468SML code, including memory for the stack (or stacks, if there are\r
30469multiple threads). It does not, however, include any memory used for\r
30470code itself or memory used by C globals, the C stack, or malloc.</simpara>\r
30471</listitem>\r
30472<listitem>\r
30473<simpara>\r
30474<literal>gc-messages</literal>\r
30475</simpara>\r
30476<simpara>Print a message at the start and end of every garbage collection.</simpara>\r
30477</listitem>\r
30478<listitem>\r
30479<simpara>\r
30480<literal>gc-summary</literal>\r
30481</simpara>\r
30482<simpara>Print a summary of garbage collection statistics upon program\r
30483termination to standard error.</simpara>\r
30484</listitem>\r
30485<listitem>\r
30486<simpara>\r
30487<literal>gc-summary-file <emphasis>file</emphasis></literal>\r
30488</simpara>\r
30489<simpara>Print a summary of garbage collection statistics upon program\r
30490termination to the file specified by <emphasis>file</emphasis>.</simpara>\r
30491</listitem>\r
30492<listitem>\r
30493<simpara>\r
30494<literal>load-world <emphasis>world</emphasis></literal>\r
30495</simpara>\r
30496<simpara>Restart the computation with the file specified by <emphasis>world</emphasis>, which must\r
30497have been created by a call to <literal>MLton.World.save</literal> by the same\r
30498executable. See <link linkend="MLtonWorld">MLtonWorld</link>.</simpara>\r
30499</listitem>\r
30500<listitem>\r
30501<simpara>\r
30502<literal>max-heap <emphasis>x</emphasis>{k|K|m|M|g|G}</literal>\r
30503</simpara>\r
30504<simpara>Run the computation with an automatically resized heap that is never\r
30505larger than <emphasis>x</emphasis>, where <emphasis>x</emphasis> is a real number and the trailing letter\r
30506indicates the units as with <literal>fixed-heap</literal>. The heap size for\r
30507<literal>max-heap</literal> is accounted for as with <literal>fixed-heap</literal>.</simpara>\r
30508</listitem>\r
30509<listitem>\r
30510<simpara>\r
30511<literal>may-page-heap {false|true}</literal>\r
30512</simpara>\r
30513<simpara>Enable paging the heap to disk when unable to grow the heap to a\r
30514desired size.</simpara>\r
30515</listitem>\r
30516<listitem>\r
30517<simpara>\r
30518<literal>no-load-world</literal>\r
30519</simpara>\r
30520<simpara>Disable <literal>load-world</literal>. This can be used as an argument to the compiler\r
30521via <literal>-runtime no-load-world</literal> to create executables that will not load\r
30522a world. This may be useful to ensure that set-uid executables do not\r
30523load some strange world.</simpara>\r
30524</listitem>\r
30525<listitem>\r
30526<simpara>\r
30527<literal>ram-slop <emphasis>x</emphasis></literal>\r
30528</simpara>\r
30529<simpara>Multiply <emphasis>x</emphasis> by the amount of RAM on the machine to obtain what the\r
30530runtime views as the amount of RAM it can use. Typically <emphasis>x</emphasis> is less\r
30531than 1, and is used to account for space used by other programs\r
30532running on the same machine.</simpara>\r
30533</listitem>\r
30534<listitem>\r
30535<simpara>\r
30536<literal>stop</literal>\r
30537</simpara>\r
30538<simpara>Causes the runtime to stop processing <literal>@MLton</literal> arguments once the next\r
30539<literal>--</literal> is reached. This can be used as an argument to the compiler via\r
30540<literal>-runtime stop</literal> to create executables that don&#8217;t process any <literal>@MLton</literal>\r
30541arguments.</simpara>\r
30542</listitem>\r
30543</itemizedlist>\r
30544<simpara><?asciidoc-pagebreak?></simpara>\r
30545</section>\r
30546</section>\r
30547<section id="ScopeInference">\r
30548<title>ScopeInference</title>\r
30549<simpara>Scope inference is an analysis/rewrite pass for the <link linkend="AST">AST</link>\r
30550<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="Elaborate">Elaborate</link>.</simpara>\r
30551<section id="_description_53">\r
30552<title>Description</title>\r
30553<simpara>This pass adds free type variables to the <literal>val</literal> or <literal>fun</literal>\r
30554declaration where they are implicitly scoped.</simpara>\r
30555</section>\r
30556<section id="_implementation_58">\r
30557<title>Implementation</title>\r
30558<simpara><ulink url="https://github.com/MLton/mlton/blob/master/mlton/elaborate/scope.sig"><literal>scope.sig</literal></ulink>\r
30559<ulink url="https://github.com/MLton/mlton/blob/master/mlton/elaborate/scope.fun"><literal>scope.fun</literal></ulink></simpara>\r
30560</section>\r
30561<section id="_details_and_notes_56">\r
30562<title>Details and Notes</title>\r
30563<simpara>Scope inference determines for each type variable, the declaration\r
30564where it is bound. Scope inference is a direct implementation of the\r
30565specification given in section 4.6 of the\r
30566<link linkend="DefinitionOfStandardML">Definition</link>. Recall that a free occurrence\r
30567of a type variable <literal>'a</literal> in a declaration <literal>d</literal> is <emphasis>unguarded</emphasis>\r
30568in <literal>d</literal> if <literal>'a</literal> is not part of a smaller declaration. A type\r
30569variable <literal>'a</literal> is implicitly scoped at <literal>d</literal> if <literal>'a</literal> is\r
30570unguarded in <literal>d</literal> and <literal>'a</literal> does not occur unguarded in any\r
30571declaration containing <literal>d</literal>.</simpara>\r
30572<simpara>The first pass of scope inference walks down the tree and renames all\r
30573explicitly bound type variables in order to avoid name collisions. It\r
30574then walks up the tree and adds to each declaration the set of\r
30575unguarded type variables occurring in that declaration. At this\r
30576point, if declaration <literal>d</literal> contains an unguarded type variable\r
30577<literal>'a</literal> and the immediately containing declaration does not contain\r
30578<literal>'a</literal>, then <literal>'a</literal> is implicitly scoped at <literal>d</literal>. The final\r
30579pass walks down the tree leaving a <literal>'a</literal> at the a declaration where\r
30580it is scoped and removing it from all enclosed declarations.</simpara>\r
30581<simpara><?asciidoc-pagebreak?></simpara>\r
30582</section>\r
30583</section>\r
30584<section id="SelfCompiling">\r
30585<title>SelfCompiling</title>\r
30586<simpara>If you want to compile MLton, you must first get the <link linkend="Sources">Sources</link>. You\r
30587can compile with either MLton or SML/NJ, but we strongly recommend\r
30588using MLton, since it generates a much faster and more robust\r
30589executable.</simpara>\r
30590<section id="_compiling_with_mlton">\r
30591<title>Compiling with MLton</title>\r
30592<simpara>To compile with MLton, you need the binary versions of <literal>mlton</literal>,\r
30593<literal>mllex</literal>, and <literal>mlyacc</literal> that come with the MLton binary package. To be\r
30594safe, you should use the same version of MLton that you are building.\r
30595However, older versions may work, as long as they don&#8217;t go back too\r
30596far. To build MLton, run <literal>make</literal> from within the root directory of the\r
30597sources. This will build MLton first with the already installed\r
30598binary version of MLton and will then rebuild MLton with itself.</simpara>\r
30599<simpara>First, the <literal>Makefile</literal> calls <literal>mllex</literal> and <literal>mlyacc</literal> to build the lexer\r
30600and parser, and then calls <literal>mlton</literal> to compile itself. When making\r
30601MLton using another version the <literal>Makefile</literal> automatically uses\r
30602<literal>mlton-stubs.mlb</literal>, which will put in enough stubs to emulate the\r
30603<literal>structure MLton</literal>. Once MLton is built, the <literal>Makefile</literal> will rebuild\r
30604MLton with itself, this time using <literal>mlton.mlb</literal> and the real\r
30605<literal>structure MLton</literal> from the <link linkend="BasisLibrary">Basis Library</link>. This second round\r
30606of compilation is essential in order to achieve a fast and robust\r
30607MLton.</simpara>\r
30608<simpara>Compiling MLton requires at least 1GB of RAM for 32-bit platforms (2GB is\r
30609preferable) and at least 2GB RAM for 64-bit platforms (4GB is preferable).\r
30610If your machine has less RAM, self-compilation will\r
30611likely fail, or at least take a very long time due to paging. Even if\r
30612you have enough memory, there simply may not be enough available, due\r
30613to memory consumed by other processes. In this case, you may see an\r
30614<literal>Out of memory</literal> message, or self-compilation may become extremely\r
30615slow. The only fix is to make sure that enough memory is available.</simpara>\r
30616<section id="_possible_errors">\r
30617<title>Possible Errors</title>\r
30618<itemizedlist>\r
30619<listitem>\r
30620<simpara>\r
30621The C compiler may not be able to find the <link linkend="GnuMP">GnuMP</link> header file,\r
30622<literal>gmp.h</literal> leading to an error like the following.\r
30623</simpara>\r
30624<screen> cenv.h:49:18: fatal error: gmp.h: No such file or directory</screen>\r
30625<simpara>The solution is to install (or build) GnuMP on your machine. If you\r
30626install it at a location not on the default seach path, then run\r
30627<literal>make WITH_GMP_INC_DIR=<emphasis>/path/to/gmp/include</emphasis> WITH_GMP_LIB_DIR=<emphasis>/path/to/gmp/lib</emphasis></literal>.</simpara>\r
30628</listitem>\r
30629<listitem>\r
30630<simpara>\r
30631The following errors indicates that a binary version of MLton could\r
30632not be found in your path.\r
30633</simpara>\r
30634<screen>/bin/sh: mlton: command not found</screen>\r
30635<screen>make[2]: mlton: Command not found</screen>\r
30636<simpara>You need to have <literal>mlton</literal> in your path to build MLton from source.</simpara>\r
30637<simpara>During the build process, there are various times that the <literal>Makefile</literal>-s\r
30638look for a <literal>mlton</literal> in your path and in <literal>src/build/bin</literal>. It is OK if\r
30639the latter doesn&#8217;t exist when the build starts; it is the target being\r
30640built. Failure to find a <literal>mlton</literal> in your path will abort the build.</simpara>\r
30641</listitem>\r
30642</itemizedlist>\r
30643</section>\r
30644</section>\r
30645<section id="_compiling_with_sml_nj">\r
30646<title>Compiling with SML/NJ</title>\r
30647<simpara>To compile with SML/NJ, run <literal>make bootstrap-smlnj</literal> from within the\r
30648root directory of the sources. You must use a recent version of\r
30649SML/NJ. First, the <literal>Makefile</literal> calls <literal>ml-lex</literal> and <literal>ml-yacc</literal> to build\r
30650the lexer and parser. Then, it calls SML/NJ with the appropriate\r
30651<literal>sources.cm</literal> file. Once MLton is built with SML/NJ, the <literal>Makefile</literal>\r
30652will rebuild MLton with this SML/NJ built MLton and then will rebuild\r
30653MLton with the MLton built MLton. Building with SML/NJ takes\r
30654significant time (particularly during the "<literal>parseAndElaborate</literal>" phase\r
30655when the SML/NJ built MLton is compiling MLton). Unless you are doing\r
30656compiler development and need rapid recompilation, we recommend\r
30657compiling with MLton.</simpara>\r
30658<simpara><?asciidoc-pagebreak?></simpara>\r
30659</section>\r
30660</section>\r
30661<section id="Serialization">\r
30662<title>Serialization</title>\r
30663<simpara><link linkend="StandardML">Standard ML</link> does not have built-in support for\r
30664serialization. Here are papers that describe user-level approaches:</simpara>\r
30665<itemizedlist>\r
30666<listitem>\r
30667<simpara>\r
30668<link linkend="References_Elsman04">Elsman04</link>\r
30669</simpara>\r
30670</listitem>\r
30671<listitem>\r
30672<simpara>\r
30673<link linkend="References_Kennedy04">Kennedy04</link>\r
30674</simpara>\r
30675</listitem>\r
30676</itemizedlist>\r
30677<simpara>The MLton repository also contains an experimental generic programming\r
30678library (see\r
30679<ulink url="https://github.com/MLton/mltonlib/blob/master/com/ssh/generic/unstable/README"><literal>README</literal></ulink>) that\r
30680includes a pickling (serialization) generic (see\r
30681<ulink url="https://github.com/MLton/mltonlib/blob/master/com/ssh/generic/unstable/public/value/pickle.sig"><literal>pickle.sig</literal></ulink>).</simpara>\r
30682<simpara><?asciidoc-pagebreak?></simpara>\r
30683</section>\r
30684<section id="ShareZeroVec">\r
30685<title>ShareZeroVec</title>\r
30686<simpara><link linkend="ShareZeroVec">ShareZeroVec</link> is an optimization pass for the <link linkend="SSA">SSA</link>\r
30687<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="SSASimplify">SSASimplify</link>.</simpara>\r
30688<section id="_description_54">\r
30689<title>Description</title>\r
30690<simpara>An SSA optimization to share zero-length vectors.</simpara>\r
30691<simpara>From <ulink url="https://github.com/MLton/mlton/commit/be8c5f576"><literal>be8c5f576</literal></ulink>, which replaced the use of the\r
30692<literal>Array_array0Const</literal> primitive in the Basis Library implementation with a\r
30693(nullary) <literal>Vector_vector</literal> primitive:</simpara>\r
30694<blockquote>\r
30695<simpara>The original motivation for the <literal>Array_array0Const</literal> primitive was to share the\r
30696heap space required for zero-length vectors among all vectors (of a given type).\r
30697It was claimed that this optimization is important, e.g., in a self-compile,\r
30698where vectors are used for lots of syntax tree elements and many of those\r
30699vectors are empty. See:\r
30700<ulink url="http://www.mlton.org/pipermail/mlton-devel/2002-February/021523.html">http://www.mlton.org/pipermail/mlton-devel/2002-February/021523.html</ulink></simpara>\r
30701<simpara>Curiously, the full effect of this optimization has been missing for quite some\r
30702time (perhaps since the port of <link linkend="ConstantPropagation">ConstantPropagation</link> to the SSA IL). While\r
30703<link linkend="ConstantPropagation">ConstantPropagation</link> has "globalized" the nullary application of the\r
30704<literal>Array_array0Const</literal> primitive, it also simultaneously transformed it to an\r
30705application of the <literal>Array_uninit</literal> (previously, the <literal>Array_array</literal>) primitive to\r
30706the zero constant. The hash-consing of globals, meant to create exactly one\r
30707global for each distinct constant, treats <literal>Array_uninit</literal> primitives as unequal\r
30708(appropriately, since <literal>Array_uninit</literal> allocates an array with identity (though\r
30709the identity may be supressed by a subsequent <literal>Array_toVector</literal>)), hence each\r
30710distinct <literal>Array_array0Const</literal> primitive in the program remained as distinct\r
30711globals. The limited amount of inlining prior to <link linkend="ConstantPropagation">ConstantPropagation</link> meant\r
30712that there were typically fewer than a dozen "copies" of the same empty vector\r
30713in a program for a given type.</simpara>\r
30714<simpara>As a "functional" primitive, a nullary <literal>Vector_vector</literal> is globalized by\r
30715ClosureConvert, but is further recognized by ConstantPropagation and hash-consed\r
30716into a unique instance for each type.</simpara>\r
30717</blockquote>\r
30718<simpara>However, a single, shared, global <literal>Vector_vector ()</literal> inhibits the\r
30719coercion-based optimizations of <literal>Useless</literal>. For example, consider the\r
30720following program:</simpara>\r
30721<programlisting language="sml" linenumbering="unnumbered"> val n = valOf (Int.fromString (hd (CommandLine.arguments ())))\r
30722\r
30723 val v1 = Vector.tabulate (n, fn i =&gt;\r
30724 let val w = Word16.fromInt i\r
30725 in (w - 0wx1, w, w + 0wx1 + w)\r
30726 end)\r
30727 val v2 = Vector.map (fn (w1, w2, w3) =&gt; (w1, 0wx2 * w2, 0wx3 * w3)) v1\r
30728 val v3 = VectorSlice.vector (VectorSlice.slice (v1, 1, SOME (n - 2)))\r
30729 val ans1 = Vector.foldl (fn ((w1,w2,w3),w) =&gt; w + w1 + w2 + w3) 0wx0 v1\r
30730 val ans2 = Vector.foldl (fn ((_,w2,_),w) =&gt; w + w2) 0wx0 v2\r
30731 val ans3 = Vector.foldl (fn ((_,w2,_),w) =&gt; w + w2) 0wx0 v3\r
30732\r
30733 val _ = print (concat ["ans1 = ", Word16.toString ans1, " ",\r
30734 "ans2 = ", Word16.toString ans2, " ",\r
30735 "ans3 = ", Word16.toString ans3, "\n"])</programlisting>\r
30736<simpara>We would like <literal>v2</literal> and <literal>v3</literal> to be optimized from\r
30737<literal>(word16 * word16 * word16) vector</literal> to <literal>word16 vector</literal> because only\r
30738the 2nd component of the elements is needed to compute the answer.</simpara>\r
30739<simpara>With <literal>Array_array0Const</literal>, each distinct occurrence of\r
30740<literal>Array_array0Const((word16 * word16 * word16))</literal> arising from\r
30741polyvariance and inlining remained a distinct\r
30742<literal>Array_uninit((word16 * word16 * word16)) (0x0)</literal> global, which\r
30743resulted in distinct occurrences for the\r
30744<literal>val v1 = Vector.tabulate ...</literal> and for the\r
30745<literal>val v2 = Vector.map ...</literal>. The latter could be optimized to\r
30746<literal>Array_uninit(word16) (0x0)</literal> by <literal>Useless</literal>, because its result only\r
30747flows to places requiring the 2nd component of the elements.</simpara>\r
30748<simpara>With <literal>Vector_vector ()</literal>, the distinct occurrences of\r
30749<literal>Vector_vector((word16 * word16 * word16)) ()</literal> arising from\r
30750polyvariance are globalized during <literal>ClosureConvert</literal>, those global\r
30751references may be further duplicated by inlining, but the distinct\r
30752occurrences of <literal>Vector_vector((word16 * word16 * word16)) ()</literal> are\r
30753merged to a single occurrence. Because this result flows to places\r
30754requiring all three components of the elements, it remains\r
30755<literal>Vector_vector((word16 * word16 * word16)) ()</literal> after\r
30756<literal>Useless</literal>. Furthermore, because one cannot (in constant time) coerce a\r
30757<literal>(word16 * word16 * word16) vector</literal> to a <literal>word16 vector</literal>, the <literal>v2</literal>\r
30758value remains of type <literal>(word16 * word16 * word16) vector</literal>.</simpara>\r
30759<simpara>One option would be to drop the 0-element vector "optimization"\r
30760entirely. This costs some space (no sharing of empty vectors) and\r
30761some time (allocation and garbage collection of empty vectors).</simpara>\r
30762<simpara>Another option would be to reinstate the <literal>Array_array0Const</literal> primitive\r
30763and associated <literal>ConstantPropagation</literal> treatment. But, the semantics\r
30764and purpose of <literal>Array_array0Const</literal> was poorly understood, resulting in\r
30765this break.</simpara>\r
30766<simpara>The <link linkend="ShareZeroVec">ShareZeroVec</link> pass pursues a different approach: perform the 0-element\r
30767vector "optimization" as a separate optimization, after\r
30768<literal>ConstantPropagation</literal> and <literal>Useless</literal>. A trivial static analysis is\r
30769used to match <literal>val v: t vector = Array_toVector(t) (a)</literal> with\r
30770corresponding <literal>val a: array = Array_uninit(t) (l)</literal> and the later are\r
30771expanded to\r
30772<literal>val a: t array = if 0 = l then zeroArr_[t] else Array_uninit(t) (l)</literal>\r
30773with a single global <literal>val zeroArr_[t] = Array_uninit(t) (0)</literal> created\r
30774for each distinct type (after coercion-based optimizations).</simpara>\r
30775<simpara>One disadvantage of this approach, compared to the <literal>Vector_vector(t) ()</literal>\r
30776approach, is that <literal>Array_toVector</literal> is applied each time a vector\r
30777is created, even if it is being applied to the <literal>zeroArr_[t]</literal>\r
30778zero-length array. (Although, this was the behavior of the\r
30779<literal>Array_array0Const</literal> approach.) This updates the object header each\r
30780time, whereas the <literal>Vector_vector(t) ()</literal> approach would have updated\r
30781the object header once, when the global was created, and the\r
30782<literal>zeroVec_[t]</literal> global and the <literal>Array_toVector</literal> result would flow to the\r
30783join point.</simpara>\r
30784<simpara>It would be possible to properly share zero-length vectors, but doing\r
30785so is a more sophisticated analysis and transformation, because there\r
30786can be arbitrary code between the\r
30787<literal>val a: t array = Array_uninit(t) (l)</literal> and the corresponding\r
30788<literal>val v: v vector = Array_toVector(t) (a)</literal>, although, in practice,\r
30789nothing happens when a zero-length vector is created. It may be best\r
30790to pursue a more general "array to vector" optimization that\r
30791transforms creations of static-length vectors (e.g., all the\r
30792<literal>Vector.new&lt;N&gt;</literal> functions) into <literal>Vector_vector</literal> primitives (some of\r
30793which could be globalized).</simpara>\r
30794</section>\r
30795<section id="_implementation_59">\r
30796<title>Implementation</title>\r
30797<itemizedlist>\r
30798<listitem>\r
30799<simpara>\r
30800<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/share-zero-vec.fun"><literal>share-zero-vec.fun</literal></ulink>\r
30801</simpara>\r
30802</listitem>\r
30803</itemizedlist>\r
30804</section>\r
30805<section id="_details_and_notes_57">\r
30806<title>Details and Notes</title>\r
30807<simpara></simpara>\r
30808<simpara><?asciidoc-pagebreak?></simpara>\r
30809</section>\r
30810</section>\r
30811<section id="ShowBasis">\r
30812<title>ShowBasis</title>\r
30813<simpara>MLton has a flag, <literal>-show-basis &lt;file&gt;</literal>, that causes MLton to pretty\r
30814print to <emphasis>file</emphasis> the basis defined by the input program. For example,\r
30815if <literal>foo.sml</literal> contains</simpara>\r
30816<programlisting language="sml" linenumbering="unnumbered">fun f x = x + 1</programlisting>\r
30817<simpara>then <literal>mlton -show-basis foo.basis foo.sml</literal> will create <literal>foo.basis</literal>\r
30818with the following contents.</simpara>\r
30819<screen>val f: int -&gt; int</screen>\r
30820<simpara>If you only want to see the basis and do not wish to compile the\r
30821program, you can call MLton with <literal>-stop tc</literal>.</simpara>\r
30822<section id="_displaying_signatures">\r
30823<title>Displaying signatures</title>\r
30824<simpara>When displaying signatures, MLton prefixes types defined in the\r
30825signature them with <literal>_sig.</literal> to distinguish them from types defined in the\r
30826environment. For example,</simpara>\r
30827<programlisting language="sml" linenumbering="unnumbered">signature SIG =\r
30828 sig\r
30829 type t\r
30830 val x: t * int -&gt; unit\r
30831 end</programlisting>\r
30832<simpara>is displayed as</simpara>\r
30833<screen>signature SIG =\r
30834 sig\r
30835 type t\r
30836 val x: _sig.t * int -&gt; unit\r
30837 end</screen>\r
30838<simpara>Notice that <literal>int</literal> occurs without the <literal>_sig.</literal> prefix.</simpara>\r
30839<simpara>MLton also uses a canonical name for each type in the signature, and\r
30840that name is used everywhere for that type, no matter what the input\r
30841signature looked like. For example:</simpara>\r
30842<programlisting language="sml" linenumbering="unnumbered">signature SIG =\r
30843 sig\r
30844 type t\r
30845 type u = t\r
30846 val x: t\r
30847 val y: u\r
30848 end</programlisting>\r
30849<simpara>is displayed as</simpara>\r
30850<screen>signature SIG =\r
30851 sig\r
30852 type t\r
30853 type u = _sig.t\r
30854 val x: _sig.t\r
30855 val y: _sig.t\r
30856 end</screen>\r
30857<simpara>Canonical names are always relative to the "top" of the signature,\r
30858even when used in nested substructures. For example:</simpara>\r
30859<programlisting language="sml" linenumbering="unnumbered">signature S =\r
30860 sig\r
30861 type t\r
30862 val w: t\r
30863 structure U:\r
30864 sig\r
30865 type u\r
30866 val x: t\r
30867 val y: u\r
30868 end\r
30869 val z: U.u\r
30870 end</programlisting>\r
30871<simpara>is displayed as</simpara>\r
30872<screen>signature S =\r
30873 sig\r
30874 type t\r
30875 val w: _sig.t\r
30876 val z: _sig.U.u\r
30877 structure U:\r
30878 sig\r
30879 type u\r
30880 val x: _sig.t\r
30881 val y: _sig.U.u\r
30882 end\r
30883 end</screen>\r
30884</section>\r
30885<section id="_displaying_structures">\r
30886<title>Displaying structures</title>\r
30887<simpara>When displaying structures, MLton uses signature constraints wherever\r
30888possible, combined with <literal>where type</literal> clauses to specify the meanings\r
30889of the types defined within the signature. For example:</simpara>\r
30890<programlisting language="sml" linenumbering="unnumbered">signature SIG =\r
30891 sig\r
30892 type t\r
30893 val x: t\r
30894 end\r
30895structure S: SIG =\r
30896 struct\r
30897 type t = int\r
30898 val x = 13\r
30899 end\r
30900structure S2:&gt; SIG = S</programlisting>\r
30901<simpara>is displayed as</simpara>\r
30902<screen>signature SIG =\r
30903 sig\r
30904 type t\r
30905 val x: _sig.t\r
30906 end\r
30907structure S: SIG\r
30908 where type t = int\r
30909structure S2: SIG\r
30910 where type t = S2.t</screen>\r
30911<simpara><?asciidoc-pagebreak?></simpara>\r
30912</section>\r
30913</section>\r
30914<section id="ShowBasisDirective">\r
30915<title>ShowBasisDirective</title>\r
30916<simpara>A comment of the form <literal>(*#showBasis "&lt;file&gt;"*)</literal> is recognized as a directive to\r
30917save the current basis (i.e., environment) to <literal>&lt;file&gt;</literal> (in the same format as\r
30918the <literal>-show-basis &lt;file&gt;</literal> <link linkend="CompileTimeOptions">compile-time option</link>). The\r
30919<literal>&lt;file&gt;</literal> is interpreted relative to the source file in which it appears. The\r
30920comment is lexed as a distinct token and is parsed as a structure-level\r
30921declaration. [Note that treating the directive as a top-level declaration would\r
30922prohibit using it inside a functor body, which would make the feature\r
30923significantly less useful in the context of the MLton compiler sources (with its\r
30924nearly fully functorial style).]</simpara>\r
30925<simpara>This feature is meant to facilitate auto-completion via\r
30926<ulink url="https://github.com/MatthewFluet/company-mlton"><literal>company-mlton</literal></ulink> and similar\r
30927tools.</simpara>\r
30928<simpara><?asciidoc-pagebreak?></simpara>\r
30929</section>\r
30930<section id="ShowProf">\r
30931<title>ShowProf</title>\r
30932<simpara>If an executable is compiled for <link linkend="Profiling">profiling</link>, then it\r
30933accepts a special command-line runtime system argument, <literal>show-prof</literal>,\r
30934that outputs information about the source functions that are profiled.\r
30935Normally, this information is used by <literal>mlprof</literal>. This page documents\r
30936the <literal>show-prof</literal> output format, and is intended for those working on\r
30937the profiler internals.</simpara>\r
30938<simpara>The <literal>show-prof</literal> output is ASCII, and consists of a sequence of lines.</simpara>\r
30939<itemizedlist>\r
30940<listitem>\r
30941<simpara>\r
30942The magic number of the executable.\r
30943</simpara>\r
30944</listitem>\r
30945<listitem>\r
30946<simpara>\r
30947The number of source names in the executable.\r
30948</simpara>\r
30949</listitem>\r
30950<listitem>\r
30951<simpara>\r
30952A line for each source name giving the name of the function, a tab,\r
30953the filename of the file containing the function, a colon, a space,\r
30954and the line number that the function starts on in that file.\r
30955</simpara>\r
30956</listitem>\r
30957<listitem>\r
30958<simpara>\r
30959The number of (split) source functions.\r
30960</simpara>\r
30961</listitem>\r
30962<listitem>\r
30963<simpara>\r
30964A line for each (split) source function, where each line consists of\r
30965a source-name index (into the array of source names) and a successors\r
30966index (into the array of split-source sequences, defined below).\r
30967</simpara>\r
30968</listitem>\r
30969<listitem>\r
30970<simpara>\r
30971The number of split-source sequences.\r
30972</simpara>\r
30973</listitem>\r
30974<listitem>\r
30975<simpara>\r
30976A line for each split-source sequence, where each line is a space\r
30977separated list of (split) source functions.\r
30978</simpara>\r
30979</listitem>\r
30980</itemizedlist>\r
30981<simpara>The latter two arrays, split sources and split-source sequences,\r
30982define a directed graph, which is the call-graph of the program.</simpara>\r
30983<simpara><?asciidoc-pagebreak?></simpara>\r
30984</section>\r
30985<section id="Shrink">\r
30986<title>Shrink</title>\r
30987<simpara><link linkend="Shrink">Shrink</link> is a rewrite pass for the <link linkend="SSA">SSA</link> and <link linkend="SSA2">SSA2</link>\r
30988<link linkend="IntermediateLanguage">IntermediateLanguage</link>s, invoked from every optimization pass (see\r
30989<link linkend="SSASimplify">SSASimplify</link> and <link linkend="SSA2Simplify">SSA2Simplify</link>).</simpara>\r
30990<section id="_description_55">\r
30991<title>Description</title>\r
30992<simpara>This pass implements a whole family of compile-time reductions, like:</simpara>\r
30993<itemizedlist>\r
30994<listitem>\r
30995<simpara>\r
30996<literal>#1(a, b)</literal> &#8658; <literal>a</literal>\r
30997</simpara>\r
30998</listitem>\r
30999<listitem>\r
31000<simpara>\r
31001<literal>case C x of C y =&gt; e</literal> &#8658; <literal>let y = x in e</literal>\r
31002</simpara>\r
31003</listitem>\r
31004<listitem>\r
31005<simpara>\r
31006constant folding, copy propagation\r
31007</simpara>\r
31008</listitem>\r
31009<listitem>\r
31010<simpara>\r
31011eta blocks\r
31012</simpara>\r
31013</listitem>\r
31014<listitem>\r
31015<simpara>\r
31016tuple reconstruction elimination\r
31017</simpara>\r
31018</listitem>\r
31019</itemizedlist>\r
31020</section>\r
31021<section id="_implementation_60">\r
31022<title>Implementation</title>\r
31023<itemizedlist>\r
31024<listitem>\r
31025<simpara>\r
31026<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/shrink.sig"><literal>shrink.sig</literal></ulink>\r
31027</simpara>\r
31028</listitem>\r
31029<listitem>\r
31030<simpara>\r
31031<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/shrink.fun"><literal>shrink.fun</literal></ulink>\r
31032</simpara>\r
31033</listitem>\r
31034<listitem>\r
31035<simpara>\r
31036<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/shrink2.sig"><literal>shrink2.sig</literal></ulink>\r
31037</simpara>\r
31038</listitem>\r
31039<listitem>\r
31040<simpara>\r
31041<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/shrink2.fun"><literal>shrink2.fun</literal></ulink>\r
31042</simpara>\r
31043</listitem>\r
31044</itemizedlist>\r
31045</section>\r
31046<section id="_details_and_notes_58">\r
31047<title>Details and Notes</title>\r
31048<simpara>The <link linkend="Shrink">Shrink</link> pass is run after every <link linkend="SSA">SSA</link> and <link linkend="SSA2">SSA2</link>\r
31049optimization pass.</simpara>\r
31050<simpara>The <link linkend="Shrink">Shrink</link> implementation also includes functions to eliminate\r
31051unreachable blocks from a <link linkend="SSA">SSA</link> or <link linkend="SSA2">SSA2</link> program or function.\r
31052The <link linkend="Shrink">Shrink</link> pass does not guarantee to eliminate all unreachable\r
31053blocks. Doing so would unduly complicate the implementation, and it\r
31054is almost always the case that all unreachable blocks are eliminated.\r
31055However, a small number of optimization passes require that the input\r
31056have no unreachable blocks (essentially, when the analysis works on\r
31057the control flow graph and the rewrite iterates on the vector of\r
31058blocks). These passes explicitly call <literal>eliminateDeadBlocks</literal>.</simpara>\r
31059<simpara>The <link linkend="Shrink">Shrink</link> pass has a special case to turn a non-tail call where\r
31060the continuation and handler only do <literal>Profile</literal> statements into a tail\r
31061call where the <literal>Profile</literal> statements precede the tail call.</simpara>\r
31062<simpara><?asciidoc-pagebreak?></simpara>\r
31063</section>\r
31064</section>\r
31065<section id="SimplifyTypes">\r
31066<title>SimplifyTypes</title>\r
31067<simpara><link linkend="SimplifyTypes">SimplifyTypes</link> is an optimization pass for the <link linkend="SSA">SSA</link>\r
31068<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="SSASimplify">SSASimplify</link>.</simpara>\r
31069<section id="_description_56">\r
31070<title>Description</title>\r
31071<simpara>This pass computes a "cardinality" of each datatype, which is an\r
31072abstraction of the number of values of the datatype.</simpara>\r
31073<itemizedlist>\r
31074<listitem>\r
31075<simpara>\r
31076<literal>Zero</literal> means the datatype has no values (except for bottom).\r
31077</simpara>\r
31078</listitem>\r
31079<listitem>\r
31080<simpara>\r
31081<literal>One</literal> means the datatype has one value (except for bottom).\r
31082</simpara>\r
31083</listitem>\r
31084<listitem>\r
31085<simpara>\r
31086<literal>Many</literal> means the datatype has many values.\r
31087</simpara>\r
31088</listitem>\r
31089</itemizedlist>\r
31090<simpara>This pass removes all datatypes whose cardinality is <literal>Zero</literal> or <literal>One</literal>\r
31091and removes:</simpara>\r
31092<itemizedlist>\r
31093<listitem>\r
31094<simpara>\r
31095components of tuples\r
31096</simpara>\r
31097</listitem>\r
31098<listitem>\r
31099<simpara>\r
31100function args\r
31101</simpara>\r
31102</listitem>\r
31103<listitem>\r
31104<simpara>\r
31105constructor args\r
31106</simpara>\r
31107</listitem>\r
31108</itemizedlist>\r
31109<simpara>which are such datatypes.</simpara>\r
31110<simpara>This pass marks constructors as one of:</simpara>\r
31111<itemizedlist>\r
31112<listitem>\r
31113<simpara>\r
31114<literal>Useless</literal>: it never appears in a <literal>ConApp</literal>.\r
31115</simpara>\r
31116</listitem>\r
31117<listitem>\r
31118<simpara>\r
31119<literal>Transparent</literal>: it is the only variant in its datatype and its argument type does not contain any uses of <literal>array</literal> or <literal>vector</literal>.\r
31120</simpara>\r
31121</listitem>\r
31122<listitem>\r
31123<simpara>\r
31124<literal>Useful</literal>: otherwise\r
31125</simpara>\r
31126</listitem>\r
31127</itemizedlist>\r
31128<simpara>This pass also removes <literal>Useless</literal> and <literal>Transparent</literal> constructors.</simpara>\r
31129</section>\r
31130<section id="_implementation_61">\r
31131<title>Implementation</title>\r
31132<itemizedlist>\r
31133<listitem>\r
31134<simpara>\r
31135<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/simplify-types.fun"><literal>simplify-types.fun</literal></ulink>\r
31136</simpara>\r
31137</listitem>\r
31138</itemizedlist>\r
31139</section>\r
31140<section id="_details_and_notes_59">\r
31141<title>Details and Notes</title>\r
31142<simpara>This pass must happen before polymorphic equality is implemented because</simpara>\r
31143<itemizedlist>\r
31144<listitem>\r
31145<simpara>\r
31146it will make polymorphic equality faster because some types are simpler\r
31147</simpara>\r
31148</listitem>\r
31149<listitem>\r
31150<simpara>\r
31151it removes uses of polymorphic equality that must return true\r
31152</simpara>\r
31153</listitem>\r
31154</itemizedlist>\r
31155<simpara>We must keep track of <literal>Transparent</literal> constructors whose argument type\r
31156uses <literal>array</literal> because of datatypes like the following:</simpara>\r
31157<programlisting language="sml" linenumbering="unnumbered">datatype t = T of t array</programlisting>\r
31158<simpara>Such a datatype has <literal>Cardinality.Many</literal>, but we cannot eliminate the\r
31159datatype and replace the lhs by the rhs, i.e. we must keep the\r
31160circularity around.</simpara>\r
31161<simpara>Must do similar things for <literal>vectors</literal>.</simpara>\r
31162<simpara>Also, to eliminate as many <literal>Transparent</literal> constructors as possible, for\r
31163something like the following,</simpara>\r
31164<programlisting language="sml" linenumbering="unnumbered">datatype t = T of u array\r
31165 and u = U of t vector</programlisting>\r
31166<simpara>we (arbitrarily) expand one of the datatypes first. The result will\r
31167be something like</simpara>\r
31168<programlisting language="sml" linenumbering="unnumbered">datatype u = U of u array array</programlisting>\r
31169<simpara>where all uses of <literal>t</literal> are replaced by <literal>u array</literal>.</simpara>\r
31170<simpara><?asciidoc-pagebreak?></simpara>\r
31171</section>\r
31172</section>\r
31173<section id="SML3d">\r
31174<title>SML3d</title>\r
31175<simpara>The <ulink url="http://sml3d.cs.uchicago.edu/">SML3d Project</ulink> is a collection of\r
31176libraries to support 3D graphics programming using Standard ML and the\r
31177<ulink url="http://www.opengl.org/">OpenGL</ulink> graphics API. It currently requires the\r
31178MLton implementation of SML and is supported on Linux, Mac OS X, and\r
31179Microsoft Windows. There is also support for\r
31180<ulink url="http://www.khronos.org/opencl/">OpenCL</ulink>.</simpara>\r
31181<simpara><?asciidoc-pagebreak?></simpara>\r
31182</section>\r
31183<section id="SMLNET">\r
31184<title>SMLNET</title>\r
31185<simpara><ulink url="http://www.cl.cam.ac.uk/research/tsg/SMLNET">SML.NET</ulink> is a\r
31186<link linkend="StandardMLImplementations">Standard ML implementation</link> that\r
31187targets the .NET Common Language Runtime.</simpara>\r
31188<simpara>SML.NET is based on the <link linkend="MLj">MLj</link> compiler.</simpara>\r
31189<section id="_also_see_43">\r
31190<title>Also see</title>\r
31191<itemizedlist>\r
31192<listitem>\r
31193<simpara>\r
31194<link linkend="References_BentonEtAl04">BentonEtAl04</link>\r
31195</simpara>\r
31196</listitem>\r
31197</itemizedlist>\r
31198<simpara><?asciidoc-pagebreak?></simpara>\r
31199</section>\r
31200</section>\r
31201<section id="SMLNJ">\r
31202<title>SMLNJ</title>\r
31203<simpara><ulink url="http://www.smlnj.org/">SML/NJ</ulink> is a\r
31204<link linkend="StandardMLImplementations">Standard ML implementation</link>. It is a\r
31205native code compiler that runs on a variety of platforms and has a\r
31206number of libraries and tools.</simpara>\r
31207<simpara>We maintain a list of SML/NJ&#8217;s <link linkend="SMLNJDeviations">deviations</link> from\r
31208<link linkend="DefinitionOfStandardML">The Definition of Standard ML</link>.</simpara>\r
31209<simpara>MLton has support for some features of SML/NJ in order to ease porting\r
31210between MLton and SML/NJ.</simpara>\r
31211<itemizedlist>\r
31212<listitem>\r
31213<simpara>\r
31214<link linkend="CompilationManager">CompilationManager</link> (CM)\r
31215</simpara>\r
31216</listitem>\r
31217<listitem>\r
31218<simpara>\r
31219<link linkend="LineDirective">LineDirective</link>s\r
31220</simpara>\r
31221</listitem>\r
31222<listitem>\r
31223<simpara>\r
31224<link linkend="SMLofNJStructure">SMLofNJStructure</link>\r
31225</simpara>\r
31226</listitem>\r
31227<listitem>\r
31228<simpara>\r
31229<link linkend="UnsafeStructure">UnsafeStructure</link>\r
31230</simpara>\r
31231</listitem>\r
31232</itemizedlist>\r
31233<simpara><?asciidoc-pagebreak?></simpara>\r
31234</section>\r
31235<section id="SMLNJDeviations">\r
31236<title>SMLNJDeviations</title>\r
31237<simpara>Here are some deviations of <link linkend="SMLNJ">SML/NJ</link> from\r
31238<link linkend="DefinitionOfStandardML">The Definition of Standard ML (Revised)</link>.\r
31239Some of these are documented in the\r
31240<ulink url="http://www.smlnj.org/doc/Conversion/index.html">SML '97 Conversion Guide</ulink>.\r
31241Since MLton does not deviate from the Definition, you should look here\r
31242if you are having trouble porting a program from MLton to SML/NJ or\r
31243vice versa. If you discover other deviations of SML/NJ that aren&#8217;t\r
31244listed here, please send mail to\r
31245<ulink url="mailto:MLton-devel@mlton.org"><literal>MLton-devel@mlton.org</literal></ulink>.</simpara>\r
31246<itemizedlist>\r
31247<listitem>\r
31248<simpara>\r
31249SML/NJ allows spaces in long identifiers, as in <literal>S . x</literal>. Section\r
312502.5 of the Definition implies that <literal>S . x</literal> should be treated as three\r
31251separate lexical items.\r
31252</simpara>\r
31253</listitem>\r
31254<listitem>\r
31255<simpara>\r
31256SML/NJ allows <literal>op</literal> to appear in <literal>val</literal> specifications:\r
31257</simpara>\r
31258<programlisting language="sml" linenumbering="unnumbered">signature FOO = sig\r
31259 val op + : int * int -&gt; int\r
31260end</programlisting>\r
31261<simpara>The grammar on page 14 of the Definition does not allow it. Recent\r
31262versions of SML/NJ do give a warning.</simpara>\r
31263</listitem>\r
31264<listitem>\r
31265<simpara>\r
31266SML/NJ rejects\r
31267</simpara>\r
31268<programlisting language="sml" linenumbering="unnumbered">(op *)</programlisting>\r
31269<simpara>as an unmatched close comment.</simpara>\r
31270</listitem>\r
31271<listitem>\r
31272<simpara>\r
31273SML/NJ allows <literal>=</literal> to be rebound by the declaration:\r
31274</simpara>\r
31275<programlisting language="sml" linenumbering="unnumbered">val op = = 13</programlisting>\r
31276<simpara>This is explicitly forbidden on page 5 of the Definition. Recent\r
31277versions of SML/NJ do give a warning.</simpara>\r
31278</listitem>\r
31279<listitem>\r
31280<simpara>\r
31281SML/NJ allows rebinding <literal>true</literal>, <literal>false</literal>, <literal>nil</literal>, <literal>::</literal>, and <literal>ref</literal> by\r
31282the declarations:\r
31283</simpara>\r
31284<programlisting language="sml" linenumbering="unnumbered">fun true () = ()\r
31285fun false () = ()\r
31286fun nil () = ()\r
31287fun op :: () = ()\r
31288fun ref () = ()</programlisting>\r
31289<simpara>This is explicitly forbidden on page 9 of the Definition.</simpara>\r
31290</listitem>\r
31291<listitem>\r
31292<simpara>\r
31293SML/NJ extends the syntax of the language to allow vector\r
31294expressions and patterns like the following:\r
31295</simpara>\r
31296<programlisting language="sml" linenumbering="unnumbered">val v = #[1,2,3]\r
31297val #[x,y,z] = v</programlisting>\r
31298<simpara>MLton supports vector expressions and patterns with the <link linkend="SuccessorML_VectorExpsAndPats"><literal>allowVectorExpsAndPats</literal></link> <link linkend="MLBasisAnnotations">ML Basis annotation</link>.</simpara>\r
31299</listitem>\r
31300<listitem>\r
31301<simpara>\r
31302SML/NJ extends the syntax of the language to allow <emphasis>or patterns</emphasis>\r
31303like the following:\r
31304</simpara>\r
31305<programlisting language="sml" linenumbering="unnumbered">datatype foo = Foo of int | Bar of int\r
31306val (Foo x | Bar x) = Foo 13</programlisting>\r
31307<simpara>MLton supports or patterns with the <link linkend="SuccessorML_OrPats"><literal>allowOrPats</literal></link> <link linkend="MLBasisAnnotations">ML Basis annotation</link>.</simpara>\r
31308</listitem>\r
31309<listitem>\r
31310<simpara>\r
31311SML/NJ allows higher-order functors, that is, functors can be\r
31312components of structures and can be passed as functor arguments and\r
31313returned as functor results. As a consequence, SML/NJ allows\r
31314abbreviated functor definitions, as in the following:\r
31315</simpara>\r
31316<programlisting language="sml" linenumbering="unnumbered">signature S =\r
31317 sig\r
31318 type t\r
31319 val x: t\r
31320 end\r
31321functor F (structure A: S): S =\r
31322 struct\r
31323 type t = A.t * A.t\r
31324 val x = (A.x, A.x)\r
31325 end\r
31326functor G = F</programlisting>\r
31327</listitem>\r
31328<listitem>\r
31329<simpara>\r
31330SML/NJ extends the syntax of the language to allow <literal>functor</literal> and\r
31331<literal>signature</literal> declarations to occur within the scope of <literal>local</literal> and\r
31332<literal>structure</literal> declarations.\r
31333</simpara>\r
31334</listitem>\r
31335<listitem>\r
31336<simpara>\r
31337SML/NJ allows duplicate type specifications in signatures when the\r
31338duplicates are introduced by <literal>include</literal>, as in the following:\r
31339</simpara>\r
31340<programlisting language="sml" linenumbering="unnumbered">signature SIG1 =\r
31341 sig\r
31342 type t\r
31343 type u\r
31344 end\r
31345signature SIG2 =\r
31346 sig\r
31347 type t\r
31348 type v\r
31349 end\r
31350signature SIG =\r
31351 sig\r
31352 include SIG1\r
31353 include SIG2\r
31354 end</programlisting>\r
31355<simpara>This is disallowed by rule 77 of the Definition.</simpara>\r
31356</listitem>\r
31357<listitem>\r
31358<simpara>\r
31359SML/NJ allows sharing constraints between type abbreviations in\r
31360signatures, as in the following:\r
31361</simpara>\r
31362<programlisting language="sml" linenumbering="unnumbered">signature SIG =\r
31363 sig\r
31364 type t = int * int\r
31365 type u = int * int\r
31366 sharing type t = u\r
31367 end</programlisting>\r
31368<simpara>These are disallowed by rule 78 of the Definition. Recent versions of\r
31369SML/NJ correctly disallow sharing constraints between type\r
31370abbreviations in signatures.</simpara>\r
31371</listitem>\r
31372<listitem>\r
31373<simpara>\r
31374SML/NJ disallows multiple <literal>where type</literal> specifications of the same\r
31375type name, as in the following\r
31376</simpara>\r
31377<programlisting language="sml" linenumbering="unnumbered">signature S =\r
31378 sig\r
31379 type t\r
31380 type u = t\r
31381 end\r
31382 where type u = int</programlisting>\r
31383<simpara>This is allowed by rule 64 of the Definition.</simpara>\r
31384</listitem>\r
31385<listitem>\r
31386<simpara>\r
31387SML/NJ allows <literal>and</literal> in <literal>sharing</literal> specs in signatures, as in\r
31388</simpara>\r
31389<programlisting language="sml" linenumbering="unnumbered">signature S =\r
31390 sig\r
31391 type t\r
31392 type u\r
31393 type v\r
31394 sharing type t = u\r
31395 and type u = v\r
31396 end</programlisting>\r
31397</listitem>\r
31398<listitem>\r
31399<simpara>\r
31400SML/NJ does not expand the <literal>withtype</literal> derived form as described by\r
31401the Definition. According to page 55 of the Definition, the type\r
31402bindings of a <literal>withtype</literal> declaration are substituted simultaneously in\r
31403the connected datatype. Consider the following program.\r
31404</simpara>\r
31405<programlisting language="sml" linenumbering="unnumbered">type u = real ;\r
31406datatype a =\r
31407 A of t\r
31408 | B of u\r
31409withtype u = int\r
31410and t = u</programlisting>\r
31411<simpara>According to the Definition, it should be expanded to the following.</simpara>\r
31412<programlisting language="sml" linenumbering="unnumbered">type u = real ;\r
31413datatype a =\r
31414 A of u\r
31415 | B of int ;\r
31416type u = int\r
31417and t = u</programlisting>\r
31418<simpara>However, SML/NJ expands <literal>withtype</literal> bindings sequentially, meaning that\r
31419earlier bindings are expanded within later ones. Hence, the above\r
31420program is expanded to the following.</simpara>\r
31421<programlisting language="sml" linenumbering="unnumbered">type u = real ;\r
31422datatype a =\r
31423 A of int\r
31424 | B of int ;\r
31425type u = int\r
31426type t = int</programlisting>\r
31427</listitem>\r
31428<listitem>\r
31429<simpara>\r
31430SML/NJ allows <literal>withtype</literal> specifications in signatures.\r
31431</simpara>\r
31432<simpara>MLton supports <literal>withtype</literal> specifications in signatures with the <link linkend="SuccessorML_SigWithtype"><literal>allowSigWithtype</literal></link> <link linkend="MLBasisAnnotations">ML Basis annotation</link>.</simpara>\r
31433</listitem>\r
31434<listitem>\r
31435<simpara>\r
31436SML/NJ allows a <literal>where</literal> structure specification that is similar to a\r
31437<literal>where type</literal> specification. For example:\r
31438</simpara>\r
31439<programlisting language="sml" linenumbering="unnumbered">structure S = struct type t = int end\r
31440signature SIG =\r
31441 sig\r
31442 structure T : sig type t end\r
31443 end where T = S</programlisting>\r
31444<simpara>This is equivalent to:</simpara>\r
31445<programlisting language="sml" linenumbering="unnumbered">structure S = struct type t = int end\r
31446signature SIG =\r
31447 sig\r
31448 structure T : sig type t end\r
31449 end where type T.t = S.t</programlisting>\r
31450<simpara>SML/NJ also allows a definitional structure specification that is\r
31451similar to a definitional type specification. For example:</simpara>\r
31452<programlisting language="sml" linenumbering="unnumbered">structure S = struct type t = int end\r
31453signature SIG =\r
31454 sig\r
31455 structure T : sig type t end = S\r
31456 end</programlisting>\r
31457<simpara>This is equivalent to the previous examples and to:</simpara>\r
31458<programlisting language="sml" linenumbering="unnumbered">structure S = struct type t = int end\r
31459signature SIG =\r
31460 sig\r
31461 structure T : sig type t end where type t = S.t\r
31462 end</programlisting>\r
31463</listitem>\r
31464<listitem>\r
31465<simpara>\r
31466SML/NJ disallows binding non-datatypes with datatype replication.\r
31467For example, it rejects the following program that should be allowed\r
31468according to the Definition.\r
31469</simpara>\r
31470<programlisting language="sml" linenumbering="unnumbered">type ('a, 'b) t = 'a * 'b\r
31471datatype u = datatype t</programlisting>\r
31472<simpara>This idiom can be useful when one wants to rename a type without\r
31473rewriting all the type arguments. For example, the above would have\r
31474to be written in SML/NJ as follows.</simpara>\r
31475<programlisting language="sml" linenumbering="unnumbered">type ('a, 'b) t = 'a * 'b\r
31476type ('a, 'b) u = ('a, 'b) t</programlisting>\r
31477</listitem>\r
31478<listitem>\r
31479<simpara>\r
31480SML/NJ disallows sharing a structure with one of its substructures.\r
31481For example, SML/NJ disallows the following.\r
31482</simpara>\r
31483<programlisting language="sml" linenumbering="unnumbered">signature SIG =\r
31484 sig\r
31485 structure S:\r
31486 sig\r
31487 type t\r
31488 structure T: sig type t end\r
31489 end\r
31490 sharing S = S.T\r
31491 end</programlisting>\r
31492<simpara>This signature is allowed by the Definition.</simpara>\r
31493</listitem>\r
31494<listitem>\r
31495<simpara>\r
31496SML/NJ disallows polymorphic generalization of refutable\r
31497patterns. For example, SML/NJ disallows the following.\r
31498</simpara>\r
31499<programlisting language="sml" linenumbering="unnumbered">val [x] = [[]]\r
31500val _ = (1 :: x, "one" :: x)</programlisting>\r
31501<simpara>Recent versions of SML/NJ correctly allow polymorphic generalization\r
31502of refutable patterns.</simpara>\r
31503</listitem>\r
31504<listitem>\r
31505<simpara>\r
31506SML/NJ uses an overly restrictive context for type inference. For\r
31507example, SML/NJ rejects both of the following.\r
31508</simpara>\r
31509<programlisting language="sml" linenumbering="unnumbered">structure S =\r
31510struct\r
31511 val z = (fn x =&gt; x) []\r
31512 val y = z :: [true] :: nil\r
31513end</programlisting>\r
31514<programlisting language="sml" linenumbering="unnumbered">structure S : sig val z : bool list end =\r
31515struct\r
31516 val z = (fn x =&gt; x) []\r
31517end</programlisting>\r
31518<simpara>These structures are allowed by the Definition.</simpara>\r
31519</listitem>\r
31520</itemizedlist>\r
31521<section id="_deviations_from_the_basis_library_specification">\r
31522<title>Deviations from the Basis Library Specification</title>\r
31523<simpara>Here are some deviations of SML/NJ from the <link linkend="BasisLibrary">Basis Library</link>\r
31524<ulink url="http://www.standardml.org/Basis">specification</ulink>.</simpara>\r
31525<itemizedlist>\r
31526<listitem>\r
31527<simpara>\r
31528SML/NJ exposes the equality of the <literal>vector</literal> type in structures such\r
31529as <literal>Word8Vector</literal> that abstractly match <literal>MONO_VECTOR</literal>, which says\r
31530<literal>type vector</literal>, not <literal>eqtype vector</literal>. So, for example, SML/NJ accepts\r
31531the following program:\r
31532</simpara>\r
31533<programlisting language="sml" linenumbering="unnumbered">fun f (v: Word8Vector.vector) = v = v</programlisting>\r
31534</listitem>\r
31535<listitem>\r
31536<simpara>\r
31537SML/NJ exposes the equality property of the type <literal>status</literal> in\r
31538<literal>OS.Process</literal>. This means that programs which directly compare two\r
31539values of type <literal>status</literal> will work with SML/NJ but not MLton.\r
31540</simpara>\r
31541</listitem>\r
31542<listitem>\r
31543<simpara>\r
31544Under SML/NJ on Windows, <literal>OS.Path.validVolume</literal> incorrectly considers\r
31545absolute empty volumes to be valid. In other words, when the\r
31546expression\r
31547</simpara>\r
31548<programlisting language="sml" linenumbering="unnumbered">OS.Path.validVolume { isAbs = true, vol = "" }</programlisting>\r
31549<simpara>is evaluated by SML/NJ on Windows, the result is <literal>true</literal>. MLton, on\r
31550the other hand, correctly follows the Basis Library Specification,\r
31551which states that on Windows, <literal>OS.Path.validVolume</literal> should return\r
31552<literal>false</literal> whenever <literal>isAbs = true</literal> and <literal>vol = ""</literal>.</simpara>\r
31553<simpara>This incorrect behavior causes other <literal>OS.Path</literal> functions to behave\r
31554differently. For example, when the expression</simpara>\r
31555<programlisting language="sml" linenumbering="unnumbered">OS.Path.toString (OS.Path.fromString "\\usr\\local")</programlisting>\r
31556<simpara>is evaluated by SML/NJ on Windows, the result is <literal>"\\usr\\local"</literal>,\r
31557whereas under MLton on Windows, evaluating this expression (correctly)\r
31558causes an <literal>OS.Path.Path</literal> exception to be raised.</simpara>\r
31559</listitem>\r
31560</itemizedlist>\r
31561<simpara><?asciidoc-pagebreak?></simpara>\r
31562</section>\r
31563</section>\r
31564<section id="SMLNJLibrary">\r
31565<title>SMLNJLibrary</title>\r
31566<simpara>The <ulink url="http://www.smlnj.org/doc/smlnj-lib/index.html">SML/NJ Library</ulink> is a\r
31567collection of libraries that are distributed with SML/NJ. Due to\r
31568differences between SML/NJ and MLton, these libraries will not work\r
31569out-of-the box with MLton.</simpara>\r
31570<simpara>As of 20180119, MLton includes a port of the SML/NJ Library\r
31571synchronized with SML/NJ version 110.82.</simpara>\r
31572<section id="_usage_8">\r
31573<title>Usage</title>\r
31574<itemizedlist>\r
31575<listitem>\r
31576<simpara>\r
31577You can import a sub-library of the SML/NJ Library into an MLB file with:\r
31578</simpara>\r
31579<informaltable\r
31580frame="all"\r
31581rowsep="1" colsep="1"\r
31582>\r
31583<tgroup cols="2">\r
31584<colspec colname="col_1" colwidth="50*"/>\r
31585<colspec colname="col_2" colwidth="50*"/>\r
31586<thead>\r
31587<row>\r
31588<entry align="left" valign="top">MLB file</entry>\r
31589<entry align="left" valign="top">Description</entry>\r
31590</row>\r
31591</thead>\r
31592<tbody>\r
31593<row>\r
31594<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/smlnj-lib/Util/smlnj-lib.mlb</literal></simpara></entry>\r
31595<entry align="left" valign="top"><simpara>Various utility modules, included collections, simple formating, &#8230;</simpara></entry>\r
31596</row>\r
31597<row>\r
31598<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/smlnj-lib/Controls/controls-lib.mlb</literal></simpara></entry>\r
31599<entry align="left" valign="top"><simpara>A library for managing control flags in an application.</simpara></entry>\r
31600</row>\r
31601<row>\r
31602<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/smlnj-lib/HashCons/hash-cons-lib.mlb</literal></simpara></entry>\r
31603<entry align="left" valign="top"><simpara>Support for implementing hash-consed data structures.</simpara></entry>\r
31604</row>\r
31605<row>\r
31606<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/smlnj-lib/HTML/html-lib.mlb</literal></simpara></entry>\r
31607<entry align="left" valign="top"><simpara>HTML 3.2 parsing and pretty-printing library.</simpara></entry>\r
31608</row>\r
31609<row>\r
31610<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/smlnj-lib/HTML4/html4-lib.mlb</literal></simpara></entry>\r
31611<entry align="left" valign="top"><simpara>HTML 4.01 parsing and pretty-printing library.</simpara></entry>\r
31612</row>\r
31613<row>\r
31614<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/smlnj-lib/INet/inet-lib.mlb</literal></simpara></entry>\r
31615<entry align="left" valign="top"><simpara>Networking utilities; supported on both Unix and Windows systems.</simpara></entry>\r
31616</row>\r
31617<row>\r
31618<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/smlnj-lib/JSON/json-lib.mlb</literal></simpara></entry>\r
31619<entry align="left" valign="top"><simpara>JavaScript Object Notation (JSON) reading and writing library.</simpara></entry>\r
31620</row>\r
31621<row>\r
31622<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/smlnj-lib/PP/pp-lib.mlb</literal></simpara></entry>\r
31623<entry align="left" valign="top"><simpara>Pretty-printing library.</simpara></entry>\r
31624</row>\r
31625<row>\r
31626<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/smlnj-lib/Reactive/reactive-lib.mlb</literal></simpara></entry>\r
31627<entry align="left" valign="top"><simpara>Reactive scripting library.</simpara></entry>\r
31628</row>\r
31629<row>\r
31630<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/smlnj-lib/RegExp/regexp-lib.mlb</literal></simpara></entry>\r
31631<entry align="left" valign="top"><simpara>Regular expression library.</simpara></entry>\r
31632</row>\r
31633<row>\r
31634<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/smlnj-lib/SExp/sexp-lib.mlb</literal></simpara></entry>\r
31635<entry align="left" valign="top"><simpara>S-expression library.</simpara></entry>\r
31636</row>\r
31637<row>\r
31638<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/smlnj-lib/Unix/unix-lib.mlb</literal></simpara></entry>\r
31639<entry align="left" valign="top"><simpara>Utilities for Unix-based operating systems.</simpara></entry>\r
31640</row>\r
31641<row>\r
31642<entry align="left" valign="top"><simpara><literal>$(SML_LIB)/smlnj-lib/XML/xml-lib.mlb</literal></simpara></entry>\r
31643<entry align="left" valign="top"><simpara>XML library.</simpara></entry>\r
31644</row>\r
31645</tbody>\r
31646</tgroup>\r
31647</informaltable>\r
31648</listitem>\r
31649<listitem>\r
31650<simpara>\r
31651If you are porting a project from SML/NJ&#8217;s <link linkend="CompilationManager">CompilationManager</link> to\r
31652MLton&#8217;s <link linkend="MLBasis">ML Basis system</link> using <literal>cm2mlb</literal>, note that the\r
31653following maps are included by default:\r
31654</simpara>\r
31655<screen># SMLNJ Library\r
31656$SMLNJ-LIB $(SML_LIB)/smlnj-lib\r
31657$smlnj-lib.cm $(SML_LIB)/smlnj-lib/Util\r
31658$controls-lib.cm $(SML_LIB)/smlnj-lib/Controls\r
31659$hash-cons-lib.cm $(SML_LIB)/smlnj-lib/HashCons\r
31660$html-lib.cm $(SML_LIB)/smlnj-lib/HTML\r
31661$html4-lib.cm $(SML_LIB)/smlnj-lib/HTML4\r
31662$inet-lib.cm $(SML_LIB)/smlnj-lib/INet\r
31663$json-lib.cm $(SML_LIB)/smlnj-lib/JSON\r
31664$pp-lib.cm $(SML_LIB)/smlnj-lib/PP\r
31665$reactive-lib.cm $(SML_LIB)/smlnj-lib/Reactive\r
31666$regexp-lib.cm $(SML_LIB)/smlnj-lib/RegExp\r
31667$sexp-lib.cm $(SML_LIB)/smlnj-lib/SExp\r
31668$unix-lib.cm $(SML_LIB)/smlnj-lib/Unix\r
31669$xml-lib.cm $(SML_LIB)/smlnj-lib/XML</screen>\r
31670<simpara>This will automatically convert a <literal>$/smlnj-lib.cm</literal> import in an input\r
31671<literal>.cm</literal> file into a <literal>$(SML_LIB)/smlnj-lib/Util/smlnj-lib.mlb</literal> import in\r
31672the output <literal>.mlb</literal> file.</simpara>\r
31673</listitem>\r
31674</itemizedlist>\r
31675</section>\r
31676<section id="_details_4">\r
31677<title>Details</title>\r
31678<simpara>The following changes were made to the SML/NJ Library, in addition to\r
31679deriving the <literal>.mlb</literal> files from the <literal>.cm</literal> files:</simpara>\r
31680<itemizedlist>\r
31681<listitem>\r
31682<simpara>\r
31683<literal>HTML4/pp-init.sml</literal> (added): Implements <literal>structure PrettyPrint</literal> using the SML/NJ PP Library. This implementation is taken from the SML/NJ compiler source, since the SML/NJ HTML4 Library used the <literal>structure PrettyPrint</literal> provided by the SML/NJ compiler itself.\r
31684</simpara>\r
31685</listitem>\r
31686<listitem>\r
31687<simpara>\r
31688<literal>Util/base64.sml</literal> (modified): Rewrote use of <literal>Unsafe.CharVector.create</literal> and <literal>Unsafe.CharVector.update</literal>; MLton assumes that vectors are immutable.\r
31689</simpara>\r
31690</listitem>\r
31691<listitem>\r
31692<simpara>\r
31693<literal>Util/engine.mlton.sml</literal> (added, not exported): Implements <literal>structure Engine</literal>, providing time-limited, resumable computations using <link linkend="MLtonThread">MLtonThread</link>, <link linkend="MLtonSignal">MLtonSignal</link>, and <link linkend="MLtonItimer">MLtonItimer</link>.\r
31694</simpara>\r
31695</listitem>\r
31696<listitem>\r
31697<simpara>\r
31698<literal>Util/graph-scc-fn.sml</literal> (modified): Rewrote use of <literal>where</literal> structure specification.\r
31699</simpara>\r
31700</listitem>\r
31701<listitem>\r
31702<simpara>\r
31703<literal>Util/redblack-map-fn.sml</literal> (modified): Rewrote use of <literal>where</literal> structure specification.\r
31704</simpara>\r
31705</listitem>\r
31706<listitem>\r
31707<simpara>\r
31708<literal>Util/redblack-set-fn.sml</literal> (modified): Rewrote use of <literal>where</literal> structure specification.\r
31709</simpara>\r
31710</listitem>\r
31711<listitem>\r
31712<simpara>\r
31713<literal>Util/time-limit.mlb</literal> (added): Exports <literal>structure TimeLimit</literal>, which is <emphasis>not</emphasis> exported by <literal>smlnj-lib.mlb</literal>. Since MLton is very conservative in the presence of threads and signals, program performance may be adversely affected by unnecessarily including <literal>structure TimeLimit</literal>.\r
31714</simpara>\r
31715</listitem>\r
31716<listitem>\r
31717<simpara>\r
31718<literal>Util/time-limit.mlton.sml</literal> (added): Implements <literal>structure TimeLimit</literal> using <literal>structure Engine</literal>. The SML/NJ implementation of <literal>structure TimeLimit</literal> uses SML/NJ&#8217;s first-class continuations, signals, and interval timer.\r
31719</simpara>\r
31720</listitem>\r
31721</itemizedlist>\r
31722</section>\r
31723<section id="_patch_4">\r
31724<title>Patch</title>\r
31725<itemizedlist>\r
31726<listitem>\r
31727<simpara>\r
31728<ulink url="https://github.com/MLton/mlton/blob/master/lib/smlnj-lib/smlnj-lib.patch"><literal>smlnj-lib.patch</literal></ulink>\r
31729</simpara>\r
31730</listitem>\r
31731</itemizedlist>\r
31732<simpara><?asciidoc-pagebreak?></simpara>\r
31733</section>\r
31734</section>\r
31735<section id="SMLofNJStructure">\r
31736<title>SMLofNJStructure</title>\r
31737<programlisting language="sml" linenumbering="unnumbered">signature SML_OF_NJ =\r
31738 sig\r
31739 structure Cont:\r
31740 sig\r
31741 type 'a cont\r
31742 val callcc: ('a cont -&gt; 'a) -&gt; 'a\r
31743 val isolate: ('a -&gt; unit) -&gt; 'a cont\r
31744 val throw: 'a cont -&gt; 'a -&gt; 'b\r
31745 end\r
31746 structure SysInfo:\r
31747 sig\r
31748 exception UNKNOWN\r
31749 datatype os_kind = BEOS | MACOS | OS2 | UNIX | WIN32\r
31750\r
31751 val getHostArch: unit -&gt; string\r
31752 val getOSKind: unit -&gt; os_kind\r
31753 val getOSName: unit -&gt; string\r
31754 end\r
31755\r
31756 val exnHistory: exn -&gt; string list\r
31757 val exportFn: string * (string * string list -&gt; OS.Process.status) -&gt; unit\r
31758 val exportML: string -&gt; bool\r
31759 val getAllArgs: unit -&gt; string list\r
31760 val getArgs: unit -&gt; string list\r
31761 val getCmdName: unit -&gt; string\r
31762 end</programlisting>\r
31763<simpara><literal>SMLofNJ</literal> implements a subset of the structure of the same name\r
31764provided in <link linkend="SMLNJ">Standard ML of New Jersey</link>. It is included to\r
31765make it easier to port programs between the two systems. The\r
31766semantics of these functions may be different than in SML/NJ.</simpara>\r
31767<itemizedlist>\r
31768<listitem>\r
31769<simpara>\r
31770<literal>structure Cont</literal>\r
31771</simpara>\r
31772<simpara>implements continuations.</simpara>\r
31773</listitem>\r
31774<listitem>\r
31775<simpara>\r
31776<literal>SysInfo.getHostArch ()</literal>\r
31777</simpara>\r
31778<simpara>returns the string for the architecture.</simpara>\r
31779</listitem>\r
31780<listitem>\r
31781<simpara>\r
31782<literal>SysInfo.getOSKind</literal>\r
31783</simpara>\r
31784<simpara>returns the OS kind.</simpara>\r
31785</listitem>\r
31786<listitem>\r
31787<simpara>\r
31788<literal>SysInfo.getOSName ()</literal>\r
31789</simpara>\r
31790<simpara>returns the string for the host.</simpara>\r
31791</listitem>\r
31792<listitem>\r
31793<simpara>\r
31794<literal>exnHistory</literal>\r
31795</simpara>\r
31796<simpara>the same as <literal>MLton.Exn.history</literal>.</simpara>\r
31797</listitem>\r
31798<listitem>\r
31799<simpara>\r
31800<literal>getCmdName ()</literal>\r
31801</simpara>\r
31802<simpara>the same as <literal>CommandLine.name ()</literal>.</simpara>\r
31803</listitem>\r
31804<listitem>\r
31805<simpara>\r
31806<literal>getArgs ()</literal>\r
31807</simpara>\r
31808<simpara>the same as <literal>CommandLine.arguments ()</literal>.</simpara>\r
31809</listitem>\r
31810<listitem>\r
31811<simpara>\r
31812<literal>getAllArgs ()</literal>\r
31813</simpara>\r
31814<simpara>the same as <literal>getCmdName()::getArgs()</literal>.</simpara>\r
31815</listitem>\r
31816<listitem>\r
31817<simpara>\r
31818<literal>exportFn f</literal>\r
31819</simpara>\r
31820<simpara>saves the state of the computation to a file that will apply <literal>f</literal> to\r
31821the command-line arguments upon restart.</simpara>\r
31822</listitem>\r
31823<listitem>\r
31824<simpara>\r
31825<literal>exportML f</literal>\r
31826</simpara>\r
31827<simpara>saves the state of the computation to file <literal>f</literal> and continue. Returns\r
31828<literal>true</literal> in the restarted computation and <literal>false</literal> in the continuing\r
31829computation.</simpara>\r
31830</listitem>\r
31831</itemizedlist>\r
31832<simpara><?asciidoc-pagebreak?></simpara>\r
31833</section>\r
31834<section id="SMLSharp">\r
31835<title>SMLSharp</title>\r
31836<simpara><ulink url="http://www.pllab.riec.tohoku.ac.jp/smlsharp/">SML#</ulink> is an\r
31837<link linkend="StandardMLImplementations">implementation</link> of an extension of SML.</simpara>\r
31838<simpara>It includes some\r
31839<ulink url="http://www.pllab.riec.tohoku.ac.jp/smlsharp/?Tools">generally useful SML tools</ulink>\r
31840including a pretty printer generator, a document generator, and a\r
31841regression testing framework, and\r
31842<ulink url="http://www.pllab.riec.tohoku.ac.jp/smlsharp/?Library%2FScripting">scripting library</ulink>.</simpara>\r
31843<simpara><?asciidoc-pagebreak?></simpara>\r
31844</section>\r
31845<section id="Sources">\r
31846<title>Sources</title>\r
31847<simpara>We maintain our sources with <link linkend="Git">Git</link>. You can\r
31848<ulink url="https://github.com/MLton/mlton/">view them on the web</ulink> or access\r
31849them with a git client.</simpara>\r
31850<simpara>Anonymous read-only access is available via</simpara>\r
31851<screen>https://github.com/MLton/mlton.git</screen>\r
31852<simpara>or</simpara>\r
31853<screen>git://github.com/MLton/mlton.git</screen>\r
31854<section id="_commit_email">\r
31855<title>Commit email</title>\r
31856<simpara>All commits are sent to\r
31857<ulink url="mailto:MLton-commit@mlton.org"><literal>MLton-commit@mlton.org</literal></ulink>\r
31858(<ulink url="https://lists.sourceforge.net/lists/listinfo/mlton-commit">subscribe</ulink>,\r
31859<ulink url="https://sourceforge.net/mailarchive/forum.php?forum_name=mlton-commit">archive</ulink>,\r
31860<ulink url="http://www.mlton.org/pipermail/mlton-commit/">archive</ulink>) which is a\r
31861read-only mailing list for commit emails. Discussion should go to\r
31862<ulink url="mailto:MLton-devel@mlton.org"><literal>MLton-devel@mlton.org</literal></ulink>.</simpara>\r
31863</section>\r
31864<section id="_changelog">\r
31865<title>Changelog</title>\r
31866<simpara>See <ulink url="https://github.com/MLton/mlton/blob/master/CHANGELOG.adoc"><literal>CHANGELOG.adoc</literal></ulink> for a list of\r
31867changes and bug fixes.</simpara>\r
31868</section>\r
31869<section id="_subversion">\r
31870<title>Subversion</title>\r
31871<simpara>Prior to 20130308, we used <link linkend="Subversion">Subversion</link>.</simpara>\r
31872</section>\r
31873<section id="_cvs">\r
31874<title>CVS</title>\r
31875<simpara>Prior to 20050730, we used <link linkend="CVS">CVS</link>.</simpara>\r
31876<simpara><?asciidoc-pagebreak?></simpara>\r
31877</section>\r
31878</section>\r
31879<section id="SpaceSafety">\r
31880<title>SpaceSafety</title>\r
31881<simpara>Informally, space safety is a property of a language implementation\r
31882that asymptotically bounds the space used by a running program.</simpara>\r
31883<section id="_also_see_44">\r
31884<title>Also see</title>\r
31885<itemizedlist>\r
31886<listitem>\r
31887<simpara>\r
31888Chapter 12 of <link linkend="References_Appel92">Appel92</link>\r
31889</simpara>\r
31890</listitem>\r
31891<listitem>\r
31892<simpara>\r
31893<link linkend="References_Clinger98">Clinger98</link>\r
31894</simpara>\r
31895</listitem>\r
31896</itemizedlist>\r
31897<simpara><?asciidoc-pagebreak?></simpara>\r
31898</section>\r
31899</section>\r
31900<section id="SSA">\r
31901<title>SSA</title>\r
31902<simpara><link linkend="SSA">SSA</link> is an <link linkend="IntermediateLanguage">IntermediateLanguage</link>, translated from <link linkend="SXML">SXML</link> by\r
31903<link linkend="ClosureConvert">ClosureConvert</link>, optimized by <link linkend="SSASimplify">SSASimplify</link>, and translated by\r
31904<link linkend="ToSSA2">ToSSA2</link> to <link linkend="SSA2">SSA2</link>.</simpara>\r
31905<section id="_description_57">\r
31906<title>Description</title>\r
31907<simpara><link linkend="SSA">SSA</link> is a <link linkend="FirstOrder">FirstOrder</link>, <link linkend="SimplyTyped">SimplyTyped</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link>.\r
31908It is the main <link linkend="IntermediateLanguage">IntermediateLanguage</link> used for optimizations.</simpara>\r
31909<simpara>An <link linkend="SSA">SSA</link> program consists of a collection of datatype declarations,\r
31910a sequence of global statements, and a collection of functions, along\r
31911with a distinguished "main" function. Each function consists of a\r
31912collection of basic blocks, where each basic block is a sequence of\r
31913statements ending with some control transfer.</simpara>\r
31914</section>\r
31915<section id="_implementation_62">\r
31916<title>Implementation</title>\r
31917<itemizedlist>\r
31918<listitem>\r
31919<simpara>\r
31920<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/ssa.sig"><literal>ssa.sig</literal></ulink>\r
31921</simpara>\r
31922</listitem>\r
31923<listitem>\r
31924<simpara>\r
31925<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/ssa.fun"><literal>ssa.fun</literal></ulink>\r
31926</simpara>\r
31927</listitem>\r
31928<listitem>\r
31929<simpara>\r
31930<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/ssa-tree.sig"><literal>ssa-tree.sig</literal></ulink>\r
31931</simpara>\r
31932</listitem>\r
31933<listitem>\r
31934<simpara>\r
31935<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/ssa-tree.fun"><literal>ssa-tree.fun</literal></ulink>\r
31936</simpara>\r
31937</listitem>\r
31938</itemizedlist>\r
31939</section>\r
31940<section id="_type_checking_5">\r
31941<title>Type Checking</title>\r
31942<simpara>Type checking (<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/type-check.sig"><literal>type-check.sig</literal></ulink>,\r
31943<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/type-check.fun"><literal>type-check.fun</literal></ulink>) of a <link linkend="SSA">SSA</link> program\r
31944verifies the following:</simpara>\r
31945<itemizedlist>\r
31946<listitem>\r
31947<simpara>\r
31948no duplicate definitions (tycons, cons, vars, labels, funcs)\r
31949</simpara>\r
31950</listitem>\r
31951<listitem>\r
31952<simpara>\r
31953no out of scope references (tycons, cons, vars, labels, funcs)\r
31954</simpara>\r
31955</listitem>\r
31956<listitem>\r
31957<simpara>\r
31958variable definitions dominate variable uses\r
31959</simpara>\r
31960</listitem>\r
31961<listitem>\r
31962<simpara>\r
31963case transfers are exhaustive and irredundant\r
31964</simpara>\r
31965</listitem>\r
31966<listitem>\r
31967<simpara>\r
31968<literal>Enter</literal>/<literal>Leave</literal> profile statements match\r
31969</simpara>\r
31970</listitem>\r
31971<listitem>\r
31972<simpara>\r
31973"traditional" well-typedness\r
31974</simpara>\r
31975</listitem>\r
31976</itemizedlist>\r
31977</section>\r
31978<section id="_details_and_notes_60">\r
31979<title>Details and Notes</title>\r
31980<simpara>SSA is an abbreviation for Static Single Assignment.</simpara>\r
31981<simpara>For some initial design discussion, see the thread at:</simpara>\r
31982<itemizedlist>\r
31983<listitem>\r
31984<simpara>\r
31985<ulink url="http://mlton.org/pipermail/mlton/2001-August/019689.html">http://mlton.org/pipermail/mlton/2001-August/019689.html</ulink>\r
31986</simpara>\r
31987</listitem>\r
31988</itemizedlist>\r
31989<simpara>For some retrospectives, see the threads at:</simpara>\r
31990<itemizedlist>\r
31991<listitem>\r
31992<simpara>\r
31993<ulink url="http://mlton.org/pipermail/mlton/2003-January/023054.html">http://mlton.org/pipermail/mlton/2003-January/023054.html</ulink>\r
31994</simpara>\r
31995</listitem>\r
31996<listitem>\r
31997<simpara>\r
31998<ulink url="http://mlton.org/pipermail/mlton/2007-February/029597.html">http://mlton.org/pipermail/mlton/2007-February/029597.html</ulink>\r
31999</simpara>\r
32000</listitem>\r
32001</itemizedlist>\r
32002<simpara><?asciidoc-pagebreak?></simpara>\r
32003</section>\r
32004</section>\r
32005<section id="SSA2">\r
32006<title>SSA2</title>\r
32007<simpara><link linkend="SSA2">SSA2</link> is an <link linkend="IntermediateLanguage">IntermediateLanguage</link>, translated from <link linkend="SSA">SSA</link> by\r
32008<link linkend="ToSSA2">ToSSA2</link>, optimized by <link linkend="SSA2Simplify">SSA2Simplify</link>, and translated by\r
32009<link linkend="ToRSSA">ToRSSA</link> to <link linkend="RSSA">RSSA</link>.</simpara>\r
32010<section id="_description_58">\r
32011<title>Description</title>\r
32012<simpara><link linkend="SSA2">SSA2</link> is a <link linkend="FirstOrder">FirstOrder</link>, <link linkend="SimplyTyped">SimplyTyped</link>\r
32013<link linkend="IntermediateLanguage">IntermediateLanguage</link>, a slight variant of the <link linkend="SSA">SSA</link>\r
32014<link linkend="IntermediateLanguage">IntermediateLanguage</link>,</simpara>\r
32015<simpara>Like <link linkend="SSA">SSA</link>, an <link linkend="SSA2">SSA2</link> program consists of a collection of datatype\r
32016declarations, a sequence of global statements, and a collection of\r
32017functions, along with a distinguished "main" function. Each function\r
32018consists of a collection of basic blocks, where each basic block is a\r
32019sequence of statements ending with some control transfer.</simpara>\r
32020<simpara>Unlike <link linkend="SSA">SSA</link>, <link linkend="SSA2">SSA2</link> includes mutable fields in objects and makes\r
32021the vector type constructor n-ary instead of unary. This allows\r
32022optimizations like <link linkend="RefFlatten">RefFlatten</link> and <link linkend="DeepFlatten">DeepFlatten</link> to be expressed.</simpara>\r
32023</section>\r
32024<section id="_implementation_63">\r
32025<title>Implementation</title>\r
32026<itemizedlist>\r
32027<listitem>\r
32028<simpara>\r
32029<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/ssa2.sig"><literal>ssa2.sig</literal></ulink>\r
32030</simpara>\r
32031</listitem>\r
32032<listitem>\r
32033<simpara>\r
32034<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/ssa2.fun"><literal>ssa2.fun</literal></ulink>\r
32035</simpara>\r
32036</listitem>\r
32037<listitem>\r
32038<simpara>\r
32039<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/ssa-tree2.sig"><literal>ssa-tree2.sig</literal></ulink>\r
32040</simpara>\r
32041</listitem>\r
32042<listitem>\r
32043<simpara>\r
32044<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/ssa-tree2.fun"><literal>ssa-tree2.fun</literal></ulink>\r
32045</simpara>\r
32046</listitem>\r
32047</itemizedlist>\r
32048</section>\r
32049<section id="_type_checking_6">\r
32050<title>Type Checking</title>\r
32051<simpara>Type checking (<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/type-check2.sig"><literal>type-check2.sig</literal></ulink>,\r
32052<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/type-check2.fun"><literal>type-check2.fun</literal></ulink>) of a <link linkend="SSA2">SSA2</link>\r
32053program verifies the following:</simpara>\r
32054<itemizedlist>\r
32055<listitem>\r
32056<simpara>\r
32057no duplicate definitions (tycons, cons, vars, labels, funcs)\r
32058</simpara>\r
32059</listitem>\r
32060<listitem>\r
32061<simpara>\r
32062no out of scope references (tycons, cons, vars, labels, funcs)\r
32063</simpara>\r
32064</listitem>\r
32065<listitem>\r
32066<simpara>\r
32067variable definitions dominate variable uses\r
32068</simpara>\r
32069</listitem>\r
32070<listitem>\r
32071<simpara>\r
32072case transfers are exhaustive and irredundant\r
32073</simpara>\r
32074</listitem>\r
32075<listitem>\r
32076<simpara>\r
32077<literal>Enter</literal>/<literal>Leave</literal> profile statements match\r
32078</simpara>\r
32079</listitem>\r
32080<listitem>\r
32081<simpara>\r
32082"traditional" well-typedness\r
32083</simpara>\r
32084</listitem>\r
32085</itemizedlist>\r
32086</section>\r
32087<section id="_details_and_notes_61">\r
32088<title>Details and Notes</title>\r
32089<simpara>SSA is an abbreviation for Static Single Assignment.</simpara>\r
32090<simpara><?asciidoc-pagebreak?></simpara>\r
32091</section>\r
32092</section>\r
32093<section id="SSA2Simplify">\r
32094<title>SSA2Simplify</title>\r
32095<simpara>The optimization passes for the <link linkend="SSA2">SSA2</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link> are\r
32096collected and controlled by the <literal>Simplify2</literal> functor\r
32097(<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/simplify2.sig"><literal>simplify2.sig</literal></ulink>,\r
32098<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/simplify2.fun"><literal>simplify2.fun</literal></ulink>).</simpara>\r
32099<simpara>The following optimization passes are implemented:</simpara>\r
32100<itemizedlist>\r
32101<listitem>\r
32102<simpara>\r
32103<link linkend="DeepFlatten">DeepFlatten</link>\r
32104</simpara>\r
32105</listitem>\r
32106<listitem>\r
32107<simpara>\r
32108<link linkend="RefFlatten">RefFlatten</link>\r
32109</simpara>\r
32110</listitem>\r
32111<listitem>\r
32112<simpara>\r
32113<link linkend="RemoveUnused">RemoveUnused</link>\r
32114</simpara>\r
32115</listitem>\r
32116<listitem>\r
32117<simpara>\r
32118<link linkend="Zone">Zone</link>\r
32119</simpara>\r
32120</listitem>\r
32121</itemizedlist>\r
32122<simpara>There are additional analysis and rewrite passes that augment many of the other optimization passes:</simpara>\r
32123<itemizedlist>\r
32124<listitem>\r
32125<simpara>\r
32126<link linkend="Restore">Restore</link>\r
32127</simpara>\r
32128</listitem>\r
32129<listitem>\r
32130<simpara>\r
32131<link linkend="Shrink">Shrink</link>\r
32132</simpara>\r
32133</listitem>\r
32134</itemizedlist>\r
32135<simpara>The optimization passes can be controlled from the command-line by the options</simpara>\r
32136<itemizedlist>\r
32137<listitem>\r
32138<simpara>\r
32139<literal>-diag-pass &lt;pass&gt;</literal>&#8201;&#8212;&#8201;keep diagnostic info for pass\r
32140</simpara>\r
32141</listitem>\r
32142<listitem>\r
32143<simpara>\r
32144<literal>-disable-pass &lt;pass&gt;</literal>&#8201;&#8212;&#8201;skip optimization pass (if normally performed)\r
32145</simpara>\r
32146</listitem>\r
32147<listitem>\r
32148<simpara>\r
32149<literal>-enable-pass &lt;pass&gt;</literal>&#8201;&#8212;&#8201;perform optimization pass (if normally skipped)\r
32150</simpara>\r
32151</listitem>\r
32152<listitem>\r
32153<simpara>\r
32154<literal>-keep-pass &lt;pass&gt;</literal>&#8201;&#8212;&#8201;keep the results of pass\r
32155</simpara>\r
32156</listitem>\r
32157<listitem>\r
32158<simpara>\r
32159<literal>-loop-passes &lt;n&gt;</literal>&#8201;&#8212;&#8201;loop optimization passes\r
32160</simpara>\r
32161</listitem>\r
32162<listitem>\r
32163<simpara>\r
32164<literal>-ssa2-passes &lt;passes&gt;</literal>&#8201;&#8212;&#8201;ssa optimization passes\r
32165</simpara>\r
32166</listitem>\r
32167</itemizedlist>\r
32168<simpara><?asciidoc-pagebreak?></simpara>\r
32169</section>\r
32170<section id="SSASimplify">\r
32171<title>SSASimplify</title>\r
32172<simpara>The optimization passes for the <link linkend="SSA">SSA</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link> are\r
32173collected and controlled by the <literal>Simplify</literal> functor\r
32174(<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/simplify.sig"><literal>simplify.sig</literal></ulink>,\r
32175<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/simplify.fun"><literal>simplify.fun</literal></ulink>).</simpara>\r
32176<simpara>The following optimization passes are implemented:</simpara>\r
32177<itemizedlist>\r
32178<listitem>\r
32179<simpara>\r
32180<link linkend="CombineConversions">CombineConversions</link>\r
32181</simpara>\r
32182</listitem>\r
32183<listitem>\r
32184<simpara>\r
32185<link linkend="CommonArg">CommonArg</link>\r
32186</simpara>\r
32187</listitem>\r
32188<listitem>\r
32189<simpara>\r
32190<link linkend="CommonBlock">CommonBlock</link>\r
32191</simpara>\r
32192</listitem>\r
32193<listitem>\r
32194<simpara>\r
32195<link linkend="CommonSubexp">CommonSubexp</link>\r
32196</simpara>\r
32197</listitem>\r
32198<listitem>\r
32199<simpara>\r
32200<link linkend="ConstantPropagation">ConstantPropagation</link>\r
32201</simpara>\r
32202</listitem>\r
32203<listitem>\r
32204<simpara>\r
32205<link linkend="Contify">Contify</link>\r
32206</simpara>\r
32207</listitem>\r
32208<listitem>\r
32209<simpara>\r
32210<link linkend="Flatten">Flatten</link>\r
32211</simpara>\r
32212</listitem>\r
32213<listitem>\r
32214<simpara>\r
32215<link linkend="Inline">Inline</link>\r
32216</simpara>\r
32217</listitem>\r
32218<listitem>\r
32219<simpara>\r
32220<link linkend="IntroduceLoops">IntroduceLoops</link>\r
32221</simpara>\r
32222</listitem>\r
32223<listitem>\r
32224<simpara>\r
32225<link linkend="KnownCase">KnownCase</link>\r
32226</simpara>\r
32227</listitem>\r
32228<listitem>\r
32229<simpara>\r
32230<link linkend="LocalFlatten">LocalFlatten</link>\r
32231</simpara>\r
32232</listitem>\r
32233<listitem>\r
32234<simpara>\r
32235<link linkend="LocalRef">LocalRef</link>\r
32236</simpara>\r
32237</listitem>\r
32238<listitem>\r
32239<simpara>\r
32240<link linkend="LoopInvariant">LoopInvariant</link>\r
32241</simpara>\r
32242</listitem>\r
32243<listitem>\r
32244<simpara>\r
32245<link linkend="LoopUnfoll">LoopUnfoll</link>\r
32246</simpara>\r
32247</listitem>\r
32248<listitem>\r
32249<simpara>\r
32250<link linkend="LoopUnswitch">LoopUnswitch</link>\r
32251</simpara>\r
32252</listitem>\r
32253<listitem>\r
32254<simpara>\r
32255<link linkend="Redundant">Redundant</link>\r
32256</simpara>\r
32257</listitem>\r
32258<listitem>\r
32259<simpara>\r
32260<link linkend="RedundantTests">RedundantTests</link>\r
32261</simpara>\r
32262</listitem>\r
32263<listitem>\r
32264<simpara>\r
32265<link linkend="RemoveUnused">RemoveUnused</link>\r
32266</simpara>\r
32267</listitem>\r
32268<listitem>\r
32269<simpara>\r
32270<link linkend="ShareZeroVec">ShareZeroVec</link>\r
32271</simpara>\r
32272</listitem>\r
32273<listitem>\r
32274<simpara>\r
32275<link linkend="SimplifyTypes">SimplifyTypes</link>\r
32276</simpara>\r
32277</listitem>\r
32278<listitem>\r
32279<simpara>\r
32280<link linkend="Useless">Useless</link>\r
32281</simpara>\r
32282</listitem>\r
32283</itemizedlist>\r
32284<simpara>The following implementation passes are implemented:</simpara>\r
32285<itemizedlist>\r
32286<listitem>\r
32287<simpara>\r
32288<link linkend="PolyEqual">PolyEqual</link>\r
32289</simpara>\r
32290</listitem>\r
32291<listitem>\r
32292<simpara>\r
32293<link linkend="PolyHash">PolyHash</link>\r
32294</simpara>\r
32295</listitem>\r
32296</itemizedlist>\r
32297<simpara>There are additional analysis and rewrite passes that augment many of the other optimization passes:</simpara>\r
32298<itemizedlist>\r
32299<listitem>\r
32300<simpara>\r
32301<link linkend="Multi">Multi</link>\r
32302</simpara>\r
32303</listitem>\r
32304<listitem>\r
32305<simpara>\r
32306<link linkend="Restore">Restore</link>\r
32307</simpara>\r
32308</listitem>\r
32309<listitem>\r
32310<simpara>\r
32311<link linkend="Shrink">Shrink</link>\r
32312</simpara>\r
32313</listitem>\r
32314</itemizedlist>\r
32315<simpara>The optimization passes can be controlled from the command-line by the options:</simpara>\r
32316<itemizedlist>\r
32317<listitem>\r
32318<simpara>\r
32319<literal>-diag-pass &lt;pass&gt;</literal>&#8201;&#8212;&#8201;keep diagnostic info for pass\r
32320</simpara>\r
32321</listitem>\r
32322<listitem>\r
32323<simpara>\r
32324<literal>-disable-pass &lt;pass&gt;</literal>&#8201;&#8212;&#8201;skip optimization pass (if normally performed)\r
32325</simpara>\r
32326</listitem>\r
32327<listitem>\r
32328<simpara>\r
32329<literal>-enable-pass &lt;pass&gt;</literal>&#8201;&#8212;&#8201;perform optimization pass (if normally skipped)\r
32330</simpara>\r
32331</listitem>\r
32332<listitem>\r
32333<simpara>\r
32334<literal>-keep-pass &lt;pass&gt;</literal>&#8201;&#8212;&#8201;keep the results of pass\r
32335</simpara>\r
32336</listitem>\r
32337<listitem>\r
32338<simpara>\r
32339<literal>-loop-passes &lt;n&gt;</literal>&#8201;&#8212;&#8201;loop optimization passes\r
32340</simpara>\r
32341</listitem>\r
32342<listitem>\r
32343<simpara>\r
32344<literal>-ssa-passes &lt;passes&gt;</literal>&#8201;&#8212;&#8201;ssa optimization passes\r
32345</simpara>\r
32346</listitem>\r
32347</itemizedlist>\r
32348<simpara><?asciidoc-pagebreak?></simpara>\r
32349</section>\r
32350<section id="Stabilizers">\r
32351<title>Stabilizers</title>\r
32352<section id="_installation">\r
32353<title>Installation</title>\r
32354<itemizedlist>\r
32355<listitem>\r
32356<simpara>\r
32357Stabilizers currently require the MLton sources, this should be fixed by the next release\r
32358</simpara>\r
32359</listitem>\r
32360</itemizedlist>\r
32361</section>\r
32362<section id="_license">\r
32363<title>License</title>\r
32364<itemizedlist>\r
32365<listitem>\r
32366<simpara>\r
32367Stabilizers are released under the MLton License\r
32368</simpara>\r
32369</listitem>\r
32370</itemizedlist>\r
32371</section>\r
32372<section id="_instructions">\r
32373<title>Instructions</title>\r
32374<itemizedlist>\r
32375<listitem>\r
32376<simpara>\r
32377Download and build a source copy of MLton\r
32378</simpara>\r
32379</listitem>\r
32380<listitem>\r
32381<simpara>\r
32382Extract the tar.gz file attached to this page\r
32383</simpara>\r
32384</listitem>\r
32385<listitem>\r
32386<simpara>\r
32387Some examples are provided in the "examples/" sub directory, more examples will be added to this page in the following week\r
32388</simpara>\r
32389</listitem>\r
32390</itemizedlist>\r
32391</section>\r
32392<section id="_bug_reports_suggestions">\r
32393<title>Bug reports / Suggestions</title>\r
32394<itemizedlist>\r
32395<listitem>\r
32396<simpara>\r
32397Please send any errors you encounter to schatzp and lziarek at cs.purdue.edu\r
32398</simpara>\r
32399</listitem>\r
32400<listitem>\r
32401<simpara>\r
32402We are looking to expand the usability of stabilizers\r
32403</simpara>\r
32404</listitem>\r
32405<listitem>\r
32406<simpara>\r
32407Please send any suggestions and desired functionality to the above email addresses\r
32408</simpara>\r
32409</listitem>\r
32410</itemizedlist>\r
32411</section>\r
32412<section id="_note">\r
32413<title>Note</title>\r
32414<itemizedlist>\r
32415<listitem>\r
32416<simpara>\r
32417This is an alpha release. We expect to have another release shortly with added functionality soon\r
32418</simpara>\r
32419</listitem>\r
32420<listitem>\r
32421<simpara>\r
32422More documentation, such as signatures and descriptions of functionality, will be forthcoming\r
32423</simpara>\r
32424</listitem>\r
32425</itemizedlist>\r
32426</section>\r
32427<section id="_documentation">\r
32428<title>Documentation</title>\r
32429<programlisting language="sml" linenumbering="unnumbered">signature STABLE =\r
32430 sig\r
32431 type checkpoint\r
32432\r
32433 val stable: ('a -&gt; 'b) -&gt; ('a -&gt; 'b)\r
32434 val stabilize: unit -&gt; 'a\r
32435\r
32436 val stableCP: (('a -&gt; 'b) * (unit -&gt; unit)) -&gt;\r
32437 (('a -&gt; 'b) * checkpoint)\r
32438 val stabilizeCP: checkpoint -&gt; unit\r
32439\r
32440 val unmonitoredAssign: ('a ref * 'a) -&gt; unit\r
32441 val monitoredAssign: ('a ref * 'a) -&gt; unit\r
32442 end</programlisting>\r
32443<simpara><literal>Stable</literal> provides functions to manage stable sections.</simpara>\r
32444<itemizedlist>\r
32445<listitem>\r
32446<simpara>\r
32447<literal>type checkpoint</literal>\r
32448</simpara>\r
32449<simpara>handle used to stabilize contexts other than the current one.</simpara>\r
32450</listitem>\r
32451<listitem>\r
32452<simpara>\r
32453<literal>stable f</literal>\r
32454</simpara>\r
32455<simpara>returns a function identical to <literal>f</literal> that will execute within a stable section.</simpara>\r
32456</listitem>\r
32457<listitem>\r
32458<simpara>\r
32459<literal>stabilize ()</literal>\r
32460</simpara>\r
32461<simpara>unrolls the effects made up to the current context to at least the\r
32462nearest enclosing <emphasis>stable</emphasis> section. These effects may have propagated\r
32463to other threads, so all affected threads are returned to a globally\r
32464consistent previous state. The return is undefined because control\r
32465cannot resume after stabilize is called.</simpara>\r
32466</listitem>\r
32467<listitem>\r
32468<simpara>\r
32469<literal>stableCP (f, comp)</literal>\r
32470</simpara>\r
32471<simpara>returns a function <literal>f'</literal> and checkpoint tag <literal>cp</literal>. Function <literal>f'</literal> is\r
32472identical to <literal>f</literal> but when applied will execute within a stable\r
32473section. <literal>comp</literal> will be executed if <literal>f'</literal> is later stabilized. <literal>cp</literal>\r
32474is used by <literal>stabilizeCP</literal> to stabilize a given checkpoint.</simpara>\r
32475</listitem>\r
32476<listitem>\r
32477<simpara>\r
32478<literal>stabilizeCP cp</literal>\r
32479</simpara>\r
32480<simpara>same as stabilize except that the (possibly current) checkpoint to\r
32481stabilize is provided.</simpara>\r
32482</listitem>\r
32483<listitem>\r
32484<simpara>\r
32485<literal>unmonitoredAssign (r, v)</literal>\r
32486</simpara>\r
32487<simpara>standard assignment (<literal>:=</literal>). The version of CML distributed rebinds\r
32488<literal>:=</literal> to a monitored version so interesting effects can be recorded.</simpara>\r
32489</listitem>\r
32490<listitem>\r
32491<simpara>\r
32492<literal>monitoredAssign (r, v)</literal>\r
32493</simpara>\r
32494<simpara>the assignment operator that should be used in programs that use\r
32495stabilizers. <literal>:=</literal> is rebound to this by including CML.</simpara>\r
32496</listitem>\r
32497</itemizedlist>\r
32498</section>\r
32499<section id="_download_7">\r
32500<title>Download</title>\r
32501<itemizedlist>\r
32502<listitem>\r
32503<simpara>\r
32504<ulink url="guide/Stabilizers.attachments/stabilizers_alpha_2006-10-09.tar.gz"><literal>stabilizers_alpha_2006-10-09.tar.gz</literal></ulink>\r
32505</simpara>\r
32506</listitem>\r
32507</itemizedlist>\r
32508</section>\r
32509<section id="_also_see_45">\r
32510<title>Also see</title>\r
32511<itemizedlist>\r
32512<listitem>\r
32513<simpara>\r
32514<link linkend="References_ZiarekEtAl06">ZiarekEtAl06</link>\r
32515</simpara>\r
32516</listitem>\r
32517</itemizedlist>\r
32518<simpara><?asciidoc-pagebreak?></simpara>\r
32519</section>\r
32520</section>\r
32521<section id="StandardML">\r
32522<title>StandardML</title>\r
32523<simpara>Standard ML (SML) is a programming language that combines excellent\r
32524support for rapid prototyping, modularity, and development of large\r
32525programs, with performance approaching that of C.</simpara>\r
32526<section id="_sml_resources">\r
32527<title>SML Resources</title>\r
32528<itemizedlist>\r
32529<listitem>\r
32530<simpara>\r
32531<link linkend="StandardMLTutorials">Tutorials</link>\r
32532</simpara>\r
32533</listitem>\r
32534<listitem>\r
32535<simpara>\r
32536<link linkend="StandardMLBooks">Books</link>\r
32537</simpara>\r
32538</listitem>\r
32539<listitem>\r
32540<simpara>\r
32541<link linkend="StandardMLImplementations">Implementations</link>\r
32542</simpara>\r
32543</listitem>\r
32544</itemizedlist>\r
32545</section>\r
32546<section id="_aspects_of_sml">\r
32547<title>Aspects of SML</title>\r
32548<itemizedlist>\r
32549<listitem>\r
32550<simpara>\r
32551<link linkend="DefineTypeBeforeUse">DefineTypeBeforeUse</link>\r
32552</simpara>\r
32553</listitem>\r
32554<listitem>\r
32555<simpara>\r
32556<link linkend="EqualityType">EqualityType</link>\r
32557</simpara>\r
32558</listitem>\r
32559<listitem>\r
32560<simpara>\r
32561<link linkend="EqualityTypeVariable">EqualityTypeVariable</link>\r
32562</simpara>\r
32563</listitem>\r
32564<listitem>\r
32565<simpara>\r
32566<link linkend="GenerativeDatatype">GenerativeDatatype</link>\r
32567</simpara>\r
32568</listitem>\r
32569<listitem>\r
32570<simpara>\r
32571<link linkend="GenerativeException">GenerativeException</link>\r
32572</simpara>\r
32573</listitem>\r
32574<listitem>\r
32575<simpara>\r
32576<link linkend="Identifier">Identifier</link>\r
32577</simpara>\r
32578</listitem>\r
32579<listitem>\r
32580<simpara>\r
32581<link linkend="OperatorPrecedence">OperatorPrecedence</link>\r
32582</simpara>\r
32583</listitem>\r
32584<listitem>\r
32585<simpara>\r
32586<link linkend="Overloading">Overloading</link>\r
32587</simpara>\r
32588</listitem>\r
32589<listitem>\r
32590<simpara>\r
32591<link linkend="PolymorphicEquality">PolymorphicEquality</link>\r
32592</simpara>\r
32593</listitem>\r
32594<listitem>\r
32595<simpara>\r
32596<link linkend="TypeVariableScope">TypeVariableScope</link>\r
32597</simpara>\r
32598</listitem>\r
32599<listitem>\r
32600<simpara>\r
32601<link linkend="ValueRestriction">ValueRestriction</link>\r
32602</simpara>\r
32603</listitem>\r
32604</itemizedlist>\r
32605</section>\r
32606<section id="_using_sml">\r
32607<title>Using SML</title>\r
32608<itemizedlist>\r
32609<listitem>\r
32610<simpara>\r
32611<link linkend="Fixpoints">Fixpoints</link>\r
32612</simpara>\r
32613</listitem>\r
32614<listitem>\r
32615<simpara>\r
32616<link linkend="ForLoops">ForLoops</link>\r
32617</simpara>\r
32618</listitem>\r
32619<listitem>\r
32620<simpara>\r
32621<link linkend="FunctionalRecordUpdate">FunctionalRecordUpdate</link>\r
32622</simpara>\r
32623</listitem>\r
32624<listitem>\r
32625<simpara>\r
32626<link linkend="InfixingOperators">InfixingOperators</link>\r
32627</simpara>\r
32628</listitem>\r
32629<listitem>\r
32630<simpara>\r
32631<link linkend="Lazy">Lazy</link>\r
32632</simpara>\r
32633</listitem>\r
32634<listitem>\r
32635<simpara>\r
32636<link linkend="ObjectOrientedProgramming">ObjectOrientedProgramming</link>\r
32637</simpara>\r
32638</listitem>\r
32639<listitem>\r
32640<simpara>\r
32641<link linkend="OptionalArguments">OptionalArguments</link>\r
32642</simpara>\r
32643</listitem>\r
32644<listitem>\r
32645<simpara>\r
32646<link linkend="Printf">Printf</link>\r
32647</simpara>\r
32648</listitem>\r
32649<listitem>\r
32650<simpara>\r
32651<link linkend="PropertyList">PropertyList</link>\r
32652</simpara>\r
32653</listitem>\r
32654<listitem>\r
32655<simpara>\r
32656<link linkend="ReturnStatement">ReturnStatement</link>\r
32657</simpara>\r
32658</listitem>\r
32659<listitem>\r
32660<simpara>\r
32661<link linkend="Serialization">Serialization</link>\r
32662</simpara>\r
32663</listitem>\r
32664<listitem>\r
32665<simpara>\r
32666<link linkend="StandardMLGotchas">StandardMLGotchas</link>\r
32667</simpara>\r
32668</listitem>\r
32669<listitem>\r
32670<simpara>\r
32671<link linkend="StyleGuide">StyleGuide</link>\r
32672</simpara>\r
32673</listitem>\r
32674<listitem>\r
32675<simpara>\r
32676<link linkend="TipsForWritingConciseSML">TipsForWritingConciseSML</link>\r
32677</simpara>\r
32678</listitem>\r
32679<listitem>\r
32680<simpara>\r
32681<link linkend="UniversalType">UniversalType</link>\r
32682</simpara>\r
32683</listitem>\r
32684</itemizedlist>\r
32685</section>\r
32686<section id="_programming_in_sml">\r
32687<title>Programming in SML</title>\r
32688<itemizedlist>\r
32689<listitem>\r
32690<simpara>\r
32691<link linkend="Emacs">Emacs</link>\r
32692</simpara>\r
32693</listitem>\r
32694<listitem>\r
32695<simpara>\r
32696<link linkend="Enscript">Enscript</link>\r
32697</simpara>\r
32698</listitem>\r
32699<listitem>\r
32700<simpara>\r
32701<link linkend="Pygments">Pygments</link>\r
32702</simpara>\r
32703</listitem>\r
32704</itemizedlist>\r
32705</section>\r
32706<section id="_notes_18">\r
32707<title>Notes</title>\r
32708<itemizedlist>\r
32709<listitem>\r
32710<simpara>\r
32711<link linkend="StandardMLHistory">History of SML</link>\r
32712</simpara>\r
32713</listitem>\r
32714<listitem>\r
32715<simpara>\r
32716<link linkend="Regions">Regions</link>\r
32717</simpara>\r
32718</listitem>\r
32719</itemizedlist>\r
32720</section>\r
32721<section id="_related_languages">\r
32722<title>Related Languages</title>\r
32723<itemizedlist>\r
32724<listitem>\r
32725<simpara>\r
32726<link linkend="Alice">Alice</link>\r
32727</simpara>\r
32728</listitem>\r
32729<listitem>\r
32730<simpara>\r
32731<link linkend="FSharp">F#</link>\r
32732</simpara>\r
32733</listitem>\r
32734<listitem>\r
32735<simpara>\r
32736<link linkend="OCaml">OCaml</link>\r
32737</simpara>\r
32738</listitem>\r
32739</itemizedlist>\r
32740<simpara><?asciidoc-pagebreak?></simpara>\r
32741</section>\r
32742</section>\r
32743<section id="StandardMLBooks">\r
32744<title>StandardMLBooks</title>\r
32745<section id="_introductory_books">\r
32746<title>Introductory Books</title>\r
32747<itemizedlist>\r
32748<listitem>\r
32749<simpara>\r
32750<link linkend="References_Ullman98">Elements of ML Programming</link>\r
32751</simpara>\r
32752</listitem>\r
32753<listitem>\r
32754<simpara>\r
32755<link linkend="References_Paulson96">ML For the Working Programmer</link>\r
32756</simpara>\r
32757</listitem>\r
32758<listitem>\r
32759<simpara>\r
32760<link linkend="References_HansenRichel99">Introduction to Programming using SML</link>\r
32761</simpara>\r
32762</listitem>\r
32763<listitem>\r
32764<simpara>\r
32765<link linkend="References_FelleisenFreidman98">The Little MLer</link>\r
32766</simpara>\r
32767</listitem>\r
32768</itemizedlist>\r
32769</section>\r
32770<section id="_applications_3">\r
32771<title>Applications</title>\r
32772<itemizedlist>\r
32773<listitem>\r
32774<simpara>\r
32775<link linkend="References_Shipman02">Unix System Programming with Standard ML</link>\r
32776</simpara>\r
32777</listitem>\r
32778</itemizedlist>\r
32779</section>\r
32780<section id="_reference_books">\r
32781<title>Reference Books</title>\r
32782<itemizedlist>\r
32783<listitem>\r
32784<simpara>\r
32785<link linkend="References_GansnerReppy04">The Standard ML Basis Library</link>\r
32786</simpara>\r
32787</listitem>\r
32788<listitem>\r
32789<simpara>\r
32790<link linkend="DefinitionOfStandardML">The Definition of Standard ML (Revised)</link>\r
32791</simpara>\r
32792</listitem>\r
32793</itemizedlist>\r
32794</section>\r
32795<section id="_related_topics">\r
32796<title>Related Topics</title>\r
32797<itemizedlist>\r
32798<listitem>\r
32799<simpara>\r
32800<link linkend="References_Reppy07">Concurrent Programming in ML</link>\r
32801</simpara>\r
32802</listitem>\r
32803<listitem>\r
32804<simpara>\r
32805<link linkend="References_Okasaki99">Purely Functional Data Structures</link>\r
32806</simpara>\r
32807</listitem>\r
32808</itemizedlist>\r
32809<simpara><?asciidoc-pagebreak?></simpara>\r
32810</section>\r
32811</section>\r
32812<section id="StandardMLGotchas">\r
32813<title>StandardMLGotchas</title>\r
32814<simpara>This page contains brief explanations of some recurring sources of\r
32815confusion and problems that SML newbies encounter.</simpara>\r
32816<simpara>Many confusions about the syntax of SML seem to arise from the use of\r
32817an interactive REPL (Read-Eval Print Loop) while trying to learn the\r
32818basics of the language. While writing your first SML programs, you\r
32819should keep the source code of your programs in a form that is\r
32820accepted by an SML compiler as a whole.</simpara>\r
32821<section id="_the_literal_and_literal_keyword">\r
32822<title>The <literal>and</literal> keyword</title>\r
32823<simpara>It is a common mistake to misuse the <literal>and</literal> keyword or to not know how\r
32824to introduce mutually recursive definitions. The purpose of the <literal>and</literal>\r
32825keyword is to introduce mutually recursive definitions of functions\r
32826and datatypes. For example,</simpara>\r
32827<programlisting language="sml" linenumbering="unnumbered">fun isEven 0w0 = true\r
32828 | isEven 0w1 = false\r
32829 | isEven n = isOdd (n-0w1)\r
32830and isOdd 0w0 = false\r
32831 | isOdd 0w1 = true\r
32832 | isOdd n = isEven (n-0w1)</programlisting>\r
32833<simpara>and</simpara>\r
32834<programlisting language="sml" linenumbering="unnumbered">datatype decl = VAL of id * pat * expr\r
32835 (* | ... *)\r
32836 and expr = LET of decl * expr\r
32837 (* | ... *)</programlisting>\r
32838<simpara>You can also use <literal>and</literal> as a shorthand in a couple of other places, but\r
32839it is not necessary.</simpara>\r
32840</section>\r
32841<section id="_constructed_patterns">\r
32842<title>Constructed patterns</title>\r
32843<simpara>It is a common mistake to forget to parenthesize constructed patterns\r
32844in <literal>fun</literal> bindings. Consider the following invalid definition:</simpara>\r
32845<programlisting language="sml" linenumbering="unnumbered">fun length nil = 0\r
32846 | length h :: t = 1 + length t</programlisting>\r
32847<variablelist>\r
32848<varlistentry>\r
32849<term>\r
32850The pattern `h \r
32851</term>\r
32852<listitem>\r
32853<simpara>\r
32854t` needs to be parenthesized:\r
32855</simpara>\r
32856</listitem>\r
32857</varlistentry>\r
32858</variablelist>\r
32859<programlisting language="sml" linenumbering="unnumbered">fun length nil = 0\r
32860 | length (h :: t) = 1 + length t</programlisting>\r
32861<simpara>The parentheses are needed, because a <literal>fun</literal> definition may have\r
32862multiple consecutive constructed patterns through currying.</simpara>\r
32863<simpara>The same applies to nonfix constructors. For example, the parentheses\r
32864in</simpara>\r
32865<programlisting language="sml" linenumbering="unnumbered">fun valOf NONE = raise Option\r
32866 | valOf (SOME x) = x</programlisting>\r
32867<simpara>are required. However, the outermost constructed pattern in a <literal>fn</literal> or\r
32868<literal>case</literal> expression need not be parenthesized, because in those cases\r
32869there is always just one constructed pattern. So, both</simpara>\r
32870<programlisting language="sml" linenumbering="unnumbered">val valOf = fn NONE =&gt; raise Option\r
32871 | SOME x =&gt; x</programlisting>\r
32872<simpara>and</simpara>\r
32873<programlisting language="sml" linenumbering="unnumbered">fun valOf x = case x of\r
32874 NONE =&gt; raise Option\r
32875 | SOME x =&gt; x</programlisting>\r
32876<simpara>are fine.</simpara>\r
32877</section>\r
32878<section id="_declarations_and_expressions">\r
32879<title>Declarations and expressions</title>\r
32880<simpara>It is a common mistake to confuse expressions and declarations.\r
32881Normally an SML source file should only contain declarations. The\r
32882following are declarations:</simpara>\r
32883<programlisting language="sml" linenumbering="unnumbered">datatype dt = ...\r
32884fun f ... = ...\r
32885functor Fn (...) = ...\r
32886infix ...\r
32887infixr ...\r
32888local ... in ... end\r
32889nonfix ...\r
32890open ...\r
32891signature SIG = ...\r
32892structure Struct = ...\r
32893type t = ...\r
32894val v = ...</programlisting>\r
32895<simpara>Note that</simpara>\r
32896<programlisting language="sml" linenumbering="unnumbered">let ... in ... end</programlisting>\r
32897<simpara>isn&#8217;t a declaration.</simpara>\r
32898<simpara>To specify a side-effecting computation in a source file, you can write:</simpara>\r
32899<programlisting language="sml" linenumbering="unnumbered">val () = ...</programlisting>\r
32900</section>\r
32901<section id="_equality_types">\r
32902<title>Equality types</title>\r
32903<simpara>SML has a fairly intricate built-in notion of equality. See\r
32904<link linkend="EqualityType">EqualityType</link> and <link linkend="EqualityTypeVariable">EqualityTypeVariable</link> for a thorough\r
32905discussion.</simpara>\r
32906</section>\r
32907<section id="_nested_cases">\r
32908<title>Nested cases</title>\r
32909<simpara>It is a common mistake to write nested case expressions without the\r
32910necessary parentheses. See <link linkend="UnresolvedBugs">UnresolvedBugs</link> for a discussion.</simpara>\r
32911</section>\r
32912<section id="_op">\r
32913<title>(op *)</title>\r
32914<simpara>It used to be a common mistake to parenthesize <literal>op *</literal> as <literal>(op *)</literal>.\r
32915Before SML&#8217;97, <literal>*)</literal> was considered a comment terminator in SML and\r
32916caused a syntax error. At the time of writing, <link linkend="SMLNJ">SML/NJ</link> still\r
32917rejects the code. An extra space may be used for portability:\r
32918<literal>(op * )</literal>. However, parenthesizing <literal>op</literal> is redundant, even though it\r
32919is a widely used convention.</simpara>\r
32920</section>\r
32921<section id="_overloading">\r
32922<title>Overloading</title>\r
32923<simpara>A number of standard operators (<literal>+</literal>, <literal>-</literal>, <literal>~</literal>, <literal>*</literal>, <literal>&lt;</literal>, <literal>&gt;</literal>, &#8230;) and\r
32924numeric constants are overloaded for some of the numeric types (<literal>int</literal>,\r
32925<literal>real</literal>, <literal>word</literal>). It is a common surprise that definitions using\r
32926overloaded operators such as</simpara>\r
32927<programlisting language="sml" linenumbering="unnumbered">fun min (x, y) = if y &lt; x then y else x</programlisting>\r
32928<simpara>are not overloaded themselves. SML doesn&#8217;t really support\r
32929(user-defined) overloading or other forms of ad hoc polymorphism. In\r
32930cases such as the above where the context doesn&#8217;t resolve the\r
32931overloading, expressions using overloaded operators or constants get\r
32932assigned a default type. The above definition gets the type</simpara>\r
32933<programlisting language="sml" linenumbering="unnumbered">val min : int * int -&gt; int</programlisting>\r
32934<simpara>See <link linkend="Overloading">Overloading</link> and <link linkend="TypeIndexedValues">TypeIndexedValues</link> for further discussion.</simpara>\r
32935</section>\r
32936<section id="_semicolons">\r
32937<title>Semicolons</title>\r
32938<simpara>It is a common mistake to use redundant semicolons in SML code. This\r
32939is probably caused by the fact that in an SML REPL, a semicolon (and\r
32940enter) is used to signal the REPL that it should evaluate the\r
32941preceding chunk of code as a unit. In SML source files, semicolons\r
32942are really needed in only two places. Namely, in expressions of the\r
32943form</simpara>\r
32944<programlisting language="sml" linenumbering="unnumbered">(exp ; ... ; exp)</programlisting>\r
32945<simpara>and</simpara>\r
32946<programlisting language="sml" linenumbering="unnumbered">let ... in exp ; ... ; exp end</programlisting>\r
32947<simpara>Note that semicolons act as expression (or declaration) separators\r
32948rather than as terminators.</simpara>\r
32949</section>\r
32950<section id="_stale_bindings">\r
32951<title>Stale bindings</title>\r
32952<simpara></simpara>\r
32953</section>\r
32954<section id="_unresolved_records">\r
32955<title>Unresolved records</title>\r
32956<simpara></simpara>\r
32957</section>\r
32958<section id="_value_restriction">\r
32959<title>Value restriction</title>\r
32960<simpara>See <link linkend="ValueRestriction">ValueRestriction</link>.</simpara>\r
32961</section>\r
32962<section id="_type_variable_scope">\r
32963<title>Type Variable Scope</title>\r
32964<simpara>See <link linkend="TypeVariableScope">TypeVariableScope</link>.</simpara>\r
32965<simpara><?asciidoc-pagebreak?></simpara>\r
32966</section>\r
32967</section>\r
32968<section id="StandardMLHistory">\r
32969<title>StandardMLHistory</title>\r
32970<simpara><link linkend="StandardML">Standard ML</link> grew out of <link linkend="ML">ML</link> in the early 1980s.</simpara>\r
32971<simpara>For an excellent overview of SML&#8217;s history, see Appendix F of the\r
32972<link linkend="DefinitionOfStandardML">Definition</link>.</simpara>\r
32973<simpara>For an overview if its history before 1982, see <link linkend="References_Milner82">How ML Evolved</link>.</simpara>\r
32974<simpara><?asciidoc-pagebreak?></simpara>\r
32975</section>\r
32976<section id="StandardMLImplementations">\r
32977<title>StandardMLImplementations</title>\r
32978<simpara>There are a number of implementations of <link linkend="StandardML">Standard ML</link>,\r
32979from interpreters, to byte-code compilers, to incremental compilers,\r
32980to whole-program compilers.</simpara>\r
32981<itemizedlist>\r
32982<listitem>\r
32983<simpara>\r
32984<link linkend="Alice">Alice ML</link>\r
32985</simpara>\r
32986</listitem>\r
32987<listitem>\r
32988<simpara>\r
32989<link linkend="HaMLet">HaMLet</link>\r
32990</simpara>\r
32991</listitem>\r
32992<listitem>\r
32993<simpara>\r
32994<link linkend="MLKit">ML Kit</link>\r
32995</simpara>\r
32996</listitem>\r
32997<listitem>\r
32998<simpara>\r
32999<link linkend="Home">MLton</link>\r
33000</simpara>\r
33001</listitem>\r
33002<listitem>\r
33003<simpara>\r
33004<link linkend="MoscowML">Moscow ML</link>\r
33005</simpara>\r
33006</listitem>\r
33007<listitem>\r
33008<simpara>\r
33009<link linkend="PolyML">Poly/ML</link>\r
33010</simpara>\r
33011</listitem>\r
33012<listitem>\r
33013<simpara>\r
33014<link linkend="SMLSharp">SML#</link>\r
33015</simpara>\r
33016</listitem>\r
33017<listitem>\r
33018<simpara>\r
33019<link linkend="SMLNJ">SML/NJ</link>\r
33020</simpara>\r
33021</listitem>\r
33022<listitem>\r
33023<simpara>\r
33024<link linkend="SMLNET">SML.NET</link>\r
33025</simpara>\r
33026</listitem>\r
33027<listitem>\r
33028<simpara>\r
33029<link linkend="TILT">TILT</link>\r
33030</simpara>\r
33031</listitem>\r
33032</itemizedlist>\r
33033<section id="_not_actively_maintained">\r
33034<title>Not Actively Maintained</title>\r
33035<itemizedlist>\r
33036<listitem>\r
33037<simpara>\r
33038<ulink url="http://www.dcs.ed.ac.uk/home/edml/">Edinburgh ML</ulink>\r
33039</simpara>\r
33040</listitem>\r
33041<listitem>\r
33042<simpara>\r
33043<link linkend="MLj">MLj</link>\r
33044</simpara>\r
33045</listitem>\r
33046<listitem>\r
33047<simpara>\r
33048MLWorks\r
33049</simpara>\r
33050</listitem>\r
33051<listitem>\r
33052<simpara>\r
33053<link linkend="Poplog">Poplog</link>\r
33054</simpara>\r
33055</listitem>\r
33056<listitem>\r
33057<simpara>\r
33058<ulink url="http://www.cs.cornell.edu/Info/People/jgm/til.tar.Z">TIL</ulink>\r
33059</simpara>\r
33060</listitem>\r
33061</itemizedlist>\r
33062<simpara><?asciidoc-pagebreak?></simpara>\r
33063</section>\r
33064</section>\r
33065<section id="StandardMLPortability">\r
33066<title>StandardMLPortability</title>\r
33067<simpara>Technically, SML&#8217;97 as defined in the\r
33068<link linkend="DefinitionOfStandardML">Definition</link>\r
33069requires only a minimal initial basis, which, while including the\r
33070types <literal>int</literal>, <literal>real</literal>, <literal>char</literal>, and <literal>string</literal>, need have\r
33071no operations on those base types. Hence, the only observable output\r
33072of an SML&#8217;97 program is termination or raising an exception. Most SML\r
33073compilers should agree there, to the degree each agrees with the\r
33074Definition. See <link linkend="UnresolvedBugs">UnresolvedBugs</link> for MLton&#8217;s very few corner cases.</simpara>\r
33075<simpara>Realistically, a program needs to make use of the\r
33076<link linkend="BasisLibrary">Basis Library</link>.\r
33077Within the Basis Library, there are numerous places where the behavior\r
33078is implementation dependent. For a trivial example:</simpara>\r
33079<programlisting language="sml" linenumbering="unnumbered">val _ = valOf (Int.maxInt)</programlisting>\r
33080<simpara>may either raise the <literal>Option</literal> exception (if\r
33081<literal>Int.maxInt == NONE</literal>) or may terminate normally. The default\r
33082Int/Real/Word sizes are the biggest implementation dependent aspect;\r
33083so, one implementation may raise <literal>Overflow</literal> while another can\r
33084accommodate the result. Also, maximum array and vector lengths are\r
33085implementation dependent. Interfacing with the operating system is a\r
33086bit murky, and implementations surely differ in handling of errors\r
33087there.</simpara>\r
33088<simpara><?asciidoc-pagebreak?></simpara>\r
33089</section>\r
33090<section id="StandardMLTutorials">\r
33091<title>StandardMLTutorials</title>\r
33092<itemizedlist>\r
33093<listitem>\r
33094<simpara>\r
33095<ulink url="http://www.dcs.napier.ac.uk/course-notes/sml/manual.html">A Gentle Introduction to ML</ulink>.\r
33096Andrew Cummings.\r
33097</simpara>\r
33098</listitem>\r
33099<listitem>\r
33100<simpara>\r
33101<ulink url="http://www.dcs.ed.ac.uk/home/stg/NOTES/">Programming in Standard ML '97: An Online Tutorial</ulink>.\r
33102Stephen Gilmore.\r
33103</simpara>\r
33104</listitem>\r
33105<listitem>\r
33106<simpara>\r
33107<link linkend="References_Harper11">Programming in Standard ML</link>.\r
33108Robert Harper.\r
33109</simpara>\r
33110</listitem>\r
33111<listitem>\r
33112<simpara>\r
33113<link linkend="References_Tofte96">Essentials of Standard ML Modules</link>.\r
33114Mads Tofte.\r
33115</simpara>\r
33116</listitem>\r
33117<listitem>\r
33118<simpara>\r
33119<link linkend="References_Tofte09">Tips for Computer Scientists on Standard ML (Revised)</link>.\r
33120Mads Tofte.\r
33121</simpara>\r
33122</listitem>\r
33123</itemizedlist>\r
33124<simpara><?asciidoc-pagebreak?></simpara>\r
33125</section>\r
33126<section id="StaticSum">\r
33127<title>StaticSum</title>\r
33128<simpara>While SML makes it impossible to write functions whose types would\r
33129depend on the values of their arguments, or so called dependently\r
33130typed functions, it is possible, and arguably commonplace, to write\r
33131functions whose types depend on the types of their arguments. Indeed,\r
33132the types of parametrically polymorphic functions like <literal>map</literal> and\r
33133<literal>foldl</literal> can be said to depend on the types of their arguments. What\r
33134is less commonplace, however, is to write functions whose behavior\r
33135would depend on the types of their arguments. Nevertheless, there are\r
33136several techniques for writing such functions.\r
33137<link linkend="TypeIndexedValues">Type-indexed values</link> and <link linkend="Fold">fold</link> are two such\r
33138techniques. This page presents another such technique dubbed static\r
33139sums.</simpara>\r
33140<section id="_ordinary_sums">\r
33141<title>Ordinary Sums</title>\r
33142<simpara>Consider the sum type as defined below:</simpara>\r
33143<programlisting language="sml" linenumbering="unnumbered">structure Sum = struct\r
33144 datatype ('a, 'b) t = INL of 'a | INR of 'b\r
33145end</programlisting>\r
33146<simpara>While a generic sum type such as defined above is very useful, it has\r
33147a number of limitations. As an example, we could write the function\r
33148<literal>out</literal> to extract the value from a sum as follows:</simpara>\r
33149<programlisting language="sml" linenumbering="unnumbered">fun out (s : ('a, 'a) Sum.t) : 'a =\r
33150 case s\r
33151 of Sum.INL a =&gt; a\r
33152 | Sum.INR a =&gt; a</programlisting>\r
33153<simpara>As can be seen from the type of <literal>out</literal>, it is limited in the sense that\r
33154it requires both variants of the sum to have the same type. So, <literal>out</literal>\r
33155cannot be used to extract the value of a sum of two different types,\r
33156such as the type <literal>(int, real) Sum.t</literal>. As another example of a\r
33157limitation, consider the following attempt at a <literal>succ</literal> function:</simpara>\r
33158<programlisting language="sml" linenumbering="unnumbered">fun succ (s : (int, real) Sum.t) : ??? =\r
33159 case s\r
33160 of Sum.INL i =&gt; i + 1\r
33161 | Sum.INR r =&gt; Real.nextAfter (r, Real.posInf)</programlisting>\r
33162<simpara>The above definition of <literal>succ</literal> cannot be typed, because there is no\r
33163type for the codomain within SML.</simpara>\r
33164</section>\r
33165<section id="_static_sums">\r
33166<title>Static Sums</title>\r
33167<simpara>Interestingly, it is possible to define values <literal>inL</literal>, <literal>inR</literal>, and\r
33168<literal>match</literal> that satisfy the laws</simpara>\r
33169<screen>match (inL x) (f, g) = f x\r
33170match (inR x) (f, g) = g x</screen>\r
33171<simpara>and do not suffer from the same limitions. The definitions are\r
33172actually quite trivial:</simpara>\r
33173<programlisting language="sml" linenumbering="unnumbered">structure StaticSum = struct\r
33174 fun inL x (f, _) = f x\r
33175 fun inR x (_, g) = g x\r
33176 fun match x = x\r
33177end</programlisting>\r
33178<simpara>Now, given the <literal>succ</literal> function defined as</simpara>\r
33179<programlisting language="sml" linenumbering="unnumbered">fun succ s =\r
33180 StaticSum.match s\r
33181 (fn i =&gt; i + 1,\r
33182 fn r =&gt; Real.nextAfter (r, Real.posInf))</programlisting>\r
33183<simpara>we get</simpara>\r
33184<programlisting language="sml" linenumbering="unnumbered">succ (StaticSum.inL 1) = 2\r
33185succ (StaticSum.inR Real.maxFinite) = Real.posInf</programlisting>\r
33186<simpara>To better understand how this works, consider the following signature\r
33187for static sums:</simpara>\r
33188<programlisting language="sml" linenumbering="unnumbered">structure StaticSum :&gt; sig\r
33189 type ('dL, 'cL, 'dR, 'cR, 'c) t\r
33190 val inL : 'dL -&gt; ('dL, 'cL, 'dR, 'cR, 'cL) t\r
33191 val inR : 'dR -&gt; ('dL, 'cL, 'dR, 'cR, 'cR) t\r
33192 val match : ('dL, 'cL, 'dR, 'cR, 'c) t -&gt; ('dL -&gt; 'cL) * ('dR -&gt; 'cR) -&gt; 'c\r
33193end = struct\r
33194 type ('dL, 'cL, 'dR, 'cR, 'c) t = ('dL -&gt; 'cL) * ('dR -&gt; 'cR) -&gt; 'c\r
33195 open StaticSum\r
33196end</programlisting>\r
33197<simpara>Above, <literal>'d</literal> stands for domain and <literal>'c</literal> for codomain. The key\r
33198difference between an ordinary sum type, like <literal>(int, real) Sum.t</literal>, and\r
33199a static sum type, like <literal>(int, real, real, int, real) StaticSum.t</literal>, is\r
33200that the ordinary sum type says nothing about the type of the result\r
33201of deconstructing a sum while the static sum type specifies the type.</simpara>\r
33202<simpara>With the sealed static sum module, we get the type</simpara>\r
33203<programlisting language="sml" linenumbering="unnumbered">val succ : (int, int, real, real, 'a) StaticSum.t -&gt; 'a</programlisting>\r
33204<simpara>for the previously defined <literal>succ</literal> function. The type specifies that\r
33205<literal>succ</literal> maps a left <literal>int</literal> to an <literal>int</literal> and a right <literal>real</literal> to a <literal>real</literal>.\r
33206For example, the type of <literal>StaticSum.inL 1</literal> is\r
33207<literal>(int, 'cL, 'dR, 'cR, 'cL) StaticSum.t</literal>. Unifying this with the\r
33208argument type of <literal>succ</literal> gives the type <literal>(int, int, real, real, int)\r
33209StaticSum.t -&gt; int</literal>.</simpara>\r
33210<simpara>The <literal>out</literal> function is quite useful on its own. Here is how it can be\r
33211defined:</simpara>\r
33212<programlisting language="sml" linenumbering="unnumbered">structure StaticSum = struct\r
33213 open StaticSum\r
33214 val out : ('a, 'a, 'b, 'b, 'c) t -&gt; 'c =\r
33215 fn s =&gt; match s (fn x =&gt; x, fn x =&gt; x)\r
33216end</programlisting>\r
33217<simpara>Due to the value restriction, lack of first class polymorphism and\r
33218polymorphic recursion, the usefulness and convenience of static sums\r
33219is somewhat limited in SML. So, don&#8217;t throw away the ordinary sum\r
33220type just yet. Static sums can nevertheless be quite useful.</simpara>\r
33221<section id="_example_send_and_receive_with_argument_type_dependent_result_types">\r
33222<title>Example: Send and Receive with Argument Type Dependent Result Types</title>\r
33223<simpara>In some situations it would seem useful to define functions whose\r
33224result type would depend on some of the arguments. Traditionally such\r
33225functions have been thought to be impossible in SML and the solution\r
33226has been to define multiple functions. For example, the\r
33227<ulink url="http://www.standardml.org/Basis/socket.html"><literal>Socket</literal> structure</ulink> of the\r
33228Basis library defines 16 <literal>send</literal> and 16 <literal>recv</literal> functions. In contrast,\r
33229the Net structure\r
33230(<ulink url="https://github.com/MLton/mltonlib/blob/master/com/sweeks/basic/unstable/net.sig"><literal>net.sig</literal></ulink>) of the\r
33231Basic library designed by Stephen Weeks defines only a single <literal>send</literal>\r
33232and a single <literal>receive</literal> and the result types of the functions depend on\r
33233their arguments. The implementation\r
33234(<ulink url="https://github.com/MLton/mltonlib/blob/master/com/sweeks/basic/unstable/net.sml"><literal>net.sml</literal></ulink>) uses\r
33235static sums (with a slighly different signature:\r
33236<ulink url="https://github.com/MLton/mltonlib/blob/master/com/sweeks/basic/unstable/static-sum.sig"><literal>static-sum.sig</literal></ulink>).</simpara>\r
33237</section>\r
33238<section id="_example_picking_monad_results">\r
33239<title>Example: Picking Monad Results</title>\r
33240<simpara>Suppose that we need to write a parser that accepts a pair of integers\r
33241and returns their sum given a monadic parsing combinator library. A\r
33242part of the signature of such library could look like this</simpara>\r
33243<programlisting language="sml" linenumbering="unnumbered">signature PARSING = sig\r
33244 include MONAD\r
33245 val int : int t\r
33246 val lparen : unit t\r
33247 val rparen : unit t\r
33248 val comma : unit t\r
33249 (* ... *)\r
33250end</programlisting>\r
33251<simpara>where the <literal>MONAD</literal> signature could be defined as</simpara>\r
33252<programlisting language="sml" linenumbering="unnumbered">signature MONAD = sig\r
33253 type 'a t\r
33254 val return : 'a -&gt; 'a t\r
33255 val &gt;&gt;= : 'a t * ('a -&gt; 'b t) -&gt; 'b t\r
33256end\r
33257infix &gt;&gt;=</programlisting>\r
33258<simpara>The straightforward, but tedious, way to write the desired parser is:</simpara>\r
33259<programlisting language="sml" linenumbering="unnumbered">val p = lparen &gt;&gt;= (fn _ =&gt;\r
33260 int &gt;&gt;= (fn x =&gt;\r
33261 comma &gt;&gt;= (fn _ =&gt;\r
33262 int &gt;&gt;= (fn y =&gt;\r
33263 rparen &gt;&gt;= (fn _ =&gt;\r
33264 return (x + y))))))</programlisting>\r
33265<simpara>In Haskell, the parser could be written using the <literal>do</literal> notation\r
33266considerably less verbosely as:</simpara>\r
33267<programlisting language="haskell" linenumbering="unnumbered">p = do { lparen ; x &lt;- int ; comma ; y &lt;- int ; rparen ; return $ x + y }</programlisting>\r
33268<simpara>SML doesn&#8217;t provide a <literal>do</literal> notation, so we need another solution.</simpara>\r
33269<simpara>Suppose we would have a "pick" notation for monads that would allows\r
33270us to write the parser as</simpara>\r
33271<programlisting language="sml" linenumbering="unnumbered">val p = `lparen ^ \int ^ `comma ^ \int ^ `rparen @ (fn x &amp; y =&gt; x + y)</programlisting>\r
33272<simpara>using four auxiliary combinators: <literal>&grave;</literal>, <literal>\</literal>, <literal>^</literal>, and <literal>@</literal>.</simpara>\r
33273<simpara>Roughly speaking</simpara>\r
33274<itemizedlist>\r
33275<listitem>\r
33276<simpara>\r
33277<literal>&grave;p</literal> means that the result of <literal>p</literal> is dropped,\r
33278</simpara>\r
33279</listitem>\r
33280<listitem>\r
33281<simpara>\r
33282<literal>\p</literal> means that the result of <literal>p</literal> is taken,\r
33283</simpara>\r
33284</listitem>\r
33285<listitem>\r
33286<simpara>\r
33287<literal>p ^ q</literal> means that results of <literal>p</literal> and <literal>q</literal> are taken as a product, and\r
33288</simpara>\r
33289</listitem>\r
33290<listitem>\r
33291<simpara>\r
33292<literal>p @ a</literal> means that the results of <literal>p</literal> are passed to the function <literal>a</literal> and that result is returned.\r
33293</simpara>\r
33294</listitem>\r
33295</itemizedlist>\r
33296<simpara>The difficulty is in implementing the concatenation combinator <literal>^</literal>.\r
33297The type of the result of the concatenation depends on the types of\r
33298the arguments.</simpara>\r
33299<simpara>Using static sums and the <link linkend="ProductType">product type</link>, the pick\r
33300notation for monads can be implemented as follows:</simpara>\r
33301<programlisting language="sml" linenumbering="unnumbered">functor MkMonadPick (include MONAD) = let\r
33302 open StaticSum\r
33303in\r
33304 struct\r
33305 fun `a = inL (a &gt;&gt;= (fn _ =&gt; return ()))\r
33306 val \ = inR\r
33307 fun a @ f = out a &gt;&gt;= (return o f)\r
33308 fun a ^ b =\r
33309 (match b o match a)\r
33310 (fn a =&gt;\r
33311 (fn b =&gt; inL (a &gt;&gt;= (fn _ =&gt; b)),\r
33312 fn b =&gt; inR (a &gt;&gt;= (fn _ =&gt; b))),\r
33313 fn a =&gt;\r
33314 (fn b =&gt; inR (a &gt;&gt;= (fn a =&gt; b &gt;&gt;= (fn _ =&gt; return a))),\r
33315 fn b =&gt; inR (a &gt;&gt;= (fn a =&gt; b &gt;&gt;= (fn b =&gt; return (a &amp; b))))))\r
33316 end\r
33317end</programlisting>\r
33318<simpara>The above implementation is inefficient, however. It uses many more\r
33319bind operations, <literal>&gt;&gt;=</literal>, than necessary. That can be solved with an\r
33320additional level of abstraction:</simpara>\r
33321<programlisting language="sml" linenumbering="unnumbered">functor MkMonadPick (include MONAD) = let\r
33322 open StaticSum\r
33323in\r
33324 struct\r
33325 fun `a = inL (fn b =&gt; a &gt;&gt;= (fn _ =&gt; b ()))\r
33326 fun \a = inR (fn b =&gt; a &gt;&gt;= b)\r
33327 fun a @ f = out a (return o f)\r
33328 fun a ^ b =\r
33329 (match b o match a)\r
33330 (fn a =&gt; (fn b =&gt; inL (fn c =&gt; a (fn () =&gt; b c)),\r
33331 fn b =&gt; inR (fn c =&gt; a (fn () =&gt; b c))),\r
33332 fn a =&gt; (fn b =&gt; inR (fn c =&gt; a (fn a =&gt; b (fn () =&gt; c a))),\r
33333 fn b =&gt; inR (fn c =&gt; a (fn a =&gt; b (fn b =&gt; c (a &amp; b))))))\r
33334 end\r
33335end</programlisting>\r
33336<simpara>After instantiating and opening either of the above monad pick\r
33337implementations, the previously given definition of <literal>p</literal> can be\r
33338compiled and results in a parser whose result is of type <literal>int</literal>. Here\r
33339is a functor to test the theory:</simpara>\r
33340<programlisting language="sml" linenumbering="unnumbered">functor Test (Arg : PARSING) = struct\r
33341 local\r
33342 structure Pick = MkMonadPick (Arg)\r
33343 open Pick Arg\r
33344 in\r
33345 val p : int t =\r
33346 `lparen ^ \int ^ `comma ^ \int ^ `rparen @ (fn x &amp; y =&gt; x + y)\r
33347 end\r
33348end</programlisting>\r
33349</section>\r
33350</section>\r
33351<section id="_also_see_46">\r
33352<title>Also see</title>\r
33353<simpara>There are a number of related techniques. Here are some of them.</simpara>\r
33354<itemizedlist>\r
33355<listitem>\r
33356<simpara>\r
33357<link linkend="Fold">Fold</link>\r
33358</simpara>\r
33359</listitem>\r
33360<listitem>\r
33361<simpara>\r
33362<link linkend="TypeIndexedValues">TypeIndexedValues</link>\r
33363</simpara>\r
33364</listitem>\r
33365</itemizedlist>\r
33366<simpara><?asciidoc-pagebreak?></simpara>\r
33367</section>\r
33368</section>\r
33369<section id="StephenWeeks">\r
33370<title>StephenWeeks</title>\r
33371<simpara>I live in the New York City area and work at <ulink url="http://janestcapital.com">Jane Street Capital</ulink>.</simpara>\r
33372<simpara>My <ulink url="http://sweeks.com/">home page</ulink>.</simpara>\r
33373<simpara>You can email me at <ulink url="mailto:sweeks@sweeks.com">sweeks@sweeks.com</ulink>.</simpara>\r
33374<simpara><?asciidoc-pagebreak?></simpara>\r
33375</section>\r
33376<section id="StyleGuide">\r
33377<title>StyleGuide</title>\r
33378<simpara>These conventions are chosen so that inertia is towards modularity, code reuse and finding bugs early, <emphasis>not</emphasis> to save typing.</simpara>\r
33379<itemizedlist>\r
33380<listitem>\r
33381<simpara>\r
33382<link linkend="SyntacticConventions">SyntacticConventions</link>\r
33383</simpara>\r
33384</listitem>\r
33385</itemizedlist>\r
33386<simpara><?asciidoc-pagebreak?></simpara>\r
33387</section>\r
33388<section id="Subversion">\r
33389<title>Subversion</title>\r
33390<simpara><ulink url="http://subversion.apache.org/">Subversion</ulink> is a version control system.\r
33391The MLton project used Subversion to maintain its\r
33392<link linkend="Sources">source code</link>, but switched to <link linkend="Git">Git</link> on 20130308.</simpara>\r
33393<simpara>Here are some online Subversion resources.</simpara>\r
33394<itemizedlist>\r
33395<listitem>\r
33396<simpara>\r
33397<ulink url="http://svnbook.red-bean.com">Version Control with Subversion</ulink>\r
33398</simpara>\r
33399</listitem>\r
33400</itemizedlist>\r
33401<simpara><?asciidoc-pagebreak?></simpara>\r
33402</section>\r
33403<section id="SuccessorML">\r
33404<title>SuccessorML</title>\r
33405<simpara>The purpose of <ulink url="http://sml-family.org/successor-ml/">successor ML</ulink>, or\r
33406sML for short, is to provide a vehicle for the continued evolution of\r
33407ML, using Standard ML as a starting point. The intention is for\r
33408successor ML to be a living, evolving dialect of ML that is responsive\r
33409to community needs and advances in language design, implementation,\r
33410and semantics.</simpara>\r
33411<section id="_successorml_features_in_mlton">\r
33412<title>SuccessorML Features in MLton</title>\r
33413<simpara>The following SuccessorML features have been implemented in MLton.\r
33414The features are disabled by default, and may be enabled utilizing the\r
33415feature&#8217;s corresponding <link linkend="MLBasisAnnotations">ML Basis annotation</link>\r
33416which is listed directly after the feature name. In addition, the\r
33417<literal>allowSuccessorML {false|true}</literal> annotation can be used to\r
33418simultaneously enable all of the features.</simpara>\r
33419<itemizedlist>\r
33420<listitem>\r
33421<simpara>\r
33422<anchor id="SuccessorML_DoDecls" xreflabel="[SuccessorML_DoDecls]"/>\r
33423<literal>do</literal> Declarations: <literal>allowDoDecls {false|true}</literal>\r
33424</simpara>\r
33425<simpara>Allow a <literal>do <emphasis>exp</emphasis></literal> declaration form, which evaluates <emphasis>exp</emphasis> for its\r
33426side effects. The following example uses a <literal>do</literal> declaration:</simpara>\r
33427<programlisting language="sml" linenumbering="unnumbered">do print "Hello world.\n"</programlisting>\r
33428<simpara>and is equivalent to:</simpara>\r
33429<programlisting language="sml" linenumbering="unnumbered">val () = print "Hello world.\n"</programlisting>\r
33430</listitem>\r
33431<listitem>\r
33432<simpara>\r
33433<anchor id="SuccessorML_ExtendedConsts" xreflabel="[SuccessorML_ExtendedConsts]"/>\r
33434Extended Constants: <literal>allowExtendedConsts {false|true}</literal>\r
33435</simpara>\r
33436<simpara>Allow or disallow all of the extended constants features. This is a\r
33437proxy for all of the following annotations.</simpara>\r
33438<itemizedlist>\r
33439<listitem>\r
33440<simpara>\r
33441<anchor id="SuccessorML_ExtendedNumConsts" xreflabel="[SuccessorML_ExtendedNumConsts]"/>\r
33442Extended Numeric Constants: <literal>allowExtendedNumConsts {false|true}</literal>\r
33443</simpara>\r
33444<simpara>Allow underscores as a separator in numeric constants and allow binary\r
33445integer and word constants.</simpara>\r
33446<simpara>Underscores in a numeric constant must occur between digits and\r
33447consecutive underscores are allowed.</simpara>\r
33448<simpara>Binary integer constants use the prefix <literal>0b</literal> and binary word constants\r
33449use the prefix <literal>0wb</literal>.</simpara>\r
33450<simpara>The following example uses extended numeric constants (although it may\r
33451be incorrectly syntax highlighted):</simpara>\r
33452<programlisting language="sml" linenumbering="unnumbered">val pb = 0b10101\r
33453val nb = ~0b10_10_10\r
33454val wb = 0wb1010\r
33455val i = 4__327__829\r
33456val r = 6.022_140_9e23</programlisting>\r
33457</listitem>\r
33458<listitem>\r
33459<simpara>\r
33460<anchor id="SuccessorML_ExtendedTextConsts" xreflabel="[SuccessorML_ExtendedTextConsts]"/> Extended Text Constants: <literal>allowExtendedTextConsts {false|true}</literal>\r
33461</simpara>\r
33462<simpara>Allow characters with integer codes &ge; 128 and &le; 247 that\r
33463correspond to syntactically well-formed UTF-8 byte sequences in text\r
33464constants.</simpara>\r
33465<simpara>Any 1, 2, 3, or 4 byte sequence that can be properly decoded to a\r
33466binary number according to the UTF-8 encoding/decoding scheme is\r
33467allowed in a text constant (but invalid sequences are not explicitly\r
33468rejected) and denotes the corresponding sequence of characters with\r
33469integer codes &ge; 128 and &le; 247. This feature enables "UTF-8\r
33470convenience" (but not comprehensive Unicode support); in particular,\r
33471it allows one to copy text from a browser and paste it into a string\r
33472constant in an editor and, furthermore, if the string is printed to a\r
33473terminal, then will (typically) appear as the original text. The\r
33474following example uses UTF-8 byte sequences:</simpara>\r
33475<programlisting language="sml" linenumbering="unnumbered">val s1 : String.string = "\240\159\130\161"\r
33476val s2 : String.string = "🂡"\r
33477val _ = print ("s1 --&gt; " ^ s1 ^ "\n")\r
33478val _ = print ("s2 --&gt; " ^ s2 ^ "\n")\r
33479val _ = print ("String.size s1 --&gt; " ^ Int.toString (String.size s1) ^ "\n")\r
33480val _ = print ("String.size s2 --&gt; " ^ Int.toString (String.size s2) ^ "\n")\r
33481val _ = print ("s1 = s2 --&gt; " ^ Bool.toString (s1 = s2) ^ "\n")</programlisting>\r
33482<simpara>and, when compiled and executed, will display:</simpara>\r
33483<screen>s1 --&gt; 🂡\r
33484s2 --&gt; 🂡\r
33485String.size s1 --&gt; 4\r
33486String.size s2 --&gt; 4\r
33487s1 = s2 --&gt; true</screen>\r
33488<simpara>Note that the <literal>String.string</literal> type corresponds to any sequence of\r
334898-bit values, including invalid UTF-8 sequences; hence the string\r
33490constant <literal>"\192"</literal> (a UTF-8 leading byte with no UTF-8 continuation\r
33491byte) is valid. Similarly, the <literal>Char.char</literal> type corresponds to a\r
33492single 8-bit value; hence the char constant <literal>#"α"</literal> is not valid, as\r
33493the text constant <literal>"α"</literal> denotes a sequence of two 8-bit values.</simpara>\r
33494</listitem>\r
33495</itemizedlist>\r
33496</listitem>\r
33497<listitem>\r
33498<simpara>\r
33499<anchor id="SuccessorML_LineComments" xreflabel="[SuccessorML_LineComments]"/>\r
33500Line Comments: <literal>allowLineComments {false|true}</literal>\r
33501</simpara>\r
33502<simpara>Allow line comments beginning with the token <literal>(*)</literal>. The following\r
33503example uses a line comment:</simpara>\r
33504<programlisting language="sml" linenumbering="unnumbered">(*) This is a line comment</programlisting>\r
33505<simpara>Line comments properly nest within block comments. The following\r
33506example uses line comments nested within block comments:</simpara>\r
33507<programlisting language="sml" linenumbering="unnumbered">(*\r
33508val x = 4 (*) This is a line comment\r
33509*)\r
33510\r
33511(*\r
33512val y = 5 (*) This is a line comment *)\r
33513*)</programlisting>\r
33514</listitem>\r
33515<listitem>\r
33516<simpara>\r
33517<anchor id="SuccessorML_OptBar" xreflabel="[SuccessorML_OptBar]"/>\r
33518Optional Pattern Bars: <literal>allowOptBar {false|true}</literal>\r
33519</simpara>\r
33520<simpara>Allow a bar to appear before the first match rule of a <literal>case</literal>, <literal>fn</literal>,\r
33521or <literal>handle</literal> expression, allow a bar to appear before the first\r
33522function-value binding of a <literal>fun</literal> declaration, and allow a bar to\r
33523appear before the first constructor binding or description of a\r
33524<literal>datatype</literal> declaration or specification. The following example uses\r
33525leading bars in a <literal>datatype</literal> declaration, a <literal>fun</literal> declaration, and a\r
33526<literal>case</literal> expression:</simpara>\r
33527<programlisting language="sml" linenumbering="unnumbered">datatype t =\r
33528 | C\r
33529 | B\r
33530 | A\r
33531\r
33532fun\r
33533 | f NONE = 0\r
33534 | f (SOME t) =\r
33535 (case t of\r
33536 | A =&gt; 1\r
33537 | B =&gt; 2\r
33538 | C =&gt; 3)</programlisting>\r
33539<simpara>By eliminating the special case of the first element, this feature\r
33540allows for simpler refactoring (e.g., sorting the lines of the\r
33541<literal>datatype</literal> declaration&#8217;s constructor bindings to put the constructors\r
33542in alphabetical order).</simpara>\r
33543</listitem>\r
33544<listitem>\r
33545<simpara>\r
33546<anchor id="SuccessorML_OptSemicolon" xreflabel="[SuccessorML_OptSemicolon]"/>\r
33547Optional Semicolons: <literal>allowOptSemicolon {false|true}</literal>\r
33548</simpara>\r
33549<simpara>Allow a semicolon to appear after the last expression in a sequence or\r
33550<literal>let</literal>-body expression. The following example uses a trailing\r
33551semicolon in the body of a <literal>let</literal> expression:</simpara>\r
33552<programlisting language="sml" linenumbering="unnumbered">fun h z =\r
33553 let\r
33554 val x = 3 * z\r
33555 in\r
33556 f x ;\r
33557 g x ;\r
33558 end</programlisting>\r
33559<simpara>By eliminating the special case of the last element, this feature\r
33560allows for simpler refactoring.</simpara>\r
33561</listitem>\r
33562<listitem>\r
33563<simpara>\r
33564<anchor id="SuccessorML_OrPats" xreflabel="[SuccessorML_OrPats]"/>\r
33565Disjunctive (Or) Patterns: <literal>allowOrPats {false|true}</literal>\r
33566</simpara>\r
33567<simpara>Allow disjunctive (a.k.a., "or") patterns of the form <literal><emphasis>pat<subscript>1</subscript></emphasis> |\r
33568<emphasis>pat<subscript>2</subscript></emphasis></literal>, which matches a value that matches either <literal><emphasis>pat<subscript>1</subscript></emphasis></literal> or\r
33569<literal><emphasis>pat<subscript>2</subscript></emphasis></literal>. Disjunctive patterns have lower precedence than <literal>as</literal>\r
33570patterns and constraint patterns, much as <literal>orelse</literal> expressions have\r
33571lower precedence than <literal>andalso</literal> expressions and constraint\r
33572expressions. Both sub-patterns of a disjunctive pattern must bind the\r
33573same variables with the same types. The following example uses\r
33574disjunctive patterns:</simpara>\r
33575<programlisting language="sml" linenumbering="unnumbered">datatype t = A of int | B of int | C of int | D of int * int | E of int * int\r
33576\r
33577fun f t =\r
33578 case t of\r
33579 A x | B x | C x =&gt; x + 1\r
33580 | D (x, _) | E (_, x) =&gt; x * 2</programlisting>\r
33581</listitem>\r
33582<listitem>\r
33583<simpara>\r
33584<anchor id="SuccessorML_RecordPunExps" xreflabel="[SuccessorML_RecordPunExps]"/>\r
33585Record Punning Expressions: <literal>allowRecordPunExps {false|true}</literal>\r
33586</simpara>\r
33587<simpara>Allow record punning expressions, whereby an identifier <literal><emphasis>vid</emphasis></literal> as an\r
33588expression row in a record expression denotes the expression row\r
33589<literal><emphasis>vid</emphasis> = <emphasis>vid</emphasis></literal> (i.e., treating a label as a variable). The following\r
33590example uses record punning expressions (and also record punning\r
33591patterns):</simpara>\r
33592<programlisting language="sml" linenumbering="unnumbered">fun incB r =\r
33593 case r of {a, b, c} =&gt; {a, b = b + 1, c}</programlisting>\r
33594<simpara>and is equivalent to:</simpara>\r
33595<programlisting language="sml" linenumbering="unnumbered">fun incB r =\r
33596 case r of {a = a, b = b, c = c} =&gt; {a = a, b = b + 1, c = c}</programlisting>\r
33597</listitem>\r
33598<listitem>\r
33599<simpara>\r
33600<anchor id="SuccessorML_SigWithtype" xreflabel="[SuccessorML_SigWithtype]"/>\r
33601<literal>withtype</literal> in Signatures: <literal>allowSigWithtype {false|true}</literal>\r
33602</simpara>\r
33603<simpara>Allow <literal>withtype</literal> to modify a <literal>datatype</literal> specification in a signature.\r
33604The following example uses <literal>withtype</literal> in a signature (and also\r
33605<literal>withtype</literal> in a declaration):</simpara>\r
33606<programlisting language="sml" linenumbering="unnumbered">signature STREAM =\r
33607 sig\r
33608 datatype 'a u = Nil | Cons of 'a * 'a t\r
33609 withtype 'a t = unit -&gt; 'a u\r
33610 end\r
33611structure Stream : STREAM =\r
33612 struct\r
33613 datatype 'a u = Nil | Cons of 'a * 'a t\r
33614 withtype 'a t = unit -&gt; 'a u\r
33615 end</programlisting>\r
33616<simpara>and is equivalent to:</simpara>\r
33617<programlisting language="sml" linenumbering="unnumbered">signature STREAM =\r
33618 sig\r
33619 datatype 'a u = Nil | Cons of 'a * (unit -&gt; 'a u)\r
33620 type 'a t = unit -&gt; 'a u\r
33621 end\r
33622structure Stream : STREAM =\r
33623 struct\r
33624 datatype 'a u = Nil | Cons of 'a * (unit -&gt; 'a u)\r
33625 type 'a t = unit -&gt; 'a u\r
33626 end</programlisting>\r
33627</listitem>\r
33628<listitem>\r
33629<simpara>\r
33630<anchor id="SuccessorML_VectorExpsAndPats" xreflabel="[SuccessorML_VectorExpsAndPats]"/>\r
33631Vector Expressions and Patterns: <literal>allowVectorExpsAndPats {false|true}</literal>\r
33632</simpara>\r
33633<simpara>Allow or disallow vector expressions and vector patterns. This is a\r
33634proxy for all of the following annotations.</simpara>\r
33635<itemizedlist>\r
33636<listitem>\r
33637<simpara>\r
33638<anchor id="SuccessorML_VectorExps" xreflabel="[SuccessorML_VectorExps]"/>\r
33639Vector Expressions: <literal>allowVectorExps {false|true}</literal>\r
33640</simpara>\r
33641<simpara>Allow vector expressions of the form <literal>#[<emphasis>exp<subscript>0</subscript></emphasis>, <emphasis>exp<subscript>1</subscript></emphasis>, &#8230;, <emphasis>exp<subscript>n-1</subscript></emphasis>]</literal> (where <emphasis>n ≥ 0</emphasis>). The expression has type <literal><emphasis>τ</emphasis> vector</literal> when each expression <emphasis>exp<subscript>i</subscript></emphasis> has type <literal><emphasis>τ</emphasis></literal>.</simpara>\r
33642</listitem>\r
33643<listitem>\r
33644<simpara>\r
33645<anchor id="SuccessorML_VectorPats" xreflabel="[SuccessorML_VectorPats]"/>\r
33646Vector Patterns: <literal>allowVectorPats {false|true}</literal>\r
33647</simpara>\r
33648<simpara>Allow vector patterns of the form <literal>#[<emphasis>pat<subscript>0</subscript></emphasis>, <emphasis>pat<subscript>1</subscript></emphasis>, &#8230;, <emphasis>pat<subscript>n-1</subscript></emphasis>]</literal> (where <emphasis>n ≥ 0</emphasis>). The pattern matches values of type <literal><emphasis>τ</emphasis> vector</literal> when each pattern <emphasis>pat<subscript>i</subscript></emphasis> matches values of type <literal><emphasis>τ</emphasis></literal>.</simpara>\r
33649</listitem>\r
33650</itemizedlist>\r
33651</listitem>\r
33652</itemizedlist>\r
33653<simpara><?asciidoc-pagebreak?></simpara>\r
33654</section>\r
33655</section>\r
33656<section id="SureshJagannathan">\r
33657<title>SureshJagannathan</title>\r
33658<simpara>I am an Associate Professor at the <ulink url="http://www.cs.purdue.edu/">Department of Computer Science</ulink> at Purdue University.\r
33659My research focus is in programming language design and implementation, concurrency,\r
33660and distributed systems. I am interested in various aspects of MLton, mostly related to (in no particular order): (1) control-flow analysis (2) representation\r
33661strategies (e.g., flattening), (3) IR formats, and (4) extensions for distributed programming.</simpara>\r
33662<simpara>Please see my <ulink url="http://www.cs.purdue.edu/homes/suresh/index.html">Home page</ulink> for more details.</simpara>\r
33663<simpara><?asciidoc-pagebreak?></simpara>\r
33664</section>\r
33665<section id="Swerve">\r
33666<title>Swerve</title>\r
33667<simpara><ulink url="http://ftp.sun.ac.za/ftp/mirrorsites/ocaml/Systems_programming/book/c3253.html">Swerve</ulink>\r
33668is an HTTP server written in SML, originally developed with SML/NJ.\r
33669<link linkend="RayRacine">RayRacine</link> ported Swerve to MLton in January 2005.</simpara>\r
33670<simpara><ulink url="guide/Swerve.attachments/swerve.tar.bz2">Download</ulink> the port.</simpara>\r
33671<simpara>Excerpt from the included <literal>README</literal>:</simpara>\r
33672<blockquote>\r
33673<simpara>Total testing of this port consisted of a successful compile, startup,\r
33674and serving one html page with one gif image. Given that the original\r
33675code was throughly designed and implemented in a thoughtful manner and\r
33676I expect it is quite usable modulo a few minor bugs introduced by my\r
33677porting effort.</simpara>\r
33678</blockquote>\r
33679<simpara>Swerve is described in <link linkend="References_Shipman02">Shipman02</link>.</simpara>\r
33680<simpara><?asciidoc-pagebreak?></simpara>\r
33681</section>\r
33682<section id="SXML">\r
33683<title>SXML</title>\r
33684<simpara><link linkend="SXML">SXML</link> is an <link linkend="IntermediateLanguage">IntermediateLanguage</link>, translated from <link linkend="XML">XML</link> by\r
33685<link linkend="Monomorphise">Monomorphise</link>, optimized by <link linkend="SXMLSimplify">SXMLSimplify</link>, and translated by\r
33686<link linkend="ClosureConvert">ClosureConvert</link> to <link linkend="SSA">SSA</link>.</simpara>\r
33687<section id="_description_59">\r
33688<title>Description</title>\r
33689<simpara>SXML is a simply-typed version of <link linkend="XML">XML</link>.</simpara>\r
33690</section>\r
33691<section id="_implementation_64">\r
33692<title>Implementation</title>\r
33693<itemizedlist>\r
33694<listitem>\r
33695<simpara>\r
33696<ulink url="https://github.com/MLton/mlton/blob/master/mlton/xml/sxml.sig"><literal>sxml.sig</literal></ulink>\r
33697</simpara>\r
33698</listitem>\r
33699<listitem>\r
33700<simpara>\r
33701<ulink url="https://github.com/MLton/mlton/blob/master/mlton/xml/sxml.fun"><literal>sxml.fun</literal></ulink>\r
33702</simpara>\r
33703</listitem>\r
33704<listitem>\r
33705<simpara>\r
33706<ulink url="https://github.com/MLton/mlton/blob/master/mlton/xml/sxml-tree.sig"><literal>sxml-tree.sig</literal></ulink>\r
33707</simpara>\r
33708</listitem>\r
33709</itemizedlist>\r
33710</section>\r
33711<section id="_type_checking_7">\r
33712<title>Type Checking</title>\r
33713<simpara><link linkend="SXML">SXML</link> shares the type checker for <link linkend="XML">XML</link>.</simpara>\r
33714</section>\r
33715<section id="_details_and_notes_62">\r
33716<title>Details and Notes</title>\r
33717<simpara>There are only two differences between <link linkend="XML">XML</link> and <link linkend="SXML">SXML</link>. First,\r
33718<link linkend="SXML">SXML</link> <literal>val</literal>, <literal>fun</literal>, and <literal>datatype</literal> declarations always have an\r
33719empty list of type variables. Second, <link linkend="SXML">SXML</link> variable references\r
33720always have an empty list of type arguments. Constructors uses can\r
33721only have a nonempty list of type arguments if the constructor is a\r
33722primitive.</simpara>\r
33723<simpara>Although we could rely on the type system to enforce these constraints\r
33724by parameterizing the <link linkend="XML">XML</link> signature, <link linkend="StephenWeeks">StephenWeeks</link> did so in a\r
33725previous version of the compiler, and the software engineering gains\r
33726were not worth the effort.</simpara>\r
33727<simpara><?asciidoc-pagebreak?></simpara>\r
33728</section>\r
33729</section>\r
33730<section id="SXMLShrink">\r
33731<title>SXMLShrink</title>\r
33732<simpara>SXMLShrink is an optimization pass for the <link linkend="SXML">SXML</link>\r
33733<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="SXMLSimplify">SXMLSimplify</link>.</simpara>\r
33734<section id="_description_60">\r
33735<title>Description</title>\r
33736<simpara>This pass performs optimizations based on a reduction system.</simpara>\r
33737</section>\r
33738<section id="_implementation_65">\r
33739<title>Implementation</title>\r
33740<itemizedlist>\r
33741<listitem>\r
33742<simpara>\r
33743<ulink url="https://github.com/MLton/mlton/blob/master/mlton/xml/shrink.sig"><literal>shrink.sig</literal></ulink>\r
33744</simpara>\r
33745</listitem>\r
33746<listitem>\r
33747<simpara>\r
33748<ulink url="https://github.com/MLton/mlton/blob/master/mlton/xml/shrink.fun"><literal>shrink.fun</literal></ulink>\r
33749</simpara>\r
33750</listitem>\r
33751</itemizedlist>\r
33752</section>\r
33753<section id="_details_and_notes_63">\r
33754<title>Details and Notes</title>\r
33755<simpara><link linkend="SXML">SXML</link> shares the <link linkend="XMLShrink">XMLShrink</link> simplifier.</simpara>\r
33756<simpara><?asciidoc-pagebreak?></simpara>\r
33757</section>\r
33758</section>\r
33759<section id="SXMLSimplify">\r
33760<title>SXMLSimplify</title>\r
33761<simpara>The optimization passes for the <link linkend="SXML">SXML</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link> are\r
33762collected and controlled by the <literal>SxmlSimplify</literal> functor\r
33763(<ulink url="https://github.com/MLton/mlton/blob/master/mlton/xml/sxml-simplify.sig"><literal>sxml-simplify.sig</literal></ulink>,\r
33764<ulink url="https://github.com/MLton/mlton/blob/master/mlton/xml/sxml-simplify.fun"><literal>sxml-simplify.fun</literal></ulink>).</simpara>\r
33765<simpara>The following optimization passes are implemented:</simpara>\r
33766<itemizedlist>\r
33767<listitem>\r
33768<simpara>\r
33769<link linkend="Polyvariance">Polyvariance</link>\r
33770</simpara>\r
33771</listitem>\r
33772<listitem>\r
33773<simpara>\r
33774<link linkend="SXMLShrink">SXMLShrink</link>\r
33775</simpara>\r
33776</listitem>\r
33777</itemizedlist>\r
33778<simpara>The following implementation passes are implemented:</simpara>\r
33779<itemizedlist>\r
33780<listitem>\r
33781<simpara>\r
33782<link linkend="ImplementExceptions">ImplementExceptions</link>\r
33783</simpara>\r
33784</listitem>\r
33785<listitem>\r
33786<simpara>\r
33787<link linkend="ImplementSuffix">ImplementSuffix</link>\r
33788</simpara>\r
33789</listitem>\r
33790</itemizedlist>\r
33791<simpara>The following optimization passes are not implemented, but might prove useful:</simpara>\r
33792<itemizedlist>\r
33793<listitem>\r
33794<simpara>\r
33795<link linkend="Uncurry">Uncurry</link>\r
33796</simpara>\r
33797</listitem>\r
33798<listitem>\r
33799<simpara>\r
33800<link linkend="LambdaLift">LambdaLift</link>\r
33801</simpara>\r
33802</listitem>\r
33803</itemizedlist>\r
33804<simpara>The optimization passes can be controlled from the command-line by the options</simpara>\r
33805<itemizedlist>\r
33806<listitem>\r
33807<simpara>\r
33808<literal>-diag-pass &lt;pass&gt;</literal>&#8201;&#8212;&#8201;keep diagnostic info for pass\r
33809</simpara>\r
33810</listitem>\r
33811<listitem>\r
33812<simpara>\r
33813<literal>-disable-pass &lt;pass&gt;</literal>&#8201;&#8212;&#8201;skip optimization pass (if normally performed)\r
33814</simpara>\r
33815</listitem>\r
33816<listitem>\r
33817<simpara>\r
33818<literal>-enable-pass &lt;pass&gt;</literal>&#8201;&#8212;&#8201;perform optimization pass (if normally skipped)\r
33819</simpara>\r
33820</listitem>\r
33821<listitem>\r
33822<simpara>\r
33823<literal>-keep-pass &lt;pass&gt;</literal>&#8201;&#8212;&#8201;keep the results of pass\r
33824</simpara>\r
33825</listitem>\r
33826<listitem>\r
33827<simpara>\r
33828<literal>-sxml-passes &lt;passes&gt;</literal>&#8201;&#8212;&#8201;sxml optimization passes\r
33829</simpara>\r
33830</listitem>\r
33831</itemizedlist>\r
33832<simpara><?asciidoc-pagebreak?></simpara>\r
33833</section>\r
33834<section id="SyntacticConventions">\r
33835<title>SyntacticConventions</title>\r
33836<simpara>Here are a number of syntactic conventions useful for programming in\r
33837SML.</simpara>\r
33838<section id="_general">\r
33839<title>General</title>\r
33840<itemizedlist>\r
33841<listitem>\r
33842<simpara>\r
33843A line of code never exceeds 80 columns.\r
33844</simpara>\r
33845</listitem>\r
33846<listitem>\r
33847<simpara>\r
33848Only split a syntactic entity across multiple lines if it doesn&#8217;t fit on one line within 80 columns.\r
33849</simpara>\r
33850</listitem>\r
33851<listitem>\r
33852<simpara>\r
33853Use alphabetical order wherever possible.\r
33854</simpara>\r
33855</listitem>\r
33856<listitem>\r
33857<simpara>\r
33858Avoid redundant parentheses.\r
33859</simpara>\r
33860</listitem>\r
33861<listitem>\r
33862<simpara>\r
33863When using <literal>:</literal>, there is no space before the colon, and a single space after it.\r
33864</simpara>\r
33865</listitem>\r
33866</itemizedlist>\r
33867</section>\r
33868<section id="_identifiers">\r
33869<title>Identifiers</title>\r
33870<itemizedlist>\r
33871<listitem>\r
33872<simpara>\r
33873Variables, record labels and type constructors begin with and use\r
33874small letters, using capital letters to separate words.\r
33875</simpara>\r
33876<programlisting language="sml" linenumbering="unnumbered">cost\r
33877maxValue</programlisting>\r
33878</listitem>\r
33879<listitem>\r
33880<simpara>\r
33881Variables that represent collections of objects (lists, arrays,\r
33882vectors, &#8230;) are often suffixed with an <literal>s</literal>.\r
33883</simpara>\r
33884<programlisting language="sml" linenumbering="unnumbered">xs\r
33885employees</programlisting>\r
33886</listitem>\r
33887<listitem>\r
33888<simpara>\r
33889Constructors, structure identifiers, and functor identifiers begin\r
33890with a capital letter.\r
33891</simpara>\r
33892<programlisting language="sml" linenumbering="unnumbered">Queue\r
33893LinkedList</programlisting>\r
33894</listitem>\r
33895<listitem>\r
33896<simpara>\r
33897Signature identifiers are in all capitals, using <literal>_</literal> to separate\r
33898words.\r
33899</simpara>\r
33900<programlisting language="sml" linenumbering="unnumbered">LIST\r
33901BINARY_HEAP</programlisting>\r
33902</listitem>\r
33903</itemizedlist>\r
33904</section>\r
33905<section id="_types_2">\r
33906<title>Types</title>\r
33907<itemizedlist>\r
33908<listitem>\r
33909<simpara>\r
33910Alphabetize record labels. In a record type, there are spaces after\r
33911colons and commas, but not before colons or commas, or at the\r
33912delimiters <literal>{</literal> and <literal>}</literal>.\r
33913</simpara>\r
33914<programlisting language="sml" linenumbering="unnumbered">{bar: int, foo: int}</programlisting>\r
33915</listitem>\r
33916<listitem>\r
33917<simpara>\r
33918Only split a record type across multiple lines if it doesn&#8217;t fit on\r
33919one line. If a record type must be split over multiple lines, put one\r
33920field per line.\r
33921</simpara>\r
33922<programlisting language="sml" linenumbering="unnumbered">{bar: int,\r
33923 foo: real * real,\r
33924 zoo: bool}</programlisting>\r
33925</listitem>\r
33926<listitem>\r
33927<simpara>\r
33928In a tuple type, there are spaces before and after each <literal>*</literal>.\r
33929</simpara>\r
33930<programlisting language="sml" linenumbering="unnumbered">int * bool * real</programlisting>\r
33931</listitem>\r
33932<listitem>\r
33933<simpara>\r
33934Only split a tuple type across multiple lines if it doesn&#8217;t fit on\r
33935one line. In a tuple type split over multiple lines, there is one\r
33936type per line, and the <literal>*</literal>-s go at the beginning of the lines.\r
33937</simpara>\r
33938<programlisting language="sml" linenumbering="unnumbered">int\r
33939* bool\r
33940* real</programlisting>\r
33941<simpara>It may also be useful to parenthesize to make the grouping more\r
33942apparent.</simpara>\r
33943<programlisting language="sml" linenumbering="unnumbered">(int\r
33944 * bool\r
33945 * real)</programlisting>\r
33946</listitem>\r
33947<listitem>\r
33948<simpara>\r
33949In an arrow type split over multiple lines, put the arrow at the\r
33950beginning of its line.\r
33951</simpara>\r
33952<programlisting language="sml" linenumbering="unnumbered">int * real\r
33953-&gt; bool</programlisting>\r
33954<simpara>It may also be useful to parenthesize to make the grouping more\r
33955apparent.</simpara>\r
33956<programlisting language="sml" linenumbering="unnumbered">(int * real\r
33957 -&gt; bool)</programlisting>\r
33958</listitem>\r
33959<listitem>\r
33960<simpara>\r
33961Avoid redundant parentheses.\r
33962</simpara>\r
33963</listitem>\r
33964<listitem>\r
33965<simpara>\r
33966Arrow types associate to the right, so write\r
33967</simpara>\r
33968<programlisting language="sml" linenumbering="unnumbered">a -&gt; b -&gt; c</programlisting>\r
33969<simpara>not</simpara>\r
33970<programlisting language="sml" linenumbering="unnumbered">a -&gt; (b -&gt; c)</programlisting>\r
33971</listitem>\r
33972<listitem>\r
33973<simpara>\r
33974Type constructor application associates to the left, so write\r
33975</simpara>\r
33976<programlisting language="sml" linenumbering="unnumbered">int ref list</programlisting>\r
33977<simpara>not</simpara>\r
33978<programlisting language="sml" linenumbering="unnumbered">(int ref) list</programlisting>\r
33979</listitem>\r
33980<listitem>\r
33981<simpara>\r
33982Type constructor application binds more tightly than a tuple type,\r
33983so write\r
33984</simpara>\r
33985<programlisting language="sml" linenumbering="unnumbered">int list * bool list</programlisting>\r
33986<simpara>not</simpara>\r
33987<programlisting language="sml" linenumbering="unnumbered">(int list) * (bool list)</programlisting>\r
33988</listitem>\r
33989<listitem>\r
33990<simpara>\r
33991Tuple types bind more tightly than arrow types, so write\r
33992</simpara>\r
33993<programlisting language="sml" linenumbering="unnumbered">int * bool -&gt; real</programlisting>\r
33994<simpara>not</simpara>\r
33995<programlisting language="sml" linenumbering="unnumbered">(int * bool) -&gt; real</programlisting>\r
33996</listitem>\r
33997</itemizedlist>\r
33998</section>\r
33999<section id="_core">\r
34000<title>Core</title>\r
34001<itemizedlist>\r
34002<listitem>\r
34003<simpara>\r
34004A core expression or declaration split over multiple lines does not\r
34005contain any blank lines.\r
34006</simpara>\r
34007</listitem>\r
34008<listitem>\r
34009<simpara>\r
34010A record field selector has no space between the <literal>#</literal> and the record\r
34011label. So, write\r
34012</simpara>\r
34013<programlisting language="sml" linenumbering="unnumbered">#foo</programlisting>\r
34014<simpara>not</simpara>\r
34015<programlisting language="sml" linenumbering="unnumbered"># foo</programlisting>\r
34016</listitem>\r
34017<listitem>\r
34018<simpara>\r
34019A tuple has a space after each comma, but not before, and not at the\r
34020delimiters <literal>(</literal> and <literal>)</literal>.\r
34021</simpara>\r
34022<programlisting language="sml" linenumbering="unnumbered">(e1, e2, e3)</programlisting>\r
34023</listitem>\r
34024<listitem>\r
34025<simpara>\r
34026A tuple split over multiple lines has one element per line, and the\r
34027commas go at the end of the lines.\r
34028</simpara>\r
34029<programlisting language="sml" linenumbering="unnumbered">(e1,\r
34030 e2,\r
34031 e3)</programlisting>\r
34032</listitem>\r
34033<listitem>\r
34034<simpara>\r
34035A list has a space after each comma, but not before, and not at the\r
34036delimiters <literal>[</literal> and <literal>]</literal>.\r
34037</simpara>\r
34038<programlisting language="sml" linenumbering="unnumbered">[e1, e2, e3]</programlisting>\r
34039</listitem>\r
34040<listitem>\r
34041<simpara>\r
34042A list split over multiple lines has one element per line, and the\r
34043commas at the end of the lines.\r
34044</simpara>\r
34045<programlisting language="sml" linenumbering="unnumbered">[e1,\r
34046 e2,\r
34047 e3]</programlisting>\r
34048</listitem>\r
34049<listitem>\r
34050<simpara>\r
34051A record has spaces before and after <literal>=</literal>, a space after each comma,\r
34052but not before, and not at the delimiters <literal>{</literal> and <literal>}</literal>. Field names\r
34053appear in alphabetical order.\r
34054</simpara>\r
34055<programlisting language="sml" linenumbering="unnumbered">{bar = 13, foo = true}</programlisting>\r
34056</listitem>\r
34057<listitem>\r
34058<simpara>\r
34059A sequence expression has a space after each semicolon, but not before.\r
34060</simpara>\r
34061<programlisting language="sml" linenumbering="unnumbered">(e1; e2; e3)</programlisting>\r
34062</listitem>\r
34063<listitem>\r
34064<simpara>\r
34065A sequence expression split over multiple lines has one expression\r
34066per line, and the semicolons at the beginning of lines. Lisp and\r
34067Scheme programmers may find this hard to read at first.\r
34068</simpara>\r
34069<programlisting language="sml" linenumbering="unnumbered">(e1\r
34070 ; e2\r
34071 ; e3)</programlisting>\r
34072<simpara><emphasis>Rationale</emphasis>: this makes it easy to visually spot the beginning of each\r
34073expression, which becomes more valuable as the expressions themselves\r
34074are split across multiple lines.</simpara>\r
34075</listitem>\r
34076<listitem>\r
34077<simpara>\r
34078An application expression has a space between the function and the\r
34079argument. There are no parens unless the argument is a tuple (in\r
34080which case the parens are really part of the tuple, not the\r
34081application).\r
34082</simpara>\r
34083<programlisting language="sml" linenumbering="unnumbered">f a\r
34084f (a1, a2, a3)</programlisting>\r
34085</listitem>\r
34086<listitem>\r
34087<simpara>\r
34088Avoid redundant parentheses. Application associates to left, so\r
34089write\r
34090</simpara>\r
34091<programlisting language="sml" linenumbering="unnumbered">f a1 a2 a3</programlisting>\r
34092<simpara>not</simpara>\r
34093<programlisting language="sml" linenumbering="unnumbered">((f a1) a2) a3</programlisting>\r
34094</listitem>\r
34095<listitem>\r
34096<simpara>\r
34097Infix operators have a space before and after the operator.\r
34098</simpara>\r
34099<programlisting language="sml" linenumbering="unnumbered">x + y\r
34100x * y - z</programlisting>\r
34101</listitem>\r
34102<listitem>\r
34103<simpara>\r
34104Avoid redundant parentheses. Use <link linkend="OperatorPrecedence">OperatorPrecedence</link>. So, write\r
34105</simpara>\r
34106<programlisting language="sml" linenumbering="unnumbered">x + y * z</programlisting>\r
34107<simpara>not</simpara>\r
34108<programlisting language="sml" linenumbering="unnumbered">x + (y * z)</programlisting>\r
34109</listitem>\r
34110<listitem>\r
34111<simpara>\r
34112An <literal>andalso</literal> expression split over multiple lines has the <literal>andalso</literal>\r
34113at the beginning of subsequent lines.\r
34114</simpara>\r
34115<programlisting language="sml" linenumbering="unnumbered">e1\r
34116andalso e2\r
34117andalso e3</programlisting>\r
34118</listitem>\r
34119<listitem>\r
34120<simpara>\r
34121A <literal>case</literal> expression is indented as follows\r
34122</simpara>\r
34123<programlisting language="sml" linenumbering="unnumbered">case e1 of\r
34124 p1 =&gt; e1\r
34125 | p2 =&gt; e2\r
34126 | p3 =&gt; e3</programlisting>\r
34127</listitem>\r
34128<listitem>\r
34129<simpara>\r
34130A <literal>datatype</literal>'s constructors are alphabetized.\r
34131</simpara>\r
34132<programlisting language="sml" linenumbering="unnumbered">datatype t = A | B | C</programlisting>\r
34133</listitem>\r
34134<listitem>\r
34135<simpara>\r
34136A <literal>datatype</literal> declaration has a space before and after each <literal>|</literal>.\r
34137</simpara>\r
34138<programlisting language="sml" linenumbering="unnumbered">datatype t = A | B of int | C</programlisting>\r
34139</listitem>\r
34140<listitem>\r
34141<simpara>\r
34142A <literal>datatype</literal> split over multiple lines has one constructor per line,\r
34143with the <literal>|</literal> at the beginning of lines and the constructors beginning\r
341443 columns to the right of the <literal>datatype</literal>.\r
34145</simpara>\r
34146<programlisting language="sml" linenumbering="unnumbered">datatype t =\r
34147 A\r
34148 | B\r
34149 | C</programlisting>\r
34150</listitem>\r
34151<listitem>\r
34152<simpara>\r
34153A <literal>fun</literal> declaration may start its body on the subsequent line,\r
34154indented 3 spaces.\r
34155</simpara>\r
34156<programlisting language="sml" linenumbering="unnumbered">fun f x y =\r
34157 let\r
34158 val z = x + y + z\r
34159 in\r
34160 z\r
34161 end</programlisting>\r
34162</listitem>\r
34163<listitem>\r
34164<simpara>\r
34165An <literal>if</literal> expression is indented as follows.\r
34166</simpara>\r
34167<programlisting language="sml" linenumbering="unnumbered">if e1\r
34168 then e2\r
34169else e3</programlisting>\r
34170</listitem>\r
34171<listitem>\r
34172<simpara>\r
34173A sequence of <literal>if</literal>-<literal>then</literal>-<literal>else</literal>-s is indented as follows.\r
34174</simpara>\r
34175<programlisting language="sml" linenumbering="unnumbered">if e1\r
34176 then e2\r
34177else if e3\r
34178 then e4\r
34179else if e5\r
34180 then e6\r
34181else e7</programlisting>\r
34182</listitem>\r
34183<listitem>\r
34184<simpara>\r
34185A <literal>let</literal> expression has the <literal>let</literal>, <literal>in</literal>, and <literal>end</literal> on their own\r
34186lines, starting in the same column. Declarations and the body are\r
34187indented 3 spaces.\r
34188</simpara>\r
34189<programlisting language="sml" linenumbering="unnumbered">let\r
34190 val x = 13\r
34191 val y = 14\r
34192in\r
34193 x + y\r
34194end</programlisting>\r
34195</listitem>\r
34196<listitem>\r
34197<simpara>\r
34198A <literal>local</literal> declaration has the <literal>local</literal>, <literal>in</literal>, and <literal>end</literal> on their own\r
34199lines, starting in the same column. Declarations are indented 3\r
34200spaces.\r
34201</simpara>\r
34202<programlisting language="sml" linenumbering="unnumbered">local\r
34203 val x = 13\r
34204in\r
34205 val y = x\r
34206end</programlisting>\r
34207</listitem>\r
34208<listitem>\r
34209<simpara>\r
34210An <literal>orelse</literal> expression split over multiple lines has the <literal>orelse</literal> at\r
34211the beginning of subsequent lines.\r
34212</simpara>\r
34213<programlisting language="sml" linenumbering="unnumbered">e1\r
34214orelse e2\r
34215orelse e3</programlisting>\r
34216</listitem>\r
34217<listitem>\r
34218<simpara>\r
34219A <literal>val</literal> declaration has a space before and after the <literal>=</literal>.\r
34220</simpara>\r
34221<programlisting language="sml" linenumbering="unnumbered">val p = e</programlisting>\r
34222</listitem>\r
34223<listitem>\r
34224<simpara>\r
34225A <literal>val</literal> declaration can start the expression on the subsequent line,\r
34226indented 3 spaces.\r
34227</simpara>\r
34228<programlisting language="sml" linenumbering="unnumbered">val p =\r
34229 if e1 then e2 else e3</programlisting>\r
34230</listitem>\r
34231</itemizedlist>\r
34232</section>\r
34233<section id="_signatures">\r
34234<title>Signatures</title>\r
34235<itemizedlist>\r
34236<listitem>\r
34237<simpara>\r
34238A <literal>signature</literal> declaration is indented as follows.\r
34239</simpara>\r
34240<programlisting language="sml" linenumbering="unnumbered">signature FOO =\r
34241 sig\r
34242 val x: int\r
34243 end</programlisting>\r
34244<simpara><emphasis>Exception</emphasis>: a signature declaration in a file to itself can omit the\r
34245indentation to save horizontal space.</simpara>\r
34246<programlisting language="sml" linenumbering="unnumbered">signature FOO =\r
34247sig\r
34248\r
34249val x: int\r
34250\r
34251end</programlisting>\r
34252<simpara>In this case, there should be a blank line after the <literal>sig</literal> and before\r
34253the <literal>end</literal>.</simpara>\r
34254</listitem>\r
34255<listitem>\r
34256<simpara>\r
34257A <literal>val</literal> specification has a space after the colon, but not before.\r
34258</simpara>\r
34259<programlisting language="sml" linenumbering="unnumbered">val x: int</programlisting>\r
34260<simpara><emphasis>Exception</emphasis>: in the case of operators (like <literal>+</literal>), there is a space\r
34261before the colon to avoid lexing the colon as part of the operator.</simpara>\r
34262<programlisting language="sml" linenumbering="unnumbered">val + : t * t -&gt; t</programlisting>\r
34263</listitem>\r
34264<listitem>\r
34265<simpara>\r
34266Alphabetize specifications in signatures.\r
34267</simpara>\r
34268<programlisting language="sml" linenumbering="unnumbered">sig\r
34269 val x: int\r
34270 val y: bool\r
34271end</programlisting>\r
34272</listitem>\r
34273</itemizedlist>\r
34274</section>\r
34275<section id="_structures">\r
34276<title>Structures</title>\r
34277<itemizedlist>\r
34278<listitem>\r
34279<simpara>\r
34280A <literal>structure</literal> declaration has a space on both sides of the <literal>=</literal>.\r
34281</simpara>\r
34282<programlisting language="sml" linenumbering="unnumbered">structure Foo = Bar</programlisting>\r
34283</listitem>\r
34284<listitem>\r
34285<simpara>\r
34286A <literal>structure</literal> declaration split over multiple lines is indented as\r
34287follows.\r
34288</simpara>\r
34289<programlisting language="sml" linenumbering="unnumbered">structure S =\r
34290 struct\r
34291 val x = 13\r
34292 end</programlisting>\r
34293<simpara><emphasis>Exception</emphasis>: a structure declaration in a file to itself can omit the\r
34294indentation to save horizontal space.</simpara>\r
34295<programlisting language="sml" linenumbering="unnumbered">structure S =\r
34296struct\r
34297\r
34298val x = 13\r
34299\r
34300end</programlisting>\r
34301<simpara>In this case, there should be a blank line after the <literal>struct</literal> and\r
34302before the <literal>end</literal>.</simpara>\r
34303</listitem>\r
34304<listitem>\r
34305<simpara>\r
34306Declarations in a <literal>struct</literal> are separated by blank lines.\r
34307</simpara>\r
34308<programlisting language="sml" linenumbering="unnumbered">struct\r
34309 val x =\r
34310 let\r
34311 y = 13\r
34312 in\r
34313 y + 1\r
34314 end\r
34315\r
34316 val z = 14\r
34317end</programlisting>\r
34318</listitem>\r
34319</itemizedlist>\r
34320</section>\r
34321<section id="_functors">\r
34322<title>Functors</title>\r
34323<itemizedlist>\r
34324<listitem>\r
34325<simpara>\r
34326A <literal>functor</literal> declaration has spaces after each <literal>:</literal> (or <literal>:&gt;</literal>) but not\r
34327before, and a space before and after the <literal>=</literal>. It is indented as\r
34328follows.\r
34329</simpara>\r
34330<programlisting language="sml" linenumbering="unnumbered">functor Foo (S: FOO_ARG): FOO =\r
34331 struct\r
34332 val x = S.x\r
34333 end</programlisting>\r
34334<simpara><emphasis>Exception</emphasis>: a functor declaration in a file to itself can omit the\r
34335indentation to save horizontal space.</simpara>\r
34336<programlisting language="sml" linenumbering="unnumbered">functor Foo (S: FOO_ARG): FOO =\r
34337struct\r
34338\r
34339val x = S.x\r
34340\r
34341end</programlisting>\r
34342<simpara>In this case, there should be a blank line after the <literal>struct</literal>\r
34343and before the <literal>end</literal>.</simpara>\r
34344</listitem>\r
34345</itemizedlist>\r
34346<simpara><?asciidoc-pagebreak?></simpara>\r
34347</section>\r
34348</section>\r
34349<section id="Talk">\r
34350<title>Talk</title>\r
34351<section id="_the_mlton_standard_ml_compiler">\r
34352<title>The MLton Standard ML Compiler</title>\r
34353<simpara><emphasis role="strong">Henry Cejtin, Matthew Fluet, Suresh Jagannathan, Stephen Weeks</emphasis></simpara>\r
34354<simpara>&#160;<?asciidoc-br?>\r
34355&#160;<?asciidoc-br?>\r
34356&#160;<?asciidoc-br?></simpara>\r
34357<simpara><?asciidoc-hr?></simpara>\r
34358<informaltable\r
34359frame="all"\r
34360rowsep="1" colsep="1"\r
34361>\r
34362<tgroup cols="2">\r
34363<colspec colname="col_1" colwidth="50*"/>\r
34364<colspec colname="col_2" colwidth="50*"/>\r
34365<tbody>\r
34366<row>\r
34367<entry align="left" valign="top"><simpara></simpara></entry>\r
34368<entry align="right" valign="top"><simpara><link linkend="TalkStandardML">Next</link></simpara></entry>\r
34369</row>\r
34370</tbody>\r
34371</tgroup>\r
34372</informaltable>\r
34373<simpara><?asciidoc-pagebreak?></simpara>\r
34374</section>\r
34375</section>\r
34376<section id="TalkDiveIn">\r
34377<title>TalkDiveIn</title>\r
34378<section id="_dive_in">\r
34379<title>Dive In</title>\r
34380<itemizedlist>\r
34381<listitem>\r
34382<simpara>\r
34383to <link linkend="Development">Development</link>\r
34384</simpara>\r
34385</listitem>\r
34386<listitem>\r
34387<simpara>\r
34388to <link linkend="Documentation">Documentation</link>\r
34389</simpara>\r
34390</listitem>\r
34391<listitem>\r
34392<simpara>\r
34393to <link linkend="Download">Download</link>\r
34394</simpara>\r
34395</listitem>\r
34396</itemizedlist>\r
34397<simpara>&#160;<?asciidoc-br?>\r
34398&#160;<?asciidoc-br?>\r
34399&#160;<?asciidoc-br?></simpara>\r
34400<simpara><?asciidoc-hr?></simpara>\r
34401<informaltable\r
34402frame="all"\r
34403rowsep="1" colsep="1"\r
34404>\r
34405<tgroup cols="2">\r
34406<colspec colname="col_1" colwidth="50*"/>\r
34407<colspec colname="col_2" colwidth="50*"/>\r
34408<tbody>\r
34409<row>\r
34410<entry align="left" valign="top"><simpara><link linkend="TalkMLtonHistory">Prev</link></simpara></entry>\r
34411<entry align="right" valign="top"><simpara></simpara></entry>\r
34412</row>\r
34413</tbody>\r
34414</tgroup>\r
34415</informaltable>\r
34416<simpara><?asciidoc-pagebreak?></simpara>\r
34417</section>\r
34418</section>\r
34419<section id="TalkFolkLore">\r
34420<title>TalkFolkLore</title>\r
34421<section id="_folk_lore">\r
34422<title>Folk Lore</title>\r
34423<itemizedlist>\r
34424<listitem>\r
34425<simpara>\r
34426Defunctorization and monomorphisation are feasible\r
34427</simpara>\r
34428</listitem>\r
34429<listitem>\r
34430<simpara>\r
34431Global control-flow analysis is feasible\r
34432</simpara>\r
34433</listitem>\r
34434<listitem>\r
34435<simpara>\r
34436Early closure conversion is feasible\r
34437</simpara>\r
34438</listitem>\r
34439</itemizedlist>\r
34440<simpara>&#160;<?asciidoc-br?>\r
34441&#160;<?asciidoc-br?>\r
34442&#160;<?asciidoc-br?></simpara>\r
34443<simpara><?asciidoc-hr?></simpara>\r
34444<informaltable\r
34445frame="all"\r
34446rowsep="1" colsep="1"\r
34447>\r
34448<tgroup cols="2">\r
34449<colspec colname="col_1" colwidth="50*"/>\r
34450<colspec colname="col_2" colwidth="50*"/>\r
34451<tbody>\r
34452<row>\r
34453<entry align="left" valign="top"><simpara><link linkend="TalkWholeProgram">Prev</link></simpara></entry>\r
34454<entry align="right" valign="top"><simpara><link linkend="TalkMLtonFeatures">Next</link></simpara></entry>\r
34455</row>\r
34456</tbody>\r
34457</tgroup>\r
34458</informaltable>\r
34459<simpara><?asciidoc-pagebreak?></simpara>\r
34460</section>\r
34461</section>\r
34462<section id="TalkFromSMLTo">\r
34463<title>TalkFromSMLTo</title>\r
34464<section id="_from_standard_ml_to_s_t_f_o_il">\r
34465<title>From Standard ML to S-T F-O IL</title>\r
34466<itemizedlist>\r
34467<listitem>\r
34468<simpara>\r
34469What issues arise when translating from Standard ML into an intermediate language?\r
34470</simpara>\r
34471</listitem>\r
34472</itemizedlist>\r
34473<simpara>&#160;<?asciidoc-br?>\r
34474&#160;<?asciidoc-br?>\r
34475&#160;<?asciidoc-br?></simpara>\r
34476<simpara><?asciidoc-hr?></simpara>\r
34477<informaltable\r
34478frame="all"\r
34479rowsep="1" colsep="1"\r
34480>\r
34481<tgroup cols="2">\r
34482<colspec colname="col_1" colwidth="50*"/>\r
34483<colspec colname="col_2" colwidth="50*"/>\r
34484<tbody>\r
34485<row>\r
34486<entry align="left" valign="top"><simpara><link linkend="TalkMLtonApproach">Prev</link></simpara></entry>\r
34487<entry align="right" valign="top"><simpara><link linkend="TalkHowModules">Next</link></simpara></entry>\r
34488</row>\r
34489</tbody>\r
34490</tgroup>\r
34491</informaltable>\r
34492<simpara><?asciidoc-pagebreak?></simpara>\r
34493</section>\r
34494</section>\r
34495<section id="TalkHowHigherOrder">\r
34496<title>TalkHowHigherOrder</title>\r
34497<section id="_higher_order_functions">\r
34498<title>Higher-order Functions</title>\r
34499<itemizedlist>\r
34500<listitem>\r
34501<simpara>\r
34502How does one represent SML&#8217;s higher-order functions?\r
34503</simpara>\r
34504</listitem>\r
34505<listitem>\r
34506<simpara>\r
34507MLton&#8217;s answer: defunctionalize\r
34508</simpara>\r
34509</listitem>\r
34510</itemizedlist>\r
34511<simpara>&#160;<?asciidoc-br?>\r
34512&#160;<?asciidoc-br?></simpara>\r
34513<simpara>See <link linkend="ClosureConvert">ClosureConvert</link>.</simpara>\r
34514<simpara>&#160;<?asciidoc-br?>\r
34515&#160;<?asciidoc-br?>\r
34516&#160;<?asciidoc-br?></simpara>\r
34517<simpara><?asciidoc-hr?></simpara>\r
34518<informaltable\r
34519frame="all"\r
34520rowsep="1" colsep="1"\r
34521>\r
34522<tgroup cols="2">\r
34523<colspec colname="col_1" colwidth="50*"/>\r
34524<colspec colname="col_2" colwidth="50*"/>\r
34525<tbody>\r
34526<row>\r
34527<entry align="left" valign="top"><simpara><link linkend="TalkMLtonApproach">Prev</link></simpara></entry>\r
34528<entry align="right" valign="top"><simpara><link linkend="TalkWholeProgram">Next</link></simpara></entry>\r
34529</row>\r
34530</tbody>\r
34531</tgroup>\r
34532</informaltable>\r
34533<simpara><?asciidoc-pagebreak?></simpara>\r
34534</section>\r
34535</section>\r
34536<section id="TalkHowModules">\r
34537<title>TalkHowModules</title>\r
34538<section id="_modules">\r
34539<title>Modules</title>\r
34540<itemizedlist>\r
34541<listitem>\r
34542<simpara>\r
34543How does one represent SML&#8217;s modules?\r
34544</simpara>\r
34545</listitem>\r
34546<listitem>\r
34547<simpara>\r
34548MLton&#8217;s answer: defunctorize\r
34549</simpara>\r
34550</listitem>\r
34551</itemizedlist>\r
34552<simpara>&#160;<?asciidoc-br?>\r
34553&#160;<?asciidoc-br?></simpara>\r
34554<simpara>See <link linkend="Elaborate">Elaborate</link>.</simpara>\r
34555<simpara>&#160;<?asciidoc-br?>\r
34556&#160;<?asciidoc-br?>\r
34557&#160;<?asciidoc-br?></simpara>\r
34558<simpara><?asciidoc-hr?></simpara>\r
34559<informaltable\r
34560frame="all"\r
34561rowsep="1" colsep="1"\r
34562>\r
34563<tgroup cols="2">\r
34564<colspec colname="col_1" colwidth="50*"/>\r
34565<colspec colname="col_2" colwidth="50*"/>\r
34566<tbody>\r
34567<row>\r
34568<entry align="left" valign="top"><simpara><link linkend="TalkFromSMLTo">Prev</link></simpara></entry>\r
34569<entry align="right" valign="top"><simpara><link linkend="TalkHowPolymorphism">Next</link></simpara></entry>\r
34570</row>\r
34571</tbody>\r
34572</tgroup>\r
34573</informaltable>\r
34574<simpara><?asciidoc-pagebreak?></simpara>\r
34575</section>\r
34576</section>\r
34577<section id="TalkHowPolymorphism">\r
34578<title>TalkHowPolymorphism</title>\r
34579<section id="_polymorphism">\r
34580<title>Polymorphism</title>\r
34581<itemizedlist>\r
34582<listitem>\r
34583<simpara>\r
34584How does one represent SML&#8217;s polymorphism?\r
34585</simpara>\r
34586</listitem>\r
34587<listitem>\r
34588<simpara>\r
34589MLton&#8217;s answer: monomorphise\r
34590</simpara>\r
34591</listitem>\r
34592</itemizedlist>\r
34593<simpara>&#160;<?asciidoc-br?>\r
34594&#160;<?asciidoc-br?></simpara>\r
34595<simpara>See <link linkend="Monomorphise">Monomorphise</link>.</simpara>\r
34596<simpara>&#160;<?asciidoc-br?>\r
34597&#160;<?asciidoc-br?>\r
34598&#160;<?asciidoc-br?></simpara>\r
34599<simpara><?asciidoc-hr?></simpara>\r
34600<informaltable\r
34601frame="all"\r
34602rowsep="1" colsep="1"\r
34603>\r
34604<tgroup cols="2">\r
34605<colspec colname="col_1" colwidth="50*"/>\r
34606<colspec colname="col_2" colwidth="50*"/>\r
34607<tbody>\r
34608<row>\r
34609<entry align="left" valign="top"><simpara><link linkend="TalkHowModules">Prev</link></simpara></entry>\r
34610<entry align="right" valign="top"><simpara><link linkend="TalkHowHigherOrder">Next</link></simpara></entry>\r
34611</row>\r
34612</tbody>\r
34613</tgroup>\r
34614</informaltable>\r
34615<simpara><?asciidoc-pagebreak?></simpara>\r
34616</section>\r
34617</section>\r
34618<section id="TalkMLtonApproach">\r
34619<title>TalkMLtonApproach</title>\r
34620<section id="_mlton_8217_s_approach">\r
34621<title>MLton&#8217;s Approach</title>\r
34622<itemizedlist>\r
34623<listitem>\r
34624<simpara>\r
34625whole-program optimization using a simply-typed, first-order intermediate language\r
34626</simpara>\r
34627</listitem>\r
34628<listitem>\r
34629<simpara>\r
34630ensures programs are not penalized for exploiting abstraction and modularity\r
34631</simpara>\r
34632</listitem>\r
34633</itemizedlist>\r
34634<simpara>&#160;<?asciidoc-br?>\r
34635&#160;<?asciidoc-br?>\r
34636&#160;<?asciidoc-br?></simpara>\r
34637<simpara><?asciidoc-hr?></simpara>\r
34638<informaltable\r
34639frame="all"\r
34640rowsep="1" colsep="1"\r
34641>\r
34642<tgroup cols="2">\r
34643<colspec colname="col_1" colwidth="50*"/>\r
34644<colspec colname="col_2" colwidth="50*"/>\r
34645<tbody>\r
34646<row>\r
34647<entry align="left" valign="top"><simpara><link linkend="TalkStandardML">Prev</link></simpara></entry>\r
34648<entry align="right" valign="top"><simpara><link linkend="TalkFromSMLTo">Next</link></simpara></entry>\r
34649</row>\r
34650</tbody>\r
34651</tgroup>\r
34652</informaltable>\r
34653<simpara><?asciidoc-pagebreak?></simpara>\r
34654</section>\r
34655</section>\r
34656<section id="TalkMLtonFeatures">\r
34657<title>TalkMLtonFeatures</title>\r
34658<section id="_mlton_features">\r
34659<title>MLton Features</title>\r
34660<itemizedlist>\r
34661<listitem>\r
34662<simpara>\r
34663Supports full Standard ML language and Basis Library\r
34664</simpara>\r
34665</listitem>\r
34666<listitem>\r
34667<simpara>\r
34668Generates standalone executables\r
34669</simpara>\r
34670</listitem>\r
34671<listitem>\r
34672<simpara>\r
34673Extensions\r
34674</simpara>\r
34675<itemizedlist>\r
34676<listitem>\r
34677<simpara>\r
34678Foreign function interface (SML to C, C to SML)\r
34679</simpara>\r
34680</listitem>\r
34681<listitem>\r
34682<simpara>\r
34683ML Basis system for programming in the very large\r
34684</simpara>\r
34685</listitem>\r
34686<listitem>\r
34687<simpara>\r
34688Extension libraries\r
34689</simpara>\r
34690</listitem>\r
34691</itemizedlist>\r
34692</listitem>\r
34693</itemizedlist>\r
34694<simpara>&#160;<?asciidoc-br?>\r
34695&#160;<?asciidoc-br?></simpara>\r
34696<simpara>See <link linkend="Features">Features</link>.</simpara>\r
34697<simpara>&#160;<?asciidoc-br?>\r
34698&#160;<?asciidoc-br?>\r
34699&#160;<?asciidoc-br?></simpara>\r
34700<simpara><?asciidoc-hr?></simpara>\r
34701<informaltable\r
34702frame="all"\r
34703rowsep="1" colsep="1"\r
34704>\r
34705<tgroup cols="2">\r
34706<colspec colname="col_1" colwidth="50*"/>\r
34707<colspec colname="col_2" colwidth="50*"/>\r
34708<tbody>\r
34709<row>\r
34710<entry align="left" valign="top"><simpara><link linkend="TalkFolkLore">Prev</link></simpara></entry>\r
34711<entry align="right" valign="top"><simpara><link linkend="TalkMLtonHistory">Next</link></simpara></entry>\r
34712</row>\r
34713</tbody>\r
34714</tgroup>\r
34715</informaltable>\r
34716<simpara><?asciidoc-pagebreak?></simpara>\r
34717</section>\r
34718</section>\r
34719<section id="TalkMLtonHistory">\r
34720<title>TalkMLtonHistory</title>\r
34721<section id="_mlton_history">\r
34722<title>MLton History</title>\r
34723<informaltable\r
34724frame="all"\r
34725rowsep="1" colsep="1"\r
34726>\r
34727<tgroup cols="2">\r
34728<colspec colname="col_1" colwidth="25*"/>\r
34729<colspec colname="col_2" colwidth="75*"/>\r
34730<tbody>\r
34731<row>\r
34732<entry align="left" valign="top"><simpara>April 1997</simpara></entry>\r
34733<entry align="left" valign="top"><simpara>Stephen Weeks wrote a defunctorizer for SML/NJ</simpara></entry>\r
34734</row>\r
34735<row>\r
34736<entry align="left" valign="top"><simpara>Aug. 1997</simpara></entry>\r
34737<entry align="left" valign="top"><simpara>Begin independent compiler (<literal>smlc</literal>)</simpara></entry>\r
34738</row>\r
34739<row>\r
34740<entry align="left" valign="top"><simpara>Oct. 1997</simpara></entry>\r
34741<entry align="left" valign="top"><simpara>Monomorphiser</simpara></entry>\r
34742</row>\r
34743<row>\r
34744<entry align="left" valign="top"><simpara>Nov. 1997</simpara></entry>\r
34745<entry align="left" valign="top"><simpara>Polyvariant higher-order control-flow analysis (10,000 lines)</simpara></entry>\r
34746</row>\r
34747<row>\r
34748<entry align="left" valign="top"><simpara>March 1999</simpara></entry>\r
34749<entry align="left" valign="top"><simpara>First release of MLton (48,006 lines)</simpara></entry>\r
34750</row>\r
34751<row>\r
34752<entry align="left" valign="top"><simpara>Jan. 2002</simpara></entry>\r
34753<entry align="left" valign="top"><simpara>MLton at 102,541 lines</simpara></entry>\r
34754</row>\r
34755<row>\r
34756<entry align="left" valign="top"><simpara>Jan. 2003</simpara></entry>\r
34757<entry align="left" valign="top"><simpara>MLton at 112,204 lines</simpara></entry>\r
34758</row>\r
34759<row>\r
34760<entry align="left" valign="top"><simpara>Jan. 2004</simpara></entry>\r
34761<entry align="left" valign="top"><simpara>MLton at 122,299 lines</simpara></entry>\r
34762</row>\r
34763<row>\r
34764<entry align="left" valign="top"><simpara>Nov. 2004</simpara></entry>\r
34765<entry align="left" valign="top"><simpara>MLton at 141,311 lines</simpara></entry>\r
34766</row>\r
34767</tbody>\r
34768</tgroup>\r
34769</informaltable>\r
34770<simpara>&#160;<?asciidoc-br?>\r
34771&#160;<?asciidoc-br?></simpara>\r
34772<simpara>See <link linkend="History">History</link>.</simpara>\r
34773<simpara>&#160;<?asciidoc-br?>\r
34774&#160;<?asciidoc-br?>\r
34775&#160;<?asciidoc-br?></simpara>\r
34776<simpara><?asciidoc-hr?></simpara>\r
34777<informaltable\r
34778frame="all"\r
34779rowsep="1" colsep="1"\r
34780>\r
34781<tgroup cols="2">\r
34782<colspec colname="col_1" colwidth="50*"/>\r
34783<colspec colname="col_2" colwidth="50*"/>\r
34784<tbody>\r
34785<row>\r
34786<entry align="left" valign="top"><simpara><link linkend="TalkMLtonFeatures">Prev</link></simpara></entry>\r
34787<entry align="right" valign="top"><simpara><link linkend="TalkDiveIn">Next</link></simpara></entry>\r
34788</row>\r
34789</tbody>\r
34790</tgroup>\r
34791</informaltable>\r
34792<simpara><?asciidoc-pagebreak?></simpara>\r
34793</section>\r
34794</section>\r
34795<section id="TalkStandardML">\r
34796<title>TalkStandardML</title>\r
34797<section id="_standard_ml">\r
34798<title>Standard ML</title>\r
34799<itemizedlist>\r
34800<listitem>\r
34801<simpara>\r
34802a high-level language makes\r
34803</simpara>\r
34804<itemizedlist>\r
34805<listitem>\r
34806<simpara>\r
34807a programmer&#8217;s life easier\r
34808</simpara>\r
34809</listitem>\r
34810<listitem>\r
34811<simpara>\r
34812a compiler writer&#8217;s life harder\r
34813</simpara>\r
34814</listitem>\r
34815</itemizedlist>\r
34816</listitem>\r
34817<listitem>\r
34818<simpara>\r
34819perceived overheads of features discourage their use\r
34820</simpara>\r
34821<itemizedlist>\r
34822<listitem>\r
34823<simpara>\r
34824higher-order functions\r
34825</simpara>\r
34826</listitem>\r
34827<listitem>\r
34828<simpara>\r
34829polymorphic datatypes\r
34830</simpara>\r
34831</listitem>\r
34832<listitem>\r
34833<simpara>\r
34834separate modules\r
34835</simpara>\r
34836</listitem>\r
34837</itemizedlist>\r
34838</listitem>\r
34839</itemizedlist>\r
34840<simpara>&#160;<?asciidoc-br?>\r
34841&#160;<?asciidoc-br?></simpara>\r
34842<simpara>Also see <link linkend="StandardML">Standard ML</link>.</simpara>\r
34843<simpara>&#160;<?asciidoc-br?>\r
34844&#160;<?asciidoc-br?>\r
34845&#160;<?asciidoc-br?></simpara>\r
34846<simpara><?asciidoc-hr?></simpara>\r
34847<informaltable\r
34848frame="all"\r
34849rowsep="1" colsep="1"\r
34850>\r
34851<tgroup cols="2">\r
34852<colspec colname="col_1" colwidth="50*"/>\r
34853<colspec colname="col_2" colwidth="50*"/>\r
34854<tbody>\r
34855<row>\r
34856<entry align="left" valign="top"><simpara><link linkend="Talk">Prev</link></simpara></entry>\r
34857<entry align="right" valign="top"><simpara><link linkend="TalkMLtonApproach">Next</link></simpara></entry>\r
34858</row>\r
34859</tbody>\r
34860</tgroup>\r
34861</informaltable>\r
34862<simpara><?asciidoc-pagebreak?></simpara>\r
34863</section>\r
34864</section>\r
34865<section id="TalkTemplate">\r
34866<title>TalkTemplate</title>\r
34867<section id="_title">\r
34868<title>Title</title>\r
34869<itemizedlist>\r
34870<listitem>\r
34871<simpara>\r
34872Bullet\r
34873</simpara>\r
34874</listitem>\r
34875<listitem>\r
34876<simpara>\r
34877Bullet\r
34878</simpara>\r
34879</listitem>\r
34880</itemizedlist>\r
34881<simpara>&#160;<?asciidoc-br?>\r
34882&#160;<?asciidoc-br?>\r
34883&#160;<?asciidoc-br?></simpara>\r
34884<simpara><?asciidoc-hr?></simpara>\r
34885<informaltable\r
34886frame="all"\r
34887rowsep="1" colsep="1"\r
34888>\r
34889<tgroup cols="2">\r
34890<colspec colname="col_1" colwidth="50*"/>\r
34891<colspec colname="col_2" colwidth="50*"/>\r
34892<tbody>\r
34893<row>\r
34894<entry align="left" valign="top"><simpara><link linkend="ZZZPrev">Prev</link></simpara></entry>\r
34895<entry align="right" valign="top"><simpara><link linkend="ZZZNext">Next</link></simpara></entry>\r
34896</row>\r
34897</tbody>\r
34898</tgroup>\r
34899</informaltable>\r
34900<simpara><?asciidoc-pagebreak?></simpara>\r
34901</section>\r
34902</section>\r
34903<section id="TalkWholeProgram">\r
34904<title>TalkWholeProgram</title>\r
34905<section id="_whole_program_compiler">\r
34906<title>Whole Program Compiler</title>\r
34907<itemizedlist>\r
34908<listitem>\r
34909<simpara>\r
34910Each of these techniques requires whole-program analysis\r
34911</simpara>\r
34912</listitem>\r
34913<listitem>\r
34914<simpara>\r
34915But, additional benefits:\r
34916</simpara>\r
34917<itemizedlist>\r
34918<listitem>\r
34919<simpara>\r
34920eliminate (some) variability in programming styles\r
34921</simpara>\r
34922</listitem>\r
34923<listitem>\r
34924<simpara>\r
34925specialize representations\r
34926</simpara>\r
34927</listitem>\r
34928<listitem>\r
34929<simpara>\r
34930simplifies and improves runtime system\r
34931</simpara>\r
34932</listitem>\r
34933</itemizedlist>\r
34934</listitem>\r
34935</itemizedlist>\r
34936<simpara>&#160;<?asciidoc-br?>\r
34937&#160;<?asciidoc-br?>\r
34938&#160;<?asciidoc-br?></simpara>\r
34939<simpara><?asciidoc-hr?></simpara>\r
34940<informaltable\r
34941frame="all"\r
34942rowsep="1" colsep="1"\r
34943>\r
34944<tgroup cols="2">\r
34945<colspec colname="col_1" colwidth="50*"/>\r
34946<colspec colname="col_2" colwidth="50*"/>\r
34947<tbody>\r
34948<row>\r
34949<entry align="left" valign="top"><simpara><link linkend="TalkHowHigherOrder">Prev</link></simpara></entry>\r
34950<entry align="right" valign="top"><simpara><link linkend="TalkFolkLore">Next</link></simpara></entry>\r
34951</row>\r
34952</tbody>\r
34953</tgroup>\r
34954</informaltable>\r
34955<simpara><?asciidoc-pagebreak?></simpara>\r
34956</section>\r
34957</section>\r
34958<section id="TILT">\r
34959<title>TILT</title>\r
34960<simpara><ulink url="http://www.cs.cornell.edu/home/jgm/tilt.html">TILT</ulink> is a\r
34961<link linkend="StandardMLImplementations">Standard ML implementation</link>.</simpara>\r
34962<simpara><?asciidoc-pagebreak?></simpara>\r
34963</section>\r
34964<section id="TipsForWritingConciseSML">\r
34965<title>TipsForWritingConciseSML</title>\r
34966<simpara>SML is a rich enough language that there are often several ways to\r
34967express things. This page contains miscellaneous tips (ideas not\r
34968rules) for writing concise SML. The metric that we are interested in\r
34969here is the number of tokens or words (rather than the number of\r
34970lines, for example).</simpara>\r
34971<section id="_datatypes_in_signatures">\r
34972<title>Datatypes in Signatures</title>\r
34973<simpara>A seemingly frequent source of repetition in SML is that of datatype\r
34974definitions in signatures and structures. Actually, it isn&#8217;t\r
34975repetition at all. A datatype specification in a signature, such as,</simpara>\r
34976<programlisting language="sml" linenumbering="unnumbered">signature EXP = sig\r
34977 datatype exp = Fn of id * exp | App of exp * exp | Var of id\r
34978end</programlisting>\r
34979<simpara>is just a specification of a datatype that may be matched by multiple\r
34980(albeit identical) datatype declarations. For example, in</simpara>\r
34981<programlisting language="sml" linenumbering="unnumbered">structure AnExp : EXP = struct\r
34982 datatype exp = Fn of id * exp | App of exp * exp | Var of id\r
34983end\r
34984\r
34985structure AnotherExp : EXP = struct\r
34986 datatype exp = Fn of id * exp | App of exp * exp | Var of id\r
34987end</programlisting>\r
34988<simpara>the types <literal>AnExp.exp</literal> and <literal>AnotherExp.exp</literal> are two distinct types. If\r
34989such <link linkend="GenerativeDatatype">generativity</link> isn&#8217;t desired or needed, you\r
34990can avoid the repetition:</simpara>\r
34991<programlisting language="sml" linenumbering="unnumbered">structure Exp = struct\r
34992 datatype exp = Fn of id * exp | App of exp * exp | Var of id\r
34993end\r
34994\r
34995signature EXP = sig\r
34996 datatype exp = datatype Exp.exp\r
34997end\r
34998\r
34999structure Exp : EXP = struct\r
35000 open Exp\r
35001end</programlisting>\r
35002<simpara>Keep in mind that this isn&#8217;t semantically equivalent to the original.</simpara>\r
35003</section>\r
35004<section id="_clausal_function_definitions">\r
35005<title>Clausal Function Definitions</title>\r
35006<simpara>The syntax of clausal function definitions is rather repetitive. For\r
35007example,</simpara>\r
35008<programlisting language="sml" linenumbering="unnumbered">fun isSome NONE = false\r
35009 | isSome (SOME _) = true</programlisting>\r
35010<simpara>is more verbose than</simpara>\r
35011<programlisting language="sml" linenumbering="unnumbered">val isSome =\r
35012 fn NONE =&gt; false\r
35013 | SOME _ =&gt; true</programlisting>\r
35014<simpara>For recursive functions the break-even point is one clause higher. For example,</simpara>\r
35015<programlisting language="sml" linenumbering="unnumbered">fun fib 0 = 0\r
35016 | fib 1 = 1\r
35017 | fib n = fib (n-1) + fib (n-2)</programlisting>\r
35018<simpara>isn&#8217;t less verbose than</simpara>\r
35019<programlisting language="sml" linenumbering="unnumbered">val rec fib =\r
35020 fn 0 =&gt; 0\r
35021 | 1 =&gt; 1\r
35022 | n =&gt; fib (n-1) + fib (n-2)</programlisting>\r
35023<simpara>It is quite often the case that a curried function primarily examines\r
35024just one of its arguments. Such functions can be written particularly\r
35025concisely by making the examined argument last. For example, instead\r
35026of</simpara>\r
35027<programlisting language="sml" linenumbering="unnumbered">fun eval (Fn (v, b)) env =&gt; ...\r
35028 | eval (App (f, a) env =&gt; ...\r
35029 | eval (Var v) env =&gt; ...</programlisting>\r
35030<simpara>consider writing</simpara>\r
35031<programlisting language="sml" linenumbering="unnumbered">fun eval env =\r
35032 fn Fn (v, b) =&gt; ...\r
35033 | App (f, a) =&gt; ...\r
35034 | Var v =&gt; ...</programlisting>\r
35035</section>\r
35036<section id="_parentheses">\r
35037<title>Parentheses</title>\r
35038<simpara>It is a good idea to avoid using lots of irritating superfluous\r
35039parentheses. An important rule to know is that prefix function\r
35040application in SML has higher precedence than any infix operator. For\r
35041example, the outer parentheses in</simpara>\r
35042<programlisting language="sml" linenumbering="unnumbered">(square (5 + 1)) + (square (5 * 2))</programlisting>\r
35043<simpara>are superfluous.</simpara>\r
35044<simpara>People trained in other languages often use superfluous parentheses in\r
35045a number of places. In particular, the parentheses in the following\r
35046examples are practically always superfluous and are best avoided:</simpara>\r
35047<programlisting language="sml" linenumbering="unnumbered">if (condition) then ... else ...\r
35048while (condition) do ...</programlisting>\r
35049<simpara>The same basically applies to case expressions:</simpara>\r
35050<programlisting language="sml" linenumbering="unnumbered">case (expression) of ...</programlisting>\r
35051<simpara>It is not uncommon to match a tuple of two or more values:</simpara>\r
35052<programlisting language="sml" linenumbering="unnumbered">case (a, b) of\r
35053 (A1, B1) =&gt; ...\r
35054 | (A2, B2) =&gt; ...</programlisting>\r
35055<simpara>Such case expressions can be written more concisely with an\r
35056<link linkend="ProductType">infix product constructor</link>:</simpara>\r
35057<programlisting language="sml" linenumbering="unnumbered">case a &amp; b of\r
35058 A1 &amp; B1 =&gt; ...\r
35059 | A2 &amp; B2 =&gt; ...</programlisting>\r
35060</section>\r
35061<section id="_conditionals">\r
35062<title>Conditionals</title>\r
35063<simpara>Repeated sequences of conditionals such as</simpara>\r
35064<programlisting language="sml" linenumbering="unnumbered">if x &lt; y then ...\r
35065else if x = y then ...\r
35066else ...</programlisting>\r
35067<simpara>can often be written more concisely as case expressions such as</simpara>\r
35068<programlisting language="sml" linenumbering="unnumbered">case Int.compare (x, y) of\r
35069 LESS =&gt; ...\r
35070 | EQUAL =&gt; ...\r
35071 | GREATER =&gt; ...</programlisting>\r
35072<simpara>For a custom comparison, you would then define an appropriate datatype\r
35073and a reification function. An alternative to using datatypes is to\r
35074use dispatch functions</simpara>\r
35075<programlisting language="sml" linenumbering="unnumbered">comparing (x, y)\r
35076{lt = fn () =&gt; ...,\r
35077 eq = fn () =&gt; ...,\r
35078 gt = fn () =&gt; ...}</programlisting>\r
35079<simpara>where</simpara>\r
35080<programlisting language="sml" linenumbering="unnumbered">fun comparing (x, y) {lt, eq, gt} =\r
35081 (case Int.compare (x, y) of\r
35082 LESS =&gt; lt\r
35083 | EQUAL =&gt; eq\r
35084 | GREATER =&gt; gt) ()</programlisting>\r
35085<simpara>An advantage is that no datatype definition is needed. A disadvantage\r
35086is that you can&#8217;t combine multiple dispatch results easily.</simpara>\r
35087</section>\r
35088<section id="_command_query_fusion">\r
35089<title>Command-Query Fusion</title>\r
35090<simpara>Many are familiar with the\r
35091<ulink url="http://en.wikipedia.org/wiki/Command-Query_Separation">Command-Query\r
35092Separation Principle</ulink>. Adhering to the principle, a signature for an\r
35093imperative stack might contain specifications</simpara>\r
35094<programlisting language="sml" linenumbering="unnumbered">val isEmpty : 'a t -&gt; bool\r
35095val pop : 'a t -&gt; 'a</programlisting>\r
35096<simpara>and use of a stack would look like</simpara>\r
35097<programlisting language="sml" linenumbering="unnumbered">if isEmpty stack\r
35098then ... pop stack ...\r
35099else ...</programlisting>\r
35100<simpara>or, when the element needs to be named,</simpara>\r
35101<programlisting language="sml" linenumbering="unnumbered">if isEmpty stack\r
35102then let val elem = pop stack in ... end\r
35103else ...</programlisting>\r
35104<simpara>For efficiency, correctness, and conciseness, it is often better to\r
35105combine the query and command and return the result as an option:</simpara>\r
35106<programlisting language="sml" linenumbering="unnumbered">val pop : 'a t -&gt; 'a option</programlisting>\r
35107<simpara>A use of a stack would then look like this:</simpara>\r
35108<programlisting language="sml" linenumbering="unnumbered">case pop stack of\r
35109 NONE =&gt; ...\r
35110 | SOME elem =&gt; ...</programlisting>\r
35111<simpara><?asciidoc-pagebreak?></simpara>\r
35112</section>\r
35113</section>\r
35114<section id="ToMachine">\r
35115<title>ToMachine</title>\r
35116<simpara><link linkend="ToMachine">ToMachine</link> is a translation pass from the <link linkend="RSSA">RSSA</link>\r
35117<link linkend="IntermediateLanguage">IntermediateLanguage</link> to the <link linkend="Machine">Machine</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link>.</simpara>\r
35118<section id="_description_61">\r
35119<title>Description</title>\r
35120<simpara>This pass converts from a <link linkend="RSSA">RSSA</link> program into a <link linkend="Machine">Machine</link> program.</simpara>\r
35121<simpara>It uses <link linkend="AllocateRegisters">AllocateRegisters</link>, <link linkend="Chunkify">Chunkify</link>, and <link linkend="ParallelMove">ParallelMove</link>.</simpara>\r
35122</section>\r
35123<section id="_implementation_66">\r
35124<title>Implementation</title>\r
35125<itemizedlist>\r
35126<listitem>\r
35127<simpara>\r
35128<ulink url="https://github.com/MLton/mlton/blob/master/mlton/backend/backend.sig"><literal>backend.sig</literal></ulink>\r
35129</simpara>\r
35130</listitem>\r
35131<listitem>\r
35132<simpara>\r
35133<ulink url="https://github.com/MLton/mlton/blob/master/mlton/backend/backend.fun"><literal>backend.fun</literal></ulink>\r
35134</simpara>\r
35135</listitem>\r
35136</itemizedlist>\r
35137</section>\r
35138<section id="_details_and_notes_64">\r
35139<title>Details and Notes</title>\r
35140<simpara>Because the MLton runtime system is shared by all <link linkend="Codegen">codegens</link>, it is most\r
35141convenient to decide on stack layout <emphasis>before</emphasis> any <link linkend="Codegen">codegen</link> takes over.\r
35142In particular, we compute all the stack frame info for each <link linkend="RSSA">RSSA</link>\r
35143function, including stack size, <link linkend="GarbageCollection">garbage collector</link>\r
35144masks for each frame, etc. To do so, the <link linkend="Machine">Machine</link>\r
35145<link linkend="IntermediateLanguage">IntermediateLanguage</link> imagines an abstract machine with an infinite\r
35146number of (pseudo-)registers of every size. A liveness analysis\r
35147determines, for each variable, whether or not it is live across a\r
35148point where the runtime system might take over (for example, any\r
35149garbage collection point) or a non-tail call to another <link linkend="RSSA">RSSA</link>\r
35150function. Those that are live go on the stack, while those that\r
35151aren&#8217;t live go into psuedo-registers. From this information, we know\r
35152all we need to about each stack frame. On the downside, nothing\r
35153further on is allowed to change this stack info; it is set in stone.</simpara>\r
35154<simpara><?asciidoc-pagebreak?></simpara>\r
35155</section>\r
35156</section>\r
35157<section id="TomMurphy">\r
35158<title>TomMurphy</title>\r
35159<simpara>Tom Murphy VII is a long time MLton user and occasional contributor. He works on programming languages for his PhD work at Carnegie Mellon in Pittsburgh, USA. <link linkend="AdamGoode">AdamGoode</link> lives on the same floor of Wean Hall.</simpara>\r
35160<simpara><ulink url="http://tom7.org">Home page</ulink></simpara>\r
35161<simpara><?asciidoc-pagebreak?></simpara>\r
35162</section>\r
35163<section id="ToRSSA">\r
35164<title>ToRSSA</title>\r
35165<simpara><link linkend="ToRSSA">ToRSSA</link> is a translation pass from the <link linkend="SSA2">SSA2</link>\r
35166<link linkend="IntermediateLanguage">IntermediateLanguage</link> to the <link linkend="RSSA">RSSA</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link>.</simpara>\r
35167<section id="_description_62">\r
35168<title>Description</title>\r
35169<simpara>This pass converts a <link linkend="SSA2">SSA2</link> program into a <link linkend="RSSA">RSSA</link> program.</simpara>\r
35170<simpara>It uses <link linkend="PackedRepresentation">PackedRepresentation</link>.</simpara>\r
35171</section>\r
35172<section id="_implementation_67">\r
35173<title>Implementation</title>\r
35174<itemizedlist>\r
35175<listitem>\r
35176<simpara>\r
35177<ulink url="https://github.com/MLton/mlton/blob/master/mlton/backend/ssa-to-rssa.sig"><literal>ssa-to-rssa.sig</literal></ulink>\r
35178</simpara>\r
35179</listitem>\r
35180<listitem>\r
35181<simpara>\r
35182<ulink url="https://github.com/MLton/mlton/blob/master/mlton/backend/ssa-to-rssa.fun"><literal>ssa-to-rssa.fun</literal></ulink>\r
35183</simpara>\r
35184</listitem>\r
35185</itemizedlist>\r
35186</section>\r
35187<section id="_details_and_notes_65">\r
35188<title>Details and Notes</title>\r
35189<simpara></simpara>\r
35190<simpara><?asciidoc-pagebreak?></simpara>\r
35191</section>\r
35192</section>\r
35193<section id="ToSSA2">\r
35194<title>ToSSA2</title>\r
35195<simpara><link linkend="ToSSA2">ToSSA2</link> is a translation pass from the <link linkend="SSA">SSA</link>\r
35196<link linkend="IntermediateLanguage">IntermediateLanguage</link> to the <link linkend="SSA2">SSA2</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link>.</simpara>\r
35197<section id="_description_63">\r
35198<title>Description</title>\r
35199<simpara>This pass is a simple conversion from a <link linkend="SSA">SSA</link> program into a\r
35200<link linkend="SSA2">SSA2</link> program.</simpara>\r
35201<simpara>The only interesting portions of the translation are:</simpara>\r
35202<itemizedlist>\r
35203<listitem>\r
35204<simpara>\r
35205an <link linkend="SSA">SSA</link> <literal>ref</literal> type becomes an object with a single mutable field\r
35206</simpara>\r
35207</listitem>\r
35208<listitem>\r
35209<simpara>\r
35210<literal>array</literal>, <literal>vector</literal>, and <literal>ref</literal> are eliminated in favor of select and updates\r
35211</simpara>\r
35212</listitem>\r
35213<listitem>\r
35214<simpara>\r
35215<literal>Case</literal> transfers separate discrimination and constructor argument selects\r
35216</simpara>\r
35217</listitem>\r
35218</itemizedlist>\r
35219</section>\r
35220<section id="_implementation_68">\r
35221<title>Implementation</title>\r
35222<itemizedlist>\r
35223<listitem>\r
35224<simpara>\r
35225<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/ssa-to-ssa2.sig"><literal>ssa-to-ssa2.sig</literal></ulink>\r
35226</simpara>\r
35227</listitem>\r
35228<listitem>\r
35229<simpara>\r
35230<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/ssa-to-ssa2.fun"><literal>ssa-to-ssa2.fun</literal></ulink>\r
35231</simpara>\r
35232</listitem>\r
35233</itemizedlist>\r
35234</section>\r
35235<section id="_details_and_notes_66">\r
35236<title>Details and Notes</title>\r
35237<simpara></simpara>\r
35238<simpara><?asciidoc-pagebreak?></simpara>\r
35239</section>\r
35240</section>\r
35241<section id="TypeChecking">\r
35242<title>TypeChecking</title>\r
35243<simpara>MLton&#8217;s type checker follows the <link linkend="DefinitionOfStandardML">Definition</link>\r
35244closely, so you may find differences between MLton and other SML\r
35245compilers that do not follow the Definition so closely. In\r
35246particular, SML/NJ has many deviations from the Definition&#8201;&#8212;&#8201;please\r
35247see <link linkend="SMLNJDeviations">SMLNJDeviations</link> for those that we are aware of.</simpara>\r
35248<simpara>In some respects MLton&#8217;s type checker is more powerful than other SML\r
35249compilers, so there are programs that MLton accepts that are rejected\r
35250by some other SML compilers. These kinds of programs fall into a few\r
35251simple categories.</simpara>\r
35252<itemizedlist>\r
35253<listitem>\r
35254<simpara>\r
35255MLton resolves flexible record patterns using a larger context than\r
35256many other SML compilers. For example, MLton accepts the\r
35257following.\r
35258</simpara>\r
35259<programlisting language="sml" linenumbering="unnumbered">fun f {x, ...} = x\r
35260val _ = f {x = 13, y = "foo"}</programlisting>\r
35261</listitem>\r
35262<listitem>\r
35263<simpara>\r
35264MLton uses as large a context as possible to resolve the type of\r
35265variables constrained by the value restriction to be monotypes. For\r
35266example, MLton accepts the following.\r
35267</simpara>\r
35268<programlisting language="sml" linenumbering="unnumbered">structure S:\r
35269 sig\r
35270 val f: int -&gt; int\r
35271 end =\r
35272 struct\r
35273 val f = (fn x =&gt; x) (fn y =&gt; y)\r
35274 end</programlisting>\r
35275</listitem>\r
35276</itemizedlist>\r
35277<section id="_type_error_messages">\r
35278<title>Type error messages</title>\r
35279<simpara>To aid in the understanding of type errors, MLton&#8217;s type checker\r
35280displays type errors differently than other SML compilers. In\r
35281particular, when two types are different, it is important for the\r
35282programmer to easily understand why they are different. So, MLton\r
35283displays only the differences between two types that don&#8217;t match,\r
35284using underscores for the parts that match. For example, if a\r
35285function expects <literal>real * int</literal> but gets <literal>real * real</literal>, the type error\r
35286message would look like</simpara>\r
35287<screen>expects: _ * [int]\r
35288but got: _ * [real]</screen>\r
35289<simpara>As another aid to spotting differences, MLton places brackets <literal>[]</literal>\r
35290around the parts of the types that don&#8217;t match. A common situation is\r
35291when a function receives a different number of arguments than it\r
35292expects, in which case you might see an error like</simpara>\r
35293<screen>expects: [int * real]\r
35294but got: [int * real * string]</screen>\r
35295<simpara>The brackets make it easy to see that the problem is that the tuples\r
35296have different numbers of components&#8201;&#8212;&#8201;not that the components don&#8217;t\r
35297match. Contrast that with a case where a function receives the right\r
35298number of arguments, but in the wrong order, in which case you might\r
35299see an error like</simpara>\r
35300<screen>expects: [int] * [real]\r
35301but got: [real] * [int]</screen>\r
35302<simpara>Here the brackets make it easy to see that the components do not match.</simpara>\r
35303<simpara>We appreciate feedback on any type error messages that you find\r
35304confusing, or suggestions you may have for improvements to error\r
35305messages.</simpara>\r
35306</section>\r
35307<section id="_the_shortest_most_recent_rule_for_type_names">\r
35308<title>The shortest/most-recent rule for type names</title>\r
35309<simpara>In a type error message, MLton often has a number of choices in\r
35310deciding what name to use for a type. For example, in the following\r
35311type-incorrect program</simpara>\r
35312<programlisting language="sml" linenumbering="unnumbered">type t = int\r
35313fun f (x: t) = x\r
35314val _ = f "foo"</programlisting>\r
35315<simpara>MLton reports the error message</simpara>\r
35316<screen>Error: z.sml 3.9-3.15.\r
35317 Function applied to incorrect argument.\r
35318 expects: [t]\r
35319 but got: [string]\r
35320 in: f "foo"</screen>\r
35321<simpara>MLton could have reported <literal>expects: [int]</literal> instead of <literal>expects: [t]</literal>.\r
35322However, MLton uses the shortest/most-recent rule in order to decide\r
35323what type name to display. This rule means that, at the point of the\r
35324error, MLton first looks for the shortest name for a type in terms of\r
35325number of structure identifiers (e.g. <literal>foobar</literal> is shorter than <literal>A.t</literal>).\r
35326Next, if there are multiple names of the same length, then MLton uses\r
35327the most recently defined name. It is this tiebreaker that causes\r
35328MLton to prefer <literal>t</literal> to <literal>int</literal> in the above example.</simpara>\r
35329<simpara>In signature matching, most recently defined is not taken to include\r
35330all of the definitions introduced by the structure (since the matching\r
35331takes place outside the structure and before it is defined). For\r
35332example, in the following type-incorrect program</simpara>\r
35333<programlisting language="sml" linenumbering="unnumbered">structure S:\r
35334 sig\r
35335 val x: int\r
35336 end =\r
35337 struct\r
35338 type t = int\r
35339 val x = "foo"\r
35340 end</programlisting>\r
35341<simpara>MLton reports the error message</simpara>\r
35342<screen>Error: z.sml 2.4-4.6.\r
35343 Variable in structure disagrees with signature (type): x.\r
35344 structure: val x: [string]\r
35345 defn at: z.sml 7.11-7.11\r
35346 signature: val x: [int]\r
35347 spec at: z.sml 3.11-3.11</screen>\r
35348<simpara>If there is a type that only exists inside the structure being\r
35349matched, then the prefix <literal>_str.</literal> is used. For example, in the\r
35350following type-incorrect program</simpara>\r
35351<programlisting language="sml" linenumbering="unnumbered">structure S:\r
35352 sig\r
35353 val x: int\r
35354 end =\r
35355 struct\r
35356 datatype t = T\r
35357 val x = T\r
35358 end</programlisting>\r
35359<simpara>MLton reports the error message</simpara>\r
35360<screen>Error: z.sml 2.4-4.6.\r
35361 Variable in structure disagrees with signature (type): x.\r
35362 structure: val x: [_str.t]\r
35363 defn at: z.sml 7.11-7.11\r
35364 signature: val x: [int]\r
35365 spec at: z.sml 3.11-3.11</screen>\r
35366<simpara>in which the <literal>[_str.t]</literal> refers to the type defined in the structure.</simpara>\r
35367<simpara><?asciidoc-pagebreak?></simpara>\r
35368</section>\r
35369</section>\r
35370<section id="TypeConstructor">\r
35371<title>TypeConstructor</title>\r
35372<simpara>In <link linkend="StandardML">Standard ML</link>, a type constructor is a function from\r
35373types to types. Type constructors can be <emphasis>nullary</emphasis>, meaning that\r
35374they take no arguments, as in <literal>char</literal>, <literal>int</literal>, and <literal>real</literal>.\r
35375Type constructors can be <emphasis>unary</emphasis>, meaning that they take one\r
35376argument, as in <literal>array</literal>, <literal>list</literal>, and <literal>vector</literal>. A program\r
35377can define a new type constructor in two ways: a <literal>type</literal> definition\r
35378or a <literal>datatype</literal> declaration. User-defined type constructors can\r
35379can take any number of arguments.</simpara>\r
35380<programlisting language="sml" linenumbering="unnumbered">datatype t = T of int * real (* 0 arguments *)\r
35381type 'a t = 'a * int (* 1 argument *)\r
35382datatype ('a, 'b) t = A | B of 'a * 'b (* 2 arguments *)\r
35383type ('a, 'b, 'c) t = 'a * ('b -&gt; 'c) (* 3 arguments *)</programlisting>\r
35384<simpara>Here are the syntax rules for type constructor application.</simpara>\r
35385<itemizedlist>\r
35386<listitem>\r
35387<simpara>\r
35388Type constructor application is written in postfix. So, one writes\r
35389 <literal>int list</literal>, not <literal>list int</literal>.\r
35390</simpara>\r
35391</listitem>\r
35392<listitem>\r
35393<simpara>\r
35394Unary type constructors drop the parens, so one writes\r
35395 <literal>int list</literal>, not <literal>(int) list</literal>.\r
35396</simpara>\r
35397</listitem>\r
35398<listitem>\r
35399<simpara>\r
35400Nullary type constructors drop the argument entirely, so one writes\r
35401 <literal>int</literal>, not <literal>() int</literal>.\r
35402</simpara>\r
35403</listitem>\r
35404<listitem>\r
35405<simpara>\r
35406N-ary type constructors use tuple notation; for example,\r
35407 <literal>(int, real) t</literal>.\r
35408</simpara>\r
35409</listitem>\r
35410<listitem>\r
35411<simpara>\r
35412Type constructor application associates to the left. So,\r
35413 <literal>int ref list</literal> is the same as <literal>(int ref) list</literal>.\r
35414</simpara>\r
35415</listitem>\r
35416</itemizedlist>\r
35417<simpara><?asciidoc-pagebreak?></simpara>\r
35418</section>\r
35419<section id="TypeIndexedValues">\r
35420<title>TypeIndexedValues</title>\r
35421<simpara><link linkend="StandardML">Standard ML</link> does not support ad hoc polymorphism. This\r
35422presents a challenge to programmers. The problem is that at first\r
35423glance there seems to be no practical way to implement something like\r
35424a function for converting a value of any type to a string or a\r
35425function for computing a hash value for a value of any type.\r
35426Fortunately there are ways to implement type-indexed values in SML as\r
35427discussed in <link linkend="References_Yang98">Yang98</link>. Various articles such as\r
35428<link linkend="References_Danvy98">Danvy98</link>, <link linkend="References_Ramsey11">Ramsey11</link>, <link linkend="References_Elsman04">Elsman04</link>,\r
35429<link linkend="References_Kennedy04">Kennedy04</link>, and <link linkend="References_Benton05">Benton05</link> also contain examples of\r
35430type-indexed values.</simpara>\r
35431<simpara><emphasis role="strong">NOTE:</emphasis> The technique used in the following example uses an early (and\r
35432somewhat broken) variation of the basic technique used in an\r
35433experimental generic programming library (see\r
35434<ulink url="https://github.com/MLton/mltonlib/blob/master/com/ssh/generic/unstable/README"><literal>README</literal></ulink>) that can\r
35435be found from the MLton repository. The generic programming library\r
35436also includes a more advanced generic pretty printing function (see\r
35437<ulink url="https://github.com/MLton/mltonlib/blob/master/com/ssh/generic/unstable/public/value/pretty.sig"><literal>pretty.sig</literal></ulink>).</simpara>\r
35438<section id="_example_converting_any_sml_value_to_roughly_sml_syntax">\r
35439<title>Example: Converting any SML value to (roughly) SML syntax</title>\r
35440<simpara>Consider the problem of converting any SML value to a textual\r
35441presentation that matches the syntax of SML as closely as possible.\r
35442One solution is a type-indexed function that maps a given type to a\r
35443function that maps any value (of the type) to its textual\r
35444presentation. A type-indexed function like this can be useful for a\r
35445variety of purposes. For example, one could use it to show debugging\r
35446information. We&#8217;ll call this function "<literal>show</literal>".</simpara>\r
35447<simpara>We&#8217;ll do a fairly complete implementation of <literal>show</literal>. We do not\r
35448distinguish infix and nonfix constructors, but that is not an\r
35449intrinsic property of SML datatypes. We also don&#8217;t reconstruct a type\r
35450name for the value, although it would be particularly useful for\r
35451functional values. To reconstruct type names, some changes would be\r
35452needed and the reader is encouraged to consider how to do that. A\r
35453more realistic implementation would use some pretty printing\r
35454combinators to compute a layout for the result. This should be a\r
35455relatively easy change (given a suitable pretty printing library).\r
35456Cyclic values (through references and arrays) do not have a standard\r
35457textual presentation and it is impossible to convert arbitrary\r
35458functional values (within SML) to a meaningful textual presentation.\r
35459Finally, it would also make sense to show sharing of references and\r
35460arrays. We&#8217;ll leave these improvements to an actual library\r
35461implementation.</simpara>\r
35462<simpara>The following code uses the <link linkend="Fixpoints">fixpoint framework</link> and other\r
35463utilities from an Extended Basis library (see\r
35464<ulink url="https://github.com/MLton/mltonlib/blob/master/com/ssh/extended-basis/unstable/README"><literal>README</literal></ulink>).</simpara>\r
35465<section id="_signature">\r
35466<title>Signature</title>\r
35467<simpara>Let&#8217;s consider the design of the <literal>SHOW</literal> signature:</simpara>\r
35468<programlisting language="sml" linenumbering="unnumbered">infixr --&gt;\r
35469\r
35470signature SHOW = sig\r
35471 type 'a t (* complete type-index *)\r
35472 type 'a s (* incomplete sum *)\r
35473 type ('a, 'k) p (* incomplete product *)\r
35474 type u (* tuple or unlabelled product *)\r
35475 type l (* record or labelled product *)\r
35476\r
35477 val show : 'a t -&gt; 'a -&gt; string\r
35478\r
35479 (* user-defined types *)\r
35480 val inj : ('a -&gt; 'b) -&gt; 'b t -&gt; 'a t\r
35481\r
35482 (* tuples and records *)\r
35483 val * : ('a, 'k) p * ('b, 'k) p -&gt; (('a, 'b) product, 'k) p\r
35484\r
35485 val U : 'a t -&gt; ('a, u) p\r
35486 val L : string -&gt; 'a t -&gt; ('a, l) p\r
35487\r
35488 val tuple : ('a, u) p -&gt; 'a t\r
35489 val record : ('a, l) p -&gt; 'a t\r
35490\r
35491 (* datatypes *)\r
35492 val + : 'a s * 'b s -&gt; (('a, 'b) sum) s\r
35493\r
35494 val C0 : string -&gt; unit s\r
35495 val C1 : string -&gt; 'a t -&gt; 'a s\r
35496\r
35497 val data : 'a s -&gt; 'a t\r
35498\r
35499 val Y : 'a t Tie.t\r
35500\r
35501 (* exceptions *)\r
35502 val exn : exn t\r
35503 val regExn : (exn -&gt; ('a * 'a s) option) -&gt; unit\r
35504\r
35505 (* some built-in type constructors *)\r
35506 val refc : 'a t -&gt; 'a ref t\r
35507 val array : 'a t -&gt; 'a array t\r
35508 val list : 'a t -&gt; 'a list t\r
35509 val vector : 'a t -&gt; 'a vector t\r
35510 val --&gt; : 'a t * 'b t -&gt; ('a -&gt; 'b) t\r
35511\r
35512 (* some built-in base types *)\r
35513 val string : string t\r
35514 val unit : unit t\r
35515 val bool : bool t\r
35516 val char : char t\r
35517 val int : int t\r
35518 val word : word t\r
35519 val real : real t\r
35520end</programlisting>\r
35521<simpara>While some details are shaped by the specific requirements of <literal>show</literal>,\r
35522there are a number of (design) patterns that translate to other\r
35523type-indexed values. The former kind of details are mostly shaped by\r
35524the syntax of SML values that <literal>show</literal> is designed to produce. To this\r
35525end, abstract types and phantom types are used to distinguish\r
35526incomplete record, tuple, and datatype type-indices from each other\r
35527and from complete type-indices. Also, names of record labels and\r
35528datatype constructors need to be provided by the user.</simpara>\r
35529<section id="_arbitrary_user_defined_datatypes">\r
35530<title>Arbitrary user-defined datatypes</title>\r
35531<simpara>Perhaps the most important pattern is how the design supports\r
35532arbitrary user-defined datatypes. A number of combinators together\r
35533conspire to provide the functionality. First of all, to support new\r
35534user-defined types, a combinator taking a conversion function to a\r
35535previously supported type is provided:</simpara>\r
35536<programlisting language="sml" linenumbering="unnumbered">val inj : ('a -&gt; 'b) -&gt; 'b t -&gt; 'a t</programlisting>\r
35537<simpara>An injection function is sufficient in this case, but in the general\r
35538case, an embedding with injection and projection functions may be\r
35539needed.</simpara>\r
35540<simpara>To support products (tuples and records) a product combinator is\r
35541provided:</simpara>\r
35542<programlisting language="sml" linenumbering="unnumbered">val * : ('a, 'k) p * ('b, 'k) p -&gt; (('a, 'b) product, 'k) p</programlisting>\r
35543<simpara>The second (phantom) type variable <literal>'k</literal> is there to distinguish\r
35544between labelled and unlabelled products and the type <literal>p</literal>\r
35545distinguishes incomplete products from complete type-indices of type\r
35546<literal>t</literal>. Most type-indexed values do not need to make such distinctions.</simpara>\r
35547<simpara>To support sums (datatypes) a sum combinator is provided:</simpara>\r
35548<programlisting language="sml" linenumbering="unnumbered">val + : 'a s * 'b s -&gt; (('a, 'b) sum) s</programlisting>\r
35549<simpara>Again, the purpose of the type <literal>s</literal> is to distinguish incomplete sums\r
35550from complete type-indices of type <literal>t</literal>, which usually isn&#8217;t necessary.</simpara>\r
35551<simpara>Finally, to support recursive datatypes, including sets of mutually\r
35552recursive datatypes, a <link linkend="Fixpoints">fixpoint tier</link> is provided:</simpara>\r
35553<programlisting language="sml" linenumbering="unnumbered">val Y : 'a t Tie.t</programlisting>\r
35554<simpara>Together these combinators (with the more domain specific combinators\r
35555<literal>U</literal>, <literal>L</literal>, <literal>tuple</literal>, <literal>record</literal>, <literal>C0</literal>, <literal>C1</literal>, and <literal>data</literal>) enable one to\r
35556encode a type-index for any user-defined datatype.</simpara>\r
35557</section>\r
35558<section id="_exceptions">\r
35559<title>Exceptions</title>\r
35560<simpara>The <literal>exn</literal> type in SML is a <link linkend="UniversalType">universal type</link> into which\r
35561all types can be embedded. SML also allows a program to generate new\r
35562exception variants at run-time. Thus a mechanism is required to register\r
35563handlers for particular variants:</simpara>\r
35564<programlisting language="sml" linenumbering="unnumbered">val exn : exn t\r
35565val regExn : (exn -&gt; ('a * 'a s) option) -&gt; unit</programlisting>\r
35566<simpara>The universal <literal>exn</literal> type-index then makes use of the registered\r
35567handlers. The above particular form of handler, which converts an\r
35568exception value to a value of some type and a type-index for that type\r
35569(essentially an existential type) is designed to make it convenient to\r
35570write handlers. To write a handler, one can conveniently reuse\r
35571existing type-indices:</simpara>\r
35572<programlisting language="sml" linenumbering="unnumbered">exception Int of int\r
35573\r
35574local\r
35575 open Show\r
35576in\r
35577 val () = regExn (fn Int v =&gt; SOME (v, C1"Int" int)\r
35578 | _ =&gt; NONE)\r
35579end</programlisting>\r
35580<simpara>Note that a single handler may actually handle an arbitrary number of\r
35581different exceptions.</simpara>\r
35582</section>\r
35583<section id="_other_types">\r
35584<title>Other types</title>\r
35585<simpara>Some built-in and standard types typically require special treatment\r
35586due to their special nature. The most important of these are arrays\r
35587and references, because cyclic data (ignoring closures) and observable\r
35588sharing can only be constructed through them.</simpara>\r
35589<simpara>When arrow types are really supported, unlike in this case, they\r
35590usually need special treatment due to the contravariance of arguments.</simpara>\r
35591<simpara>Lists and vectors require special treatment in the case of <literal>show</literal>,\r
35592because of their special syntax. This isn&#8217;t usually the case.</simpara>\r
35593<simpara>The set of base types to support also needs to be considered unless\r
35594one exports an interface for constructing type-indices for entirely\r
35595new base types.</simpara>\r
35596</section>\r
35597</section>\r
35598</section>\r
35599<section id="_usage_9">\r
35600<title>Usage</title>\r
35601<simpara>Before going to the implementation, let&#8217;s look at some examples. For\r
35602the following examples, we&#8217;ll assume a structure binding\r
35603<literal>Show :&gt; SHOW</literal>. If you want to try the examples immediately, just\r
35604skip forward to the implementation.</simpara>\r
35605<simpara>To use <literal>show</literal>, one first needs a type-index, which is then given to\r
35606<literal>show</literal>. To show a list of integers, one would use the type-index\r
35607<literal>list int</literal>, which has the type <literal>int list Show.t</literal>:</simpara>\r
35608<programlisting language="sml" linenumbering="unnumbered">val "[3, 1, 4]" =\r
35609 let open Show in show (list int) end\r
35610 [3, 1, 4]</programlisting>\r
35611<simpara>Likewise, to show a list of lists of characters, one would use the\r
35612type-index <literal>list (list char)</literal>, which has the type <literal>char list list\r
35613Show.t</literal>:</simpara>\r
35614<programlisting language="sml" linenumbering="unnumbered">val "[[#\"a\", #\"b\", #\"c\"], []]" =\r
35615 let open Show in show (list (list char)) end\r
35616 [[#"a", #"b", #"c"], []]</programlisting>\r
35617<simpara>Handling standard types is not particularly interesting. It is more\r
35618interesting to see how user-defined types can be handled. Although\r
35619the <literal>option</literal> datatype is a standard type, it requires no special\r
35620support, so we can treat it as a user-defined type. Options can be\r
35621encoded easily using a sum:</simpara>\r
35622<programlisting language="sml" linenumbering="unnumbered">fun option t = let\r
35623 open Show\r
35624in\r
35625 inj (fn NONE =&gt; INL ()\r
35626 | SOME v =&gt; INR v)\r
35627 (data (C0"NONE" + C1"SOME" t))\r
35628end\r
35629\r
35630val "SOME 5" =\r
35631 let open Show in show (option int) end\r
35632 (SOME 5)</programlisting>\r
35633<simpara>Readers new to type-indexed values might want to type annotate each\r
35634subexpression of the above example as an exercise. (Use a compiler to\r
35635check your annotations.)</simpara>\r
35636<simpara>Using a product, user specified records can be also be encoded easily:</simpara>\r
35637<programlisting language="sml" linenumbering="unnumbered">val abc = let\r
35638 open Show\r
35639in\r
35640 inj (fn {a, b, c} =&gt; a &amp; b &amp; c)\r
35641 (record (L"a" (option int) *\r
35642 L"b" real *\r
35643 L"c" bool))\r
35644end\r
35645\r
35646val "{a = SOME 1, b = 3.0, c = false}" =\r
35647 let open Show in show abc end\r
35648 {a = SOME 1, b = 3.0, c = false}</programlisting>\r
35649<simpara>As you can see, both of the above use <literal>inj</literal> to inject user-defined\r
35650types to the general purpose sum and product types.</simpara>\r
35651<simpara>Of particular interest is whether recursive datatypes and cyclic data\r
35652can be handled. For example, how does one write a type-index for a\r
35653recursive datatype such as a cyclic graph?</simpara>\r
35654<programlisting language="sml" linenumbering="unnumbered">datatype 'a graph = VTX of 'a * 'a graph list ref\r
35655fun arcs (VTX (_, r)) = r</programlisting>\r
35656<simpara>Using the <literal>Show</literal> combinators, we could first write a new type-index\r
35657combinator for <literal>graph</literal>:</simpara>\r
35658<programlisting language="sml" linenumbering="unnumbered">fun graph a = let\r
35659 open Tie Show\r
35660in\r
35661 fix Y (fn graph_a =&gt;\r
35662 inj (fn VTX (x, y) =&gt; x &amp; y)\r
35663 (data (C1"VTX"\r
35664 (tuple (U a *\r
35665 U (refc (list graph_a)))))))\r
35666end</programlisting>\r
35667<simpara>To show a graph with integer labels</simpara>\r
35668<programlisting language="sml" linenumbering="unnumbered">val a_graph = let\r
35669 val a = VTX (1, ref [])\r
35670 val b = VTX (2, ref [])\r
35671 val c = VTX (3, ref [])\r
35672 val d = VTX (4, ref [])\r
35673 val e = VTX (5, ref [])\r
35674 val f = VTX (6, ref [])\r
35675in\r
35676 arcs a := [b, d]\r
35677 ; arcs b := [c, e]\r
35678 ; arcs c := [a, f]\r
35679 ; arcs d := [f]\r
35680 ; arcs e := [d]\r
35681 ; arcs f := [e]\r
35682 ; a\r
35683end</programlisting>\r
35684<simpara>we could then simply write</simpara>\r
35685<programlisting language="sml" linenumbering="unnumbered">val "VTX (1, ref [VTX (2, ref [VTX (3, ref [VTX (1, %0), \\r
35686 \VTX (6, ref [VTX (5, ref [VTX (4, ref [VTX (6, %3)])])] as %3)]), \\r
35687 \VTX (5, ref [VTX (4, ref [VTX (6, ref [VTX (5, %2)])])] as %2)]), \\r
35688 \VTX (4, ref [VTX (6, ref [VTX (5, ref [VTX (4, %1)])])] as %1)] as %0)" =\r
35689 let open Show in show (graph int) end\r
35690 a_graph</programlisting>\r
35691<simpara>There is a subtle gotcha with cyclic data. Consider the following code:</simpara>\r
35692<programlisting language="sml" linenumbering="unnumbered">exception ExnArray of exn array\r
35693\r
35694val () = let\r
35695 open Show\r
35696in\r
35697 regExn (fn ExnArray a =&gt;\r
35698 SOME (a, C1"ExnArray" (array exn))\r
35699 | _ =&gt; NONE)\r
35700end\r
35701\r
35702val a_cycle = let\r
35703 val a = Array.fromList [Empty]\r
35704in\r
35705 Array.update (a, 0, ExnArray a) ; a\r
35706end</programlisting>\r
35707<simpara>Although the above looks innocent enough, the evaluation of</simpara>\r
35708<programlisting language="sml" linenumbering="unnumbered">val "[|ExnArray %0|] as %0" =\r
35709 let open Show in show (array exn) end\r
35710 a_cycle</programlisting>\r
35711<simpara>goes into an infinite loop. To avoid this problem, the type-index\r
35712<literal>array exn</literal> must be evaluated only once, as in the following:</simpara>\r
35713<programlisting language="sml" linenumbering="unnumbered">val array_exn = let open Show in array exn end\r
35714\r
35715exception ExnArray of exn array\r
35716\r
35717val () = let\r
35718 open Show\r
35719in\r
35720 regExn (fn ExnArray a =&gt;\r
35721 SOME (a, C1"ExnArray" array_exn)\r
35722 | _ =&gt; NONE)\r
35723end\r
35724\r
35725val a_cycle = let\r
35726 val a = Array.fromList [Empty]\r
35727in\r
35728 Array.update (a, 0, ExnArray a) ; a\r
35729end\r
35730\r
35731val "[|ExnArray %0|] as %0" =\r
35732 let open Show in show array_exn end\r
35733 a_cycle</programlisting>\r
35734<simpara>Cyclic data (excluding closures) in Standard ML can only be\r
35735constructed imperatively through arrays and references (combined with\r
35736exceptions or recursive datatypes). Before recursing to a reference\r
35737or an array, one needs to check whether that reference or array has\r
35738already been seen before. When <literal>ref</literal> or <literal>array</literal> is called with a\r
35739type-index, a new cyclicity checker is instantiated.</simpara>\r
35740</section>\r
35741<section id="_implementation_69">\r
35742<title>Implementation</title>\r
35743<programlisting language="sml" linenumbering="unnumbered">structure SmlSyntax = struct\r
35744 local\r
35745 structure CV = CharVector and C = Char\r
35746 in\r
35747 val isSym = Char.contains "!%&amp;$#+-/:&lt;=&gt;?@\\~`^|*"\r
35748\r
35749 fun isSymId s = 0 &lt; size s andalso CV.all isSym s\r
35750\r
35751 fun isAlphaNumId s =\r
35752 0 &lt; size s\r
35753 andalso C.isAlpha (CV.sub (s, 0))\r
35754 andalso CV.all (fn c =&gt; C.isAlphaNum c\r
35755 orelse #"'" = c\r
35756 orelse #"_" = c) s\r
35757\r
35758 fun isNumLabel s =\r
35759 0 &lt; size s\r
35760 andalso #"0" &lt;&gt; CV.sub (s, 0)\r
35761 andalso CV.all C.isDigit s\r
35762\r
35763 fun isId s = isAlphaNumId s orelse isSymId s\r
35764\r
35765 fun isLongId s = List.all isId (String.fields (#"." &lt;\ op =) s)\r
35766\r
35767 fun isLabel s = isId s orelse isNumLabel s\r
35768 end\r
35769end\r
35770\r
35771structure Show :&gt; SHOW = struct\r
35772 datatype 'a t = IN of exn list * 'a -&gt; bool * string\r
35773 type 'a s = 'a t\r
35774 type ('a, 'k) p = 'a t\r
35775 type u = unit\r
35776 type l = unit\r
35777\r
35778 fun show (IN t) x = #2 (t ([], x))\r
35779\r
35780 (* user-defined types *)\r
35781 fun inj inj (IN b) = IN (b o Pair.map (id, inj))\r
35782\r
35783 local\r
35784 fun surround pre suf (_, s) = (false, concat [pre, s, suf])\r
35785 fun parenthesize x = if #1 x then surround "(" ")" x else x\r
35786 fun construct tag =\r
35787 (fn (_, s) =&gt; (true, concat [tag, " ", s])) o parenthesize\r
35788 fun check p m s = if p s then () else raise Fail (m^s)\r
35789 in\r
35790 (* tuples and records *)\r
35791 fun (IN l) * (IN r) =\r
35792 IN (fn (rs, a &amp; b) =&gt;\r
35793 (false, concat [#2 (l (rs, a)),\r
35794 ", ",\r
35795 #2 (r (rs, b))]))\r
35796\r
35797 val U = id\r
35798 fun L l = (check SmlSyntax.isLabel "Invalid label: " l\r
35799 ; fn IN t =&gt; IN (surround (l^" = ") "" o t))\r
35800\r
35801 fun tuple (IN t) = IN (surround "(" ")" o t)\r
35802 fun record (IN t) = IN (surround "{" "}" o t)\r
35803\r
35804 (* datatypes *)\r
35805 fun (IN l) + (IN r) = IN (fn (rs, INL a) =&gt; l (rs, a)\r
35806 | (rs, INR b) =&gt; r (rs, b))\r
35807\r
35808 fun C0 c = (check SmlSyntax.isId "Invalid constructor: " c\r
35809 ; IN (const (false, c)))\r
35810 fun C1 c (IN t) = (check SmlSyntax.isId "Invalid constructor: " c\r
35811 ; IN (construct c o t))\r
35812\r
35813 val data = id\r
35814\r
35815 fun Y ? = Tie.iso Tie.function (fn IN x =&gt; x, IN) ?\r
35816\r
35817 (* exceptions *)\r
35818 local\r
35819 val handlers = ref ([] : (exn -&gt; unit t option) list)\r
35820 in\r
35821 val exn = IN (fn (rs, e) =&gt; let\r
35822 fun lp [] =\r
35823 C0(concat ["&lt;exn:",\r
35824 General.exnName e,\r
35825 "&gt;"])\r
35826 | lp (f::fs) =\r
35827 case f e\r
35828 of NONE =&gt; lp fs\r
35829 | SOME t =&gt; t\r
35830 val IN f = lp (!handlers)\r
35831 in\r
35832 f (rs, ())\r
35833 end)\r
35834 fun regExn f =\r
35835 handlers := (Option.map\r
35836 (fn (x, IN f) =&gt;\r
35837 IN (fn (rs, ()) =&gt;\r
35838 f (rs, x))) o f)\r
35839 :: !handlers\r
35840 end\r
35841\r
35842 (* some built-in type constructors *)\r
35843 local\r
35844 fun cyclic (IN t) = let\r
35845 exception E of ''a * bool ref\r
35846 in\r
35847 IN (fn (rs, v : ''a) =&gt; let\r
35848 val idx = Int.toString o length\r
35849 fun lp (E (v', c)::rs) =\r
35850 if v' &lt;&gt; v then lp rs\r
35851 else (c := false ; (false, "%"^idx rs))\r
35852 | lp (_::rs) = lp rs\r
35853 | lp [] = let\r
35854 val c = ref true\r
35855 val r = t (E (v, c)::rs, v)\r
35856 in\r
35857 if !c then r\r
35858 else surround "" (" as %"^idx rs) r\r
35859 end\r
35860 in\r
35861 lp rs\r
35862 end)\r
35863 end\r
35864\r
35865 fun aggregate pre suf toList (IN t) =\r
35866 IN (surround pre suf o\r
35867 (fn (rs, a) =&gt;\r
35868 (false,\r
35869 String.concatWith\r
35870 ", "\r
35871 (map (#2 o curry t rs)\r
35872 (toList a)))))\r
35873 in\r
35874 fun refc ? = (cyclic o inj ! o C1"ref") ?\r
35875 fun array ? = (cyclic o aggregate "[|" "|]" (Array.foldr op:: [])) ?\r
35876 fun list ? = aggregate "[" "]" id ?\r
35877 fun vector ? = aggregate "#[" "]" (Vector.foldr op:: []) ?\r
35878 end\r
35879\r
35880 fun (IN _) --&gt; (IN _) = IN (const (false, "&lt;fn&gt;"))\r
35881\r
35882 (* some built-in base types *)\r
35883 local\r
35884 fun mk toS = (fn x =&gt; (false, x)) o toS o (fn (_, x) =&gt; x)\r
35885 in\r
35886 val string =\r
35887 IN (surround "\"" "\"" o mk (String.translate Char.toString))\r
35888 val unit = IN (mk (fn () =&gt; "()"))\r
35889 val bool = IN (mk Bool.toString)\r
35890 val char = IN (surround "#\"" "\"" o mk Char.toString)\r
35891 val int = IN (mk Int.toString)\r
35892 val word = IN (surround "0wx" "" o mk Word.toString)\r
35893 val real = IN (mk Real.toString)\r
35894 end\r
35895 end\r
35896end\r
35897\r
35898(* Handlers for standard top-level exceptions *)\r
35899val () = let\r
35900 open Show\r
35901 fun E0 name = SOME ((), C0 name)\r
35902in\r
35903 regExn (fn Bind =&gt; E0"Bind"\r
35904 | Chr =&gt; E0"Chr"\r
35905 | Div =&gt; E0"Div"\r
35906 | Domain =&gt; E0"Domain"\r
35907 | Empty =&gt; E0"Empty"\r
35908 | Match =&gt; E0"Match"\r
35909 | Option =&gt; E0"Option"\r
35910 | Overflow =&gt; E0"Overflow"\r
35911 | Size =&gt; E0"Size"\r
35912 | Span =&gt; E0"Span"\r
35913 | Subscript =&gt; E0"Subscript"\r
35914 | _ =&gt; NONE)\r
35915 ; regExn (fn Fail s =&gt; SOME (s, C1"Fail" string)\r
35916 | _ =&gt; NONE)\r
35917end</programlisting>\r
35918</section>\r
35919<section id="_also_see_47">\r
35920<title>Also see</title>\r
35921<simpara>There are a number of related techniques. Here are some of them.</simpara>\r
35922<itemizedlist>\r
35923<listitem>\r
35924<simpara>\r
35925<link linkend="Fold">Fold</link>\r
35926</simpara>\r
35927</listitem>\r
35928<listitem>\r
35929<simpara>\r
35930<link linkend="StaticSum">StaticSum</link>\r
35931</simpara>\r
35932</listitem>\r
35933</itemizedlist>\r
35934<simpara><?asciidoc-pagebreak?></simpara>\r
35935</section>\r
35936</section>\r
35937<section id="TypeVariableScope">\r
35938<title>TypeVariableScope</title>\r
35939<simpara>In <link linkend="StandardML">Standard ML</link>, every type variable is <emphasis>scoped</emphasis> (or\r
35940bound) at a particular point in the program. A type variable can be\r
35941either implicitly scoped or explicitly scoped. For example, <literal>'a</literal> is\r
35942implicitly scoped in</simpara>\r
35943<programlisting language="sml" linenumbering="unnumbered">val id: 'a -&gt; 'a = fn x =&gt; x</programlisting>\r
35944<simpara>and is implicitly scoped in</simpara>\r
35945<programlisting language="sml" linenumbering="unnumbered">val id = fn x: 'a =&gt; x</programlisting>\r
35946<simpara>On the other hand, <literal>'a</literal> is explicitly scoped in</simpara>\r
35947<programlisting language="sml" linenumbering="unnumbered">val 'a id: 'a -&gt; 'a = fn x =&gt; x</programlisting>\r
35948<simpara>and is explicitly scoped in</simpara>\r
35949<programlisting language="sml" linenumbering="unnumbered">val 'a id = fn x: 'a =&gt; x</programlisting>\r
35950<simpara>A type variable can be scoped at a <literal>val</literal> or <literal>fun</literal> declaration. An SML\r
35951type checker performs scope inference on each top-level declaration to\r
35952determine the scope of each implicitly scoped type variable. After\r
35953scope inference, every type variable is scoped at exactly one\r
35954enclosing <literal>val</literal> or <literal>fun</literal> declaration. Scope inference shows that the\r
35955first and second example above are equivalent to the third and fourth\r
35956example, respectively.</simpara>\r
35957<simpara>Section 4.6 of the <link linkend="DefinitionOfStandardML">Definition</link> specifies\r
35958precisely the scope of an implicitly scoped type variable. A free\r
35959occurrence of a type variable <literal>'a</literal> in a declaration <literal>d</literal> is said to be\r
35960<emphasis>unguarded</emphasis> in <literal>d</literal> if <literal>'a</literal> is not part of a smaller declaration. A\r
35961type variable <literal>'a</literal> is implicitly scoped at <literal>d</literal> if <literal>'a</literal> is unguarded in\r
35962<literal>d</literal> and <literal>'a</literal> does not occur unguarded in any declaration containing\r
35963<literal>d</literal>.</simpara>\r
35964<section id="_scope_inference_examples">\r
35965<title>Scope inference examples</title>\r
35966<itemizedlist>\r
35967<listitem>\r
35968<simpara>\r
35969In this example,\r
35970</simpara>\r
35971<programlisting language="sml" linenumbering="unnumbered">val id: 'a -&gt; 'a = fn x =&gt; x</programlisting>\r
35972<simpara><literal>'a</literal> is unguarded in <literal>val id</literal> and does not occur unguarded in any\r
35973containing declaration. Hence, <literal>'a</literal> is scoped at <literal>val id</literal> and the\r
35974declaration is equivalent to the following.</simpara>\r
35975<programlisting language="sml" linenumbering="unnumbered">val 'a id: 'a -&gt; 'a = fn x =&gt; x</programlisting>\r
35976</listitem>\r
35977<listitem>\r
35978<simpara>\r
35979In this example,\r
35980</simpara>\r
35981<programlisting language="sml" linenumbering="unnumbered"> val f = fn x =&gt; let exception E of 'a in E x end</programlisting>\r
35982<simpara><literal>'a</literal> is unguarded in <literal>val f</literal> and does not occur unguarded in any\r
35983containing declaration. Hence, <literal>'a</literal> is scoped at <literal>val f</literal> and the\r
35984declaration is equivalent to the following.</simpara>\r
35985<programlisting language="sml" linenumbering="unnumbered">val 'a f = fn x =&gt; let exception E of 'a in E x end</programlisting>\r
35986</listitem>\r
35987<listitem>\r
35988<simpara>\r
35989In this example (taken from the <link linkend="DefinitionOfStandardML">Definition</link>),\r
35990</simpara>\r
35991<programlisting language="sml" linenumbering="unnumbered">val x: int -&gt; int = let val id: 'a -&gt; 'a = fn z =&gt; z in id id end</programlisting>\r
35992<simpara><literal>'a</literal> occurs unguarded in <literal>val id</literal>, but not in <literal>val x</literal>. Hence, <literal>'a</literal> is\r
35993implicitly scoped at <literal>val id</literal>, and the declaration is equivalent to\r
35994the following.</simpara>\r
35995<programlisting language="sml" linenumbering="unnumbered">val x: int -&gt; int = let val 'a id: 'a -&gt; 'a = fn z =&gt; z in id id end</programlisting>\r
35996</listitem>\r
35997<listitem>\r
35998<simpara>\r
35999In this example,\r
36000</simpara>\r
36001<programlisting language="sml" linenumbering="unnumbered">val f = (fn x: 'a =&gt; x) (fn y =&gt; y)</programlisting>\r
36002<simpara><literal>'a</literal> occurs unguarded in <literal>val f</literal> and does not occur unguarded in any\r
36003containing declaration. Hence, <literal>'a</literal> is implicitly scoped at <literal>val f</literal>,\r
36004and the declaration is equivalent to the following.</simpara>\r
36005<programlisting language="sml" linenumbering="unnumbered">val 'a f = (fn x: 'a =&gt; x) (fn y =&gt; y)</programlisting>\r
36006<simpara>This does not type check due to the <link linkend="ValueRestriction">ValueRestriction</link>.</simpara>\r
36007</listitem>\r
36008<listitem>\r
36009<simpara>\r
36010In this example,\r
36011</simpara>\r
36012<programlisting language="sml" linenumbering="unnumbered">fun f x =\r
36013 let\r
36014 fun g (y: 'a) = if true then x else y\r
36015 in\r
36016 g x\r
36017 end</programlisting>\r
36018<simpara><literal>'a</literal> occurs unguarded in <literal>fun g</literal>, not in <literal>fun f</literal>. Hence, <literal>'a</literal> is\r
36019implicitly scoped at <literal>fun g</literal>, and the declaration is equivalent to</simpara>\r
36020<programlisting language="sml" linenumbering="unnumbered">fun f x =\r
36021 let\r
36022 fun 'a g (y: 'a) = if true then x else y\r
36023 in\r
36024 g x\r
36025 end</programlisting>\r
36026<simpara>This fails to type check because <literal>x</literal> and <literal>y</literal> must have the same type,\r
36027but the <literal>x</literal> occurs outside the scope of the type variable <literal>'a</literal>. MLton\r
36028reports the following error.</simpara>\r
36029<screen>Error: z.sml 3.21-3.41.\r
36030 Then and else branches disagree.\r
36031 then: [???]\r
36032 else: ['a]\r
36033 in: if true then x else y\r
36034 note: type would escape its scope: 'a\r
36035 escape to: z.sml 1.1-6.5</screen>\r
36036<simpara>This problem could be fixed either by adding an explicit type\r
36037constraint, as in <literal>fun f (x: 'a)</literal>, or by explicitly scoping <literal>'a</literal>, as\r
36038in <literal>fun 'a f x = ...</literal>.</simpara>\r
36039</listitem>\r
36040</itemizedlist>\r
36041</section>\r
36042<section id="_restrictions_on_type_variable_scope">\r
36043<title>Restrictions on type variable scope</title>\r
36044<simpara>It is not allowed to scope a type variable within a declaration in\r
36045which it is already in scope (see the last restriction listed on page\r
360469 of the <link linkend="DefinitionOfStandardML">Definition</link>). For example, the\r
36047following program is invalid.</simpara>\r
36048<programlisting language="sml" linenumbering="unnumbered">fun 'a f (x: 'a) =\r
36049 let\r
36050 fun 'a g (y: 'a) = y\r
36051 in\r
36052 ()\r
36053 end</programlisting>\r
36054<simpara>MLton reports the following error.</simpara>\r
36055<screen>Error: z.sml 3.11-3.12.\r
36056 Type variable scoped at an outer declaration: 'a.\r
36057 scoped at: z.sml 1.1-6.6</screen>\r
36058<simpara>This is an error even if the scoping is implicit. That is, the\r
36059following program is invalid as well.</simpara>\r
36060<programlisting language="sml" linenumbering="unnumbered">fun f (x: 'a) =\r
36061 let\r
36062 fun 'a g (y: 'a) = y\r
36063 in\r
36064 ()\r
36065 end</programlisting>\r
36066<simpara><?asciidoc-pagebreak?></simpara>\r
36067</section>\r
36068</section>\r
36069<section id="Unicode">\r
36070<title>Unicode</title>\r
36071<section id="_support_in_the_definition_of_standard_ml">\r
36072<title>Support in The Definition of Standard ML</title>\r
36073<simpara>There is no real support for Unicode in the\r
36074<link linkend="DefinitionOfStandardML">Definition</link>; there are only a few throw-away\r
36075sentences along the lines of "the characters with numbers 0 to 127\r
36076coincide with the ASCII character set."</simpara>\r
36077</section>\r
36078<section id="_support_in_the_standard_ml_basis_library">\r
36079<title>Support in The Standard ML Basis Library</title>\r
36080<simpara>Neither is there real support for Unicode in the <link linkend="BasisLibrary">Basis Library</link>. The general consensus (which includes the opinions of the\r
36081editors of the Basis Library) is that the <literal>WideChar</literal> and <literal>WideString</literal>\r
36082structures are insufficient for the purposes of Unicode. There is no\r
36083<literal>LargeChar</literal> structure, which in itself is a deficiency, since a\r
36084programmer can not program against the largest supported character\r
36085size.</simpara>\r
36086</section>\r
36087<section id="_current_support_in_mlton">\r
36088<title>Current Support in MLton</title>\r
36089<simpara>MLton, as a minor extension over the Definition, supports UTF-8 byte\r
36090sequences in text constants. This feature enables "UTF-8 convenience"\r
36091(but not comprehensive Unicode support); in particular, it allows one\r
36092to copy text from a browser and paste it into a string constant in an\r
36093editor and, furthermore, if the string is printed to a terminal, then\r
36094will (typically) appear as the original text. See the\r
36095<link linkend="SuccessorML_ExtendedTextConsts">extended text constants feature of Successor ML</link> for more details.</simpara>\r
36096<simpara>MLton, also as a minor extension over the Definition, supports\r
36097<literal>\Uxxxxxxxx</literal> numeric escapes in text constants and has preliminary\r
36098internal support for 16- and 32-bit characters and strings.</simpara>\r
36099<simpara>MLton provides <literal>WideChar</literal> and <literal>WideString</literal> structures, corresponding\r
36100to 32-bit characters and strings, respectively.</simpara>\r
36101</section>\r
36102<section id="_questions_and_discussions">\r
36103<title>Questions and Discussions</title>\r
36104<simpara>There are periodic flurries of questions and discussion about Unicode\r
36105in MLton/SML. In December 2004, there was a discussion that led to\r
36106some seemingly sound design decisions. The discussion started at:</simpara>\r
36107<itemizedlist>\r
36108<listitem>\r
36109<simpara>\r
36110<ulink url="http://www.mlton.org/pipermail/mlton/2004-December/026396.html">http://www.mlton.org/pipermail/mlton/2004-December/026396.html</ulink>\r
36111</simpara>\r
36112</listitem>\r
36113</itemizedlist>\r
36114<simpara>There is a good summary of points at:</simpara>\r
36115<itemizedlist>\r
36116<listitem>\r
36117<simpara>\r
36118<ulink url="http://www.mlton.org/pipermail/mlton/2004-December/026440.html">http://www.mlton.org/pipermail/mlton/2004-December/026440.html</ulink>\r
36119</simpara>\r
36120</listitem>\r
36121</itemizedlist>\r
36122<simpara>In November 2005, there was a followup discussion and the beginning of\r
36123some coding.</simpara>\r
36124<itemizedlist>\r
36125<listitem>\r
36126<simpara>\r
36127<ulink url="http://www.mlton.org/pipermail/mlton/2005-November/028300.html">http://www.mlton.org/pipermail/mlton/2005-November/028300.html</ulink>\r
36128</simpara>\r
36129</listitem>\r
36130</itemizedlist>\r
36131</section>\r
36132<section id="_also_see_48">\r
36133<title>Also see</title>\r
36134<simpara>The <link linkend="fxp">fxp</link> XML parser has some support for dealing with Unicode\r
36135documents.</simpara>\r
36136<simpara><?asciidoc-pagebreak?></simpara>\r
36137</section>\r
36138</section>\r
36139<section id="UniversalType">\r
36140<title>UniversalType</title>\r
36141<simpara>A universal type is a type into which all other types can be embedded.\r
36142Here&#8217;s a <link linkend="StandardML">Standard ML</link> signature for a universal type.</simpara>\r
36143<programlisting language="sml" linenumbering="unnumbered">signature UNIVERSAL_TYPE =\r
36144 sig\r
36145 type t\r
36146\r
36147 val embed: unit -&gt; ('a -&gt; t) * (t -&gt; 'a option)\r
36148 end</programlisting>\r
36149<simpara>The idea is that <literal>type t</literal> is the universal type and that each call to\r
36150<literal>embed</literal> returns a new pair of functions <literal>(inject, project)</literal>, where\r
36151<literal>inject</literal> embeds a value into the universal type and <literal>project</literal> extracts\r
36152the value from the universal type. A pair <literal>(inject, project)</literal>\r
36153returned by <literal>embed</literal> works together in that <literal>project u</literal> will return\r
36154<literal>SOME v</literal> if and only if <literal>u</literal> was created by <literal>inject v</literal>. If <literal>u</literal> was\r
36155created by a different function <literal>inject'</literal>, then <literal>project</literal> returns\r
36156<literal>NONE</literal>.</simpara>\r
36157<simpara>Here&#8217;s an example embedding integers and reals into a universal type.</simpara>\r
36158<programlisting language="sml" linenumbering="unnumbered">functor Test (U: UNIVERSAL_TYPE): sig end =\r
36159 struct\r
36160 val (intIn: int -&gt; U.t, intOut) = U.embed ()\r
36161 val r: U.t ref = ref (intIn 13)\r
36162 val s1 =\r
36163 case intOut (!r) of\r
36164 NONE =&gt; "NONE"\r
36165 | SOME i =&gt; Int.toString i\r
36166 val (realIn: real -&gt; U.t, realOut) = U.embed ()\r
36167 val () = r := realIn 13.0\r
36168 val s2 =\r
36169 case intOut (!r) of\r
36170 NONE =&gt; "NONE"\r
36171 | SOME i =&gt; Int.toString i\r
36172 val s3 =\r
36173 case realOut (!r) of\r
36174 NONE =&gt; "NONE"\r
36175 | SOME x =&gt; Real.toString x\r
36176 val () = print (concat [s1, " ", s2, " ", s3, "\n"])\r
36177 end</programlisting>\r
36178<simpara>Applying <literal>Test</literal> to an appropriate implementation will print</simpara>\r
36179<screen>13 NONE 13.0</screen>\r
36180<simpara>Note that two different calls to embed on the same type return\r
36181different embeddings.</simpara>\r
36182<simpara>Standard ML does not have explicit support for universal types;\r
36183however, there are at least two ways to implement them.</simpara>\r
36184<section id="_implementation_using_exceptions">\r
36185<title>Implementation Using Exceptions</title>\r
36186<simpara>While the intended use of SML exceptions is for exception handling, an\r
36187accidental feature of their design is that the <literal>exn</literal> type is a\r
36188universal type. The implementation relies on being able to declare\r
36189exceptions locally to a function and on the fact that exceptions are\r
36190<link linkend="GenerativeException">generative</link>.</simpara>\r
36191<programlisting language="sml" linenumbering="unnumbered">structure U:&gt; UNIVERSAL_TYPE =\r
36192 struct\r
36193 type t = exn\r
36194\r
36195 fun 'a embed () =\r
36196 let\r
36197 exception E of 'a\r
36198 fun project (e: t): 'a option =\r
36199 case e of\r
36200 E a =&gt; SOME a\r
36201 | _ =&gt; NONE\r
36202 in\r
36203 (E, project)\r
36204 end\r
36205 end</programlisting>\r
36206</section>\r
36207<section id="_implementation_using_functions_and_references">\r
36208<title>Implementation Using Functions and References</title>\r
36209<programlisting language="sml" linenumbering="unnumbered">structure U:&gt; UNIVERSAL_TYPE =\r
36210 struct\r
36211 datatype t = T of {clear: unit -&gt; unit,\r
36212 store: unit -&gt; unit}\r
36213\r
36214 fun 'a embed () =\r
36215 let\r
36216 val r: 'a option ref = ref NONE\r
36217 fun inject (a: 'a): t =\r
36218 T {clear = fn () =&gt; r := NONE,\r
36219 store = fn () =&gt; r := SOME a}\r
36220 fun project (T {clear, store}): 'a option =\r
36221 let\r
36222 val () = store ()\r
36223 val res = !r\r
36224 val () = clear ()\r
36225 in\r
36226 res\r
36227 end\r
36228 in\r
36229 (inject, project)\r
36230 end\r
36231 end</programlisting>\r
36232<simpara>Note that due to the use of a shared ref cell, the above\r
36233implementation is not thread safe.</simpara>\r
36234<simpara>One could try to simplify the above implementation by eliminating the\r
36235<literal>clear</literal> function, making <literal>type t = unit -&gt; unit</literal>.</simpara>\r
36236<programlisting language="sml" linenumbering="unnumbered">structure U:&gt; UNIVERSAL_TYPE =\r
36237 struct\r
36238 type t = unit -&gt; unit\r
36239\r
36240 fun 'a embed () =\r
36241 let\r
36242 val r: 'a option ref = ref NONE\r
36243 fun inject (a: 'a): t = fn () =&gt; r := SOME a\r
36244 fun project (f: t): 'a option = (r := NONE; f (); !r)\r
36245 in\r
36246 (inject, project)\r
36247 end\r
36248 end</programlisting>\r
36249<simpara>While correct, this approach keeps the contents of the ref cell alive\r
36250longer than necessary, which could cause a space leak. The problem is\r
36251in <literal>project</literal>, where the call to <literal>f</literal> stores some value in some ref cell\r
36252<literal>r'</literal>. Perhaps <literal>r'</literal> is the same ref cell as <literal>r</literal>, but perhaps not. If\r
36253we do not clear <literal>r'</literal> before returning from <literal>project</literal>, then <literal>r'</literal> will\r
36254keep the value alive, even though it is useless.</simpara>\r
36255</section>\r
36256<section id="_also_see_49">\r
36257<title>Also see</title>\r
36258<itemizedlist>\r
36259<listitem>\r
36260<simpara>\r
36261<link linkend="PropertyList">PropertyList</link>: Lisp-style property lists implemented with a universal type\r
36262</simpara>\r
36263</listitem>\r
36264</itemizedlist>\r
36265<simpara><?asciidoc-pagebreak?></simpara>\r
36266</section>\r
36267</section>\r
36268<section id="UnresolvedBugs">\r
36269<title>UnresolvedBugs</title>\r
36270<simpara>Here are the places where MLton deviates from\r
36271<link linkend="DefinitionOfStandardML">The Definition of Standard ML (Revised)</link> and\r
36272the <link linkend="BasisLibrary">Basis Library</link>. In general, MLton complies with\r
36273the <link linkend="DefinitionOfStandardML">Definition</link> quite closely, typically much\r
36274more closely than other SML compilers (see, e.g., our list of\r
36275<link linkend="SMLNJDeviations">SML/NJ&#8217;s deviations</link>). In fact, the four deviations\r
36276listed here are the only known deviations, and we have no immediate\r
36277plans to fix them. If you find a deviation not listed here, please\r
36278report a <link linkend="Bug">Bug</link>.</simpara>\r
36279<simpara>We don&#8217;t plan to fix these bugs because the first (parsing nested\r
36280cases) has historically never been accepted by any SML compiler, the\r
36281second clearly indicates a problem in the\r
36282<link linkend="DefinitionOfStandardML">Definition</link>, and the remaining are difficult\r
36283to resolve in the context of MLton&#8217;s implementaton of Standard ML (and\r
36284unlikely to be problematic in practice).</simpara>\r
36285<itemizedlist>\r
36286<listitem>\r
36287<simpara>\r
36288MLton does not correctly parse case expressions nested within other\r
36289matches. For example, the following fails.\r
36290</simpara>\r
36291<programlisting language="sml" linenumbering="unnumbered">fun f 0 y =\r
36292 case x of\r
36293 1 =&gt; 2\r
36294 | _ =&gt; 3\r
36295 | f _ y = 4</programlisting>\r
36296<simpara>To do this in a program, simply parenthesize the case expression.</simpara>\r
36297<simpara>Allowing such expressions, although compliant with the Definition,\r
36298would be a mistake, since using parentheses is clearer and no SML\r
36299compiler has ever allowed them. Furthermore, implementing this would\r
36300require serious yacc grammar rewriting followed by postprocessing.</simpara>\r
36301</listitem>\r
36302<listitem>\r
36303<simpara>\r
36304MLton does not raise the <literal>Bind</literal> exception at run time when\r
36305evaluating <literal>val rec</literal> (and <literal>fun</literal>) declarations that redefine\r
36306identifiers that previously had constructor status. (By default,\r
36307MLton does warn at compile time about <literal>val rec</literal> (and <literal>fun</literal>)\r
36308declarations that redefine identifiers that previously had\r
36309constructors status; see the <literal>valrecConstr</literal> <link linkend="MLBasisAnnotations">ML Basis annotation</link>.) For example, the Definition requires the\r
36310following program to type check, but also (bizarelly) requires it to\r
36311raise the <literal>Bind</literal> exception\r
36312</simpara>\r
36313<programlisting language="sml" linenumbering="unnumbered">val rec NONE = fn () =&gt; ()</programlisting>\r
36314<simpara>The Definition&#8217;s behavior is obviously an error, a mismatch between\r
36315the static semantics (rule 26) and the dynamic semantics (rule 126).\r
36316Given the comments on rule 26 in the Definition, it seems clear that\r
36317the authors meant for <literal>val rec</literal> to allow an identifier&#8217;s constructor\r
36318status to be overridden both statically and dynamically. Hence, MLton\r
36319and most SML compilers follow rule 26, but do not follow rule 126.</simpara>\r
36320</listitem>\r
36321<listitem>\r
36322<simpara>\r
36323MLton does not hide the equality aspect of types declared in\r
36324<literal>abstype</literal> declarations. So, MLton accepts programs like the following,\r
36325while the Definition rejects them.\r
36326</simpara>\r
36327<programlisting language="sml" linenumbering="unnumbered">abstype t = T with end\r
36328val _ = fn (t1, t2 : t) =&gt; t1 = t2\r
36329\r
36330abstype t = T with val a = T end\r
36331val _ = a = a</programlisting>\r
36332<simpara>One consequence of this choice is that MLton accepts the following\r
36333program, in accordance with the Definition.</simpara>\r
36334<programlisting language="sml" linenumbering="unnumbered">abstype t = T with val eq = op = end\r
36335val _ = fn (t1, t2 : t) =&gt; eq (t1, t2)</programlisting>\r
36336<simpara>Other implementations will typically reject this program, because they\r
36337make an early choice for the type of <literal>eq</literal> to be <literal>''a * ''a -&gt; bool</literal>\r
36338instead of <literal>t * t -&gt; bool</literal>. The choice is understandable, since the\r
36339Definition accepts the following program.</simpara>\r
36340<programlisting language="sml" linenumbering="unnumbered">abstype t = T with val eq = op = end\r
36341val _ = eq (1, 2)</programlisting>\r
36342</listitem>\r
36343<listitem>\r
36344<simpara>\r
36345MLton (re-)type checks each functor definition at every\r
36346corresponding functor application (the compilation technique of\r
36347defunctorization). One consequence of this implementation is that\r
36348MLton accepts the following program, while the Definition rejects\r
36349it.\r
36350</simpara>\r
36351<programlisting language="sml" linenumbering="unnumbered">functor F (X: sig type t end) = struct\r
36352 val f = id id\r
36353end\r
36354structure A = F (struct type t = int end)\r
36355structure B = F (struct type t = bool end)\r
36356val _ = A.f 10\r
36357val _ = B.f "dude"</programlisting>\r
36358<simpara>On the other hand, other implementations will typically reject the\r
36359following program, while MLton and the Definition accept it.</simpara>\r
36360<programlisting language="sml" linenumbering="unnumbered">functor F (X: sig type t end) = struct\r
36361 val f = id id\r
36362end\r
36363structure A = F (struct type t = int end)\r
36364structure B = F (struct type t = bool end)\r
36365val _ = A.f 10\r
36366val _ = B.f false</programlisting>\r
36367<simpara>See <link linkend="References_DreyerBlume07">DreyerBlume07</link> for more details.</simpara>\r
36368</listitem>\r
36369</itemizedlist>\r
36370<simpara><?asciidoc-pagebreak?></simpara>\r
36371</section>\r
36372<section id="UnsafeStructure">\r
36373<title>UnsafeStructure</title>\r
36374<simpara>This module is a subset of the <literal>Unsafe</literal> module provided by SML/NJ,\r
36375with a few extract operations for <literal>PackWord</literal> and <literal>PackReal</literal>.</simpara>\r
36376<programlisting language="sml" linenumbering="unnumbered">signature UNSAFE_MONO_ARRAY =\r
36377 sig\r
36378 type array\r
36379 type elem\r
36380\r
36381 val create: int -&gt; array\r
36382 val sub: array * int -&gt; elem\r
36383 val update: array * int * elem -&gt; unit\r
36384 end\r
36385\r
36386signature UNSAFE_MONO_VECTOR =\r
36387 sig\r
36388 type elem\r
36389 type vector\r
36390\r
36391 val sub: vector * int -&gt; elem\r
36392 end\r
36393\r
36394signature UNSAFE =\r
36395 sig\r
36396 structure Array:\r
36397 sig\r
36398 val create: int * 'a -&gt; 'a array\r
36399 val sub: 'a array * int -&gt; 'a\r
36400 val update: 'a array * int * 'a -&gt; unit\r
36401 end\r
36402 structure CharArray: UNSAFE_MONO_ARRAY\r
36403 structure CharVector: UNSAFE_MONO_VECTOR\r
36404 structure IntArray: UNSAFE_MONO_ARRAY\r
36405 structure IntVector: UNSAFE_MONO_VECTOR\r
36406 structure Int8Array: UNSAFE_MONO_ARRAY\r
36407 structure Int8Vector: UNSAFE_MONO_VECTOR\r
36408 structure Int16Array: UNSAFE_MONO_ARRAY\r
36409 structure Int16Vector: UNSAFE_MONO_VECTOR\r
36410 structure Int32Array: UNSAFE_MONO_ARRAY\r
36411 structure Int32Vector: UNSAFE_MONO_VECTOR\r
36412 structure Int64Array: UNSAFE_MONO_ARRAY\r
36413 structure Int64Vector: UNSAFE_MONO_VECTOR\r
36414 structure IntInfArray: UNSAFE_MONO_ARRAY\r
36415 structure IntInfVector: UNSAFE_MONO_VECTOR\r
36416 structure LargeIntArray: UNSAFE_MONO_ARRAY\r
36417 structure LargeIntVector: UNSAFE_MONO_VECTOR\r
36418 structure LargeRealArray: UNSAFE_MONO_ARRAY\r
36419 structure LargeRealVector: UNSAFE_MONO_VECTOR\r
36420 structure LargeWordArray: UNSAFE_MONO_ARRAY\r
36421 structure LargeWordVector: UNSAFE_MONO_VECTOR\r
36422 structure RealArray: UNSAFE_MONO_ARRAY\r
36423 structure RealVector: UNSAFE_MONO_VECTOR\r
36424 structure Real32Array: UNSAFE_MONO_ARRAY\r
36425 structure Real32Vector: UNSAFE_MONO_VECTOR\r
36426 structure Real64Array: UNSAFE_MONO_ARRAY\r
36427 structure Vector:\r
36428 sig\r
36429 val sub: 'a vector * int -&gt; 'a\r
36430 end\r
36431 structure Word8Array: UNSAFE_MONO_ARRAY\r
36432 structure Word8Vector: UNSAFE_MONO_VECTOR\r
36433 structure Word16Array: UNSAFE_MONO_ARRAY\r
36434 structure Word16Vector: UNSAFE_MONO_VECTOR\r
36435 structure Word32Array: UNSAFE_MONO_ARRAY\r
36436 structure Word32Vector: UNSAFE_MONO_VECTOR\r
36437 structure Word64Array: UNSAFE_MONO_ARRAY\r
36438 structure Word64Vector: UNSAFE_MONO_VECTOR\r
36439\r
36440 structure PackReal32Big : PACK_REAL\r
36441 structure PackReal32Little : PACK_REAL\r
36442 structure PackReal64Big : PACK_REAL\r
36443 structure PackReal64Little : PACK_REAL\r
36444 structure PackRealBig : PACK_REAL\r
36445 structure PackRealLittle : PACK_REAL\r
36446 structure PackWord16Big : PACK_WORD\r
36447 structure PackWord16Little : PACK_WORD\r
36448 structure PackWord32Big : PACK_WORD\r
36449 structure PackWord32Little : PACK_WORD\r
36450 structure PackWord64Big : PACK_WORD\r
36451 structure PackWord64Little : PACK_WORD\r
36452 end</programlisting>\r
36453<simpara><?asciidoc-pagebreak?></simpara>\r
36454</section>\r
36455<section id="Useless">\r
36456<title>Useless</title>\r
36457<simpara><link linkend="Useless">Useless</link> is an optimization pass for the <link linkend="SSA">SSA</link>\r
36458<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="SSASimplify">SSASimplify</link>.</simpara>\r
36459<section id="_description_64">\r
36460<title>Description</title>\r
36461<simpara>This pass:</simpara>\r
36462<itemizedlist>\r
36463<listitem>\r
36464<simpara>\r
36465removes components of tuples that are constants (use unification)\r
36466</simpara>\r
36467</listitem>\r
36468<listitem>\r
36469<simpara>\r
36470removes function arguments that are constants\r
36471</simpara>\r
36472</listitem>\r
36473<listitem>\r
36474<simpara>\r
36475builds some kind of dependence graph where\r
36476</simpara>\r
36477<itemizedlist>\r
36478<listitem>\r
36479<simpara>\r
36480a value of ground type is useful if it is an arg to a primitive\r
36481</simpara>\r
36482</listitem>\r
36483<listitem>\r
36484<simpara>\r
36485a tuple is useful if it contains a useful component\r
36486</simpara>\r
36487</listitem>\r
36488<listitem>\r
36489<simpara>\r
36490a constructor is useful if it contains a useful component or is used in a <literal>Case</literal> transfer\r
36491</simpara>\r
36492</listitem>\r
36493</itemizedlist>\r
36494</listitem>\r
36495</itemizedlist>\r
36496<simpara>If a useful tuple is coerced to another useful tuple, then all of\r
36497their components must agree (exactly). It is trivial to convert a\r
36498useful value to a useless one.</simpara>\r
36499</section>\r
36500<section id="_implementation_70">\r
36501<title>Implementation</title>\r
36502<itemizedlist>\r
36503<listitem>\r
36504<simpara>\r
36505<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/useless.fun"><literal>useless.fun</literal></ulink>\r
36506</simpara>\r
36507</listitem>\r
36508</itemizedlist>\r
36509</section>\r
36510<section id="_details_and_notes_67">\r
36511<title>Details and Notes</title>\r
36512<simpara>It is also trivial to convert a useful tuple to one of its useful\r
36513components&#8201;&#8212;&#8201;but this seems hard.</simpara>\r
36514<simpara>Suppose that you have a <literal>ref</literal>/<literal>array</literal>/<literal>vector</literal> that is useful, but the\r
36515components aren&#8217;t&#8201;&#8212;&#8201;then the components are converted to type <literal>unit</literal>,\r
36516and any primitive args must be as well.</simpara>\r
36517<simpara>Unify all handler arguments so that <literal>raise</literal>/<literal>handle</literal> has a consistent\r
36518calling convention.</simpara>\r
36519<simpara><?asciidoc-pagebreak?></simpara>\r
36520</section>\r
36521</section>\r
36522<section id="Users">\r
36523<title>Users</title>\r
36524<simpara>Here is a list of companies, projects, and courses that use or have\r
36525used MLton. If you use MLton and are not here, please add your\r
36526project with a brief description and a link. Thanks.</simpara>\r
36527<section id="_companies">\r
36528<title>Companies</title>\r
36529<itemizedlist>\r
36530<listitem>\r
36531<simpara>\r
36532<ulink url="http://www.hardcoreprocessing.com/">Hardcore Processing</ulink> uses MLton as a <ulink url="http://www.hardcoreprocessing.com/Freeware/MLTonWin32.html">crosscompiler from Linux to Windows</ulink> for graphics and game software.\r
36533</simpara>\r
36534<itemizedlist>\r
36535<listitem>\r
36536<simpara>\r
36537<ulink url="http://www.cex3d.net/">CEX3D Converter</ulink>, a conversion program for 3D objects.\r
36538</simpara>\r
36539</listitem>\r
36540<listitem>\r
36541<simpara>\r
36542<ulink url="http://www.hardcoreprocessing.com/company/showreel/index.html">Interactive Showreel</ulink>, which contains a crossplatform GUI-toolkit and a realtime renderer for a subset of RenderMan written in Standard ML.\r
36543</simpara>\r
36544</listitem>\r
36545<listitem>\r
36546<simpara>\r
36547various <ulink url="http://www.hardcoreprocessing.com/entertainment/index.html">games</ulink>\r
36548</simpara>\r
36549</listitem>\r
36550</itemizedlist>\r
36551</listitem>\r
36552<listitem>\r
36553<simpara>\r
36554<ulink url="http://www.mathworks.com/products/polyspace/">MathWorks/PolySpace Technologies</ulink> builds their product that detects runtime errors in embedded systems based on abstract interpretation.\r
36555</simpara>\r
36556</listitem>\r
36557<listitem>\r
36558<simpara>\r
36559<ulink url="http://www.reactive-systems.com/">Reactive Systems</ulink> uses MLton to build Reactis, a model-based testing and validation package used in the automotive and aerospace industries.\r
36560</simpara>\r
36561</listitem>\r
36562</itemizedlist>\r
36563</section>\r
36564<section id="_projects">\r
36565<title>Projects</title>\r
36566<itemizedlist>\r
36567<listitem>\r
36568<simpara>\r
36569<ulink url="http://www-ia.hiof.no/%7Erolando/adate_intro.html">ADATE</ulink>, Automatic Design of Algorithms Through Evolution, a system for automatic programming i.e., inductive inference of algorithms. ADATE can automatically generate non-trivial and novel algorithms written in Standard ML.\r
36570</simpara>\r
36571</listitem>\r
36572<listitem>\r
36573<simpara>\r
36574<ulink url="http://types.bu.edu/reports/Dim+Wes+Mul+Tur+Wel+Con:TIC-2000-LNCS.html">CIL</ulink>, a compiler for SML based on intersection and union types.\r
36575</simpara>\r
36576</listitem>\r
36577<listitem>\r
36578<simpara>\r
36579<ulink url="http://www.cs.cmu.edu/%7Econcert/">ConCert</ulink>, a project investigating certified code for grid computing.\r
36580</simpara>\r
36581</listitem>\r
36582<listitem>\r
36583<simpara>\r
36584<ulink url="http://hcoop.sourceforge.net/">Cooperative Internet hosting tools</ulink>\r
36585</simpara>\r
36586</listitem>\r
36587<listitem>\r
36588<simpara>\r
36589<ulink url="http://www.fantasy-coders.de/projects/gh/">Guugelhupf</ulink>, a simple search engine.\r
36590</simpara>\r
36591</listitem>\r
36592<listitem>\r
36593<simpara>\r
36594<ulink url="http://www.mpi-sws.org/%7Erossberg/hamlet/">HaMLet</ulink>, a model implementation of Standard ML.\r
36595</simpara>\r
36596</listitem>\r
36597<listitem>\r
36598<simpara>\r
36599<ulink url="http://code.google.com/p/kepler-code/">KeplerCode</ulink>, independent verification of the computational aspects of proofs of the Kepler conjecture and the Dodecahedral conjecture.\r
36600</simpara>\r
36601</listitem>\r
36602<listitem>\r
36603<simpara>\r
36604<ulink url="http://www.gilith.com/research/metis/">Metis</ulink>, a first-order prover (used in the <ulink url="http://hol.sourceforge.net/">HOL4 theorem prover</ulink> and the <ulink url="http://isabelle.in.tum.de/">Isabelle theorem prover</ulink>).\r
36605</simpara>\r
36606</listitem>\r
36607<listitem>\r
36608<simpara>\r
36609<ulink url="http://tom7misc.cvs.sourceforge.net/viewvc/tom7misc/net/mlftpd/">mlftpd</ulink>, an ftp daemon written in SML. <link linkend="TomMurphy">TomMurphy</link> is also working on <ulink url="http://tom7misc.cvs.sourceforge.net/viewvc/tom7misc/net/">replacements for standard network services</ulink> in SML. He also uses MLton to build his entries (<ulink url="http://www.cs.cmu.edu/%7Etom7/icfp2001/">2001</ulink>, <ulink url="http://www.cs.cmu.edu/%7Etom7/icfp2002/">2002</ulink>, <ulink url="http://www.cs.cmu.edu/%7Etom7/icfp2004/">2004</ulink>, <ulink url="http://www.cs.cmu.edu/%7Etom7/icfp2005/">2005</ulink>) in the annual ICFP programming contest.\r
36610</simpara>\r
36611</listitem>\r
36612<listitem>\r
36613<simpara>\r
36614<ulink url="http://www.informatik.uni-freiburg.de/proglang/research/software/mlope/">MLOPE</ulink>, an offline partial evaluator for Standard ML.\r
36615</simpara>\r
36616</listitem>\r
36617<listitem>\r
36618<simpara>\r
36619<ulink url="http://www.ida.liu.se/%7Epelab/rml/">RML</ulink>, a system for developing, compiling and debugging and teaching structural operational semantics (SOS) and natural semantics specifications.\r
36620</simpara>\r
36621</listitem>\r
36622<listitem>\r
36623<simpara>\r
36624<ulink url="http://www.macs.hw.ac.uk/ultra/skalpel/index.html">Skalpel</ulink>, a type-error slicer for SML\r
36625</simpara>\r
36626</listitem>\r
36627<listitem>\r
36628<simpara>\r
36629<ulink url="http://www.cs.cmu.edu/%7Etom7/ssapre/">SSA PRE</ulink>, an implementation of Partial Redundancy Elimination for MLton.\r
36630</simpara>\r
36631</listitem>\r
36632<listitem>\r
36633<simpara>\r
36634<link linkend="Stabilizers">Stabilizers</link>, a modular checkpointing abstraction for concurrent functional programs.\r
36635</simpara>\r
36636</listitem>\r
36637<listitem>\r
36638<simpara>\r
36639<ulink url="http://ttic.uchicago.edu/%7Epl/sa-sml/">Self-Adjusting SML</ulink>, self-adjusting computation, a model of computing where programs can automatically adjust to changes to their data.\r
36640</simpara>\r
36641</listitem>\r
36642<listitem>\r
36643<simpara>\r
36644<ulink url="http://faculty.ist.unomaha.edu/winter/ShiftLab/TL_web/TL_index.html">TL System</ulink>, providing general-purpose support for rewrite-based transformation over elements belonging to a (user-defined) domain language.\r
36645</simpara>\r
36646</listitem>\r
36647<listitem>\r
36648<simpara>\r
36649<ulink url="http://projects.laas.fr/tina/">Tina</ulink> (Time Petri net Analyzer)\r
36650</simpara>\r
36651</listitem>\r
36652<listitem>\r
36653<simpara>\r
36654<ulink url="http://www.twelf.org/">Twelf</ulink> an implementation of the LF logical framework.\r
36655</simpara>\r
36656</listitem>\r
36657<listitem>\r
36658<simpara>\r
36659<ulink url="http://www.cs.indiana.edu/%7Errnewton/wavescope/">WaveScript/WaveScript</ulink>, a sensor network project; the WaveScript compiler can generate SML (MLton) code.\r
36660</simpara>\r
36661</listitem>\r
36662</itemizedlist>\r
36663</section>\r
36664<section id="_courses">\r
36665<title>Courses</title>\r
36666<itemizedlist>\r
36667<listitem>\r
36668<simpara>\r
36669<ulink url="http://www.eecs.harvard.edu/%7Enr/cs152/">Harvard CS-152</ulink>, undergraduate programming languages.\r
36670</simpara>\r
36671</listitem>\r
36672<listitem>\r
36673<simpara>\r
36674<ulink url="http://www.ia-stud.hiof.no/%7Erolando/PL/">Høgskolen i Østfold IAI30202</ulink>, programming languages.\r
36675</simpara>\r
36676</listitem>\r
36677</itemizedlist>\r
36678<simpara><?asciidoc-pagebreak?></simpara>\r
36679</section>\r
36680</section>\r
36681<section id="Utilities">\r
36682<title>Utilities</title>\r
36683<simpara>This page is a collection of basic utilities used in the examples on\r
36684various pages. See</simpara>\r
36685<itemizedlist>\r
36686<listitem>\r
36687<simpara>\r
36688<link linkend="InfixingOperators">InfixingOperators</link>, and\r
36689</simpara>\r
36690</listitem>\r
36691<listitem>\r
36692<simpara>\r
36693<link linkend="ProductType">ProductType</link>\r
36694</simpara>\r
36695</listitem>\r
36696</itemizedlist>\r
36697<simpara>for longer discussions on some of these utilities.</simpara>\r
36698<programlisting language="sml" linenumbering="unnumbered">(* Operator precedence table *)\r
36699infix 8 * / div mod (* +1 from Basis Library *)\r
36700infix 7 + - ^ (* +1 from Basis Library *)\r
36701infixr 6 :: @ (* +1 from Basis Library *)\r
36702infix 5 = &lt;&gt; &gt; &gt;= &lt; &lt;= (* +1 from Basis Library *)\r
36703infix 4 &lt;\ \&gt;\r
36704infixr 4 &lt;/ /&gt;\r
36705infix 3 o\r
36706infix 2 &gt;|\r
36707infixr 2 |&lt;\r
36708infix 1 := (* -2 from Basis Library *)\r
36709infix 0 before &amp;\r
36710\r
36711(* Some basic combinators *)\r
36712fun const x _ = x\r
36713fun cross (f, g) (x, y) = (f x, g y)\r
36714fun curry f x y = f (x, y)\r
36715fun fail e _ = raise e\r
36716fun id x = x\r
36717\r
36718(* Product type *)\r
36719datatype ('a, 'b) product = &amp; of 'a * 'b\r
36720\r
36721(* Sum type *)\r
36722datatype ('a, 'b) sum = INL of 'a | INR of 'b\r
36723\r
36724(* Some type shorthands *)\r
36725type 'a uop = 'a -&gt; 'a\r
36726type 'a fix = 'a uop -&gt; 'a\r
36727type 'a thunk = unit -&gt; 'a\r
36728type 'a effect = 'a -&gt; unit\r
36729type ('a, 'b) emb = ('a -&gt; 'b) * ('b -&gt; 'a)\r
36730\r
36731(* Infixing, sectioning, and application operators *)\r
36732fun x &lt;\ f = fn y =&gt; f (x, y)\r
36733fun f \&gt; y = f y\r
36734fun f /&gt; y = fn x =&gt; f (x, y)\r
36735fun x &lt;/ f = f x\r
36736\r
36737(* Piping operators *)\r
36738val op&gt;| = op&lt;/\r
36739val op|&lt; = op\&gt;</programlisting>\r
36740<simpara><?asciidoc-pagebreak?></simpara>\r
36741</section>\r
36742<section id="ValueRestriction">\r
36743<title>ValueRestriction</title>\r
36744<simpara>The value restriction is a rule that governs when type inference is\r
36745allowed to polymorphically generalize a value declaration. In short,\r
36746the value restriction says that generalization can only occur if the\r
36747right-hand side of an expression is syntactically a value. For\r
36748example, in</simpara>\r
36749<programlisting language="sml" linenumbering="unnumbered">val f = fn x =&gt; x\r
36750val _ = (f "foo"; f 13)</programlisting>\r
36751<simpara>the expression <literal>fn x =&gt; x</literal> is syntactically a value, so <literal>f</literal> has\r
36752polymorphic type <literal>'a -&gt; 'a</literal> and both calls to <literal>f</literal> type check. On the\r
36753other hand, in</simpara>\r
36754<programlisting language="sml" linenumbering="unnumbered">val f = let in fn x =&gt; x end\r
36755val _ = (f "foo"; f 13)</programlisting>\r
36756<simpara>the expression <literal>let in fn x =&gt; end end</literal> is not syntactically a value\r
36757and so <literal>f</literal> can either have type <literal>int -&gt; int</literal> or <literal>string -&gt; string</literal>,\r
36758but not <literal>'a -&gt; 'a</literal>. Hence, the program does not type check.</simpara>\r
36759<simpara><link linkend="DefinitionOfStandardML">The Definition of Standard ML</link> spells out\r
36760precisely which expressions are syntactic values (it refers to such\r
36761expressions as <emphasis>non-expansive</emphasis>). An expression is a value if it is of\r
36762one of the following forms.</simpara>\r
36763<itemizedlist>\r
36764<listitem>\r
36765<simpara>\r
36766a constant (<literal>13</literal>, <literal>"foo"</literal>, <literal>13.0</literal>, &#8230;)\r
36767</simpara>\r
36768</listitem>\r
36769<listitem>\r
36770<simpara>\r
36771a variable (<literal>x</literal>, <literal>y</literal>, &#8230;)\r
36772</simpara>\r
36773</listitem>\r
36774<listitem>\r
36775<simpara>\r
36776a function (<literal>fn x =&gt; e</literal>)\r
36777</simpara>\r
36778</listitem>\r
36779<listitem>\r
36780<simpara>\r
36781the application of a constructor other than <literal>ref</literal> to a value (<literal>Foo v</literal>)\r
36782</simpara>\r
36783</listitem>\r
36784<listitem>\r
36785<simpara>\r
36786a type constrained value (<literal>v: t</literal>)\r
36787</simpara>\r
36788</listitem>\r
36789<listitem>\r
36790<simpara>\r
36791a tuple in which each field is a value <literal>(v1, v2, ...)</literal>\r
36792</simpara>\r
36793</listitem>\r
36794<listitem>\r
36795<simpara>\r
36796a record in which each field is a value <literal>{l1 = v1, l2 = v2, ...}</literal>\r
36797</simpara>\r
36798</listitem>\r
36799<listitem>\r
36800<simpara>\r
36801a list in which each element is a value <literal>[v1, v2, ...]</literal>\r
36802</simpara>\r
36803</listitem>\r
36804</itemizedlist>\r
36805<section id="_why_the_value_restriction_exists">\r
36806<title>Why the value restriction exists</title>\r
36807<simpara>The value restriction prevents a ref cell (or an array) from holding\r
36808values of different types, which would allow a value of one type to be\r
36809cast to another and hence would break type safety. If the restriction\r
36810were not in place, the following program would type check.</simpara>\r
36811<programlisting language="sml" linenumbering="unnumbered">val r: 'a option ref = ref NONE\r
36812val r1: string option ref = r\r
36813val r2: int option ref = r\r
36814val () = r1 := SOME "foo"\r
36815val v: int = valOf (!r2)</programlisting>\r
36816<simpara>The first line violates the value restriction because <literal>ref NONE</literal> is\r
36817not a value. All other lines are type correct. By its last line, the\r
36818program has cast the string <literal>"foo"</literal> to an integer. This breaks type\r
36819safety, because now we can add a string to an integer with an\r
36820expression like <literal>v + 13</literal>. We could even be more devious, by adding\r
36821the following two lines, which allow us to threat the string <literal>"foo"</literal>\r
36822as a function.</simpara>\r
36823<programlisting language="sml" linenumbering="unnumbered">val r3: (int -&gt; int) option ref = r\r
36824val v: int -&gt; int = valOf (!r3)</programlisting>\r
36825<simpara>Eliminating the explicit <literal>ref</literal> does nothing to fix the problem. For\r
36826example, we could replace the declaration of <literal>r</literal> with the following.</simpara>\r
36827<programlisting language="sml" linenumbering="unnumbered">val f: unit -&gt; 'a option ref = fn () =&gt; ref NONE\r
36828val r: 'a option ref = f ()</programlisting>\r
36829<simpara>The declaration of <literal>f</literal> is well typed, while the declaration of <literal>r</literal>\r
36830violates the value restriction because <literal>f ()</literal> is not a value.</simpara>\r
36831</section>\r
36832<section id="_unnecessarily_rejected_programs">\r
36833<title>Unnecessarily rejected programs</title>\r
36834<simpara>Unfortunately, the value restriction rejects some programs that could\r
36835be accepted.</simpara>\r
36836<programlisting language="sml" linenumbering="unnumbered">val id: 'a -&gt; 'a = fn x =&gt; x\r
36837val f: 'a -&gt; 'a = id id</programlisting>\r
36838<simpara>The type constraint on <literal>f</literal> requires <literal>f</literal> to be polymorphic, which is\r
36839disallowed because <literal>id id</literal> is not a value. MLton reports the\r
36840following type error.</simpara>\r
36841<screen>Error: z.sml 2.5-2.5.\r
36842 Type of variable cannot be generalized in expansive declaration: f.\r
36843 type: ['a] -&gt; ['a]\r
36844 in: val 'a f: ('a -&gt; 'a) = id id</screen>\r
36845<simpara>MLton indicates the inability to make <literal>f</literal> polymorphic by saying that\r
36846the type of <literal>f</literal> cannot be generalized (made polymorphic) its\r
36847declaration is expansive (not a value). MLton doesn&#8217;t explicitly\r
36848mention the value restriction, but that is the reason. If we leave\r
36849the type constraint off of <literal>f</literal></simpara>\r
36850<programlisting language="sml" linenumbering="unnumbered">val id: 'a -&gt; 'a = fn x =&gt; x\r
36851val f = id id</programlisting>\r
36852<simpara>then the program succeeds; however, MLton gives us the following\r
36853warning.</simpara>\r
36854<screen>Warning: z.sml 2.5-2.5.\r
36855 Type of variable was not inferred and could not be generalized: f.\r
36856 type: ??? -&gt; ???\r
36857 in: val f = id id</screen>\r
36858<simpara>This warning indicates that MLton couldn&#8217;t polymorphically generalize\r
36859<literal>f</literal>, nor was there enough context using <literal>f</literal> to determine its type.\r
36860This in itself is not a type error, but it it is a hint that something\r
36861is wrong with our program. Using <literal>f</literal> provides enough context to\r
36862eliminate the warning.</simpara>\r
36863<programlisting language="sml" linenumbering="unnumbered">val id: 'a -&gt; 'a = fn x =&gt; x\r
36864val f = id id\r
36865val _ = f 13</programlisting>\r
36866<simpara>But attempting to use <literal>f</literal> as a polymorphic function will fail.</simpara>\r
36867<programlisting language="sml" linenumbering="unnumbered">val id: 'a -&gt; 'a = fn x =&gt; x\r
36868val f = id id\r
36869val _ = f 13\r
36870val _ = f "foo"</programlisting>\r
36871<screen>Error: z.sml 4.9-4.15.\r
36872 Function applied to incorrect argument.\r
36873 expects: [int]\r
36874 but got: [string]\r
36875 in: f "foo"</screen>\r
36876</section>\r
36877<section id="_alternatives_to_the_value_restriction">\r
36878<title>Alternatives to the value restriction</title>\r
36879<simpara>There would be nothing wrong with treating <literal>f</literal> as polymorphic in</simpara>\r
36880<programlisting language="sml" linenumbering="unnumbered">val id: 'a -&gt; 'a = fn x =&gt; x\r
36881val f = id id</programlisting>\r
36882<simpara>One might think that the value restriction could be relaxed, and that\r
36883only types involving <literal>ref</literal> should be disallowed. Unfortunately, the\r
36884following example shows that even the type <literal>'a -&gt; 'a</literal> can cause\r
36885problems. If this program were allowed, then we could cast an integer\r
36886to a string (or any other type).</simpara>\r
36887<programlisting language="sml" linenumbering="unnumbered">val f: 'a -&gt; 'a =\r
36888 let\r
36889 val r: 'a option ref = ref NONE\r
36890 in\r
36891 fn x =&gt;\r
36892 let\r
36893 val y = !r\r
36894 val () = r := SOME x\r
36895 in\r
36896 case y of\r
36897 NONE =&gt; x\r
36898 | SOME y =&gt; y\r
36899 end\r
36900 end\r
36901val _ = f 13\r
36902val _ = f "foo"</programlisting>\r
36903<simpara>The previous version of Standard ML took a different approach\r
36904(<link linkend="References_MilnerEtAl90">MilnerEtAl90</link>, <link linkend="References_Tofte90">Tofte90</link>, <link linkend="ImperativeTypeVariable">ImperativeTypeVariable</link>)\r
36905than the value restriction. It encoded information in the type system\r
36906about when ref cells would be created, and used this to prevent a ref\r
36907cell from holding multiple types. Although it allowed more programs\r
36908to be type checked, this approach had significant drawbacks. First,\r
36909it was significantly more complex, both for implementers and for\r
36910programmers. Second, it had an unfortunate interaction with the\r
36911modularity, because information about ref usage was exposed in module\r
36912signatures. This either prevented the use of references for\r
36913implementing a signature, or required information that one would like\r
36914to keep hidden to propagate across modules.</simpara>\r
36915<simpara>In the early nineties, Andrew Wright studied about 250,000 lines of\r
36916existing SML code and discovered that it did not make significant use\r
36917of the extended typing ability, and proposed the value restriction as\r
36918a simpler alternative (<link linkend="References_Wright95">Wright95</link>). This was adopted in the\r
36919revised <link linkend="DefinitionOfStandardML">Definition</link>.</simpara>\r
36920</section>\r
36921<section id="_working_with_the_value_restriction">\r
36922<title>Working with the value restriction</title>\r
36923<simpara>One technique that works with the value restriction is\r
36924<link linkend="EtaExpansion">EtaExpansion</link>. We can use eta expansion to make our <literal>id id</literal>\r
36925example type check follows.</simpara>\r
36926<programlisting language="sml" linenumbering="unnumbered">val id: 'a -&gt; 'a = fn x =&gt; x\r
36927val f: 'a -&gt; 'a = fn z =&gt; (id id) z</programlisting>\r
36928<simpara>This solution means that the computation (in this case <literal>id id</literal>) will\r
36929be performed each time <literal>f</literal> is applied, instead of just once when <literal>f</literal>\r
36930is declared. In this case, that is not a problem, but it could be if\r
36931the declaration of <literal>f</literal> performs substantial computation or creates a\r
36932shared data structure.</simpara>\r
36933<simpara>Another technique that sometimes works is to move a monomorphic\r
36934computation prior to a (would-be) polymorphic declaration so that the\r
36935expression is a value. Consider the following program, which fails\r
36936due to the value restriction.</simpara>\r
36937<programlisting language="sml" linenumbering="unnumbered">datatype 'a t = A of string | B of 'a\r
36938val x: 'a t = A (if true then "yes" else "no")</programlisting>\r
36939<simpara>It is easy to rewrite this program as</simpara>\r
36940<programlisting language="sml" linenumbering="unnumbered">datatype 'a t = A of string | B of 'a\r
36941local\r
36942 val s = if true then "yes" else "no"\r
36943in\r
36944 val x: 'a t = A s\r
36945end</programlisting>\r
36946<simpara>The following example (taken from <link linkend="References_Wright95">Wright95</link>) creates a ref\r
36947cell to count the number of times a function is called.</simpara>\r
36948<programlisting language="sml" linenumbering="unnumbered">val count: ('a -&gt; 'a) -&gt; ('a -&gt; 'a) * (unit -&gt; int) =\r
36949 fn f =&gt;\r
36950 let\r
36951 val r = ref 0\r
36952 in\r
36953 (fn x =&gt; (r := 1 + !r; f x), fn () =&gt; !r)\r
36954 end\r
36955val id: 'a -&gt; 'a = fn x =&gt; x\r
36956val (countId: 'a -&gt; 'a, numCalls) = count id</programlisting>\r
36957<simpara>The example does not type check, due to the value restriction.\r
36958However, it is easy to rewrite the program, staging the ref cell\r
36959creation before the polymorphic code.</simpara>\r
36960<programlisting language="sml" linenumbering="unnumbered">datatype t = T of int ref\r
36961val count1: unit -&gt; t = fn () =&gt; T (ref 0)\r
36962val count2: t * ('a -&gt; 'a) -&gt; (unit -&gt; int) * ('a -&gt; 'a) =\r
36963 fn (T r, f) =&gt; (fn () =&gt; !r, fn x =&gt; (r := 1 + !r; f x))\r
36964val id: 'a -&gt; 'a = fn x =&gt; x\r
36965val t = count1 ()\r
36966val countId: 'a -&gt; 'a = fn z =&gt; #2 (count2 (t, id)) z\r
36967val numCalls = #1 (count2 (t, id))</programlisting>\r
36968<simpara>Of course, one can hide the constructor <literal>T</literal> inside a <literal>local</literal> or behind\r
36969a signature.</simpara>\r
36970</section>\r
36971<section id="_also_see_50">\r
36972<title>Also see</title>\r
36973<itemizedlist>\r
36974<listitem>\r
36975<simpara>\r
36976<link linkend="ImperativeTypeVariable">ImperativeTypeVariable</link>\r
36977</simpara>\r
36978</listitem>\r
36979</itemizedlist>\r
36980<simpara><?asciidoc-pagebreak?></simpara>\r
36981</section>\r
36982</section>\r
36983<section id="VariableArityPolymorphism">\r
36984<title>VariableArityPolymorphism</title>\r
36985<simpara><link linkend="StandardML">Standard ML</link> programmers often face the problem of how to\r
36986provide a variable-arity polymorphic function. For example, suppose\r
36987one is defining a combinator library, e.g. for parsing or pickling.\r
36988The signature for such a library might look something like the\r
36989following.</simpara>\r
36990<programlisting language="sml" linenumbering="unnumbered">signature COMBINATOR =\r
36991 sig\r
36992 type 'a t\r
36993\r
36994 val int: int t\r
36995 val real: real t\r
36996 val string: string t\r
36997 val unit: unit t\r
36998 val tuple2: 'a1 t * 'a2 t -&gt; ('a1 * 'a2) t\r
36999 val tuple3: 'a1 t * 'a2 t * 'a3 t -&gt; ('a1 * 'a2 * 'a3) t\r
37000 val tuple4: 'a1 t * 'a2 t * 'a3 t * 'a4 t\r
37001 -&gt; ('a1 * 'a2 * 'a3 * 'a4) t\r
37002 ...\r
37003 end</programlisting>\r
37004<simpara>The question is how to define a variable-arity tuple combinator.\r
37005Traditionally, the only way to take a variable number of arguments in\r
37006SML is to put the arguments in a list (or vector) and pass that. So,\r
37007one might define a tuple combinator with the following signature.</simpara>\r
37008<programlisting language="sml" linenumbering="unnumbered">val tupleN: 'a list -&gt; 'a list t</programlisting>\r
37009<simpara>The problem with this approach is that as soon as one places values in\r
37010a list, they must all have the same type. So, programmers often take\r
37011an alternative approach, and define a family of <literal>tuple&lt;N&gt;</literal> functions,\r
37012as we see in the <literal>COMBINATOR</literal> signature above.</simpara>\r
37013<simpara>The family-of-functions approach is ugly for many reasons. First, it\r
37014clutters the signature with a number of functions when there should\r
37015really only be one. Second, it is <emphasis>closed</emphasis>, in that there are a fixed\r
37016number of tuple combinators in the interface, and should a client need\r
37017a combinator for a large tuple, he is out of luck. Third, this\r
37018approach often requires a lot of duplicate code in the implementation\r
37019of the combinators.</simpara>\r
37020<simpara>Fortunately, using <link linkend="Fold01N">Fold01N</link> and <link linkend="ProductType">products</link>, one can\r
37021provide an interface and implementation that solves all these\r
37022problems. Here is a simple pickling module that converts values to\r
37023strings.</simpara>\r
37024<programlisting language="sml" linenumbering="unnumbered">structure Pickler =\r
37025 struct\r
37026 type 'a t = 'a -&gt; string\r
37027\r
37028 val unit = fn () =&gt; ""\r
37029\r
37030 val int = Int.toString\r
37031\r
37032 val real = Real.toString\r
37033\r
37034 val string = id\r
37035\r
37036 type 'a accum = 'a * string list -&gt; string list\r
37037\r
37038 val tuple =\r
37039 fn z =&gt;\r
37040 Fold01N.fold\r
37041 {finish = fn ps =&gt; fn x =&gt; concat (rev (ps (x, []))),\r
37042 start = fn p =&gt; fn (x, l) =&gt; p x :: l,\r
37043 zero = unit}\r
37044 z\r
37045\r
37046 val ` =\r
37047 fn z =&gt;\r
37048 Fold01N.step1\r
37049 {combine = (fn (p, p') =&gt; fn (x &amp; x', l) =&gt; p' x' :: "," :: p (x, l))}\r
37050 z\r
37051 end</programlisting>\r
37052<simpara>If one has <literal>n</literal> picklers of types</simpara>\r
37053<programlisting language="sml" linenumbering="unnumbered">val p1: a1 Pickler.t\r
37054val p2: a2 Pickler.t\r
37055...\r
37056val pn: an Pickler.t</programlisting>\r
37057<simpara>then one can construct a pickler for n-ary products as follows.</simpara>\r
37058<programlisting language="sml" linenumbering="unnumbered">tuple `p1 `p2 ... `pn $ : (a1 &amp; a2 &amp; ... &amp; an) Pickler.t</programlisting>\r
37059<simpara>For example, with <literal>Pickler</literal> in scope, one can prove the following\r
37060equations.</simpara>\r
37061<programlisting language="sml" linenumbering="unnumbered">"" = tuple $ ()\r
37062"1" = tuple `int $ 1\r
37063"1,2.0" = tuple `int `real $ (1 &amp; 2.0)\r
37064"1,2.0,three" = tuple `int `real `string $ (1 &amp; 2.0 &amp; "three")</programlisting>\r
37065<simpara>Here is the signature for <literal>Pickler</literal>. It shows why the <literal>accum</literal> type is\r
37066useful.</simpara>\r
37067<programlisting language="sml" linenumbering="unnumbered">signature PICKLER =\r
37068 sig\r
37069 type 'a t\r
37070\r
37071 val int: int t\r
37072 val real: real t\r
37073 val string: string t\r
37074 val unit: unit t\r
37075\r
37076 type 'a accum\r
37077 val ` : ('a accum, 'b t, ('a, 'b) prod accum,\r
37078 'z1, 'z2, 'z3, 'z4, 'z5, 'z6, 'z7) Fold01N.step1\r
37079 val tuple: ('a t, 'a accum, 'b accum, 'b t, unit t,\r
37080 'z1, 'z2, 'z3, 'z4, 'z5) Fold01N.t\r
37081 end\r
37082\r
37083structure Pickler: PICKLER = Pickler</programlisting>\r
37084<simpara><?asciidoc-pagebreak?></simpara>\r
37085</section>\r
37086<section id="Variant">\r
37087<title>Variant</title>\r
37088<simpara>A <emphasis>variant</emphasis> is an arm of a datatype declaration. For example, the\r
37089datatype</simpara>\r
37090<programlisting language="sml" linenumbering="unnumbered">datatype t = A | B of int | C of real</programlisting>\r
37091<simpara>has three variants: <literal>A</literal>, <literal>B</literal>, and <literal>C</literal>.</simpara>\r
37092<simpara><?asciidoc-pagebreak?></simpara>\r
37093</section>\r
37094<section id="VesaKarvonen">\r
37095<title>VesaKarvonen</title>\r
37096<simpara>Vesa Karvonen is a student at the <ulink url="http://www.cs.helsinki.fi/index.en.html">University of Helsinki</ulink>.\r
37097His interests lie in programming techniques that allow complex programs to be expressed\r
37098clearly and concisely and the design and implementation of programming languages.</simpara>\r
37099<informalfigure>\r
37100<mediaobject>\r
37101 <imageobject>\r
37102 <imagedata fileref="VesaKarvonen.attachments/vesa-in-mlton-t-shirt.jpg" align="center"/>\r
37103 </imageobject>\r
37104 <textobject><phrase>VesaKarvonen.attachments/vesa-in-mlton-t-shirt.jpg</phrase></textobject>\r
37105</mediaobject>\r
37106</informalfigure>\r
37107<simpara>Things he&#8217;d like to see for SML and hopes to be able to contribute towards:</simpara>\r
37108<itemizedlist>\r
37109<listitem>\r
37110<simpara>\r
37111A practical tool for documenting libraries. Preferably one that is\r
37112based on extracting the documentation from source code comments.\r
37113</simpara>\r
37114</listitem>\r
37115<listitem>\r
37116<simpara>\r
37117A good IDE. Possibly an enhanced SML mode (<literal>esml-mode</literal>) for Emacs.\r
37118Google for <ulink url="http://www.google.com/search?&amp;q=SLIME+video">SLIME video</ulink> to\r
37119get an idea of what he&#8217;d like to see. Some specific notes:\r
37120</simpara>\r
37121<itemizedlist>\r
37122<listitem>\r
37123<simpara>\r
37124show type at point\r
37125</simpara>\r
37126</listitem>\r
37127<listitem>\r
37128<simpara>\r
37129robust, consistent indentation\r
37130</simpara>\r
37131</listitem>\r
37132<listitem>\r
37133<simpara>\r
37134show documentation\r
37135</simpara>\r
37136</listitem>\r
37137<listitem>\r
37138<simpara>\r
37139jump to definition (see <link linkend="EmacsDefUseMode">EmacsDefUseMode</link>)\r
37140</simpara>\r
37141</listitem>\r
37142</itemizedlist>\r
37143<simpara><link linkend="EmacsBgBuildMode">EmacsBgBuildMode</link> has also been written for working with MLton.</simpara>\r
37144</listitem>\r
37145<listitem>\r
37146<simpara>\r
37147Documented and cataloged libraries. Perhaps something like\r
37148<ulink url="http://www.boost.org">Boost</ulink>, but for SML libraries. Here is a partial\r
37149list of libraries, tools, and frameworks Vesa is or has been working\r
37150on:\r
37151</simpara>\r
37152<itemizedlist>\r
37153<listitem>\r
37154<simpara>\r
37155Asynchronous Programming Library (<ulink url="https://github.com/MLton/mltonlib/blob/master/com/ssh/async/unstable/README"><literal>README</literal></ulink>)\r
37156</simpara>\r
37157</listitem>\r
37158<listitem>\r
37159<simpara>\r
37160Extended Basis Library (<ulink url="https://github.com/MLton/mltonlib/blob/master/com/ssh/extended-basis/unstable/README"><literal>README</literal></ulink>)\r
37161</simpara>\r
37162</listitem>\r
37163<listitem>\r
37164<simpara>\r
37165Generic Programming Library (<ulink url="https://github.com/MLton/mltonlib/blob/master/com/ssh/generic/unstable/README"><literal>README</literal></ulink>)\r
37166</simpara>\r
37167</listitem>\r
37168<listitem>\r
37169<simpara>\r
37170Pretty Printing Library (<ulink url="https://github.com/MLton/mltonlib/blob/master/com/ssh/prettier/unstable/README"><literal>README</literal></ulink>)\r
37171</simpara>\r
37172</listitem>\r
37173<listitem>\r
37174<simpara>\r
37175Random Generator Library (<ulink url="https://github.com/MLton/mltonlib/blob/master/com/ssh/random/unstable/README"><literal>README</literal></ulink>)\r
37176</simpara>\r
37177</listitem>\r
37178<listitem>\r
37179<simpara>\r
37180RPC (Remote Procedure Call) Library (<ulink url="https://github.com/MLton/mltonlib/blob/master/org/mlton/vesak/rpc-lib/unstable/README"><literal>README</literal></ulink>)\r
37181</simpara>\r
37182</listitem>\r
37183<listitem>\r
37184<simpara>\r
37185<ulink url="http://www.libsdl.org/">SDL</ulink> Binding (<ulink url="https://github.com/MLton/mltonlib/blob/master/org/mlton/vesak/sdl/unstable/README"><literal>README</literal></ulink>)\r
37186</simpara>\r
37187</listitem>\r
37188<listitem>\r
37189<simpara>\r
37190Unit Testing Library (<ulink url="https://github.com/MLton/mltonlib/blob/master/com/ssh/unit-test/unstable/README"><literal>README</literal></ulink>)\r
37191</simpara>\r
37192</listitem>\r
37193<listitem>\r
37194<simpara>\r
37195Use Library (<ulink url="https://github.com/MLton/mltonlib/blob/master/org/mlton/vesak/use-lib/unstable/README"><literal>README</literal></ulink>)\r
37196</simpara>\r
37197</listitem>\r
37198<listitem>\r
37199<simpara>\r
37200Windows Library (<ulink url="https://github.com/MLton/mltonlib/blob/master/com/ssh/windows/unstable/README"><literal>README</literal></ulink>)\r
37201</simpara>\r
37202</listitem>\r
37203</itemizedlist>\r
37204</listitem>\r
37205</itemizedlist>\r
37206<simpara>Note that most of these libraries have been ported to several <link linkend="StandardMLImplementations">SML implementations</link>.</simpara>\r
37207<simpara><?asciidoc-pagebreak?></simpara>\r
37208</section>\r
37209<section id="WarnUnusedAnomalies">\r
37210<title>WarnUnusedAnomalies</title>\r
37211<simpara>The <literal>warnUnused</literal> <link linkend="MLBasisAnnotations">MLBasis annotation</link> can be used\r
37212to report unused identifiers. This can be useful for catching bugs\r
37213and for code maintenance (e.g., eliminating dead code). However, the\r
37214<literal>warnUnused</literal> annotation can sometimes behave in counter-intuitive\r
37215ways. This page gives some of the anomalies that have been reported.</simpara>\r
37216<itemizedlist>\r
37217<listitem>\r
37218<simpara>\r
37219Functions whose only uses are recursive uses within their bodies are\r
37220not warned as unused:\r
37221</simpara>\r
37222<programlisting language="sml" linenumbering="unnumbered">local\r
37223fun foo () = foo () : unit\r
37224val bar = let fun baz () = baz () : unit in baz end\r
37225in\r
37226end</programlisting>\r
37227<screen>Warning: z.sml 3.5.\r
37228 Unused variable: bar.</screen>\r
37229</listitem>\r
37230<listitem>\r
37231<simpara>\r
37232Components of actual functor argument that are necessary to match\r
37233the functor argument signature but are unused in the body of the\r
37234functor are warned as unused:\r
37235</simpara>\r
37236<programlisting language="sml" linenumbering="unnumbered">functor Warning (type t val x : t) = struct\r
37237 val y = x\r
37238end\r
37239structure X = Warning (type t = int val x = 1)</programlisting>\r
37240<screen>Warning: z.sml 4.29.\r
37241 Unused type: t.</screen>\r
37242</listitem>\r
37243<listitem>\r
37244<simpara>\r
37245No component of a functor result is warned as unused. In the\r
37246following, the only uses of <literal>f2</literal> are to match the functor argument\r
37247signatures of <literal>functor G</literal> and <literal>functor H</literal> and there are no uses of\r
37248<literal>z</literal>:\r
37249</simpara>\r
37250<programlisting language="sml" linenumbering="unnumbered">functor F(structure X : sig type t end) = struct\r
37251 type t = X.t\r
37252 fun f1 (_ : X.t) = ()\r
37253 fun f2 (_ : X.t) = ()\r
37254 val z = ()\r
37255end\r
37256functor G(structure Y : sig\r
37257 type t\r
37258 val f1 : t -&gt; unit\r
37259 val f2 : t -&gt; unit\r
37260 val z : unit\r
37261 end) = struct\r
37262 fun g (x : Y.t) = Y.f1 x\r
37263end\r
37264functor H(structure Y : sig\r
37265 type t\r
37266 val f1 : t -&gt; unit\r
37267 val f2 : t -&gt; unit\r
37268 val z : unit\r
37269 end) = struct\r
37270 fun h (x : Y.t) = Y.f1 x\r
37271end\r
37272functor Z() = struct\r
37273 structure S = F(structure X = struct type t = unit end)\r
37274 structure SG = G(structure Y = S)\r
37275 structure SH = H(structure Y = S)\r
37276end\r
37277structure U = Z()\r
37278val _ = U.SG.g ()\r
37279val _ = U.SH.h ()</programlisting>\r
37280<screen></screen>\r
37281</listitem>\r
37282</itemizedlist>\r
37283<simpara><?asciidoc-pagebreak?></simpara>\r
37284</section>\r
37285<section id="WesleyTerpstra">\r
37286<title>WesleyTerpstra</title>\r
37287<simpara>Wesley W. Terpstra is a PhD student at the Technische Universitat Darmstadt (Germany).</simpara>\r
37288<simpara>Research interests</simpara>\r
37289<itemizedlist>\r
37290<listitem>\r
37291<simpara>\r
37292Distributed systems (P2P)\r
37293</simpara>\r
37294</listitem>\r
37295<listitem>\r
37296<simpara>\r
37297Number theory (Error-correcting codes)\r
37298</simpara>\r
37299</listitem>\r
37300</itemizedlist>\r
37301<simpara>My interest in SML is centered on the fact the the language is able to directly express ideas from number theory which are important for my work. Modules and Functors seem to be a very natural basis for implementing many algebraic structures. MLton provides an ideal platform for actual implementation as it is fast and has unboxed words.</simpara>\r
37302<simpara>Things I would like from MLton in the future:</simpara>\r
37303<itemizedlist>\r
37304<listitem>\r
37305<simpara>\r
37306Some better optimization of mathematical expressions\r
37307</simpara>\r
37308</listitem>\r
37309<listitem>\r
37310<simpara>\r
37311IPv6 and multicast support\r
37312</simpara>\r
37313</listitem>\r
37314<listitem>\r
37315<simpara>\r
37316A complete GUI toolkit like mGTK\r
37317</simpara>\r
37318</listitem>\r
37319<listitem>\r
37320<simpara>\r
37321More supported platforms so that applications written under MLton have a wider audience\r
37322</simpara>\r
37323</listitem>\r
37324</itemizedlist>\r
37325<simpara><?asciidoc-pagebreak?></simpara>\r
37326</section>\r
37327<section id="WholeProgramOptimization">\r
37328<title>WholeProgramOptimization</title>\r
37329<simpara>Whole-program optimization is a compilation technique in which\r
37330optimizations operate over the entire program. This allows the\r
37331compiler many optimization opportunities that are not available when\r
37332analyzing modules separately (as with separate compilation).</simpara>\r
37333<simpara>Most of MLton&#8217;s optimizations are whole-program optimizations.\r
37334Because MLton compiles the whole program at once, it can perform\r
37335optimization across module boundaries. As a consequence, MLton often\r
37336reduces or eliminates the run-time penalty that arises with separate\r
37337compilation of SML features such as functors, modules, polymorphism,\r
37338and higher-order functions. MLton takes advantage of having the\r
37339entire program to perform transformations such as: defunctorization,\r
37340monomorphisation, higher-order control-flow analysis, inlining,\r
37341unboxing, argument flattening, redundant-argument removal, constant\r
37342folding, and representation selection. Whole-program compilation is\r
37343an integral part of the design of MLton and is not likely to change.</simpara>\r
37344<simpara><?asciidoc-pagebreak?></simpara>\r
37345</section>\r
37346<section id="WishList">\r
37347<title>WishList</title>\r
37348<simpara>This page is mainly for recording recurring feature requests. If you\r
37349have a new feature request, you probably want to query interest on one\r
37350of the <link linkend="Contact">mailing lists</link> first.</simpara>\r
37351<simpara>Please be aware of MLton&#8217;s policy on\r
37352<link linkend="LanguageChanges">language changes</link>. Nonetheless, we hope to provide\r
37353support for some of the "immediate" <link linkend="SuccessorML">SuccessorML</link> proposals in a\r
37354future release.</simpara>\r
37355<section id="_support_for_link_options_in_ml_basis_files">\r
37356<title>Support for link options in ML Basis files</title>\r
37357<simpara>Introduce a mechanism to specify link options in <link linkend="MLBasis">ML Basis</link>\r
37358files. For example, generalizing a bit, a ML Basis declaration of the\r
37359form</simpara>\r
37360<screen>option "option"</screen>\r
37361<simpara>could be introduced whose semantics would be the same (as closely as\r
37362possible) as if the option string were specified on the compiler\r
37363command line.</simpara>\r
37364<simpara>The main motivation for this is that a MLton library that would\r
37365introduce bindings (through <link linkend="ForeignFunctionInterface">FFI</link>) to an\r
37366external library could be packaged conveniently as a single MLB file.\r
37367For example, to link with library <literal>foo</literal> the MLB file would simply\r
37368contain:</simpara>\r
37369<screen>option "-link-opt -lfoo"</screen>\r
37370<simpara>Similar feature requests have been discussed previously on the mailing lists:</simpara>\r
37371<itemizedlist>\r
37372<listitem>\r
37373<simpara>\r
37374<ulink url="http://www.mlton.org/pipermail/mlton/2004-July/025553.html">http://www.mlton.org/pipermail/mlton/2004-July/025553.html</ulink>\r
37375</simpara>\r
37376</listitem>\r
37377<listitem>\r
37378<simpara>\r
37379<ulink url="http://www.mlton.org/pipermail/mlton/2005-January/026648.html">http://www.mlton.org/pipermail/mlton/2005-January/026648.html</ulink>\r
37380</simpara>\r
37381</listitem>\r
37382</itemizedlist>\r
37383<simpara><?asciidoc-pagebreak?></simpara>\r
37384</section>\r
37385</section>\r
37386<section id="XML">\r
37387<title>XML</title>\r
37388<simpara><link linkend="XML">XML</link> is an <link linkend="IntermediateLanguage">IntermediateLanguage</link>, translated from <link linkend="CoreML">CoreML</link> by\r
37389<link linkend="Defunctorize">Defunctorize</link>, optimized by <link linkend="XMLSimplify">XMLSimplify</link>, and translated by\r
37390<link linkend="Monomorphise">Monomorphise</link> to <link linkend="SXML">SXML</link>.</simpara>\r
37391<section id="_description_65">\r
37392<title>Description</title>\r
37393<simpara><link linkend="XML">XML</link> is polymorphic, higher-order, with flat patterns. Every\r
37394<link linkend="XML">XML</link> expression is annotated with its type. Polymorphic\r
37395generalization is made explicit through type variables annotating\r
37396<literal>val</literal> and <literal>fun</literal> declarations. Polymorphic instantiation is made\r
37397explicit by specifying type arguments at variable references. <link linkend="XML">XML</link>\r
37398patterns can not be nested and can not contain wildcards, constraints,\r
37399flexible records, or layering.</simpara>\r
37400</section>\r
37401<section id="_implementation_71">\r
37402<title>Implementation</title>\r
37403<itemizedlist>\r
37404<listitem>\r
37405<simpara>\r
37406<ulink url="https://github.com/MLton/mlton/blob/master/mlton/xml/xml.sig"><literal>xml.sig</literal></ulink>\r
37407</simpara>\r
37408</listitem>\r
37409<listitem>\r
37410<simpara>\r
37411<ulink url="https://github.com/MLton/mlton/blob/master/mlton/xml/xml.fun"><literal>xml.fun</literal></ulink>\r
37412</simpara>\r
37413</listitem>\r
37414<listitem>\r
37415<simpara>\r
37416<ulink url="https://github.com/MLton/mlton/blob/master/mlton/xml/xml-tree.sig"><literal>xml-tree.sig</literal></ulink>\r
37417</simpara>\r
37418</listitem>\r
37419<listitem>\r
37420<simpara>\r
37421<ulink url="https://github.com/MLton/mlton/blob/master/mlton/xml/xml-tree.fun"><literal>xml-tree.fun</literal></ulink>\r
37422</simpara>\r
37423</listitem>\r
37424</itemizedlist>\r
37425</section>\r
37426<section id="_type_checking_8">\r
37427<title>Type Checking</title>\r
37428<simpara><link linkend="XML">XML</link> also has a type checker, used for debugging. At present, the\r
37429type checker is also the best specification of the type system of\r
37430<link linkend="XML">XML</link>. If you need more details, the type checker\r
37431(<ulink url="https://github.com/MLton/mlton/blob/master/mlton/xml/type-check.sig"><literal>type-check.sig</literal></ulink>,\r
37432<ulink url="https://github.com/MLton/mlton/blob/master/mlton/xml/type-check.fun"><literal>type-check.fun</literal></ulink>), is pretty short.</simpara>\r
37433<simpara>Since the type checker does not affect the output of the compiler\r
37434(unless it reports an error), it can be turned off. The type checker\r
37435recursively descends the program, checking that the type annotating\r
37436each node is the same as the type synthesized from the types of the\r
37437expressions subnodes.</simpara>\r
37438</section>\r
37439<section id="_details_and_notes_68">\r
37440<title>Details and Notes</title>\r
37441<simpara><link linkend="XML">XML</link> uses the same atoms as <link linkend="CoreML">CoreML</link>, hence all identifiers\r
37442(constructors, variables, etc.) are unique and can have properties\r
37443attached to them. Finally, <link linkend="XML">XML</link> has a simplifier (<link linkend="XMLShrink">XMLShrink</link>),\r
37444which implements a reduction system.</simpara>\r
37445<section id="_types_3">\r
37446<title>Types</title>\r
37447<simpara><link linkend="XML">XML</link> types are either type variables or applications of n-ary type\r
37448constructors. There are many utility functions for constructing and\r
37449destructing types involving built-in type constructors.</simpara>\r
37450<simpara>A type scheme binds list of type variables in a type. The only\r
37451interesting operation on type schemes is the application of a type\r
37452scheme to a list of types, which performs a simultaneous substitution\r
37453of the type arguments for the bound type variables of the scheme. For\r
37454the purposes of type checking, it is necessary to know the type scheme\r
37455of variables, constructors, and primitives. This is done by\r
37456associating the scheme with the identifier using its property list.\r
37457This approach is used instead of the more traditional environment\r
37458approach for reasons of speed.</simpara>\r
37459</section>\r
37460<section id="_xmltree">\r
37461<title>XmlTree</title>\r
37462<simpara>Before defining <literal>XML</literal>, the signature for language <link linkend="XML">XML</link>, we need to\r
37463define an auxiliary signature <literal>XML_TREE</literal>, that contains the datatype\r
37464declarations for the expression trees of <link linkend="XML">XML</link>. This is done solely\r
37465for the purpose of modularity&#8201;&#8212;&#8201;it allows the simplifier and type\r
37466checker to be defined by separate functors (which take a structure\r
37467matching <literal>XML_TREE</literal>). Then, <literal>Xml</literal> is defined as the signature for a\r
37468module containing the expression trees, the simplifier, and the type\r
37469checker.</simpara>\r
37470<simpara>Both constructors and variables can have type schemes, hence both\r
37471constructor and variable references specify the instance of the scheme\r
37472at the point of references. An instance is specified with a vector of\r
37473types, which corresponds to the type variables in the scheme.</simpara>\r
37474<simpara><link linkend="XML">XML</link> patterns are flat (i.e. not nested). A pattern is a\r
37475constructor with an optional argument variable. Patterns only occur\r
37476in <literal>case</literal> expressions. To evaluate a case expression, compare the\r
37477test value sequentially against each pattern. For the first pattern\r
37478that matches, destruct the value if necessary to bind the pattern\r
37479variables and evaluate the corresponding expression. If no pattern\r
37480matches, evaluate the default. All patterns of a case statement are\r
37481of the same variant of <literal>Pat.t</literal>, although this is not enforced by ML&#8217;s\r
37482type system. The type checker, however, does enforce this. Because\r
37483tuple patterns are irrefutable, there will only ever be one tuple\r
37484pattern in a case expression and there will be no default.</simpara>\r
37485<simpara><link linkend="XML">XML</link> contains value, exception, and mutually recursive function\r
37486declarations. There are no free type variables in <link linkend="XML">XML</link>. All type\r
37487variables are explicitly bound at either a value or function\r
37488declaration. At some point in the future, exception declarations may\r
37489go away, and exceptions may be represented with a single datatype\r
37490containing a <literal>unit ref</literal> component to implement genericity.</simpara>\r
37491<simpara><link linkend="XML">XML</link> expressions are like those of <link linkend="CoreML">CoreML</link>, with the following\r
37492exceptions. There are no records expressions. After type inference,\r
37493all records (some of which may have originally been tuples in the\r
37494source) are converted to tuples, because once flexible record patterns\r
37495have been resolved, tuple labels are superfluous. Tuple components\r
37496are ordered based on the field ordering relation. <link linkend="XML">XML</link> eta expands\r
37497primitives and constructors so that there are always fully applied.\r
37498Hence, the only kind of value of arrow type is a lambda. This\r
37499property is useful for flow analysis and later in code generation.</simpara>\r
37500<simpara>An <link linkend="XML">XML</link> program is a list of toplevel datatype declarations and a\r
37501body expression. Because datatype declarations are not generative,\r
37502the defunctorizer can safely move them to toplevel.</simpara>\r
37503<simpara><?asciidoc-pagebreak?></simpara>\r
37504</section>\r
37505</section>\r
37506</section>\r
37507<section id="XMLShrink">\r
37508<title>XMLShrink</title>\r
37509<simpara>XMLShrink is an optimization pass for the <link linkend="XML">XML</link>\r
37510<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="XMLSimplify">XMLSimplify</link>.</simpara>\r
37511<section id="_description_66">\r
37512<title>Description</title>\r
37513<simpara>This pass performs optimizations based on a reduction system.</simpara>\r
37514</section>\r
37515<section id="_implementation_72">\r
37516<title>Implementation</title>\r
37517<itemizedlist>\r
37518<listitem>\r
37519<simpara>\r
37520<ulink url="https://github.com/MLton/mlton/blob/master/mlton/xml/shrink.sig"><literal>shrink.sig</literal></ulink>\r
37521</simpara>\r
37522</listitem>\r
37523<listitem>\r
37524<simpara>\r
37525<ulink url="https://github.com/MLton/mlton/blob/master/mlton/xml/shrink.fun"><literal>shrink.fun</literal></ulink>\r
37526</simpara>\r
37527</listitem>\r
37528</itemizedlist>\r
37529</section>\r
37530<section id="_details_and_notes_69">\r
37531<title>Details and Notes</title>\r
37532<simpara>The simplifier is based on <link linkend="References_AppelJim97">Shrinking Lambda Expressions in Linear Time</link>.</simpara>\r
37533<simpara>The source program may contain functions that are only called once, or\r
37534not even called at all. Match compilation introduces many such\r
37535functions. In order to reduce the program size, speed up later\r
37536phases, and improve the flow analysis, a source to source simplifier\r
37537is run on <link linkend="XML">XML</link> after type inference and match compilation.</simpara>\r
37538<simpara>The simplifier implements the reductions shown below. The reductions\r
37539eliminate unnecessary declarations (see the side constraint in the\r
37540figure), applications where the function is immediate, and case\r
37541statements where the test is immediate. Declarations can be\r
37542eliminated only when the expression is nonexpansive (see Section 4.7\r
37543of the <link linkend="DefinitionOfStandardML">Definition</link>), which is a syntactic\r
37544condition that ensures that the expression has no effects\r
37545(assignments, raises, or nontermination). The reductions on case\r
37546statements do not show the other irrelevant cases that may exist. The\r
37547reductions were chosen so that they were strongly normalizing and so\r
37548that they never increased tree size.</simpara>\r
37549<itemizedlist>\r
37550<listitem>\r
37551<simpara>\r
37552</simpara>\r
37553<programlisting language="sml" linenumbering="unnumbered">let x = e1 in e2</programlisting>\r
37554<simpara>reduces to</simpara>\r
37555<programlisting language="sml" linenumbering="unnumbered">e2 [x -&gt; e1]</programlisting>\r
37556<simpara>if <literal>e1</literal> is a constant or variable or if <literal>e1</literal> is nonexpansive and <literal>x</literal> occurs zero or one time in <literal>e2</literal></simpara>\r
37557</listitem>\r
37558<listitem>\r
37559<simpara>\r
37560</simpara>\r
37561<programlisting language="sml" linenumbering="unnumbered">(fn x =&gt; e1) e2</programlisting>\r
37562<simpara>reduces to</simpara>\r
37563<programlisting language="sml" linenumbering="unnumbered">let x = e2 in e1</programlisting>\r
37564</listitem>\r
37565<listitem>\r
37566<simpara>\r
37567</simpara>\r
37568<programlisting language="sml" linenumbering="unnumbered">e1 handle e2</programlisting>\r
37569<simpara>reduces to</simpara>\r
37570<programlisting language="sml" linenumbering="unnumbered">e1</programlisting>\r
37571<simpara>if <literal>e1</literal> is nonexpansive</simpara>\r
37572</listitem>\r
37573<listitem>\r
37574<simpara>\r
37575</simpara>\r
37576<programlisting language="sml" linenumbering="unnumbered">case let d in e end of p1 =&gt; e1 ...</programlisting>\r
37577<simpara>reduces to</simpara>\r
37578<programlisting language="sml" linenumbering="unnumbered">let d in case e of p1 =&gt; e1 ... end</programlisting>\r
37579</listitem>\r
37580<listitem>\r
37581<simpara>\r
37582</simpara>\r
37583<programlisting language="sml" linenumbering="unnumbered">case C e1 of C x =&gt; e2</programlisting>\r
37584<simpara>reduces to</simpara>\r
37585<programlisting language="sml" linenumbering="unnumbered">let x = e1 in e2</programlisting>\r
37586</listitem>\r
37587</itemizedlist>\r
37588<simpara><?asciidoc-pagebreak?></simpara>\r
37589</section>\r
37590</section>\r
37591<section id="XMLSimplify">\r
37592<title>XMLSimplify</title>\r
37593<simpara>The optimization passes for the <link linkend="XML">XML</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link> are\r
37594collected and controlled by the <literal>XmlSimplify</literal> functor\r
37595(<ulink url="https://github.com/MLton/mlton/blob/master/mlton/xml/xml-simplify.sig"><literal>xml-simplify.sig</literal></ulink>,\r
37596<ulink url="https://github.com/MLton/mlton/blob/master/mlton/xml/xml-simplify.fun"><literal>xml-simplify.fun</literal></ulink>).</simpara>\r
37597<simpara>The following optimization passes are implemented:</simpara>\r
37598<itemizedlist>\r
37599<listitem>\r
37600<simpara>\r
37601<link linkend="XMLSimplifyTypes">XMLSimplifyTypes</link>\r
37602</simpara>\r
37603</listitem>\r
37604<listitem>\r
37605<simpara>\r
37606<link linkend="XMLShrink">XMLShrink</link>\r
37607</simpara>\r
37608</listitem>\r
37609</itemizedlist>\r
37610<simpara>The optimization passes can be controlled from the command-line by the options</simpara>\r
37611<itemizedlist>\r
37612<listitem>\r
37613<simpara>\r
37614<literal>-diag-pass &lt;pass&gt;</literal>&#8201;&#8212;&#8201;keep diagnostic info for pass\r
37615</simpara>\r
37616</listitem>\r
37617<listitem>\r
37618<simpara>\r
37619<literal>-disable-pass &lt;pass&gt;</literal>&#8201;&#8212;&#8201;skip optimization pass (if normally performed)\r
37620</simpara>\r
37621</listitem>\r
37622<listitem>\r
37623<simpara>\r
37624<literal>-enable-pass &lt;pass&gt;</literal>&#8201;&#8212;&#8201;perform optimization pass (if normally skipped)\r
37625</simpara>\r
37626</listitem>\r
37627<listitem>\r
37628<simpara>\r
37629<literal>-keep-pass &lt;pass&gt;</literal>&#8201;&#8212;&#8201;keep the results of pass\r
37630</simpara>\r
37631</listitem>\r
37632<listitem>\r
37633<simpara>\r
37634<literal>-xml-passes &lt;passes&gt;</literal>&#8201;&#8212;&#8201;xml optimization passes\r
37635</simpara>\r
37636</listitem>\r
37637</itemizedlist>\r
37638<simpara><?asciidoc-pagebreak?></simpara>\r
37639</section>\r
37640<section id="XMLSimplifyTypes">\r
37641<title>XMLSimplifyTypes</title>\r
37642<simpara><link linkend="XMLSimplifyTypes">XMLSimplifyTypes</link> is an optimization pass for the <link linkend="XML">XML</link>\r
37643<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="XMLSimplify">XMLSimplify</link>.</simpara>\r
37644<section id="_description_67">\r
37645<title>Description</title>\r
37646<simpara>This pass simplifies types in an <link linkend="XML">XML</link> program, eliminating all\r
37647unused type arguments.</simpara>\r
37648</section>\r
37649<section id="_implementation_73">\r
37650<title>Implementation</title>\r
37651<itemizedlist>\r
37652<listitem>\r
37653<simpara>\r
37654<ulink url="https://github.com/MLton/mlton/blob/master/mlton/xml/simplify-types.sig"><literal>simplify-types.sig</literal></ulink>\r
37655</simpara>\r
37656</listitem>\r
37657<listitem>\r
37658<simpara>\r
37659<ulink url="https://github.com/MLton/mlton/blob/master/mlton/xml/simplify-types.fun"><literal>simplify-types.fun</literal></ulink>\r
37660</simpara>\r
37661</listitem>\r
37662</itemizedlist>\r
37663</section>\r
37664<section id="_details_and_notes_70">\r
37665<title>Details and Notes</title>\r
37666<simpara>It first computes a simple fixpoint on all the <literal>datatype</literal> declarations\r
37667to determine which <literal>datatype</literal> <literal>tycon</literal> args are actually used. Then it\r
37668does a single pass over the program to determine which polymorphic\r
37669declaration type variables are used, and rewrites types to eliminate\r
37670unused type arguments.</simpara>\r
37671<simpara>This pass should eliminate any spurious duplication that the\r
37672<link linkend="Monomorphise">Monomorphise</link> pass might perform due to phantom types.</simpara>\r
37673<simpara><?asciidoc-pagebreak?></simpara>\r
37674</section>\r
37675</section>\r
37676<section id="Zone">\r
37677<title>Zone</title>\r
37678<simpara><link linkend="Zone">Zone</link> is an optimization pass for the <link linkend="SSA2">SSA2</link>\r
37679<link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="SSA2Simplify">SSA2Simplify</link>.</simpara>\r
37680<section id="_description_68">\r
37681<title>Description</title>\r
37682<simpara>This pass breaks large <link linkend="SSA2">SSA2</link> functions into zones, which are\r
37683connected subgraphs of the dominator tree. For each zone, at the node\r
37684that dominates the zone (the "zone root"), it places a tuple\r
37685collecting all of the live variables at that node. It replaces any\r
37686variables used in that zone with offsets from the tuple. The goal is\r
37687to decrease the liveness information in large <link linkend="SSA">SSA</link> functions.</simpara>\r
37688</section>\r
37689<section id="_implementation_74">\r
37690<title>Implementation</title>\r
37691<itemizedlist>\r
37692<listitem>\r
37693<simpara>\r
37694<ulink url="https://github.com/MLton/mlton/blob/master/mlton/ssa/zone.fun"><literal>zone.fun</literal></ulink>\r
37695</simpara>\r
37696</listitem>\r
37697</itemizedlist>\r
37698</section>\r
37699<section id="_details_and_notes_71">\r
37700<title>Details and Notes</title>\r
37701<simpara>Compute strongly-connected components to avoid put tuple constructions\r
37702in loops.</simpara>\r
37703<simpara>There are two (expert) flags that govern the use of this pass</simpara>\r
37704<itemizedlist>\r
37705<listitem>\r
37706<simpara>\r
37707<literal>-max-function-size &lt;n&gt;</literal>\r
37708</simpara>\r
37709</listitem>\r
37710<listitem>\r
37711<simpara>\r
37712<literal>-zone-cut-depth &lt;n&gt;</literal>\r
37713</simpara>\r
37714</listitem>\r
37715</itemizedlist>\r
37716<simpara>Zone splitting only works when the number of basic blocks in a\r
37717function is greater than <literal>n</literal>. The <literal>n</literal> used to cut the dominator tree\r
37718is set by <literal>-zone-cut-depth</literal>.</simpara>\r
37719<simpara>There is currently no attempt to be safe-for-space. That is, the\r
37720tuples are not restricted to containing only "small" values.</simpara>\r
37721<simpara>In the <literal>HOL</literal> program, the particular problem is the main function,\r
37722which has 161,783 blocks and 257,519 variables&#8201;&#8212;&#8201;the product of those\r
37723two numbers being about 41 billion. Now, we&#8217;re not likely going to\r
37724need that much space since we use a sparse representation. But even\r
377251/100th would really hurt. And of course this rules out bit vectors.</simpara>\r
37726<simpara><?asciidoc-pagebreak?></simpara>\r
37727</section>\r
37728</section>\r
37729<section id="ZZZOrphanedPages">\r
37730<title>ZZZOrphanedPages</title>\r
37731<simpara>The contents of these pages have been moved to other pages.</simpara>\r
37732<simpara>These templates are used by other pages.</simpara>\r
37733<itemizedlist>\r
37734<listitem>\r
37735<simpara>\r
37736<link linkend="CompilerPassTemplate">CompilerPassTemplate</link>\r
37737</simpara>\r
37738</listitem>\r
37739<listitem>\r
37740<simpara>\r
37741<link linkend="TalkTemplate">TalkTemplate</link>\r
37742</simpara>\r
37743</listitem>\r
37744</itemizedlist>\r
37745<simpara><?asciidoc-pagebreak?></simpara>\r
37746</section>\r
37747</article>\r