Commit | Line | Data |
---|---|---|
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’s new?</title>\r | |
23 | <itemizedlist>\r | |
24 | <listitem>\r | |
25 | <simpara>\r | |
26 | 20180207: 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 | |
31 | 20140730: <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 #1405770</ulink>\r | |
38 | and\r | |
39 | <ulink url="http://www.nsf.gov/awardsearch/showAward?AWD_ID=1405614">Award #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 | |
50 | Read about MLton’s <link linkend="Features">Features</link>.\r | |
51 | </simpara>\r | |
52 | </listitem>\r | |
53 | <listitem>\r | |
54 | <simpara>\r | |
55 | Look at <link linkend="Documentation">Documentation</link>.\r | |
56 | </simpara>\r | |
57 | </listitem>\r | |
58 | <listitem>\r | |
59 | <simpara>\r | |
60 | See 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 | |
70 | Meet the MLton <link linkend="Developers">Developers</link>.\r | |
71 | </simpara>\r | |
72 | </listitem>\r | |
73 | <listitem>\r | |
74 | <simpara>\r | |
75 | Get involved with MLton <link linkend="Development">Development</link>.\r | |
76 | </simpara>\r | |
77 | </listitem>\r | |
78 | <listitem>\r | |
79 | <simpara>\r | |
80 | User-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 | |
97 | I 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 | |
102 | I 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 | |
111 | equality types, the result is an <link linkend="EqualityType">EqualityType</link>. This notion enables\r | |
112 | one to determine whether a type constructor application yields an\r | |
113 | equality type solely from the application, without looking at the\r | |
114 | definition 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 | |
117 | constructor 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 | |
124 | definition is an equality type after replacing <literal>'a1</literal>, …,\r | |
125 | <literal>'an</literal> by equality types (it doesn’t matter which equality types\r | |
126 | are chosen).</simpara>\r | |
127 | <simpara>For a nullary type definition, this amounts to the right-hand side\r | |
128 | being 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 | |
131 | an 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 | |
134 | is 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 | |
138 | is 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 | |
162 | did 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 | |
168 | equality, every <link linkend="Variant">variant</link> of the datatype must admit equality. For\r | |
169 | example, 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 | |
173 | datatype 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 | |
176 | consider each <link linkend="Variant">variant</link> as a type definition, and require that the\r | |
177 | definition 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 | |
181 | type '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 | |
186 | specification.</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 | |
199 | the problematic component of the constructor’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 | |
205 | admits 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 | |
207 | answers this question by requiring a type constructor to admit\r | |
208 | equality if it is consistent to do so. So, in our above example, if\r | |
209 | we 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 | |
211 | trivially admits equality, so does the type constructor <literal>t</literal>.\r | |
212 | Thus, it was consistent to assume that <literal>t</literal> admits equality, and\r | |
213 | so, <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 | |
217 | does not admit equality. Hence, the type constructor <literal>t</literal> does not\r | |
218 | admit equality, and our assumption was inconsistent. Hence, <literal>t</literal>\r | |
219 | does not admit equality.</simpara>\r | |
220 | <simpara>The same kind of reasoning applies to mutually recursive datatypes as\r | |
221 | well. For example, the following defines both <literal>t</literal> and <literal>u</literal> to\r | |
222 | admit equality.</simpara>\r | |
223 | <programlisting language="sml" linenumbering="unnumbered">datatype t = A | B of u\r | |
224 | and u = C | D of t</programlisting>\r | |
225 | <simpara>But the following defines neither <literal>t</literal> nor <literal>u</literal> to admit\r | |
226 | equality.</simpara>\r | |
227 | <programlisting language="sml" linenumbering="unnumbered">datatype t = A | B of u * real\r | |
228 | and 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 | |
243 | Error: 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 | |
256 | concurrency, dynamic typing, components, distribution, and constraint\r | |
257 | solving.</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 | |
267 | or 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’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 | |
299 | vector 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 | |
302 | generated code allocates a list and then converts it to an array. To\r | |
303 | alleviate 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 | |
305 | that is syntactically unwieldy.</simpara>\r | |
306 | <simpara>Fortunately, using <link linkend="Fold">Fold</link>, it is possible to define constants <literal>A</literal>,\r | |
307 | and <literal>`</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 | |
310 | Furthermore, MLton, at least, will generate the efficient code as if\r | |
311 | one 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>`</literal>, one can define a constant <literal>V</literal> that makes\r | |
314 | it 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>`</literal>, serves for both array\r | |
317 | and vector literals. Of course, the <literal>$</literal> is the end-of-arguments\r | |
318 | marker always used with <link linkend="Fold">Fold</link>. The only difference between an\r | |
319 | array 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>`</literal>. We place them\r | |
321 | in a structure and use signature abstraction to hide the type of the\r | |
322 | accumulator. See <link linkend="Fold">Fold</link> for more on this technique.</simpara>\r | |
323 | <programlisting language="sml" linenumbering="unnumbered">structure Literal:>\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 -> unit)\r | |
332 | \r | |
333 | val A =\r | |
334 | fn z =>\r | |
335 | Fold.fold\r | |
336 | ((0, NONE, ignore),\r | |
337 | fn (n, opt, fill) =>\r | |
338 | case opt of\r | |
339 | NONE =>\r | |
340 | Array.tabulate (0, fn _ => raise Fail "array0")\r | |
341 | | SOME x =>\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 => Fold.post (A, Array.vector) z\r | |
351 | \r | |
352 | val ` =\r | |
353 | fn z =>\r | |
354 | Fold.step1\r | |
355 | (fn (x, (i, opt, fill)) =>\r | |
356 | (i + 1,\r | |
357 | SOME x,\r | |
358 | fn a => (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 | |
362 | number of elements, a sample element, and a function that fills in all\r | |
363 | the elements. When the fold is complete, the finishing function\r | |
364 | allocates the array, applies the fill function, and returns the array.\r | |
365 | The only difference between <literal>A</literal> and <literal>V</literal> is at the very end; <literal>A</literal> just\r | |
366 | returns the array, while <literal>V</literal> converts it to a vector using\r | |
367 | post-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 | |
373 | and 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 | |
421 | checker. 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 | |
429 | abstract syntax tree with source location information. Every source\r | |
430 | program 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 -> node' * Region.t\r | |
437 | val makeRegion': node' * SourcePos.t * SourcePos.t -> obj\r | |
438 | val makeRegion: node' * Region.t -> obj\r | |
439 | val node: obj -> node'\r | |
440 | val region: obj -> 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 | |
443 | phrase and <literal>obj</literal> is the type of its annotated counterpart. In the\r | |
444 | implementation, 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 | |
447 | syntax phrase’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 | |
450 | particular file, line, and column. A typical use of the <literal>WRAPPED</literal>\r | |
451 | interface 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 | |
472 | of contrast, consider the approach taken by <link linkend="SMLNJ">SML/NJ</link> (and also\r | |
473 | by the <link linkend="CKitLibrary">CKit Library</link>). Each datatype denoting a syntax\r | |
474 | phrase dedicates a special constructor for annotating source\r | |
475 | locations:</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 | |
480 | sufficient to guarantee that the AST emitted from the front-end is\r | |
481 | properly 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 | |
489 | dealing with basic types, input/output, OS interfaces, and simple\r | |
490 | datatypes. It is intended as a portable library usable across all\r | |
491 | implementations of SML. For the official online version of the Basis\r | |
492 | Library 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 | |
494 | version that includes all of the online version and more. For a\r | |
495 | reverse 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 | |
498 | MLton also implements many of the optional structures. You can obtain\r | |
499 | a complete and current list of what’s available using\r | |
500 | <literal>mlton -show-basis</literal> (see <link linkend="ShowBasis">ShowBasis</link>). By default, MLton makes the\r | |
501 | Basis 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 -> unit</literal>, which conflicts with whole-program\r | |
542 | compilation 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><></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><</literal>,\r | |
591 | <literal><=</literal>,\r | |
592 | <literal>></literal>,\r | |
593 | <literal>>=</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>…</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 | |
807 | The Basis Library specification requires functions like\r | |
808 | <literal>Socket.sendVec</literal> to raise an exception if they fail. However, on some\r | |
809 | platforms, sending to a socket that hasn’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 | |
812 | exception to be raised, you can ignore <literal>SIGPIPE</literal> by adding the\r | |
813 | following to your program.\r | |
814 | </simpara>\r | |
815 | <programlisting language="sml" linenumbering="unnumbered">let\r | |
816 | open MLton.Signal\r | |
817 | in\r | |
818 | setHandler (Posix.Signal.pipe, Handler.ignore)\r | |
819 | end</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 | |
826 | The <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>…</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 | |
885 | MLton’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 | |
887 | Library 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 | |
896 | LargeInt = IntInf.int\r | |
897 | LargeReal.real = Real64.real\r | |
898 | LargeWord = 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 | |
901 | By default, the following types are equivalent:</simpara>\r | |
902 | <screen>int = Int.int = Int32.int\r | |
903 | real = Real.real = Real64.real\r | |
904 | word = 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 | |
909 | using the <literal>C</literal> math library, so the SML functions will reflect the\r | |
910 | behavior of the underlying library function. We have made some effort\r | |
911 | to unify the differences between the math libraries on different\r | |
912 | platforms, and in particular to handle exceptional cases according to\r | |
913 | the Basis Library specification. However, there will be differences\r | |
914 | due to different numerical algorithms and cases we may have missed.\r | |
915 | Please submit a <link linkend="Bug">bug report</link> if you encounter an error in\r | |
916 | the handling of an exceptional case.</simpara>\r | |
917 | <simpara>On x86, real arithmetic is implemented internally using 80 bits of\r | |
918 | precision. Using higher precision for intermediate results in\r | |
919 | computations can lead to different results than if all the computation\r | |
920 | is done at 32 or 64 bits. If you require strict IEEE compliance, you\r | |
921 | can compile with <literal>-ieee-fp true</literal>, which will cause intermediate\r | |
922 | results to be stored after each operation. This may cause a\r | |
923 | substantial 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 | |
931 | the complete SML program that caused the problem and a log of a\r | |
932 | compile of the program with <literal>-verbose 2</literal>. For large programs (over\r | |
933 | 256K), please send an email containing the discussion text and a link\r | |
934 | to any large files.</simpara>\r | |
935 | <simpara>There are some <link linkend="UnresolvedBugs">UnresolvedBugs</link> that we don’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 | |
969 | in 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’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&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 => true | _ => 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&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&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&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&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&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&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&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 | |
1086 | ignore x;\r | |
1087 | ignore 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’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&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&tr1=1.29&r2=text&tr2=1.30&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’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 | |
1166 | in 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 | |
1171 | Bug in the <ulink url="http://www.standardml.org/Basis/real.html#SIG:REAL.fmt:VAL"><literal>Real<emphasis><N></emphasis>.fmt</literal></ulink>, <ulink url="http://www.standardml.org/Basis/real.html#SIG:REAL.fromString:VAL"><literal>Real<emphasis><N></emphasis>.fromString</literal></ulink>, <ulink url="http://www.standardml.org/Basis/real.html#SIG:REAL.scan:VAL"><literal>Real<emphasis><N></emphasis>.scan</literal></ulink>, and <ulink url="http://www.standardml.org/Basis/real.html#SIG:REAL.toString:VAL"><literal>Real<emphasis><N></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><N></emphasis>.fmt StringCvt.EXACT</literal>, <literal>Real<emphasis><N></emphasis>.fromDecimal</literal>, and <literal>Real<emphasis><N></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 | |
1179 | Bug 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 | |
1187 | Bug 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 | |
1194 | The <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><OPT></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 | |
1202 | Bug 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 | |
1210 | Bug 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 | |
1218 | The <ulink url="http://www.standardml.org/Basis/pack-float.html#SIG:PACK_REAL.toBytes:VAL"><literal>PackReal<emphasis><N></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 | |
1226 | Bug 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 | |
1233 | The <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 | |
1240 | The 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 | |
1248 | Bug 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 | |
1256 | The native codegen’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 | |
1263 | The <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 | |
1277 | The 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 | |
1284 | A 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 | |
1294 | in 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 | |
1299 | Bug in the mark-compact garbage collector where the C library’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 | |
1306 | Bug 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 | |
1313 | Performance 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 | |
1321 | Performance 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 | |
1329 | Bug 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 | |
1337 | Bug 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 | |
1345 | Bug in <literal>IntInf.~>></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 | |
1352 | Bug 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 | |
1360 | Bug 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 | |
1367 | Bug 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 | |
1374 | Bug 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 | |
1382 | Bug 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 | |
1390 | Bug 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 | |
1398 | Space-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 | |
1406 | Bug 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 | |
1414 | Bug 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 | |
1422 | Bug in algebraic simplification of real primitives. <ulink url="http://www.standardml.org/Basis/real.html#SIG:REAL.\|@LTE\|:VAL"><literal>REAL<emphasis><N></emphasis>.<=(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 | |
1429 | Bug 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 | |
1437 | Bug 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 | |
1445 | Bug 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 | |
1453 | Bug 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 | |
1461 | Bug 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 | |
1469 | Bug 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 | |
1477 | Bug 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 | |
1485 | Bug 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 | |
1496 | in 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 | |
1501 | Bugs 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 | |
1509 | Bug 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 | |
1517 | Bug 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 | |
1525 | Bug 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 | |
1533 | Bug 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 | |
1540 | Bug 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 | |
1547 | Bug 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 | |
1555 | Bug 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 | |
1563 | Bug 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 | |
1571 | Bug 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 | |
1579 | Bug 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 | |
1587 | Bug 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 | |
1597 | in 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 | |
1602 | Bug 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 | |
1609 | Minor 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 | |
1616 | Minor bug erroneously accepting symbolic identifiers for strid, sigid, and fctid\r | |
1617 | and 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 | |
1624 | Minor 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 | |
1631 | Performance bug in creation of worker threads to service calls of <literal>_export</literal>-ed\r | |
1632 | functions.\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 | |
1640 | Bug in <literal>MLton.IntInf.fromRep</literal> that could yield values that violate the <literal>IntInf</literal>\r | |
1641 | representation 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 | |
1649 | Bug in equality status of some arrays, vectors, and slices in Basis Library\r | |
1650 | implementation.\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 | |
1660 | in 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 | |
1666 | create a call graph of the program in dot format, from which you can\r | |
1667 | use the <ulink url="http://www.research.att.com/sw/tools/graphviz/">graphviz</ulink>\r | |
1668 | software 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 | |
1671 | function, there will be one node in the graph that contains the\r | |
1672 | function name (and source position with <literal>-show-line true</literal>), as\r | |
1673 | well as the percentage of ticks. If you want to create a call graph\r | |
1674 | for 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 | |
1678 | on MLton’s analysis of which functions call each other. This analysis\r | |
1679 | depends on many implementation details and might display spurious\r | |
1680 | edges that a human could conclude are impossible. However, in\r | |
1681 | practice, 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 | |
1683 | to specify the nodes that you would like to see. This option also\r | |
1684 | controls which functions appear in the table that <literal>mlprof</literal> prints.\r | |
1685 | The argument to <literal>-keep</literal> is an expression describing a set of source\r | |
1686 | functions (i.e. graph nodes). The expression <emphasis>e</emphasis> should be of the\r | |
1687 | following 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 …</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 | |
1751 | a regular expression denoting the set of functions whose name\r | |
1752 | (followed by a space and the source position) has a prefix matching\r | |
1753 | the regexp. The <literal>and</literal>, <literal>not</literal>, and <literal>or</literal> expressions denote\r | |
1754 | intersection, complement, and union, respectively. The <literal>pred</literal> and\r | |
1755 | <literal>succ</literal> expressions add the set of immediate predecessors or successors\r | |
1756 | to their argument, respectively. The <literal>from</literal> and <literal>to</literal> expressions\r | |
1757 | denote the set of nodes that have paths from or to the set of nodes\r | |
1758 | denoted 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 | |
1760 | percentage of ticks, gc ticks, or stack ticks, respectively, is\r | |
1761 | greater 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 | |
1763 | you can use <literal>-keep all</literal> (this is the default). If you want to see\r | |
1764 | all nodes reachable from function <literal>foo</literal> in your program, you would\r | |
1765 | use <literal>-keep '(from "foo")'</literal>. Or, if you want to see all the\r | |
1766 | functions defined in subdirectory <literal>bar</literal> of your project that used\r | |
1767 | at 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 | |
1771 | can not use multiple <literal>-keep</literal> arguments or both <literal>-keep</literal> and <literal>-thresh</literal>.\r | |
1772 | When you use <literal>-keep</literal> to display a subset of the functions, <literal>mlprof</literal>\r | |
1773 | will add dashed edges to the call graph to indicate a path in the\r | |
1774 | original 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 | |
1776 | true</literal> to make the nodes darker or lighter depending on whether their\r | |
1777 | stack percentage is higher or lower.</simpara>\r | |
1778 | <simpara>MLton’s optimizer may duplicate source functions for any of a number\r | |
1779 | of reasons (functor duplication, monomorphisation, polyvariance,\r | |
1780 | inlining). By default, all duplicates of a function are treated as\r | |
1781 | one. If you would like to treat the duplicates separately, you can\r | |
1782 | use <literal>mlprof -split <emphasis>regexp</emphasis></literal>, which will cause all duplicates of\r | |
1783 | functions whose name has a prefix matching the regular expression to\r | |
1784 | be treated separately. This can be especially useful for higher-order\r | |
1785 | utility 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 | |
1789 | a call graph, because it describes the set of possible call stacks.\r | |
1790 | The difference is in how tail calls are displayed. For example if <literal>f</literal>\r | |
1791 | nontail calls <literal>g</literal> and <literal>g</literal> tail calls <literal>h</literal>, then the call-stack graph\r | |
1792 | has edges from <literal>f</literal> to <literal>g</literal> and <literal>f</literal> to <literal>h</literal>, while the call graph has\r | |
1793 | edges 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 | |
1794 | to <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’s <link linkend="ForeignFunctionInterface">ForeignFunctionInterface</link> allows programs to <emphasis>export</emphasis> SML\r | |
1801 | functions to be called from C. Suppose you would like export from SML\r | |
1802 | a function of type <literal>real * char -> int</literal> as the C function <literal>foo</literal>.\r | |
1803 | MLton extends the syntax of SML to allow expressions like the\r | |
1804 | following:</simpara>\r | |
1805 | <screen>_export "foo": (real * char -> int) -> unit;</screen>\r | |
1806 | <simpara>The above expression exports a C function named <literal>foo</literal>, with\r | |
1807 | prototype</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 -> int) -> 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 | |
1812 | when <literal>foo</literal> is called. So, for example, the following exports and\r | |
1813 | defines <literal>foo</literal>.</simpara>\r | |
1814 | <programlisting language="sml" linenumbering="unnumbered">val e = _export "foo": (real * char -> int) -> unit;\r | |
1815 | val _ = e (fn (x, c) => 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 -> unit;</screen>\r | |
1818 | <simpara>The type and the semicolon are not optional. As with <literal>_import</literal>, a\r | |
1819 | sequence of attributes may follow the function name.</simpara>\r | |
1820 | <simpara>MLton’s <literal>-export-header</literal> option generates a C header file with\r | |
1821 | prototypes for all of the functions exported from SML. Include this\r | |
1822 | header file in your C files to type check calls to functions exported\r | |
1823 | from 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 -> char) -> unit;\r | |
1829 | val _ = e (fn (i, r, _) =>\r | |
1830 | (print (concat ["i = ", Int.toString i,\r | |
1831 | " r = ", Real.toString r, "\n"])\r | |
1832 | ; #"g"))\r | |
1833 | val g = _import "g" public reentrant: unit -> unit;\r | |
1834 | val _ = g ()\r | |
1835 | val _ = g ()\r | |
1836 | \r | |
1837 | val e = _export "f2": (Word8.word -> word array) -> unit;\r | |
1838 | val _ = e (fn w =>\r | |
1839 | Array.tabulate (10, fn _ => Word.fromLargeWord (Word8.toLargeWord w)))\r | |
1840 | val g2 = _import "g2" public reentrant: unit -> word array;\r | |
1841 | val a = g2 ()\r | |
1842 | val _ = print (concat ["0wx", Word.toString (Array.sub (a, 0)), "\n"])\r | |
1843 | \r | |
1844 | val e = _export "f3": (unit -> unit) -> unit;\r | |
1845 | val _ = e (fn () => print "hello\n");\r | |
1846 | val g3 = _import "g3" public reentrant: unit -> unit;\r | |
1847 | val _ = g3 ()\r | |
1848 | \r | |
1849 | (* This example demonstrates mutual recursion between C and SML. *)\r | |
1850 | val e = _export "f4": (int -> unit) -> unit;\r | |
1851 | val g4 = _import "g4" public reentrant: int -> unit;\r | |
1852 | val _ = e (fn i => if i = 0 then () else g4 (i - 1))\r | |
1853 | val _ = g4 13\r | |
1854 | \r | |
1855 | val (_, zzzSet) = _symbol "zzz" alloc: (unit -> int) * (int -> unit);\r | |
1856 | val () = zzzSet 42\r | |
1857 | val g5 = _import "g5" public: unit -> unit;\r | |
1858 | val _ = g5 ()\r | |
1859 | \r | |
1860 | val _ = print "success\n"</programlisting>\r | |
1861 | <simpara>Note that the the <literal>reentrant</literal> attribute is used for <literal>_import</literal>-ing the\r | |
1862 | C 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 | |
1870 | Pointer f2 (Word8 x0);\r | |
1871 | void f3 ();\r | |
1872 | void f4 (Int32 x0);\r | |
1873 | extern 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 <stdio.h>\r | |
1876 | #include "export.h"\r | |
1877 | \r | |
1878 | /* Functions in C are by default PUBLIC symbols */\r | |
1879 | void 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 | |
1887 | Pointer 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 | |
1895 | void g3 () {\r | |
1896 | fprintf (stderr, "g3 starting\n");\r | |
1897 | f3 ();\r | |
1898 | fprintf (stderr, "g3 done\n");\r | |
1899 | }\r | |
1900 | \r | |
1901 | void g4 (Int32 i) {\r | |
1902 | fprintf (stderr, "g4 (%d)\n", i);\r | |
1903 | f4 (i);\r | |
1904 | }\r | |
1905 | \r | |
1906 | void 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 | |
1917 | g starting\r | |
1918 | ...\r | |
1919 | g4 (0)\r | |
1920 | success</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’s <link linkend="ForeignFunctionInterface">ForeignFunctionInterface</link> allows an SML program to <emphasis>import</emphasis>\r | |
1942 | C functions. Suppose you would like to import from C a function with\r | |
1943 | the 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 -> int;</screen>\r | |
1947 | <simpara>This expression denotes a function of type <literal>real * char -> int</literal> whose\r | |
1948 | behavior is implemented by calling the C function whose name is <literal>foo</literal>.\r | |
1949 | Thinking 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 | |
1951 | the 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 | |
1956 | attributes, 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 | |
1960 | as 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 | |
1964 | val ffi = _import "ffi" public: real array * int * int ref * char ref * int -> char;\r | |
1965 | open Array\r | |
1966 | \r | |
1967 | val size = 10\r | |
1968 | val a = tabulate (size, fn i => real i)\r | |
1969 | val ri = ref 0\r | |
1970 | val rc = ref #"0"\r | |
1971 | val n = 17\r | |
1972 | \r | |
1973 | (* Call the C function *)\r | |
1974 | val c = ffi (a, Array.length a, ri, rc, n)\r | |
1975 | \r | |
1976 | (* FFI_INT is declared as public in ffi-import.c *)\r | |
1977 | val (nGet, nSet) = _symbol "FFI_INT" public: (unit -> int) * (int -> unit);\r | |
1978 | \r | |
1979 | val _ = print (concat [Int.toString (nGet ()), "\n"])\r | |
1980 | \r | |
1981 | val _ =\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 | |
1988 | Int32 FFI_INT = 13;\r | |
1989 | Word32 FFI_WORD = 0xFF;\r | |
1990 | Bool FFI_BOOL = 1;\r | |
1991 | Real64 FFI_REAL = 3.14159;\r | |
1992 | \r | |
1993 | Char8 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 < 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 | |
2012 | 13\r | |
2013 | success</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 | |
2045 | is possible to make indirect function calls; that is, function calls\r | |
2046 | through a function pointer. MLton extends the syntax of SML to allow\r | |
2047 | expressions like the following:</simpara>\r | |
2048 | <screen>_import * : MLton.Pointer.t -> real * char -> int;</screen>\r | |
2049 | <simpara>This expression denotes a function of type</simpara>\r | |
2050 | <programlisting language="sml" linenumbering="unnumbered">MLton.Pointer.t -> real * char -> int</programlisting>\r | |
2051 | <simpara>whose behavior is implemented by calling the C function at the address\r | |
2052 | denoted by the <literal>MLton.Pointer.t</literal> argument, and supplying the C\r | |
2053 | function two arguments, a <literal>double</literal> and an <literal>int</literal>. The C function\r | |
2054 | pointer may be obtained, for example, by the dynamic linking loader\r | |
2055 | (<literal>dlopen</literal>, <literal>dlsym</literal>, …).</simpara>\r | |
2056 | <simpara>The general form of an indirect <literal>_import</literal> expression is:</simpara>\r | |
2057 | <screen>_import * attr... : cPtrTy -> 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 -> hndl\r | |
2071 | val dlsym : hndl * string -> fptr\r | |
2072 | val dlclose : hndl -> unit\r | |
2073 | \r | |
2074 | val RTLD_LAZY : mode\r | |
2075 | val RTLD_NOW : mode\r | |
2076 | end\r | |
2077 | \r | |
2078 | structure DynLink :> 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 -> hndl;\r | |
2089 | val dlerror =\r | |
2090 | _import "dlerror": unit -> MLton.Pointer.t;\r | |
2091 | val dlsym =\r | |
2092 | _import "dlsym" : hndl * string -> fptr;\r | |
2093 | val dlclose =\r | |
2094 | _import "dlclose" : hndl -> 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 () =>\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) =>\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 => "???"\r | |
2128 | | SOME s => s)\r | |
2129 | else hndl\r | |
2130 | end\r | |
2131 | \r | |
2132 | val dlsym = fn (hndl, symbol) =>\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 => fptr\r | |
2139 | | SOME s => raise Fail s\r | |
2140 | end\r | |
2141 | \r | |
2142 | val dlclose = fn hndl =>\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 => "???"\r | |
2157 | | SOME s => s)\r | |
2158 | end\r | |
2159 | end\r | |
2160 | \r | |
2161 | val dll =\r | |
2162 | let\r | |
2163 | open MLton.Platform.OS\r | |
2164 | in\r | |
2165 | case host of\r | |
2166 | Cygwin => "cygwin1.dll"\r | |
2167 | | Darwin => "libm.dylib"\r | |
2168 | | _ => "libm.so"\r | |
2169 | end\r | |
2170 | \r | |
2171 | val hndl = DynLink.dlopen (dll, DynLink.RTLD_LAZY)\r | |
2172 | \r | |
2173 | local\r | |
2174 | val double_to_double =\r | |
2175 | _import * : DynLink.fptr -> real -> real;\r | |
2176 | val cos_fptr = DynLink.dlsym (hndl, "cos")\r | |
2177 | in\r | |
2178 | val cos = double_to_double cos_fptr\r | |
2179 | end\r | |
2180 | \r | |
2181 | val _ = 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 | |
2184 | val _ = 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 | |
2192 | libm.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 | |
2194 | switch when linking only when on the specified platform. Compile with\r | |
2195 | <literal>-verbose 1</literal> to see in more detail what’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 | |
2213 | and 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 | |
2248 | Here 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 &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 -> 'a array` primitive to\r | |
2427 | `Array_alloc: SeqIndex.int -> 'a array`.\r | |
2428 | *** Add `Array_uninit: 'a array * SeqIndex.int -> 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 -> 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 -> '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 -> '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 -> unit` and `Array_copyVector: 'a array *\r | |
2478 | SeqIndex.int * 'a vector * SeqIndex.int * SeqIndex.int -> 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 | |
2498 | Undertaken 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) >= 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 | |
2838 | Here 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 | |
2986 | Here 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 '<name> <value>'`\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.~>>` 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 `->` 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.<= (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 '<name> <value>'` 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 | |
3258 | Here 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 <type>`,\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<N>.{scan,fromString}` operations.\r | |
3310 | `Real<N>.{scan,fromString}` were using `TO_NEAREST` semantics, but should obey\r | |
3311 | current rounding mode. (Only `Real<N>.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 <= 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<N>{Big,Little}` using `PackWord<N>{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 `<assert.h>`, rather than custom `"assert.{h,c}"`.\r | |
3366 | \r | |
3367 | * 2007-03-13\r | |
3368 | ** Implement `PackWord<N>{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 <n>`.\r | |
3378 | ** Added expert command line switch `-chunkify {coalesce<n>|func|one}`.\r | |
3379 | \r | |
3380 | * 2007-02-20\r | |
3381 | ** Fixed bug in `PackReal<N>.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 '<ty><N>'` 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 | |
3492 | Here 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 | |
3733 | Here 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 -> 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 -> string option) -> 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 `"<type> 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 | |
3893 | Here 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 | |
3898 | messages.\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 | |
3904 | readable 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 <= man * radix < 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 | |
4098 | Here 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 => 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 | |
4130 | Here 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 | |
4136 | basis 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 | |
4143 | correct 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` --> `-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 (<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 | |
4293 | Here 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 | |
4299 | library, 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` --> `-link`\r | |
4313 | *** `-L` --> `-lib-search`\r | |
4314 | *** `-o` --> `-output`\r | |
4315 | *** `-v` --> `-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,<<,~>>}` 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 | |
4387 | Here 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 | |
4393 | and generational collection, in addition to the copying collection that was\r | |
4394 | there before. It automatically switches between the the collection strategies\r | |
4395 | to 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 | |
4400 | message.\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 | |
4467 | Here 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` --> `-degug {false|true}`\r | |
4477 | *** `-h n` --> `-fixed-heap n`\r | |
4478 | *** `-p` --> `-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 | |
4594 | Here 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 _ => ()\r | |
4616 | val rec a : unit -> unit : unit -> unit = fn () => ()\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 () => ()\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 [] => f l | _ :: l => 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 | |
4706 | Here 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 | |
4715 | control-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 () => ()`\r | |
4748 | *** MLton had not accepted `val rec rec f = fn () => ()`\r | |
4749 | *** MLton had not accepted `val rec f = fn () => () and rec g = fn () => ()`\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 ; <program>\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` --> `true`\r | |
4779 | *** `A = B` --> `false`\r | |
4780 | *** `A x` = `B y` --> `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 | |
4815 | Here 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->limit -\r | |
5006 | s->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 > 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 | |
5073 | Here 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 | |
5078 | changes are that `mllex` and `mlyacc` are now included and that `mlton` can now\r | |
5079 | process 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 < 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.>>` had been used to implement\r | |
5151 | `Word8.~>>`.\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 | |
5197 | Here 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 `->`.\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 `:>`\r | |
5348 | instead of `:` so that the monomorphic array types are abstract.\r | |
5349 | \r | |
5350 | \r | |
5351 | == Version 19990712\r | |
5352 | \r | |
5353 | Here 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 <huge_val.h>`\r | |
5398 | *** added `#include <math.h>`\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 | |
5432 | Here 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 | |
5444 | size computation (`MLton.size`).\r | |
5445 | * MLton uses the GNU multiprecision (GnuMP) library to provide a fast\r | |
5446 | implementation 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 | |
5461 | program 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 | |
5481 | reasonable 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 | |
5488 | written in SML that translates C source code (after preprocessing)\r | |
5489 | into abstract syntax represented as a set of SML datatypes. The ckit\r | |
5490 | Library is distributed with SML/NJ. Due to differences between SML/NJ\r | |
5491 | and 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 | |
5493 | with 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 | |
5499 | You can import the ckit Library into an MLB file with:\r | |
5500 | </simpara>\r | |
5501 | <informaltable\r | |
5502 | frame="all"\r | |
5503 | rowsep="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 | |
5525 | If you are porting a project from SML/NJ’s <link linkend="CompilationManager">CompilationManager</link> to\r | |
5526 | MLton’s <link linkend="MLBasis">ML Basis system</link> using <literal>cm2mlb</literal>, note that the\r | |
5527 | following 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 | |
5534 | output <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 | |
5541 | deriving 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 | |
5585 | function.</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 | |
5590 | the values of the free variables of the function. For example, in the\r | |
5591 | expression</simpara>\r | |
5592 | <programlisting language="sml" linenumbering="unnumbered">let\r | |
5593 | val x = 5\r | |
5594 | in\r | |
5595 | fn y => x + y\r | |
5596 | end</programlisting>\r | |
5597 | <simpara>the closure for <literal>fn y => x + y</literal> contains a pointer to a piece of code\r | |
5598 | that knows to take its argument and add the value of <literal>x</literal> to it, plus\r | |
5599 | the 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 | |
5601 | passing 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’s Implementation</title>\r | |
5605 | <simpara>MLton does not implement closures traditionally. Instead, based on\r | |
5606 | whole-program higher-order control-flow analysis, MLton represents a\r | |
5607 | function as an element of a sum type, where the variant indicates\r | |
5608 | which 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 | |
5648 | to make it easy for compilers for different high-level languages to\r | |
5649 | share the same backend. An experimental version of MLton has been\r | |
5650 | made 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 | |
5674 | compiled 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 | |
5720 | extension/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 | |
5738 | If 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 | |
5743 | After 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 | |
5748 | When inspecting a conversion, check if the <literal>Var</literal> operand is also the\r | |
5749 | result of a conversion. If it is, try to combine the two operations.\r | |
5750 | Repeatedly simplify until hitting either a non-conversion <literal>Var</literal> or a\r | |
5751 | case 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 | |
5757 | x2 = Word_extdToWord (W1, W2, {signed=s1}) x1\r | |
5758 | x3 = Word_extdToWord (W2, W3, {signed=s2}) x2</screen>\r | |
5759 | <itemizedlist>\r | |
5760 | <listitem>\r | |
5761 | <simpara>\r | |
5762 | If <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 | |
5768 | Case <literal>W1 <= W3 <= 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 | |
5774 | Case <literal>W1 < W2 < 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 | |
5780 | Case <literal>W1 = W2 < 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 | |
5786 | Case <literal>W3 <= W2 <= W1 OR W3 <= W1 <= W2</literal>:\r | |
5787 | </simpara>\r | |
5788 | <screen>x_3 = Word_extdToWord (W1, W3, {signed=_}) x1</screen>\r | |
5789 | <simpara>because <literal>W3 <= W1 && W3 <= W2</literal>, just clip <literal>x1</literal></simpara>\r | |
5790 | </listitem>\r | |
5791 | <listitem>\r | |
5792 | <simpara>\r | |
5793 | Case <literal>W2 < W1 <= W3 OR W2 < W3 <= W1</literal>:\r | |
5794 | </simpara>\r | |
5795 | <simpara>unoptimized, because <literal>W2 < W1 && W2 < W3</literal>, has truncation effect</simpara>\r | |
5796 | </listitem>\r | |
5797 | <listitem>\r | |
5798 | <simpara>\r | |
5799 | Case <literal>W1 < W2 < 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 | |
5814 | arguments 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 | |
5820 | L_2 ()\r | |
5821 | ...\r | |
5822 | z2 = ?\r | |
5823 | ...\r | |
5824 | L_3 (x, y, z2)\r | |
5825 | L_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 | |
5833 | L_2 ()\r | |
5834 | ...\r | |
5835 | z2 = ?\r | |
5836 | ...\r | |
5837 | L_3 (z2)\r | |
5838 | L_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 | |
5842 | for the jump to <literal>L_3</literal>, space (either stack or pseudo-registers) for\r | |
5843 | the arguments of <literal>L_3</literal>, etc. It may also expose some other\r | |
5844 | optimizations, 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 | |
5859 | transformation. Only the <emphasis>Dominator Analysis</emphasis> is currently\r | |
5860 | implemented. (Implementations of the other analyses are available in\r | |
5861 | the <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 -> Var.t option list ref</screen>\r | |
5866 | <simpara>initialized to <literal>[]</literal>.</simpara>\r | |
5867 | <itemizedlist>\r | |
5868 | <listitem>\r | |
5869 | <simpara>\r | |
5870 | For 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 | |
5876 | For each <literal>L (x1, ..., xn)</literal> transfer where <literal>(a1, ..., an)</literal> are the\r | |
5877 | formals 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 | |
5882 | For each block argument a used in an unknown context (e.g.,\r | |
5883 | arguments of blocks used as continuations, handlers, arith success,\r | |
5884 | runtime 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 | |
5890 | the elements of <literal>xs</literal> are equal to <literal>SOME x</literal>, can be optimized by\r | |
5891 | setting <literal>a = x</literal> at the beginning of the block and dropping the\r | |
5892 | argument from <literal>Goto</literal> transfers.</simpara>\r | |
5893 | <simpara>That takes care of the example above. We can clearly do slightly\r | |
5894 | better, by changing the transformation criteria to the following: any\r | |
5895 | block argument a such that <literal>varInfo a = xs</literal>, where all of the elements\r | |
5896 | of <literal>xs</literal> are equal to <literal>SOME x</literal> <emphasis>or</emphasis> are equal to <literal>SOME a</literal>, can be\r | |
5897 | optimized by setting <literal>a = x</literal> at the beginning of the block and\r | |
5898 | dropping the argument from <literal>Goto</literal> transfers. This optimizes a case\r | |
5899 | like:</simpara>\r | |
5900 | <screen>L_1 ()\r | |
5901 | ... z1 = ? ...\r | |
5902 | L_3 (x, y, z1)\r | |
5903 | L_2 ()\r | |
5904 | ... z2 = ? ...\r | |
5905 | L_3(x, y, z2)\r | |
5906 | L_3 (a, b, c)\r | |
5907 | ... w = ? ...\r | |
5908 | case w of\r | |
5909 | true => L_4 | false => L_5\r | |
5910 | L_4 ()\r | |
5911 | ...\r | |
5912 | L_3 (a, b, w)\r | |
5913 | L_5 ()\r | |
5914 | ...</screen>\r | |
5915 | <simpara>where a common argument is passed to a loop (and is invariant through\r | |
5916 | the loop). Of course, the <link linkend="LoopInvariant">LoopInvariant</link> optimization pass would\r | |
5917 | normally introduce a local loop and essentially reduce this to the\r | |
5918 | first example, but I have seen this in practice, which suggests that\r | |
5919 | some optimizations after <link linkend="LoopInvariant">LoopInvariant</link> do enough simplifications\r | |
5920 | to 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’t cover the cases\r | |
5925 | where eliminating one common argument exposes the opportunity to\r | |
5926 | eliminate other common arguments. For example:</simpara>\r | |
5927 | <screen>L_1 ()\r | |
5928 | ...\r | |
5929 | L_3 (x)\r | |
5930 | L_2 ()\r | |
5931 | ...\r | |
5932 | L_3 (x)\r | |
5933 | L_3 (a)\r | |
5934 | ...\r | |
5935 | L_5 (a)\r | |
5936 | L_4 ()\r | |
5937 | ...\r | |
5938 | L_5 (x)\r | |
5939 | L_5 (b)\r | |
5940 | ...</screen>\r | |
5941 | <simpara>One pass of analysis and transformation would eliminate the argument\r | |
5942 | to <literal>L_3</literal> and rewrite the <literal>L_5(a)</literal> transfer to <literal>L_5 (x)</literal>, thereby\r | |
5943 | exposing 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 | |
5945 | performing some sort of fixed-point analysis. This analysis is\r | |
5946 | relatively simple; maintain</simpara>\r | |
5947 | <screen>varInfo: Var.t -> 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 | |
5951 | list and <literal>value ref</literal> under the hood), initialized to <literal>Bot</literal>.</simpara>\r | |
5952 | <itemizedlist>\r | |
5953 | <listitem>\r | |
5954 | <simpara>\r | |
5955 | For 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.<= (Point v, varInfo v)</literal>\r | |
5957 | </simpara>\r | |
5958 | </listitem>\r | |
5959 | <listitem>\r | |
5960 | <simpara>\r | |
5961 | For each <literal>L (x1, ..., xn)</literal> transfer where <literal>(a1, ..., an)</literal> are the\r | |
5962 | formals of <literal>L</literal>}, then <literal>VarLattice.<= (varInfo xi, varInfo ai)</literal>.\r | |
5963 | </simpara>\r | |
5964 | </listitem>\r | |
5965 | <listitem>\r | |
5966 | <simpara>\r | |
5967 | For each block argument a used in an unknown context, then\r | |
5968 | <literal>VarLattice.<= (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 | |
5973 | optimized by setting <literal>a = x</literal> at the beginning of the block and\r | |
5974 | dropping 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 <= varInfo a\r | |
5977 | varInfo a <= varInfo b\r | |
5978 | varInfo x <= varInfo b</screen>\r | |
5979 | <simpara>Assuming that <literal>varInfo x = Point x</literal>, then we get <literal>varInfo a = Point x</literal>\r | |
5980 | and <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’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 | |
5986 | G_2 ()\r | |
5987 | ... m = 2 ...\r | |
5988 | L_0 (m)\r | |
5989 | L_0 (x)\r | |
5990 | ...\r | |
5991 | L_1 ()\r | |
5992 | ...\r | |
5993 | L_3 (x)\r | |
5994 | L_2 ()\r | |
5995 | ...\r | |
5996 | L_3 (x)\r | |
5997 | L_3 (a)\r | |
5998 | ...\r | |
5999 | L_5(a)\r | |
6000 | L_4 ()\r | |
6001 | ...\r | |
6002 | L_5(x)\r | |
6003 | L_5 (b)\r | |
6004 | ...</screen>\r | |
6005 | <simpara>Now <literal>varInfo x = varInfo a = varInfo b = Top</literal>. What went wrong here?\r | |
6006 | When <literal>varInfo x</literal> went to <literal>Top</literal>, it got propagated all the way through\r | |
6007 | to <literal>a</literal> and <literal>b</literal>, and prevented the elimination of any common arguments.\r | |
6008 | What we’d like to do instead is when <literal>varInfo x</literal> goes to <literal>Top</literal>,\r | |
6009 | propagate on <literal>Point x</literal> — we have no hope of eliminating <literal>x</literal>, but if\r | |
6010 | we hold <literal>x</literal> constant, then we have a chance of eliminating arguments\r | |
6011 | for 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 | |
6016 | thought, <link linkend="MatthewFluet">MatthewFluet</link> realized that he had once before tried\r | |
6017 | proposing this kind of "fix" to a fixed-point analysis — when we were\r | |
6018 | first investigating the <link linkend="Contify">Contify</link> optimization in light of John\r | |
6019 | Reppy’s CWS paper. Of course, that "fix" failed because it defined a\r | |
6020 | non-monotonic function and one couldn’t take the fixed point. But,\r | |
6021 | <link linkend="StephenWeeks">StephenWeeks</link> suggested a dominator based approach, and we were\r | |
6022 | able to show that, indeed, the dominator analysis subsumed both the\r | |
6023 | previous call based analysis and the cont based analysis. And, a\r | |
6024 | moment’s reflection reveals further parallels: when\r | |
6025 | <literal>varInfo: Var.t -> Var.t option list ref</literal>, we have something analogous\r | |
6026 | to the call analysis, and when <literal>varInfo: Var.t -> VarLattice.t</literal>, we\r | |
6027 | have something analogous to the cont analysis. Maybe there is\r | |
6028 | something analogous to the dominator approach (and therefore superior\r | |
6029 | to 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 | |
6032 | edges(G) = {Root -> v | v bound in a Statement.t or\r | |
6033 | in the Function.t args} U\r | |
6034 | {xi -> ai | L(x1, ..., xn) transfer where (a1, ..., an)\r | |
6035 | are the formals of L} U\r | |
6036 | {Root -> 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 <> Root</literal> can\r | |
6039 | be optimized by setting <literal>a = x</literal> at the beginning of the block and\r | |
6040 | dropping the argument from <literal>Goto</literal> transfers.</simpara>\r | |
6041 | <simpara>Furthermore, experimental evidence suggests (and we are confident that\r | |
6042 | a formal presentation could prove) that the dominator analysis\r | |
6043 | subsumes the "syntactic" and "fixpoint" based analyses in this context\r | |
6044 | as 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 | |
6049 | result. At the outset, I never would have thought of a connection\r | |
6050 | between <link linkend="Contify">Contify</link> and <link linkend="CommonArg">CommonArg</link> optimizations. They would seem\r | |
6051 | to be two completely different optimizations. Although, this may not\r | |
6052 | really 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 | |
6055 | cases, but when we’re talking about analyzing code to detect that some\r | |
6056 | continuation is constant, I think it makes a lot more sense to make\r | |
6057 | all the continuation arguments completely explicit.</simpara>\r | |
6058 | <simpara>I believe that making all the continuation arguments explicit will\r | |
6059 | show that the optimization can be generalized to eliminating constant\r | |
6060 | arguments, whether continuations or not.</simpara>\r | |
6061 | </blockquote>\r | |
6062 | <simpara>What I think the common argument optimization shows is that the\r | |
6063 | dominator analysis does slightly better than the reviewer puts it: we\r | |
6064 | find more than just constant continuations, we find common\r | |
6065 | continuations. And I think this is further justified by the fact that\r | |
6066 | I have observed common argument eliminate some <literal>env_X</literal> arguments which\r | |
6067 | would appear to correspond to determining that while the closure being\r | |
6068 | executed isn’t constant it is at least the same as the closure being\r | |
6069 | passed elsewhere.</simpara>\r | |
6070 | <simpara>At first, I was curious whether or not we had missed a bigger picture\r | |
6071 | with the dominator analysis. When we wrote the contification paper, I\r | |
6072 | assumed that the dominator analysis was a specialized solution to a\r | |
6073 | specialized problem; we never suggested that it was a technique suited\r | |
6074 | to a larger class of analyses. After initially finding a connection\r | |
6075 | between <link linkend="Contify">Contify</link> and <link linkend="CommonArg">CommonArg</link> (and thinking that the only\r | |
6076 | connection was the technique), I wondered if the dominator technique\r | |
6077 | really was applicable to a larger class of analyses. That is still a\r | |
6078 | question, but after writing up the above, I’m suspecting that the\r | |
6079 | "real story" is that the dominator analysis is a solution to the\r | |
6080 | common argument optimization, and that the <link linkend="Contify">Contify</link> optimization is\r | |
6081 | specializing <link linkend="CommonArg">CommonArg</link> to the case of continuation arguments (with\r | |
6082 | a different transformation at the end). (Note, a whole-program,\r | |
6083 | inter-procedural common argument analysis doesn’t really make sense\r | |
6084 | (in our <link linkend="SSA">SSA</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link>), because the only way of\r | |
6085 | passing values between functions is as arguments. (Unless of course\r | |
6086 | in the case that the common argument is also a constant argument, in\r | |
6087 | which case <link linkend="ConstantPropagation">ConstantPropagation</link> could lift it to a global.) The\r | |
6088 | inter-procedural <link linkend="Contify">Contify</link> optimization works out because there we\r | |
6089 | move the function to the argument.)</simpara>\r | |
6090 | <simpara>Anyways, it’s still unclear to me whether or not the dominator based\r | |
6091 | approach 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’t have a huge impact on\r | |
6096 | runtime, although it does predictably saved some code size. I stuck\r | |
6097 | it in the optimization sequence after <link linkend="Flatten">Flatten</link> and (the third round\r | |
6098 | of) <link linkend="LocalFlatten">LocalFlatten</link>, since it seems to me that we could have cases\r | |
6099 | where some components of a tuple used as an argument are common, but\r | |
6100 | the whole tuple isn’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 | |
6102 | get some things that <link linkend="LoopInvariant">LoopInvariant</link> gets, it doesn’t get all of\r | |
6103 | them). 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 | |
6105 | subexpressions. 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 | |
6118 | equivalence criteria requires blocks to have no arguments or\r | |
6119 | statements and transfer via <literal>Raise</literal>, <literal>Return</literal>, or <literal>Goto</literal> of a single\r | |
6120 | global 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 | |
6137 | Rewrites\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 | |
6151 | Rewrites\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 | |
6165 | Rewrites\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 | |
6180 | share 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 | |
6220 | val b = Array_length a</screen>\r | |
6221 | <simpara>rewritten to</simpara>\r | |
6222 | <screen>val a = Array_uninit n\r | |
6223 | val 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 | |
6227 | transfer 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 | |
6234 | val k = (l + n) + ((l + m) handle Overflow => ((l + m)\r | |
6235 | handle Overflow => 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’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 | |
6249 | includes 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 | |
6251 | CM file — handling the full syntax of CM supported by your installed\r | |
6252 | SML/NJ version and correctly handling export filters. When <literal>cm2mlb</literal>\r | |
6253 | encounters a <literal>.cm</literal> import, it attempts to convert it to a\r | |
6254 | corresponding <literal>.mlb</literal> import. CM anchored paths are translated to\r | |
6255 | paths 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 | |
6257 | the 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 | |
6264 | Building <literal>cm2mlb</literal> requires that you have already installed a recent\r | |
6265 | version 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 | |
6273 | of compiler passes are listed in the left and right columns.</simpara>\r | |
6274 | <informaltable\r | |
6275 | frame="all"\r | |
6276 | rowsep="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 | |
6386 | high-level view of the compiler passes, from <link linkend="FrontEnd">FrontEnd</link> to code\r | |
6387 | generation.</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 | |
6393 | An implementation pass for the <link linkend="ZZZ">ZZZ</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="ZZZSimplify">ZZZSimplify</link>.\r | |
6394 | An optimization pass for the <link linkend="ZZZ">ZZZ</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="ZZZSimplify">ZZZSimplify</link>.\r | |
6395 | A rewrite pass for the <link linkend="ZZZ">ZZZ</link> <link linkend="IntermediateLanguage">IntermediateLanguage</link>, invoked from <link linkend="ZZZOtherPass">ZZZOtherPass</link>.\r | |
6396 | A 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’s compile-time options control the name of the output file, the\r | |
6420 | verbosity of compile-time messages, and whether or not certain\r | |
6421 | optimizations are performed. They also can specify which intermediate\r | |
6422 | files are saved and can stop the compilation process early, at some\r | |
6423 | intermediate pass, in which case compilation can be resumed by passing\r | |
6424 | the generated files to MLton. MLton uses the input file suffix to\r | |
6425 | determine 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 | |
6428 | usage message, run MLton with an invalid switch, e.g. <literal>mlton -z</literal>. In\r | |
6429 | the explanation below and in the usage message, for flags that take a\r | |
6430 | number of choices (e.g. <literal>{true|false}</literal>), the first value listed is the\r | |
6431 | default.</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 | |
6440 | The 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 | |
6447 | pass 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 | |
6460 | x86 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 | |
6462 | better 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 | |
6469 | available 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 | |
6476 | performance cost to setting this to <literal>true</literal>, both in memory usage of\r | |
6477 | exceptions and in run time, because of additional work that must be\r | |
6478 | performed 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 | |
6487 | example, <literal>-default-ann 'warnUnused true'</literal> causes unused variable\r | |
6488 | warnings to be enabled by default. A default is overridden by the\r | |
6489 | corresponding 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 | |
6497 | top-level structure <literal>Word</literal> in the <link linkend="BasisLibrary">Basis Library</link> to be\r | |
6498 | equal 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 | |
6500 | top-level structure <literal>Int</literal> in the <link linkend="BasisLibrary">Basis Library</link> to be\r | |
6501 | equal 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 | |
6508 | every ML Basis file. For example, to see <emphasis>all</emphasis> match and unused\r | |
6509 | warnings, 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 | |
6528 | IEEE floating point standard. By default, it is not, because of the\r | |
6529 | performance 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 | |
6536 | approximate 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 | |
6544 | the output file is saved.</simpara>\r | |
6545 | <informaltable\r | |
6546 | frame="all"\r | |
6547 | rowsep="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 | |
6570 | library search paths, e.g. <literal>-link-opt -Lpath</literal>, and libraries to link\r | |
6571 | with, e.g., <literal>-link-opt -lfoo</literal>, or even both at the same time,\r | |
6572 | e.g. <literal>-link-opt '-Lpath -lfoo'</literal>. If you wish to pass an option to the\r | |
6573 | linker, 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 | |
6599 | additional 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 | |
6601 | maps 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 | |
6609 | definitions 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 | |
6616 | input file name with its suffix removed and an appropriate, possibly\r | |
6617 | empty, 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 | |
6624 | such 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 | |
6631 | branch of a function definition, <literal>case</literal> expression, and <literal>if</literal>\r | |
6632 | expression.</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 | |
6639 | on 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 | |
6656 | allowed, and will pass all the arguments in order. If the same\r | |
6657 | runtime switch occurs more than once, then the last setting will take\r | |
6658 | effect. There is no need to supply the leading <literal>@MLton</literal> or the\r | |
6659 | trailing <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 | |
6661 | argument to be treated as a sequence of words by the runtime. For\r | |
6662 | example 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’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 | |
6685 | appears on a line, followed on subsequent lines by the position of\r | |
6686 | each 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 | |
6694 | frame="all"\r | |
6695 | rowsep="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 | |
6721 | by 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>…</emphasis>}</literal>\r | |
6726 | </simpara>\r | |
6727 | <simpara>Generate an executable that runs on the specified platform. The\r | |
6728 | default is <literal>self</literal>, which means to compile for the machine that MLton\r | |
6729 | is 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 | |
6737 | assembler code, except it only passes <emphasis>option</emphasis> when the target\r | |
6738 | architecture, 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 | |
6745 | except it only passes <emphasis>option</emphasis> when the target architecture, operating\r | |
6746 | system, 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 | |
6753 | it only passes <emphasis>option</emphasis> when the target architecture, operating\r | |
6754 | system, 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 | |
6762 | frame="all"\r | |
6763 | rowsep="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 | |
6796 | compiler will run much more slowly than MLton compiled by itself. We\r | |
6797 | don’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 | |
6799 | new platform.</simpara>\r | |
6800 | <simpara>If you do want to build MLton with SML/NJ, it is best to have a binary\r | |
6801 | MLton package installed. If you don’t, here are some issues you may\r | |
6802 | encounter 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 | |
6808 | proceed in spite of this error.</simpara>\r | |
6809 | <simpara>If you don’t have an <literal>mllex</literal> executable, you will get the error\r | |
6810 | message:</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 | |
6813 | distributed with a binary package of MLton. The easiest solution is\r | |
6814 | to 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 | |
6822 | library based on synchronous message passing. MLton has an initial\r | |
6823 | port of CML from SML/NJ, but is missing a thread-safe wrapper around\r | |
6824 | the Basis Library and event-based equivalents to <literal>IO</literal> and <literal>OS</literal>\r | |
6825 | functions.</simpara>\r | |
6826 | <simpara>All of the core CML functionality is present.</simpara>\r | |
6827 | <programlisting language="sml" linenumbering="unnumbered">structure CML: CML\r | |
6828 | structure SyncVar: SYNC_VAR\r | |
6829 | structure Mailbox: MAILBOX\r | |
6830 | structure Multicast: MULTICAST\r | |
6831 | structure SimpleRPC: SIMPLE_RPC\r | |
6832 | structure 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 -> bool\r | |
6837 | val doit: (unit -> unit) * Time.time option -> OS.Process.status\r | |
6838 | val shutdown: OS.Process.status -> 'a\r | |
6839 | end</programlisting>\r | |
6840 | <simpara>MLton’s <literal>RunCML</literal> structure does not include all of the cleanup and\r | |
6841 | logging operations of SML/NJ’s <literal>RunCML</literal> structure. However, the\r | |
6842 | implementation does include the <literal>CML.timeOutEvt</literal> and <literal>CML.atTimeEvt</literal>\r | |
6843 | functions, and a preemptive scheduler that knows to sleep when there\r | |
6844 | are 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 | |
6846 | to call a Basis Library function that is stateful is to wrap the call\r | |
6847 | with <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 | |
6853 | You can import the CML Library into an MLB file with:\r | |
6854 | </simpara>\r | |
6855 | <informaltable\r | |
6856 | frame="all"\r | |
6857 | rowsep="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 | |
6879 | If you are porting a project from SML/NJ’s <link linkend="CompilationManager">CompilationManager</link> to\r | |
6880 | MLton’s <link linkend="MLBasis">ML Basis system</link> using <literal>cm2mlb</literal>, note that the\r | |
6881 | following 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’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 | |
6911 | MLton in the summer of 2004. The main difference between the\r | |
6912 | implementations is that SML/NJ uses continuations to implement CML\r | |
6913 | threads, while MLton uses its underlying <link linkend="MLtonThread">thread</link>\r | |
6914 | package. Presently, MLton’s threads are a little more heavyweight\r | |
6915 | than SML/NJ’s continuations, but it’s pretty clear that there is some\r | |
6916 | fat there that could be trimmed.</simpara>\r | |
6917 | <simpara>The implementation of CML in SML/NJ is built upon the first-class\r | |
6918 | continuations of the <literal>SMLofNJ.Cont</literal> module.</simpara>\r | |
6919 | <programlisting language="sml" linenumbering="unnumbered">type 'a cont\r | |
6920 | val callcc: ('a cont -> 'a) -> 'a\r | |
6921 | val isolate: ('a -> unit) -> 'a cont\r | |
6922 | val throw: 'a cont -> 'a -> 'b</programlisting>\r | |
6923 | <simpara>The implementation of CML in MLton is built upon the first-class\r | |
6924 | threads of the <link linkend="MLtonThread">MLtonThread</link> module.</simpara>\r | |
6925 | <programlisting language="sml" linenumbering="unnumbered">type 'a t\r | |
6926 | val new: ('a -> unit) -> 'a t\r | |
6927 | val prepare: 'a t * 'a -> Runnable.t\r | |
6928 | val switch: ('a t -> Runnable.t) -> 'a</programlisting>\r | |
6929 | <simpara>The port is relatively straightforward, because CML always throws to a\r | |
6930 | continuation at most once. Hence, an "abstract" implementation of\r | |
6931 | CML could be built upon first-class one-shot continuations, which map\r | |
6932 | equally well to SML/NJ’s continuations and MLton’s threads.</simpara>\r | |
6933 | <simpara>The "essence" of the port is to transform:</simpara>\r | |
6934 | <screen>callcc (fn k => ... throw k' v')</screen>\r | |
6935 | <simpara>to</simpara>\r | |
6936 | <screen>switch (fn t => ... 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 | |
6939 | events. 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 -> 'a}\r | |
6942 | | BLOCKED of {\r | |
6943 | transId: trans_id ref,\r | |
6944 | cleanUp: unit -> unit,\r | |
6945 | next: unit -> unit\r | |
6946 | } -> 'a\r | |
6947 | type 'a base_evt = unit -> 'a event_status</programlisting>\r | |
6948 | <simpara>When synchronizing on a set of base events, which are all blocked, we\r | |
6949 | must 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 | |
6953 | becomes enabled). However, each <literal>BLOCKED</literal> function is implemented by\r | |
6954 | a callcc, so that when the event is enabled, it throws back to the\r | |
6955 | point of synchronization. Hence, the next function (which doesn’t\r | |
6956 | return) is invoked by the <literal>BLOCKED</literal> function to escape the callcc and\r | |
6957 | continue in the thread performing the synchronization. In SML/NJ this\r | |
6958 | is implemented as follows:</simpara>\r | |
6959 | <programlisting language="sml" linenumbering="unnumbered">fun ext ([], blockFns) = callcc (fn k => 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 () => 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 | |
6973 | continuation on the ready queue.) This doesn’t map well to the MLton\r | |
6974 | thread model. Although it follows the</simpara>\r | |
6975 | <screen>callcc (fn k => ... 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' => ... 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 | |
6980 | Essentially, each <literal>blockFn</literal> wants to capture this continuation, hold\r | |
6981 | on to it until the event is enabled, and continue with next; when the\r | |
6982 | event is enabled, before invoking the continuation and returning to\r | |
6983 | the synchronization point, the <literal>cleanUp</literal> and other event specific\r | |
6984 | operations are performed.</simpara>\r | |
6985 | <simpara>To accomplish the same effect in the MLton thread implementation, we\r | |
6986 | have the following:</simpara>\r | |
6987 | <programlisting language="sml" linenumbering="unnumbered">datatype 'a status =\r | |
6988 | ENABLED of {prio: int, doitFn: unit -> 'a}\r | |
6989 | | BLOCKED of {transId: trans_id,\r | |
6990 | cleanUp: unit -> unit,\r | |
6991 | next: unit -> rdy_thread} -> 'a\r | |
6992 | \r | |
6993 | type 'a base = unit -> 'a status\r | |
6994 | \r | |
6995 | fun ext ([], blockFns): 'a =\r | |
6996 | S.atomicSwitch\r | |
6997 | (fn (t: 'a S.thread) =>\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 | [] => S.next ()\r | |
7003 | | blockFn::blockFns =>\r | |
7004 | (S.prep o S.new)\r | |
7005 | (fn _ => fn () =>\r | |
7006 | let\r | |
7007 | val () = S.atomicBegin ()\r | |
7008 | val x = blockFn {transId = transId,\r | |
7009 | cleanUp = cleanUp,\r | |
7010 | next = fn () => log blockFns}\r | |
7011 | in S.switch(fn _ => 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’s own\r | |
7017 | thread, whose only purpose is to return to the synchronization point.\r | |
7018 | This corresponds to the <literal>throw (blockFn {...})</literal> in the SML/NJ\r | |
7019 | implementation. I’m worried that this implementation might be a\r | |
7020 | little expensive, starting a new thread for each blocked event (when\r | |
7021 | there are only multiple blocked events in a synchronization group).\r | |
7022 | But, I don’t see another way of implementing this behavior in the\r | |
7023 | MLton thread model.</simpara>\r | |
7024 | <simpara>Note that another way of thinking about what is going on is to\r | |
7025 | consider each <literal>blockFn</literal> as prepending a different set of actions to\r | |
7026 | the 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 -> 'a): 'b t =\r | |
7029 | let\r | |
7030 | val t =\r | |
7031 | case !r of\r | |
7032 | Dead => raise Fail "prepend to a Dead thread"\r | |
7033 | | New g => New (g o f)\r | |
7034 | | Paused (g, t) => Paused (fn h => 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 | |
7039 | prepends to the same thread (i.e., not destroying the original thread\r | |
7040 | in the process). Of course, only one of the threads could be run: if\r | |
7041 | the original thread were in the <literal>Paused</literal> state, then multiple threads\r | |
7042 | would share the underlying runtime/primitive thread. Now, this\r | |
7043 | matches the "one-shot" nature of CML continuations/threads, but I’m\r | |
7044 | not comfortable with extending <literal>MLton.Thread</literal> with such an unsafe\r | |
7045 | operation.</simpara>\r | |
7046 | <simpara>Other than this complication with blocking multiple base events, the\r | |
7047 | port was quite routine. (As a very pleasant surprise, the CML\r | |
7048 | implementation in SML/NJ doesn’t use any SML/NJ-isms.) There is a\r | |
7049 | slight difference in the way in which critical sections are handled in\r | |
7050 | SML/NJ and MLton; since <literal>MLton.Thread.switch</literal> <emphasis>always</emphasis> leaves a\r | |
7051 | critical 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 | |
7053 | section after a thread switch.</simpara>\r | |
7054 | <simpara>While looking at virtually every file in the core CML implementation,\r | |
7055 | I took the liberty of simplifying things where it seemed possible; in\r | |
7056 | terms of style, the implementation is about half-way between Reppy’s\r | |
7057 | original and MLton’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 | |
7063 | imperative) queues, (functional) priority queues. Hence, it should be\r | |
7064 | easier 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 | |
7070 | most of the interesting action takes place. I’ve made the connection\r | |
7071 | between <literal>MLton.Thread.t</literal>-s and <literal>ThreadId.thread_id</literal>-s more abstract\r | |
7072 | than 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 | |
7078 | eliminated 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 -> 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 | |
7093 | thread with the ID tid. There are three ways that a thread may\r | |
7094 | terminate: the function that was passed to spawn (or spawnc) may\r | |
7095 | return; it may call the exit function, or it may have an uncaught\r | |
7096 | exception. Note that <literal>joinEvt</literal> does not distinguish between these\r | |
7097 | cases; 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 | |
7103 | last restriction. Upon the creation of a <literal>'a Scheduler.thread</literal>, we\r | |
7104 | could attach a finalizer to the underlying <literal>'a MLton.Thread.t</literal> that\r | |
7105 | enables the <literal>joinEvt</literal> (in the associated <literal>ThreadID.thread_id</literal>) when\r | |
7106 | the <literal>'a MLton.Thread.t</literal> becomes unreachable.</simpara>\r | |
7107 | <simpara>I don’t know why CML doesn’t have</simpara>\r | |
7108 | <screen>CML.kill: thread_id -> unit</screen>\r | |
7109 | <simpara>which has a fairly simple implementation — setting a kill flag in the\r | |
7110 | <literal>thread_id</literal> and adjusting the scheduler to discard any killed threads\r | |
7111 | that it takes off the ready queue. The fairness of the scheduler\r | |
7112 | ensures that a killed thread will eventually be discarded. The\r | |
7113 | semantics are little murky for blocked threads that are killed,\r | |
7114 | though. For example, consider a thread blocked on <literal>SyncVar.mTake mv</literal>\r | |
7115 | and a thread blocked on <literal>SyncVar.mGet mv</literal>. If the first thread is\r | |
7116 | killed while blocked, and a third thread does <literal>SyncVar.mPut (mv, x)</literal>,\r | |
7117 | then we might expect that we’ll enable the second thread, and never\r | |
7118 | the first. But, when only the ready queue is able to discard killed\r | |
7119 | threads, 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 | |
7121 | leave 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 | |
7123 | canceled 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 | |
7125 | explain 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 | |
7127 | solution to the recent <literal>comp.lang.ml</literal> post about terminating a\r | |
7128 | function that doesn’t complete in a given time.</simpara>\r | |
7129 | <programlisting language="sml" linenumbering="unnumbered"> fun timeOut (f: unit -> 'a, t: Time.time): 'a option =\r | |
7130 | let\r | |
7131 | val iv = SyncVar.iVar ()\r | |
7132 | val tid = CML.spawn (fn () => SyncVar.iPut (iv, f ()))\r | |
7133 | in\r | |
7134 | CML.select\r | |
7135 | [CML.wrap (CML.timeOutEvt t, fn () => (CML.kill tid; NONE)),\r | |
7136 | CML.wrap (SyncVar.iGetEvt iv, fn x => 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’s implementation is not space\r | |
7150 | efficient, because multi-shot continuations can be held indefinitely\r | |
7151 | on event queues. MLton is better off because of the one-shot nature — when an event enables a thread, all other copies of the thread\r | |
7152 | waiting in other event queues get turned into dead threads (of zero\r | |
7153 | size).</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 | |
7164 | structures. It also performs globalization of (small) values computed\r | |
7165 | once.</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 | |
7245 | Both mailing lists are unmoderated. However, the mailing lists are\r | |
7246 | configured to discard all spam, to hold all non-subscriber posts\r | |
7247 | for moderation, to accept all subscriber posts, and to admin approve\r | |
7248 | subscription requests. Please contact\r | |
7249 | <ulink url="mailto:matthew.fluet@gmail.com">Matthew Fluet</ulink> if it appears that your\r | |
7250 | messages are being discarded as spam.\r | |
7251 | </simpara>\r | |
7252 | </listitem>\r | |
7253 | <listitem>\r | |
7254 | <simpara>\r | |
7255 | Large messages (over 256K) should not be sent. Rather, please send\r | |
7256 | an 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 | |
7263 | Discussions started on the mailing lists should stay on the mailing\r | |
7264 | lists. Private replies may be bounced to the mailing list for the\r | |
7265 | benefit of those following the discussion.\r | |
7266 | </simpara>\r | |
7267 | </listitem>\r | |
7268 | <listitem>\r | |
7269 | <simpara>\r | |
7270 | Discussions 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 | |
7273 | when the discussion shifts from how to use MLton to how to modify\r | |
7274 | MLton (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 | |
7285 | Some 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 | |
7299 | always returns to the same place into a continuation. This exposes\r | |
7300 | control-flow information that is required by many optimizations,\r | |
7301 | including 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 | |
7316 | intermediate 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 | |
7318 | Section 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 | |
7326 | translated 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 | |
7349 | checker.</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 | |
7375 | MatthewFluet, 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 | |
7410 | list.</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 | |
7427 | Alexander Abushkevich extended support for OpenBSD.\r | |
7428 | </simpara>\r | |
7429 | </listitem>\r | |
7430 | <listitem>\r | |
7431 | <simpara>\r | |
7432 | Ross 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 | |
7438 | Kevin Bradley added initial support for <link linkend="SuccessorML">SuccessorML</link> features.\r | |
7439 | </simpara>\r | |
7440 | </listitem>\r | |
7441 | <listitem>\r | |
7442 | <simpara>\r | |
7443 | Bryan 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 | |
7450 | Jason 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 | |
7457 | Christopher 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 | |
7464 | Alain 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 | |
7472 | Armando 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 | |
7478 | Martin 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 | |
7484 | Brent 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 | |
7497 | Simon Helsen provided bug reports, suggestions, and helpful\r | |
7498 | discussions.\r | |
7499 | </simpara>\r | |
7500 | </listitem>\r | |
7501 | <listitem>\r | |
7502 | <simpara>\r | |
7503 | Joe 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 | |
7517 | Richard Kelsey provided helpful discussions.\r | |
7518 | </simpara>\r | |
7519 | </listitem>\r | |
7520 | <listitem>\r | |
7521 | <simpara>\r | |
7522 | Ville 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 | |
7527 | Brian Leibig implemented the <link linkend="LLVMCodegen">LLVMCodegen</link>.\r | |
7528 | </simpara>\r | |
7529 | </listitem>\r | |
7530 | <listitem>\r | |
7531 | <simpara>\r | |
7532 | Geoffrey Mainland helped with FreeBSD packaging.\r | |
7533 | </simpara>\r | |
7534 | </listitem>\r | |
7535 | <listitem>\r | |
7536 | <simpara>\r | |
7537 | Eric 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 | |
7549 | Michael 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 | |
7555 | Barak 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 | |
7562 | Filip Pizlo ported MLton to (PowerPC) Darwin.\r | |
7563 | </simpara>\r | |
7564 | </listitem>\r | |
7565 | <listitem>\r | |
7566 | <simpara>\r | |
7567 | Vedant 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 | |
7573 | Krishna 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 | |
7579 | John Reppy assisted in porting MLton to Intel Mac.\r | |
7580 | </simpara>\r | |
7581 | </listitem>\r | |
7582 | <listitem>\r | |
7583 | <simpara>\r | |
7584 | Sam Rushing ported MLton to FreeBSD.\r | |
7585 | </simpara>\r | |
7586 | </listitem>\r | |
7587 | <listitem>\r | |
7588 | <simpara>\r | |
7589 | Rob 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 | |
7597 | Jeffrey 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 | |
7603 | Matthew 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&searchon=names&suite=all&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&searchon=names&suite=all&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 | |
7618 | Maksim 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 | |
7625 | Luke 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 | |
7630 | used code from other sources.</simpara>\r | |
7631 | <itemizedlist>\r | |
7632 | <listitem>\r | |
7633 | <simpara>\r | |
7634 | MLton 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 | |
7641 | MLton’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 | |
7649 | The MLton <link linkend="BasisLibrary">Basis Library</link> implementation of\r | |
7650 | conversions between binary and decimal representations of reals uses\r | |
7651 | David Gay’s <ulink url="http://www.netlib.org/fp/">gdtoa</ulink> library.\r | |
7652 | </simpara>\r | |
7653 | </listitem>\r | |
7654 | <listitem>\r | |
7655 | <simpara>\r | |
7656 | The 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 | |
7664 | The 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 | |
7672 | Many of the benchmarks come from the SML/NJ benchmark suite.\r | |
7673 | </simpara>\r | |
7674 | </listitem>\r | |
7675 | <listitem>\r | |
7676 | <simpara>\r | |
7677 | Many 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 | |
7684 | MLton 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 | |
7689 | MLton’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’s <literal>-target</literal> flag directs MLton to cross compile an application\r | |
7705 | for another platform. By default, MLton is only able to compile for\r | |
7706 | the machine it is running on. In order to use MLton as a cross\r | |
7707 | compiler, you need to do two things.</simpara>\r | |
7708 | <orderedlist numeration="arabic">\r | |
7709 | <listitem>\r | |
7710 | <simpara>\r | |
7711 | Install the GCC cross-compiler tools on the host so that GCC can\r | |
7712 | compile to the target.\r | |
7713 | </simpara>\r | |
7714 | </listitem>\r | |
7715 | <listitem>\r | |
7716 | <simpara>\r | |
7717 | Cross compile the MLton runtime system to build the runtime\r | |
7718 | libraries 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 | |
7723 | MLton is running on and the <emphasis>target</emphasis> as the machine that MLton is\r | |
7724 | compiling for.</simpara>\r | |
7725 | <simpara>To build a GCC cross-compiler toolset on the host, you can use the\r | |
7726 | script <literal>bin/build-cross-gcc</literal>, available in the MLton sources, as a\r | |
7727 | template. The value of the <literal>target</literal> variable in that script is\r | |
7728 | important, since that is what you will pass to MLton’s <literal>-target</literal> flag.\r | |
7729 | Once you have the toolset built, you should be able to test it by\r | |
7730 | cross 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 | |
7733 | this case, a Cygwin machine.</simpara>\r | |
7734 | <simpara>Next, you must cross compile the MLton runtime system and inform MLton\r | |
7735 | of the availability of the new target. The script <literal>bin/add-cross</literal>\r | |
7736 | from the MLton sources will help you do this. Please read the\r | |
7737 | comments at the top of the script. Here is a sample run adding a\r | |
7738 | Solaris cross compiler.</simpara>\r | |
7739 | <screen>% add-cross sparc-sun-solaris sun blade\r | |
7740 | Making runtime.\r | |
7741 | Building print-constants executable.\r | |
7742 | Running 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 | |
7744 | machine and to create <literal>print-constants</literal>, which prints out all of the\r | |
7745 | constants 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 | |
7747 | the 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 | |
7749 | applications. 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 | |
7752 | Cygwin 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 | |
7756 | find it simpler to use <literal>mlton -keep g</literal> to generate the files on the\r | |
7757 | host, then copy the files to the target, and then use <literal>gcc</literal> or <literal>mlton</literal>\r | |
7758 | on 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 | |
7765 | a 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 | |
7804 | elimination is run in order to eliminate as much of the Basis Library\r | |
7805 | as possible. The dead code elimination algorithm used is not safe in\r | |
7806 | general, and only works because the Basis Library implementation has\r | |
7807 | special properties:</simpara>\r | |
7808 | <itemizedlist>\r | |
7809 | <listitem>\r | |
7810 | <simpara>\r | |
7811 | it terminates\r | |
7812 | </simpara>\r | |
7813 | </listitem>\r | |
7814 | <listitem>\r | |
7815 | <simpara>\r | |
7816 | it 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 | |
7821 | declarations from the Basis Library so that there are no free\r | |
7822 | variables in the user program (or remaining Basis Library\r | |
7823 | implementation). It has a special hack to include all\r | |
7824 | bindings 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 | |
7828 | dead-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 | |
7840 | object, and an <literal>(int * int) array</literal> contains pairs of <literal>int</literal>-s,\r | |
7841 | rather 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 | |
7856 | consumes 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 | |
7876 | often asked whether the deep flatten pass usually has a significant\r | |
7877 | impact on performance. The standard benchmark suite was run with and\r | |
7878 | without the deep flatten pass enabled when the pass was first\r | |
7879 | introduced:</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 | |
7888 | However, these are micro benchmarks; other applications may derive\r | |
7889 | greater 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 | |
7896 | used. Because of type inference, the use of a type can be implicit;\r | |
7897 | hence, this requirement is more subtle than it might appear. For\r | |
7898 | example, the following program is not type correct, because the type\r | |
7899 | of <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 | |
7901 | datatype t = A | B\r | |
7902 | val () = r := SOME A</programlisting>\r | |
7903 | <simpara>MLton reports the following error, indicating that the type defined on\r | |
7904 | line 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 | |
7913 | Warning: 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 | |
7918 | cast an integer to a function by (implicitly) using a type before it\r | |
7919 | is 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 | |
7921 | functor <literal>F</literal>.</simpara>\r | |
7922 | <programlisting language="sml" linenumbering="unnumbered">val r = ref NONE\r | |
7923 | functor 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 | |
7929 | structure S1 = F (type t = unit -> unit\r | |
7930 | val x = fn () => ())\r | |
7931 | structure S2 = F (type t = int\r | |
7932 | val x = 13)\r | |
7933 | val () = 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 | |
7939 | Error: 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 | |
7947 | Warning: z.sml 6.11-6.13.\r | |
7948 | Type of variable was not inferred and could not be generalized: get.\r | |
7949 | type: unit -> ???\r | |
7950 | in: fun get () = (valOf (! r))\r | |
7951 | Error: 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 | |
7960 | terse and formal specification of <link linkend="StandardML">Standard ML</link>'s syntax\r | |
7961 | and semantics. The language specified by this book is often referred\r | |
7962 | to 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 | |
7964 | Andreas Rossberg).</simpara>\r | |
7965 | <simpara><link linkend="References_MilnerEtAl90">The Definition of Standard ML</link> is an older\r | |
7966 | version of the definition, published in 1990. The accompanying\r | |
7967 | <link linkend="References_MilnerTofte91">Commentary</link> introduces and explains the notation\r | |
7968 | and approach. The same notation is used in the SML 97 definition, so it\r | |
7969 | is worth keeping the older definition and its commentary at hand if you\r | |
7970 | intend 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 | |
7980 | performing:</simpara>\r | |
7981 | <itemizedlist>\r | |
7982 | <listitem>\r | |
7983 | <simpara>\r | |
7984 | linearization\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 | |
7994 | polymorphic <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 | |
8026 | variables that are not bound in the declaration itself. For example,\r | |
8027 | the 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 | |
8036 | to 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 | |
8038 | fun '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 | |
8045 | well as add any free type variables as extra arguments to the type\r | |
8046 | constructor. For example, the above program would be translated to\r | |
8047 | the following.</simpara>\r | |
8048 | <programlisting language="sml" linenumbering="unnumbered">datatype ('a, 'b) t = T of 'a * 'b\r | |
8049 | fun '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 | |
8061 | application. These duties have been adopted by the <link linkend="Elaborate">Elaborate</link>\r | |
8062 | pass.</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 | |
8069 | 2003. From left to right we have:</simpara>\r | |
8070 | <informaltable\r | |
8071 | frame="none"\r | |
8072 | rowsep="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> — <link linkend="MatthewFluet">MatthewFluet</link> — <link linkend="HenryCejtin">HenryCejtin</link> — <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 | |
8096 | contributions there. Here’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 | |
8148 | Access the <link linkend="Sources">Sources</link>.\r | |
8149 | </simpara>\r | |
8150 | </listitem>\r | |
8151 | <listitem>\r | |
8152 | <simpara>\r | |
8153 | Check 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 | |
8158 | Open <ulink url="https://github.com/MLton/mlton/issues">Issues</ulink>.\r | |
8159 | </simpara>\r | |
8160 | </listitem>\r | |
8161 | <listitem>\r | |
8162 | <simpara>\r | |
8163 | Ideas 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 | |
8247 | Using 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 | |
8287 | Help 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 | |
8294 | About 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 | |
8336 | Tools\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 | |
8367 | compilation.</simpara>\r | |
8368 | <itemizedlist>\r | |
8369 | <listitem>\r | |
8370 | <simpara>\r | |
8371 | Large compile-time memory requirement.\r | |
8372 | </simpara>\r | |
8373 | <simpara>Because MLton performs whole-program analysis and optimization,\r | |
8374 | compilation requires a large amount of memory. For example, compiling\r | |
8375 | MLton (over 140K lines) requires at least 512M RAM.</simpara>\r | |
8376 | </listitem>\r | |
8377 | <listitem>\r | |
8378 | <simpara>\r | |
8379 | Long compile times.\r | |
8380 | </simpara>\r | |
8381 | <simpara>Whole-program compilation can take a long time. For example,\r | |
8382 | compiling MLton (over 140K lines) on a 1.6GHz machine takes five to\r | |
8383 | ten minutes.</simpara>\r | |
8384 | </listitem>\r | |
8385 | <listitem>\r | |
8386 | <simpara>\r | |
8387 | No interactive top level.\r | |
8388 | </simpara>\r | |
8389 | <simpara>Because of whole-program compilation, MLton does not provide an\r | |
8390 | interactive top level. In particular, it does not implement the\r | |
8391 | optional <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 | |
8400 | for 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 | |
8402 | support 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 | |
8404 | along 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 | |
8415 | program, 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 | |
8473 | elaborates 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 | |
8478 | of tycons and of structures and then to copy signatures as dags rather\r | |
8479 | than as trees.</simpara>\r | |
8480 | </listitem>\r | |
8481 | <listitem>\r | |
8482 | <simpara>\r | |
8483 | checks functors at the point of definition, using functor summaries\r | |
8484 | to 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 | |
8487 | argument structure and the dummy result structure, as well as all the\r | |
8488 | tycons that were created while elaborating the body. Then, if we\r | |
8489 | later need to type check an application of the functor (as opposed to\r | |
8490 | defunctorize an application), we pair up tycons in the dummy argument\r | |
8491 | structure with the actual argument structure and then replace the\r | |
8492 | dummy tycons with the actual tycons in the dummy result structure,\r | |
8493 | yielding the actual result structure. We also generate new tycons for\r | |
8494 | all the tycons that we created while originally elaborating the body.</simpara>\r | |
8495 | </listitem>\r | |
8496 | <listitem>\r | |
8497 | <simpara>\r | |
8498 | handles opaque signature constraints.\r | |
8499 | </simpara>\r | |
8500 | <simpara>This is implemented by building a dummy structure realized from the\r | |
8501 | signature, just as we would for a functor argument when type checking\r | |
8502 | a functor. The dummy structure contains exactly the type information\r | |
8503 | that is in the signature, which is what opacity requires. We then\r | |
8504 | replace the variables (and constructors) in the dummy structure with\r | |
8505 | the corresponding variables (and constructors) from the actual\r | |
8506 | structure so that the translation to <link linkend="CoreML">CoreML</link> uses the right stuff.\r | |
8507 | For each tycon in the dummy structure, we keep track of the\r | |
8508 | corresponding type structure in the actual structure. This is used\r | |
8509 | when 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><dec></literal> in the <link linkend="StandardML">Standard ML</link> grammar), the <link linkend="Elaborate">Elaborate</link>\r | |
8514 | pass 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 | |
8537 | profiling insertion\r | |
8538 | </simpara>\r | |
8539 | </listitem>\r | |
8540 | <listitem>\r | |
8541 | <simpara>\r | |
8542 | unification\r | |
8543 | </simpara>\r | |
8544 | </listitem>\r | |
8545 | </itemizedlist>\r | |
8546 | </listitem>\r | |
8547 | <listitem>\r | |
8548 | <simpara>\r | |
8549 | Overloaded {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 | |
8558 | assigned 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 | |
8561 | removed. This works because the <link linkend="Elaborate">Elaborate</link> pass assigns a unique\r | |
8562 | name 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 | |
8564 | for 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 | |
8573 | All variables bound in <literal>val</literal> declarations are renamed.\r | |
8574 | </simpara>\r | |
8575 | <programlisting language="sml" linenumbering="unnumbered">val x = 13\r | |
8576 | val y = x</programlisting>\r | |
8577 | <screen>val x_0 = 13\r | |
8578 | val y_0 = x_0</screen>\r | |
8579 | </listitem>\r | |
8580 | <listitem>\r | |
8581 | <simpara>\r | |
8582 | All variables in <literal>fun</literal> declarations are renamed.\r | |
8583 | </simpara>\r | |
8584 | <programlisting language="sml" linenumbering="unnumbered">fun f x = g x\r | |
8585 | and g y = f y</programlisting>\r | |
8586 | <screen>fun f_0 x_0 = g_0 x_0\r | |
8587 | and g_0 y_0 = f_0 y_0</screen>\r | |
8588 | </listitem>\r | |
8589 | <listitem>\r | |
8590 | <simpara>\r | |
8591 | Type abbreviations are removed, and the abbreviation is expanded\r | |
8592 | wherever it is used.\r | |
8593 | </simpara>\r | |
8594 | <programlisting language="sml" linenumbering="unnumbered">type 'a u = int * 'a\r | |
8595 | type 'b t = 'b u * real\r | |
8596 | fun 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 | |
8601 | Exception declarations create a new constructor and rename the type.\r | |
8602 | </simpara>\r | |
8603 | <programlisting language="sml" linenumbering="unnumbered">type t = int\r | |
8604 | exception 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 | |
8609 | The 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 | |
8616 | Local declarations are moved to the top-level. The environment\r | |
8617 | keeps track of the variables in scope.\r | |
8618 | </simpara>\r | |
8619 | <programlisting language="sml" linenumbering="unnumbered">val x = 13\r | |
8620 | local val x = 14\r | |
8621 | in val y = x\r | |
8622 | end\r | |
8623 | val z = x</programlisting>\r | |
8624 | <screen>val x_0 = 13\r | |
8625 | val x_1 = 14\r | |
8626 | val y_0 = x_1\r | |
8627 | val z_0 = x_0</screen>\r | |
8628 | </listitem>\r | |
8629 | <listitem>\r | |
8630 | <simpara>\r | |
8631 | Structure declarations are eliminated, with all declarations moved\r | |
8632 | to 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 | |
8639 | val y : S.t = S.x</programlisting>\r | |
8640 | <screen>val x_0 : int = 13\r | |
8641 | val y_0 : int = x_0</screen>\r | |
8642 | </listitem>\r | |
8643 | <listitem>\r | |
8644 | <simpara>\r | |
8645 | Open declarations are eliminated.\r | |
8646 | </simpara>\r | |
8647 | <programlisting language="sml" linenumbering="unnumbered">val x = 13\r | |
8648 | val y = 14\r | |
8649 | structure S =\r | |
8650 | struct\r | |
8651 | val x = 15\r | |
8652 | end\r | |
8653 | open S\r | |
8654 | val z = x + y</programlisting>\r | |
8655 | <screen>val x_0 = 13\r | |
8656 | val y_0 = 14\r | |
8657 | val x_1 = 15\r | |
8658 | val z_0 = x_1 + y_0</screen>\r | |
8659 | </listitem>\r | |
8660 | <listitem>\r | |
8661 | <simpara>\r | |
8662 | Functor declarations are eliminated, and the body of a functor is\r | |
8663 | duplicated 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 | |
8669 | structure F1 = F(val x = 13)\r | |
8670 | structure F2 = F(val x = 14)\r | |
8671 | val z = F1.y + F2.y</programlisting>\r | |
8672 | <screen>val x_0 = 13\r | |
8673 | val y_0 = x_0\r | |
8674 | val x_1 = 14\r | |
8675 | val y_1 = x_1\r | |
8676 | val z_0 = y_0 + y_1</screen>\r | |
8677 | </listitem>\r | |
8678 | <listitem>\r | |
8679 | <simpara>\r | |
8680 | Signature constraints are eliminated. Note that signatures do\r | |
8681 | affect how subsequent variables are renamed.\r | |
8682 | </simpara>\r | |
8683 | <programlisting language="sml" linenumbering="unnumbered">val y = 13\r | |
8684 | structure 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 | |
8691 | open S\r | |
8692 | val z = x + y</programlisting>\r | |
8693 | <screen>val y_0 = 13\r | |
8694 | val x_0 = 14\r | |
8695 | val y_1 = x_0\r | |
8696 | val 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’t try to indent code\r | |
8741 | based on ML syntax. I gradually got skeptical about this approach\r | |
8742 | after writing the initial indentation support for caml mode and\r | |
8743 | watching it bloat insanely as the language added new features. Also,\r | |
8744 | any such attempts that I know of impose a particular coding style, or\r | |
8745 | at best a choice among a limited set of styles, which I now oppose.\r | |
8746 | Instead my mode is based on a generic package which provides manual\r | |
8747 | bindable commands for common indentation operations (example: indent\r | |
8748 | the current line under the n-th occurrence of a particular character\r | |
8749 | in 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 | |
8768 | MLton can output. It highlights definitions and uses and provides\r | |
8769 | commands 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 | |
8771 | MLton compiler source code. See <link linkend="EmacsDefUseMode">EmacsDefUseMode</link> for further\r | |
8772 | information.</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 | |
8777 | files? Now you don’t have to. See <link linkend="EmacsBgBuildMode">EmacsBgBuildMode</link> for further\r | |
8778 | information.</simpara>\r | |
8779 | </section>\r | |
8780 | <section id="_error_messages">\r | |
8781 | <title>Error messages</title>\r | |
8782 | <simpara>MLton’s error messages are not among those that the Emacs <literal>next-error</literal>\r | |
8783 | parser natively understands. The easiest way to fix this is to add\r | |
8784 | the following to your <literal>.emacs</literal> to teach Emacs to recognize MLton’s\r | |
8785 | error 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 | |
8798 | What if you had a personal slave that would restart a build of your\r | |
8799 | project whenever you save any file belonging to that project? The\r | |
8800 | bg-build mode does just that. Just save the file, a compile is\r | |
8801 | started (silently!), you can continue working without even thinking\r | |
8802 | about 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 | |
8805 | for working with MLton due to the longer compile times. By the time\r | |
8806 | you start wondering about possible errors, the build is already on the\r | |
8807 | way.</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 | |
8813 | Each time a file is saved, and after a user configurable delay\r | |
8814 | period has been exhausted, a build is started silently in the\r | |
8815 | background.\r | |
8816 | </simpara>\r | |
8817 | </listitem>\r | |
8818 | <listitem>\r | |
8819 | <simpara>\r | |
8820 | When the build is finished, a status indicator (message) is\r | |
8821 | displayed non-intrusively.\r | |
8822 | </simpara>\r | |
8823 | </listitem>\r | |
8824 | <listitem>\r | |
8825 | <simpara>\r | |
8826 | At any time, you can switch to a build process buffer where all the\r | |
8827 | messages from the build are shown.\r | |
8828 | </simpara>\r | |
8829 | </listitem>\r | |
8830 | <listitem>\r | |
8831 | <simpara>\r | |
8832 | Optionally highlights (error/warning) message locations in (source\r | |
8833 | code) buffers after a finished build.\r | |
8834 | </simpara>\r | |
8835 | </listitem>\r | |
8836 | <listitem>\r | |
8837 | <simpara>\r | |
8838 | After a build has finished, you can jump to locations of warnings\r | |
8839 | and errors from the build process buffer or by using the <literal>first-error</literal>\r | |
8840 | and <literal>next-error</literal> commands.\r | |
8841 | </simpara>\r | |
8842 | </listitem>\r | |
8843 | <listitem>\r | |
8844 | <simpara>\r | |
8845 | When a build fails, bg-build mode can optionally execute a user\r | |
8846 | specified command. By default, bg-build mode executes <literal>first-error</literal>.\r | |
8847 | </simpara>\r | |
8848 | </listitem>\r | |
8849 | <listitem>\r | |
8850 | <simpara>\r | |
8851 | When starting a build of a particular project, a possible previous\r | |
8852 | live build of the same project is interrupted first.\r | |
8853 | </simpara>\r | |
8854 | </listitem>\r | |
8855 | <listitem>\r | |
8856 | <simpara>\r | |
8857 | A project configuration file specifies the commands required to\r | |
8858 | build a project.\r | |
8859 | </simpara>\r | |
8860 | </listitem>\r | |
8861 | <listitem>\r | |
8862 | <simpara>\r | |
8863 | Multiple projects can be loaded into bg-build mode and bg-build mode\r | |
8864 | can build a given maximum number of projects concurrently.\r | |
8865 | </simpara>\r | |
8866 | </listitem>\r | |
8867 | <listitem>\r | |
8868 | <simpara>\r | |
8869 | Supports 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 | |
8878 | need 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 | |
8884 | files. 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’ll probably also want\r | |
8887 | to 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 | |
8891 | the <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 | |
8895 | regexp that would match MLton’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 | |
8915 | but the details vary. The bg-build mode needs a project configuration file to\r | |
8916 | know how to build your project. A project configuration file basically contains\r | |
8917 | an Emacs Lisp expression calling a function named <literal>bg-build</literal> that returns a\r | |
8918 | project 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 | |
8920 | file 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 | |
8929 | expression that evaluates to a string or to a nullary function that\r | |
8930 | returns 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 | |
8936 | expression that evaluates to a string, a list of strings, or to a\r | |
8937 | nullary 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 | |
8943 | should be built after some files have been modified. The predicate is\r | |
8944 | given a list of filenames and should return a non-nil value when the\r | |
8945 | project 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 | |
8951 | build process is given a lower priority by the system process\r | |
8952 | scheduler. Assuming your machine has enough memory, using nice\r | |
8953 | ensures that your computer remains responsive. (You probably won’t\r | |
8954 | even 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 | |
8957 | mode. The bg-build mode can also optionally load recent project files\r | |
8958 | automatically at startup.</simpara>\r | |
8959 | <simpara>After the project file has been loaded and bg-build mode activated,\r | |
8960 | each time you save a file in Emacs, the bg-build mode tries to build\r | |
8961 | your project.</simpara>\r | |
8962 | <simpara>The <literal>bg-build-status</literal> command creates a buffer that displays some\r | |
8963 | status information on builds and allows you to manage projects (start\r | |
8964 | builds explicitly, remove a project from bg-build, …) as well as\r | |
8965 | visit buffers created by bg-build. Notice the count of started\r | |
8966 | builds. At the end of the day it can be in the hundreds or thousands.\r | |
8967 | Imagine the number of times you’ve been relieved of starting a build\r | |
8968 | explicitly!</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 | |
8976 | locations) and accurate (including all uses and no false data)\r | |
8977 | whole-program def-use information to a file. Unlike typical tags\r | |
8978 | facilities, the information includes local variables and distinguishes\r | |
8979 | between different definitions even when they have the same name. The\r | |
8980 | def-use Emacs mode uses the information to provide navigation support,\r | |
8981 | which can be particularly useful while reading SML programs compiled\r | |
8982 | with 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 | |
9000 | Highlights definitions and uses. Different colors for definitions, unused definitions, and uses.\r | |
9001 | </simpara>\r | |
9002 | </listitem>\r | |
9003 | <listitem>\r | |
9004 | <simpara>\r | |
9005 | Shows types (with highlighting) of variable definitions in the minibuffer.\r | |
9006 | </simpara>\r | |
9007 | </listitem>\r | |
9008 | <listitem>\r | |
9009 | <simpara>\r | |
9010 | Navigation: <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 | |
9015 | Can 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 | |
9020 | Automatically reloads updated def-use files.\r | |
9021 | </simpara>\r | |
9022 | </listitem>\r | |
9023 | <listitem>\r | |
9024 | <simpara>\r | |
9025 | Automatically loads previously used def-use files at startup.\r | |
9026 | </simpara>\r | |
9027 | </listitem>\r | |
9028 | <listitem>\r | |
9029 | <simpara>\r | |
9030 | Supports 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 | |
9038 | has been relatively stable for some time already. To install the mode\r | |
9039 | you need to get the Emacs Lisp, <literal>*.el</literal>, files from MLton’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 | |
9041 | is to use <link linkend="Git">Git</link> to access MLton’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 | |
9046 | find 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’ll probably\r | |
9049 | also 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 | |
9053 | should 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’s makefile\r | |
9058 | or build script so that the def-use information is saved each time the\r | |
9059 | program is compiled. In addition to the <literal>-show-def-use <emphasis>file</emphasis></literal>\r | |
9060 | option, the <literal>-prefer-abs-paths true</literal> expert option is required.\r | |
9061 | Note that the time it takes to save the information is small (compared\r | |
9062 | to type-checking), so it is recommended to simply add the options to\r | |
9063 | the MLton invocation that compiles the program. However, it is only\r | |
9064 | necessary to type check the program (or library), so one can specify\r | |
9065 | the <literal>-stop tc</literal> option. For example, suppose you have a program\r | |
9066 | defined by an MLB file named <literal>my-prg.mlb</literal>, you can save the def-use\r | |
9067 | information 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 | |
9070 | information. This is done with the <literal>esml-du-mlton</literal> command. For\r | |
9071 | example, 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 | |
9074 | previously saved and loaded def-use information, and place the cursor\r | |
9075 | at some variable (definition or use, it doesn’t matter). You should\r | |
9076 | see the variable being highlighted. (Note that specifications in\r | |
9077 | signatures 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 | |
9084 | definitions in revision <ulink url="https://github.com/MLton/mlton/commit/%3A%2FSVN%20r6333"><literal>r6333</literal></ulink>. To get good type names, the\r | |
9085 | types 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 | |
9087 | application 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 | |
9089 | the 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 | |
9096 | PostScript, HTML, and other output languages, applying language\r | |
9097 | sensitive highlighting (similar to <link linkend="Emacs">Emacs</link>'s font lock mode). Here\r | |
9098 | are 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> — 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> — Supersedes\r | |
9110 | the above, adding highlighting of numeric constants. Due to the\r | |
9111 | limited parsing available, numeric record labels are highlighted as\r | |
9112 | numeric constants, in all contexts. Likewise, a binding precedence\r | |
9113 | separated from <literal>infix</literal> or <literal>infixr</literal> by a newline is highlighted as a\r | |
9114 | numeric 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> — Supersedes the\r | |
9123 | above, adding highlighting of type and constructor bindings,\r | |
9124 | highlighting of explicit binding of type variables at <literal>val</literal> and <literal>fun</literal>\r | |
9125 | declarations, and separate highlighting of core and modules level\r | |
9126 | keywords. Due to the limited parsing available, it is assumed that\r | |
9127 | the 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> — Supersedes the\r | |
9135 | above, adding highlighting of type annotations, in both expressions\r | |
9136 | and signatures. Due to the limited parsing available, it is assumed\r | |
9137 | that 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 | |
9146 | Version 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 | |
9151 | Copy 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 | |
9156 | Invoke <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 | |
9163 | Version 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 | |
9168 | Append <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 | |
9173 | Invoke <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 | |
9189 | applied. The <link linkend="DefinitionOfStandardML">Definition</link> and the\r | |
9190 | <link linkend="BasisLibrary">Basis Library</link> precisely spell out which types are\r | |
9191 | equality 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><N></emphasis>.int</literal>, <literal>string</literal>, and <literal>Word<emphasis><N></emphasis>.word</literal> are equality types.\r | |
9196 | </simpara>\r | |
9197 | </listitem>\r | |
9198 | <listitem>\r | |
9199 | <simpara>\r | |
9200 | for 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 | |
9205 | if <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 | |
9210 | if <literal>t1</literal>, …, <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 | |
9215 | if <literal>t1</literal>, …, <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 -> 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 | |
9226 | For example, <literal>ref 13 = ref 13</literal> is <literal>false</literal>.\r | |
9227 | On the other hand, equality for lists, strings, and vectors is by\r | |
9228 | structure, not identity. For example, the following equalities hold.</simpara>\r | |
9229 | <programlisting language="sml" linenumbering="unnumbered">val _ = [1, 2, 3] = 1 :: [2, 3]\r | |
9230 | val _ = "foo" = concat ["f", "o", "o"]\r | |
9231 | val _ = Vector.fromList [1, 2, 3] = Vector.tabulate (3, fn i => 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 | |
9237 | more primes, as in <literal>''a</literal> or <literal>''b</literal>. The canonical use of equality type\r | |
9238 | variables is in specifying the type of the <link linkend="PolymorphicEquality">PolymorphicEquality</link>\r | |
9239 | function, which is <literal>''a * ''a -> bool</literal>. Equality type variables\r | |
9240 | ensure that polymorphic equality is only used on\r | |
9241 | <link linkend="EqualityType">equality types</link>, by requiring that at every use of a\r | |
9242 | polymorphic value, equality type variables are instantiated by\r | |
9243 | equality types.</simpara>\r | |
9244 | <simpara>For example, the following program is type correct because polymorphic\r | |
9245 | equality 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 | |
9248 | polymorphic equality is applied to variables of type <literal>'a</literal>, which is\r | |
9249 | not 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 | |
9252 | equality expects equality types, but didn’t get them.</simpara>\r | |
9253 | <screen>Error: z.sml 1.30-1.34.\r | |
9254 | Function applied to incorrect argument.\r | |
9255 | expects: [<equality>] * [<equality>]\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 | |
9259 | suppose that <literal>f</literal> has polymorphic type <literal>''a -> unit</literal>. Then, <literal>f 13</literal> is\r | |
9260 | type 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 => x)</literal> are not type correct, because <literal>real</literal> and\r | |
9262 | arrow types are not equality types. We can test these facts with the\r | |
9263 | following short programs. First, we verify that such an <literal>f</literal> can be\r | |
9264 | applied to integers.</simpara>\r | |
9265 | <programlisting language="sml" linenumbering="unnumbered">functor Ok (val f: ''a -> 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 | |
9271 | any integer.</simpara>\r | |
9272 | <programlisting language="sml" linenumbering="unnumbered">functor Ok (val f: ''a -> 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’t need to introduce a dummy function name; we can\r | |
9277 | use a type constraint.</simpara>\r | |
9278 | <programlisting language="sml" linenumbering="unnumbered">functor Ok (val f: ''a -> unit): sig end =\r | |
9279 | struct\r | |
9280 | val _ = f: int -> 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 -> unit end):\r | |
9284 | sig val f: int -> unit end = S</programlisting>\r | |
9285 | <simpara>This functor concisely verifies that a function of polymorphic type\r | |
9286 | <literal>''a -> unit</literal> can be safely used as a function of type <literal>int -> unit</literal>.</simpara>\r | |
9287 | <simpara>As above, we can verify that such an <literal>f</literal> can not be used at\r | |
9288 | non-equality types.</simpara>\r | |
9289 | <programlisting language="sml" linenumbering="unnumbered">functor Bad (S: sig val f: ''a -> unit end):\r | |
9290 | sig val f: real -> unit end = S\r | |
9291 | \r | |
9292 | functor Bad (S: sig val f: ''a -> unit end):\r | |
9293 | sig val f: ('a -> 'a) -> 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: [<equality>] -> _\r | |
9298 | defn at: z.sml 1.25-1.25\r | |
9299 | signature: val f: [real] -> _\r | |
9300 | spec at: z.sml 2.12-2.12\r | |
9301 | Error: z.sml 5.4-5.36.\r | |
9302 | Variable in structure disagrees with signature (type): f.\r | |
9303 | structure: val f: [<equality>] -> _\r | |
9304 | defn at: z.sml 4.25-4.25\r | |
9305 | signature: val f: [_ -> _] -> _\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 | |
9310 | however 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 | |
9315 | applied 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 => e z</literal>, where <literal>z</literal> does not occur in <literal>e</literal>. This only\r | |
9329 | makes sense if <literal>e</literal> denotes a function, i.e. is of arrow type. Eta\r | |
9330 | expansion delays the evaluation of <literal>e</literal> until the function is\r | |
9331 | applied, and will re-evaluate <literal>e</literal> each time the function is\r | |
9332 | applied.</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 | |
9335 | directionality of the equivalence being used, namely taking <literal>e</literal> to\r | |
9336 | <literal>fn z => e z</literal> rather than <literal>fn z => e z</literal> to <literal>e</literal> (eta\r | |
9337 | contraction).</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 | |
9343 | multi-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 | |
9351 | Since we try to make as much information as possible available on the\r | |
9352 | web site and we like to avoid duplication, many of the answers are\r | |
9353 | simply 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’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 | |
9374 | counterpart (e.g. <literal>bool array</literal>, <literal>Word8.word vector</literal>). Thus, there is\r | |
9375 | no need to use the monomorphic versions except when required to\r | |
9376 | interface with the <link linkend="BasisLibrary">Basis Library</link> or for portability\r | |
9377 | with 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 | |
9388 | Compile with <literal>-verbose 3</literal> to find out if the problem is due to an\r | |
9389 | SSA optimization pass. If so, compile with <literal>-disable-pass <emphasis>pass</emphasis></literal> to\r | |
9390 | skip that pass.\r | |
9391 | </simpara>\r | |
9392 | </listitem>\r | |
9393 | <listitem>\r | |
9394 | <simpara>\r | |
9395 | Compile with <literal>@MLton hash-cons 0.5 --</literal>, which will instruct the\r | |
9396 | runtime to hash cons the heap every other GC.\r | |
9397 | </simpara>\r | |
9398 | </listitem>\r | |
9399 | <listitem>\r | |
9400 | <simpara>\r | |
9401 | Compile with <literal>-polyvariance false</literal>, which is an undocumented option\r | |
9402 | that 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 | |
9407 | better understand MLton’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 | |
9423 | Runs 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, …)\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, …)\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, …)\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 | |
9635 | Supports 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 | |
9639 | program that is invalid according to the\r | |
9640 | <link linkend="DefinitionOfStandardML">Definition</link> that is accepted by MLton, it is\r | |
9641 | a bug. For a list of known bugs, see <link linkend="UnresolvedBugs">UnresolvedBugs</link>.</simpara>\r | |
9642 | </listitem>\r | |
9643 | <listitem>\r | |
9644 | <simpara>\r | |
9645 | A complete implementation of the <link linkend="BasisLibrary">Basis Library</link>.\r | |
9646 | </simpara>\r | |
9647 | <simpara>MLton’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 | |
9649 | complete implementation of all the required modules, as well as many\r | |
9650 | of the optional modules.</simpara>\r | |
9651 | </listitem>\r | |
9652 | <listitem>\r | |
9653 | <simpara>\r | |
9654 | Generates standalone executables.\r | |
9655 | </simpara>\r | |
9656 | <simpara>No additional code or libraries are necessary in order to run an\r | |
9657 | executable, except for the standard shared libraries. MLton can also\r | |
9658 | generate statically linked executables.</simpara>\r | |
9659 | </listitem>\r | |
9660 | <listitem>\r | |
9661 | <simpara>\r | |
9662 | Compiles large programs.\r | |
9663 | </simpara>\r | |
9664 | <simpara>MLton is sufficiently efficient and robust that it can compile large\r | |
9665 | programs, including itself (over 190K lines). The distributed version\r | |
9666 | of MLton was compiled by MLton.</simpara>\r | |
9667 | </listitem>\r | |
9668 | <listitem>\r | |
9669 | <simpara>\r | |
9670 | Support 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 | |
9675 | Support 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 | |
9680 | Support 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 | |
9690 | Executables have <link linkend="Performance">excellent running times</link>.\r | |
9691 | </simpara>\r | |
9692 | </listitem>\r | |
9693 | <listitem>\r | |
9694 | <simpara>\r | |
9695 | Generates small executables.\r | |
9696 | </simpara>\r | |
9697 | <simpara>MLton takes advantage of whole-program compilation to perform very\r | |
9698 | aggressive dead-code elimination, which often leads to smaller\r | |
9699 | executables than with other SML compilers.</simpara>\r | |
9700 | </listitem>\r | |
9701 | <listitem>\r | |
9702 | <simpara>\r | |
9703 | Untagged 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 | |
9706 | and arithmetic does not have any overhead due to tagging or boxing.\r | |
9707 | Also, reals (32-bit and 64-bit) are stored unboxed, avoiding any\r | |
9708 | overhead due to boxing.</simpara>\r | |
9709 | </listitem>\r | |
9710 | <listitem>\r | |
9711 | <simpara>\r | |
9712 | Unboxed native arrays.\r | |
9713 | </simpara>\r | |
9714 | <simpara>In MLton, an array (or vector) of integers, reals, or words uses the\r | |
9715 | natural C-like representation. This is fast and supports easy\r | |
9716 | exchange of data with C. Monomorphic arrays (and vectors) use the\r | |
9717 | same C-like representations as their polymorphic counterparts.</simpara>\r | |
9718 | </listitem>\r | |
9719 | <listitem>\r | |
9720 | <simpara>\r | |
9721 | Multiple <link linkend="GarbageCollection">garbage collection</link> strategies.\r | |
9722 | </simpara>\r | |
9723 | </listitem>\r | |
9724 | <listitem>\r | |
9725 | <simpara>\r | |
9726 | Fast 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 | |
9729 | more 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 | |
9738 | Source-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 | |
9763 | A 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 | |
9768 | The <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 | |
9773 | A number of extension libraries that provide useful functionality\r | |
9774 | that cannot be implemented with the <link linkend="BasisLibrary">Basis Library</link>.\r | |
9775 | See 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 | |
9819 | a separate MLton thread, and have access to the thread that was\r | |
9820 | interrupted by the signal. Signal handlers can be used in conjunction\r | |
9821 | with 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 | |
9828 | object. This can be useful in understanding the space behavior of a\r | |
9829 | program.</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 | |
9842 | non-preemptive multitasking can be implemented. MLton also has\r | |
9843 | support 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 | |
9850 | reclaim objects that it would otherwise be forced to keep. Weak\r | |
9851 | pointers 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 | |
9858 | file and restarting it later. This facility can be used for staging\r | |
9859 | and for checkpointing computations. It can even be used from within\r | |
9860 | signal 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 | |
9871 | just like other values: pass them as arguments, store them in data\r | |
9872 | structures, etc. Although <link linkend="StandardML">Standard ML</link> does have\r | |
9873 | polymorphic 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 => x\r | |
9877 | val _ = id 13\r | |
9878 | val _ = id "foo"</programlisting>\r | |
9879 | <simpara>If SML supported first-class polymorphism, we could write the\r | |
9880 | following.</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 | |
9889 | accepts 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 -> '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 | |
9898 | Error: 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 | |
9904 | rather, it is monomorphic, with type <literal>'a -> 'a</literal>. It is perfectly\r | |
9905 | valid 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 -> '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 | |
9908 | the following two declarations?</simpara>\r | |
9909 | <programlisting language="sml" linenumbering="unnumbered">val id: 'a -> 'a = fn x => x\r | |
9910 | fun useId (id: 'a -> 'a) = (id 13; id "foo")</programlisting>\r | |
9911 | <simpara>While the type specifications on <literal>id</literal> look identical, they mean\r | |
9912 | different 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 -> 'a = fn x => x\r | |
9915 | fun 'a useId (id: 'a -> '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 -> 'a</literal>. Hence, <literal>id</literal> can be applied to arguments of\r | |
9918 | type <literal>int</literal>, <literal>real</literal>, etc. Similarly, in <literal>fun 'a useId</literal>, the scoping\r | |
9919 | means that <literal>useId</literal> is a polymorphic function that for any <literal>'a</literal> takes a\r | |
9920 | function of type <literal>'a -> 'a</literal> and does something. Thus, <literal>useId</literal> could\r | |
9921 | be applied to a function of type <literal>int -> int</literal>, <literal>real -> real</literal>, etc.</simpara>\r | |
9922 | <simpara>One could imagine an extension of SML that allowed scoping of type\r | |
9923 | variables at places other than <literal>fun</literal> or <literal>val</literal> declarations, as in the\r | |
9924 | following.</simpara>\r | |
9925 | <screen>fun useId (id: ('a).'a -> 'a) = (id 13; id "foo") (* not SML *)</screen>\r | |
9926 | <simpara>Such an extension would need to be thought through very carefully, as\r | |
9927 | it could cause significant complications with <link linkend="TypeInference">TypeInference</link>,\r | |
9928 | possible 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 | |
9934 | fixpoints over arbitrary products of abstract types. The code is from\r | |
9935 | an 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 -> t) -> 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 -> u) -> 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 | |
9952 | signature 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 -> '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 | *> val isEven & isOdd =\r | |
9963 | *> let open Tie in fix (function *` function) end\r | |
9964 | *> (fn isEven & isOdd =>\r | |
9965 | *> (fn 0 => true\r | |
9966 | *> | 1 => false\r | |
9967 | *> | n => isOdd (n-1)) &\r | |
9968 | *> (fn 0 => false\r | |
9969 | *> | 1 => true\r | |
9970 | *> | n => isEven (n-1)))\r | |
9971 | *)\r | |
9972 | \r | |
9973 | (** == Making New Witnesses == *)\r | |
9974 | \r | |
9975 | val pure : ('a * 'a UnOp.t) Thunk.t -> '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 -> '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 -> '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 -> ('a, 'b) Iso.t -> '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 -> 'b t) -> ('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 -> ('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 -> ('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 -> 'b) t\r | |
10021 | (** Witness for functions. *)\r | |
10022 | end</programlisting>\r | |
10023 | <simpara><literal>fix</literal> is a <link linkend="TypeIndexedValues">type-indexed</link> function. The type-index\r | |
10024 | parameter to <literal>fix</literal> is called a "witness". To compute fixpoints over\r | |
10025 | products, one uses the <literal>*`</literal> operator to combine witnesses. To provide\r | |
10026 | a fixpoint combinator for an abstract type, one implements a witness\r | |
10027 | providing a thunk whose instantiation allocates a fresh, mutable proxy\r | |
10028 | and a procedure for updating the proxy with the solution. Naturally\r | |
10029 | this means that not all possible ways of computing a fixpoint of a\r | |
10030 | particular type are possible under the framework. The <literal>pure</literal>\r | |
10031 | combinator is a generalization of <literal>tier</literal>. The <literal>iso</literal> combinator is\r | |
10032 | provided for reusing existing witnesses.</simpara>\r | |
10033 | <simpara>Note that instead of using an infix operator, we could alternatively\r | |
10034 | employ an interface using <link linkend="Fold">Fold</link>. Also, witnesses are eta-expanded\r | |
10035 | to work around the <link linkend="ValueRestriction">value restriction</link>, while\r | |
10036 | maintaining 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 :> TIE = struct\r | |
10040 | open Product\r | |
10041 | infix &\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 -> '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 & 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) => (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 () => let\r | |
10066 | val r = ref (Basic.raising Fix.Fix)\r | |
10067 | in\r | |
10068 | (fn x => !r x, fn f => (r := f ; f))\r | |
10069 | end) ?\r | |
10070 | end</programlisting>\r | |
10071 | <simpara>Let’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 :> sig\r | |
10074 | type 'a t\r | |
10075 | val lazy : 'a Thunk.t -> 'a t\r | |
10076 | val force : 'a t -> 'a\r | |
10077 | val Y : 'a t Tie.t\r | |
10078 | end = 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 => raise e\r | |
10088 | | THUNK f => (t := VALUE (f ()) handle e => t := EXN e ; force t)\r | |
10089 | | VALUE v => v\r | |
10090 | fun Y ? = Tie.tier (fn () => let\r | |
10091 | val r = lazy (raising Fix.Fix)\r | |
10092 | in\r | |
10093 | (r, r <\ op := o !)\r | |
10094 | end) ?\r | |
10095 | end</programlisting>\r | |
10096 | <simpara>An example use of our naive lazy promises is to implement equally naive\r | |
10097 | lazy streams:</simpara>\r | |
10098 | <programlisting language="sml" linenumbering="unnumbered">structure Stream :> sig\r | |
10099 | type 'a t\r | |
10100 | val cons : 'a * 'a t -> 'a t\r | |
10101 | val get : 'a t -> ('a * 'a t) Option.t\r | |
10102 | val Y : 'a t Tie.t\r | |
10103 | end = 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 () => SOME (x, xs)))\r | |
10106 | fun get (IN p) = Promise.force p\r | |
10107 | fun Y ? = Tie.iso Promise.Y (fn IN p => p, IN) ?\r | |
10108 | end</programlisting>\r | |
10109 | <simpara>Note that above we make use of the <literal>iso</literal> combinator. Here is a finite\r | |
10110 | representation of an infinite stream of ones:</simpara>\r | |
10111 | <programlisting language="sml" linenumbering="unnumbered">val ones = let\r | |
10112 | open Tie Stream\r | |
10113 | in\r | |
10114 | fix Y (fn ones => cons (1, ones))\r | |
10115 | end</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 | |
10125 | functions.</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 | |
10131 | The formals and call sites are changed so that the components of the\r | |
10132 | tuple are passed.\r | |
10133 | </simpara>\r | |
10134 | </listitem>\r | |
10135 | <listitem>\r | |
10136 | <simpara>\r | |
10137 | The tuple is reconstructed at the beginning of the body of the\r | |
10138 | function (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 | |
10143 | constructor, then:</simpara>\r | |
10144 | <itemizedlist>\r | |
10145 | <listitem>\r | |
10146 | <simpara>\r | |
10147 | The constructor argument datatype is changed to flatten the tuple\r | |
10148 | type.\r | |
10149 | </simpara>\r | |
10150 | </listitem>\r | |
10151 | <listitem>\r | |
10152 | <simpara>\r | |
10153 | The tuple is passed flat at each <literal>ConApp</literal>.\r | |
10154 | </simpara>\r | |
10155 | </listitem>\r | |
10156 | <listitem>\r | |
10157 | <simpara>\r | |
10158 | The 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 | |
10182 | number 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 | |
10187 | and (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 | |
10189 | and <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 | |
10193 | where <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 | |
10195 | step of the fold. The name <literal>$</literal> is chosen to mean "end of\r | |
10196 | arguments" 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 | |
10198 | over each element in the list, this fold allows the step functions to\r | |
10199 | be different from each other, and even to be of different types. Also\r | |
10200 | unlike the usual list fold, this fold includes a "finishing\r | |
10201 | function", <literal>f</literal>, that is applied to the result of the fold. The\r | |
10202 | presence of the finishing function may seem odd because there is no\r | |
10203 | analogy in list fold. However, the finishing function is essential;\r | |
10204 | without it, there would be no way for the folder to perform an\r | |
10205 | arbitrary computation after processing all the arguments. The\r | |
10206 | examples below will make this clear.</simpara>\r | |
10207 | <simpara>The functions <literal>fold</literal>, <literal>step0</literal>, and <literal>$</literal> are easy to\r | |
10208 | define.</simpara>\r | |
10209 | <programlisting language="sml" linenumbering="unnumbered">fun $ (a, f) = f a\r | |
10210 | fun id x = x\r | |
10211 | structure 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’ve placed <literal>fold</literal> and <literal>step0</literal> in the <literal>Fold</literal> structure\r | |
10217 | but left <literal>$</literal> at the toplevel because it is convenient in code to\r | |
10218 | always have <literal>$</literal> in scope. We’ve also defined the identity\r | |
10219 | function, <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 | |
10221 | above.</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’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 | |
10237 | f a $\r | |
10238 | f a a $\r | |
10239 | f a a a $\r | |
10240 | f 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 | |
10242 | are type correct SML — how can a function <literal>f</literal> accept a variable\r | |
10243 | number of curried arguments? What could the type of <literal>f</literal> be?\r | |
10244 | We’ll have more to say later on how type checking works. For now,\r | |
10245 | once we have supplied the definitions below, you can check that the\r | |
10246 | expressions are type correct by feeding them to your favorite SML\r | |
10247 | implementation.</simpara>\r | |
10248 | <simpara>It is simple to define <literal>f</literal> and <literal>a</literal>. We define <literal>f</literal> as a\r | |
10249 | folder whose base element is <literal>()</literal> and whose finish function does\r | |
10250 | nothing. We define <literal>a</literal> as the step function that does nothing.\r | |
10251 | The only trickiness is that we must <link linkend="EtaExpansion">eta expand</link> the\r | |
10252 | definition of <literal>f</literal> and <literal>a</literal> to work around the ValueRestriction;\r | |
10253 | we frequently use eta expansion for this purpose without mention.</simpara>\r | |
10254 | <programlisting language="sml" linenumbering="unnumbered">val base = ()\r | |
10255 | fun finish () = ()\r | |
10256 | fun step () = ()\r | |
10257 | val f = fn z => Fold.fold (base, finish) z\r | |
10258 | val a = fn z => Fold.step0 step z</programlisting>\r | |
10259 | <simpara>One can easily apply the fold equation to verify by hand that <literal>f</literal>\r | |
10260 | applied 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’s look at an example that computes something: a variable-argument\r | |
10271 | function <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 — 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 | |
10275 | which the folder simply returns at the end.</simpara>\r | |
10276 | <programlisting language="sml" linenumbering="unnumbered">val sum = fn z => Fold.fold (0, fn s => s) z\r | |
10277 | fun a i = Fold.step0 (fn s => 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 | |
10284 | around the steps in a fold. This is easily done by defining a new\r | |
10285 | function, <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 | |
10292 | equivalence.</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 | |
10304 | product function, <literal>prod</literal>, with a convenient syntax.</simpara>\r | |
10305 | <programlisting language="sml" linenumbering="unnumbered">val prod = fn z => Fold.fold (1, fn p => p) z\r | |
10306 | val ` = fn z => Fold.step1 (fn (i, p) => i * p) z</programlisting>\r | |
10307 | <simpara>The functions <literal>prod</literal> and <literal>`</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>`i1</literal> is two different tokens, <literal>`</literal> and\r | |
10310 | <literal>i1</literal>. We often use <literal>`</literal> for an instance of a <literal>step1</literal> function\r | |
10311 | because of its syntactic unobtrusiveness and because no space is\r | |
10312 | required to separate it from an alphanumeric token.</simpara>\r | |
10313 | <simpara>Also note that there are no parenthesis around the steps. That is,\r | |
10314 | the following expression is not the same as the above one (in fact, it\r | |
10315 | is 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 | |
10321 | However, using fold, we can define our own syntax.</simpara>\r | |
10322 | <programlisting language="sml" linenumbering="unnumbered">val list = fn z => Fold.fold ([], rev) z\r | |
10323 | val ` = fn z => Fold.step1 (op ::) z</programlisting>\r | |
10324 | <simpara>The idea is that the folder starts out with the empty list, the steps\r | |
10325 | accumulate the elements into a list, and then the finishing function\r | |
10326 | reverses 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 | |
10330 | need for the finishing function to be incorporated in <literal>fold</literal>.\r | |
10331 | Without a finishing function, every use of <literal>list</literal> would need to be\r | |
10332 | wrapped 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 | |
10335 | definition of <literal>list</literal>, and to treat <literal>list</literal> as a truly variable\r | |
10336 | argument function, performing an arbitrary computation after receiving\r | |
10337 | all 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 | |
10339 | syntax 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 | |
10344 | are applied to the accumulator left-to-right, we can define a variant\r | |
10345 | of <literal>fold</literal> that is analogous to a fold right, in which the\r | |
10346 | functions are applied to the accumulator right-to-left. That is, we\r | |
10347 | can define functions <literal>foldr</literal> and <literal>step0</literal> such that the\r | |
10348 | following 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 | |
10352 | the fold to start with <literal>f</literal> and for each step to precompose the\r | |
10353 | next <literal>hi</literal>. Then, the finisher applies the composed function to\r | |
10354 | the 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 => g a)\r | |
10358 | fun step0 h = Fold.step0 (fn g => g o h)\r | |
10359 | end</programlisting>\r | |
10360 | <simpara>Verifying the fold-right equation is straightforward, using the\r | |
10361 | fold-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 => g a)\r | |
10364 | (Fold.step0 (fn g => g o h1))\r | |
10365 | (Fold.step0 (fn g => g o h2))\r | |
10366 | ...\r | |
10367 | (Fold.step0 (fn g => g o hn)) $\r | |
10368 | = (fn g => g a)\r | |
10369 | ((fn g => g o hn) (... ((fn g => g o h2) ((fn g => g o h1) f))))\r | |
10370 | = (fn g => g a)\r | |
10371 | ((fn g => g o hn) (... ((fn g => g o h2) (f o h1))))\r | |
10372 | = (fn g => g a) ((fn g => g o hn) (... (f o h1 o h2)))\r | |
10373 | = (fn g => 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) => g o (fn a => 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 | |
10386 | right to define a syntax for list literals that doesn’t do a reversal.</simpara>\r | |
10387 | <programlisting language="sml" linenumbering="unnumbered">val list = fn z => Foldr.foldr ([], fn l => l) z\r | |
10388 | val ` = fn z => 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 | |
10392 | the fold-right approach does not have to reverse the list at the end,\r | |
10393 | since it accumulates the elements in the correct order. In practice,\r | |
10394 | MLton will simplify away all of the intermediate function composition,\r | |
10395 | so 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 | |
10400 | a fold. This need not be the case. For example, consider the\r | |
10401 | following.</simpara>\r | |
10402 | <programlisting language="sml" linenumbering="unnumbered">val n = fn z => Fold.fold (0, fn i => i) z\r | |
10403 | val I = fn z => Fold.step0 (fn i => i * 2) z\r | |
10404 | val O = fn z => Fold.step0 (fn i => i * 2 + 1) z</programlisting>\r | |
10405 | <simpara>Here we have one folder, <literal>n</literal>, that can be used with two different\r | |
10406 | steppers, <literal>I</literal> and <literal>O</literal>. By using the fold equation, one can\r | |
10407 | verify the following equations.</simpara>\r | |
10408 | <programlisting language="sml" linenumbering="unnumbered">n O $ = 0\r | |
10409 | n I $ = 1\r | |
10410 | n I O $ = 2\r | |
10411 | n I O I $ = 5\r | |
10412 | n I I I O $ = 14</programlisting>\r | |
10413 | <simpara>That is, we’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 | |
10415 | fold, one can also intermix uses of <literal>step0</literal> and <literal>step1</literal>. For\r | |
10416 | example, consider the following.</simpara>\r | |
10417 | <programlisting language="sml" linenumbering="unnumbered">val n = fn z => Fold.fold (0, fn i => i) z\r | |
10418 | val O = fn z => Fold.step0 (fn i => n * 8) z\r | |
10419 | val ` = fn z => Fold.step1 (fn (i, n) => n * 8 + i) z</programlisting>\r | |
10420 | <simpara>Using the straightforward generalization of the fold equation to mixed\r | |
10421 | steppers, one can verify the following equations.</simpara>\r | |
10422 | <programlisting language="sml" linenumbering="unnumbered">n 0 $ = 0\r | |
10423 | n `3 O $ = 24\r | |
10424 | n `1 O `7 $ = 71</programlisting>\r | |
10425 | <simpara>That is, we’ve defined a syntax for writing octal integer constants,\r | |
10426 | with a special syntax, <literal>O</literal>, for the zero digit (admittedly\r | |
10427 | contrived, since one could just write <literal>`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 | |
10429 | supports 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 | |
10434 | elements are in the list or how long the list is. Variable-argument\r | |
10435 | fold is more powerful, because the result type can vary based both on\r | |
10436 | the arguments that are passed and on their number. This can provide\r | |
10437 | the 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 => Fold.fold ((), id) z\r | |
10440 | val a = fn z => Fold.step0 (fn () => "hello") z\r | |
10441 | val b = fn z => Fold.step0 (fn () => 13) z\r | |
10442 | val c = fn z => Fold.step0 (fn () => (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 | |
10445 | f b $ = 13: int\r | |
10446 | f c $ = (1, 2): int * int</programlisting>\r | |
10447 | <simpara>That is, <literal>f</literal> returns a value of a different type depending on\r | |
10448 | whether it is applied to argument <literal>a</literal>, argument <literal>b</literal>, or\r | |
10449 | argument <literal>c</literal>.</simpara>\r | |
10450 | <simpara>The following example shows how the type of a fold can depend on the\r | |
10451 | number of arguments.</simpara>\r | |
10452 | <programlisting language="sml" linenumbering="unnumbered">val grow = fn z => Fold.fold ([], fn l => l) z\r | |
10453 | val a = fn z => Fold.step0 (fn x => [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 | |
10456 | grow a $ = [[]]: 'a list list\r | |
10457 | grow 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 | |
10459 | function 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 | |
10461 | implementation.</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 | |
10466 | arity depends on the number of arguments. For example, consider the\r | |
10467 | following.</simpara>\r | |
10468 | <programlisting language="sml" linenumbering="unnumbered">val makeSum = fn z => Fold.fold (id, fn f => f 0) z\r | |
10469 | val I = fn z => Fold.step0 (fn f => fn i => fn x => f (x + i)) z</programlisting>\r | |
10470 | <simpara>The <literal>makeSum</literal> folder constructs a function whose arity depends on\r | |
10471 | the number of <literal>I</literal> arguments and that adds together all of its\r | |
10472 | arguments. For example,\r | |
10473 | <literal>makeSum I $</literal> is of type <literal>int -> int</literal> and\r | |
10474 | <literal>makeSum I I $</literal> is of type <literal>int -> int -> int</literal>.</simpara>\r | |
10475 | <simpara>One can use the fold equation to verify that the <literal>makeSum</literal> works\r | |
10476 | correctly. For example, one can easily check by hand the following\r | |
10477 | equations.</simpara>\r | |
10478 | <programlisting language="sml" linenumbering="unnumbered">makeSum I $ 1 = 1\r | |
10479 | makeSum I I $ 1 2 = 3\r | |
10480 | makeSum I I I $ 1 2 3 = 6</programlisting>\r | |
10481 | <simpara>Returning a function becomes especially interesting when there are\r | |
10482 | steppers of different types. For example, the following <literal>makeSum</literal>\r | |
10483 | folder constructs functions that sum integers and reals.</simpara>\r | |
10484 | <programlisting language="sml" linenumbering="unnumbered">val makeSum = fn z => Foldr.foldr (id, fn f => f 0.0) z\r | |
10485 | val I = fn z => Foldr.step0 (fn f => fn x => fn i => f (x + real i)) z\r | |
10486 | val R = fn z => Foldr.step0 (fn f => fn x: real => fn r => f (x + r)) z</programlisting>\r | |
10487 | <simpara>With these definitions, <literal>makeSum I R $</literal> is of type\r | |
10488 | <literal>int -> real -> real</literal> and <literal>makeSum R I I $</literal> is of type\r | |
10489 | <literal>real -> int -> int -> real</literal>. One can use the foldr equation to\r | |
10490 | check the following equations.</simpara>\r | |
10491 | <programlisting language="sml" linenumbering="unnumbered">makeSum I $ 1 = 1.0\r | |
10492 | makeSum I R $ 1 2.5 = 3.5\r | |
10493 | makeSum 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 | |
10495 | in which the specifiers <literal>I</literal> and <literal>R</literal> appear is the same as the\r | |
10496 | order in which the arguments appear. Had we used <literal>fold</literal>, things\r | |
10497 | would have been reversed.</simpara>\r | |
10498 | <simpara>An extension of this idea is sufficient to define <link linkend="Printf">Printf</link>-like\r | |
10499 | functions 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 | |
10504 | them as a single step. As a simple example, suppose that one often\r | |
10505 | sees an integer follower by a real in the <literal>makeSum</literal> example above.\r | |
10506 | One 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 => 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>, … <literal>sn</literal> as</simpara>\r | |
10511 | <programlisting language="sml" linenumbering="unnumbered">fn u => Fold.fold u s1 s2 ... sn</programlisting>\r | |
10512 | <simpara>The following calculation shows why a compound step behaves as the\r | |
10513 | composition of its constituent steps.</simpara>\r | |
10514 | <programlisting language="sml" linenumbering="unnumbered">fold u (fn u => fold u s1 s2 ... sn)\r | |
10515 | = (fn u => 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 | |
10522 | function that is like <literal>w</literal>, but applies <literal>g</literal> to the result\r | |
10523 | produced by <literal>w</literal>. This is similar to function composition, but we\r | |
10524 | can’t just do <literal>g o w</literal>, because we don’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 | |
10526 | end-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) => s (a, g o h))\r | |
10535 | end</programlisting>\r | |
10536 | <simpara>The following calculations show that <literal>post</literal> satisfies the desired\r | |
10537 | equation, 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) => s (a, g o h))\r | |
10540 | = fold (a, f) (fn (a, h) => s (a, g o h))\r | |
10541 | = (fn (a, h) => 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 | |
10556 | equationally speaking, equivalent to the identity function on a step\r | |
10557 | function.</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 | |
10573 | lies in the typing of fold expressions, which we have, until now, left\r | |
10574 | unexplained.</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 | |
10579 | by the SML type system. The types involved in fold expressions are\r | |
10580 | complex; fortunately type inference is able to deduce them.\r | |
10581 | Nevertheless, it is instructive to study the types of fold functions\r | |
10582 | and steppers. More importantly, it is essential to understand the\r | |
10583 | typing aspects of fold in order to write down signatures of functions\r | |
10584 | defined 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 -> 'c) -> 'd\r | |
10590 | type ('a, 'b, 'c, 'd) t = ('a, 'b, 'c, 'd) step -> '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 -> ('a2, 'b, 'c, 'd) t) step\r | |
10595 | \r | |
10596 | val fold: 'a * ('b -> 'c) -> ('a, 'b, 'c, 'd) t\r | |
10597 | val lift0: ('a1, 'a2, 'a2, 'a2, 'a2) step0\r | |
10598 | -> ('a1, 'a2, 'b, 'c, 'd) step0\r | |
10599 | val post: ('a, 'b, 'c1, 'd) t * ('c1 -> 'c2)\r | |
10600 | -> ('a, 'b, 'c2, 'd) t\r | |
10601 | val step0: ('a1 -> 'a2) -> ('a1, 'a2, 'b, 'c, 'd) step0\r | |
10602 | val step1: ('a11 * 'a12 -> 'a2)\r | |
10603 | -> ('a11, 'a12, 'a2, 'b, 'c, 'd) step1\r | |
10604 | end\r | |
10605 | \r | |
10606 | structure Fold:> FOLD =\r | |
10607 | struct\r | |
10608 | type ('a, 'b, 'c, 'd) step = 'a * ('b -> 'c) -> 'd\r | |
10609 | \r | |
10610 | type ('a, 'b, 'c, 'd) t = ('a, 'b, 'c, 'd) step -> '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 -> ('a2, 'b, 'c, 'd) t) step\r | |
10617 | \r | |
10618 | fun fold (a: 'a, f: 'b -> 'c)\r | |
10619 | (g: ('a, 'b, 'c, 'd) step): 'd =\r | |
10620 | g (a, f)\r | |
10621 | \r | |
10622 | fun step0 (h: 'a1 -> 'a2)\r | |
10623 | (a1: 'a1, f: 'b -> 'c): ('a2, 'b, 'c, 'd) t =\r | |
10624 | fold (h a1, f)\r | |
10625 | \r | |
10626 | fun step1 (h: 'a11 * 'a12 -> 'a2)\r | |
10627 | (a12: 'a12, f: 'b -> '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 -> '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 -> 'c2)\r | |
10637 | (s: ('a, 'b, 'c2, 'd) step): 'd =\r | |
10638 | w (fn (a, h) => s (a, g o h))\r | |
10639 | end</programlisting>\r | |
10640 | <simpara>That’s a lot to swallow, so let’s walk through it one step at a time.\r | |
10641 | First, 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 -> 'c) -> 'd</programlisting>\r | |
10643 | <simpara>As a fold proceeds over its arguments, it maintains two things: the\r | |
10644 | accumulator, of type <literal>'a</literal>, and the finishing function, of type\r | |
10645 | <literal>'b -> 'c</literal>. Each step in the fold is a function that takes those\r | |
10646 | two pieces (i.e. <literal>'a * ('b -> 'c)</literal> and does something to them\r | |
10647 | (i.e. produces <literal>'d</literal>). The result type of the step is completely\r | |
10648 | left open to be filled in by type inference, as it is an arrow type\r | |
10649 | that 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 | |
10651 | step.</simpara>\r | |
10652 | <programlisting language="sml" linenumbering="unnumbered">type ('a, 'b, 'c, 'd) t = ('a, 'b, 'c, 'd) step -> '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 -> 'c) -> 'd) -> 'd</programlisting>\r | |
10655 | <simpara>This shows that the only thing a folder does is to hand its\r | |
10656 | accumulator (<literal>'a</literal>) and finisher (<literal>'b -> 'c</literal>) to the next step\r | |
10657 | (<literal>'a * ('b -> 'c) -> 'd</literal>). If SML had <link linkend="FirstClassPolymorphism">first-class polymorphism</link>,\r | |
10658 | we 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 -> 'd</programlisting>\r | |
10660 | <simpara>This type definition shows that a folder had nothing to do with\r | |
10661 | the 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 | |
10663 | value of the accumulator and the finishing function, and constructs a\r | |
10664 | folder, i.e. a function awaiting the next step.</simpara>\r | |
10665 | <programlisting language="sml" linenumbering="unnumbered">val fold: 'a * ('b -> 'c) -> ('a, 'b, 'c, 'd) t\r | |
10666 | fun fold (a: 'a, f: 'b -> '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 -> 'c) -> ('a2, 'b, 'c, 'd) t</programlisting>\r | |
10675 | <simpara>So, a step function takes the accumulator (<literal>'a1</literal>) and finishing\r | |
10676 | function (<literal>'b -> 'c</literal>), which will be passed to it by the previous\r | |
10677 | folder, and transforms them to a new folder. This new folder has a\r | |
10678 | new 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 | |
10680 | clearer.</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 | |
10684 | function of type <literal>'a1 -> 'a2</literal>, which is exactly what the\r | |
10685 | definition of <literal>step0</literal> does.</simpara>\r | |
10686 | <programlisting language="sml" linenumbering="unnumbered">val step0: ('a1 -> 'a2) -> ('a1, 'a2, 'b, 'c, 'd) step0\r | |
10687 | fun step0 (h: 'a1 -> 'a2)\r | |
10688 | (a1: 'a1, f: 'b -> '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 -> ('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 -> 'c</literal>) passed to it by the previous folder and transforms\r | |
10695 | them into a function that consumes the next argument (<literal>'a11</literal>) and\r | |
10696 | produces 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 -> 'a2)\r | |
10699 | (a12: 'a12, f: 'b -> '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 | |
10703 | seen as a wrapper around a binary function of type\r | |
10704 | <literal>'a11 * 'a12 -> 'a2</literal>.</simpara>\r | |
10705 | <programlisting language="sml" linenumbering="unnumbered">type ('a11, 'a12, 'a2) step1 =\r | |
10706 | Forall ('b, 'c) . ('a12, 'b, 'c, 'a11 -> ('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 | |
10708 | function that produces type <literal>'c1</literal>, and a function of type\r | |
10709 | <literal>'c1 -> 'c2</literal> to postcompose onto the folder. It returns a new\r | |
10710 | folder 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 -> 'c2)\r | |
10712 | -> ('a, 'b, 'c2, 'd) t\r | |
10713 | fun post (w: ('a, 'b, 'c1, 'd) t,\r | |
10714 | g: 'c1 -> 'c2)\r | |
10715 | (s: ('a, 'b, 'c2, 'd) step): 'd =\r | |
10716 | w (fn (a, h) => 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’s type check our simplest example, a variable-argument fold.\r | |
10722 | Recall that we have a folder <literal>f</literal> and a stepper <literal>a</literal> defined as\r | |
10723 | follows.</simpara>\r | |
10724 | <programlisting language="sml" linenumbering="unnumbered">val f = fn z => Fold.fold ((), fn () => ()) z\r | |
10725 | val a = fn z => Fold.step0 (fn () => ()) z</programlisting>\r | |
10726 | <simpara>Since the accumulator and finisher are uninteresting, we’ll use some\r | |
10727 | abbreviations to simplify things.</simpara>\r | |
10728 | <programlisting language="sml" linenumbering="unnumbered">type 'd step = (unit, unit, unit, 'd) Fold.step\r | |
10729 | type 'd fold = 'd step -> 'd</programlisting>\r | |
10730 | <simpara>With these abbreviations, <literal>f</literal> and <literal>a</literal> have the following polymorphic\r | |
10731 | types.</simpara>\r | |
10732 | <programlisting language="sml" linenumbering="unnumbered">f: 'd fold\r | |
10733 | a: '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 | |
10740 | So, 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 | |
10747 | a: unit fold step</programlisting>\r | |
10748 | <simpara>Applying the observation two more times leads to the following type\r | |
10749 | derivation.</simpara>\r | |
10750 | <programlisting language="sml" linenumbering="unnumbered">f: unit fold fold fold fold a: unit fold fold fold step\r | |
10751 | f a: unit fold fold fold a: unit fold fold step\r | |
10752 | f a a: unit fold fold a: unit fold step\r | |
10753 | f a a a: unit fold $: unit step\r | |
10754 | f a a a $: unit</programlisting>\r | |
10755 | <simpara>So, each application is a fold that consumes the next step, producing\r | |
10756 | a 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 | |
10758 | indeed a function that takes four curried arguments, each one a step\r | |
10759 | function.</simpara>\r | |
10760 | <programlisting language="sml" linenumbering="unnumbered">f: unit fold fold fold step\r | |
10761 | -> unit fold fold step\r | |
10762 | -> unit fold step\r | |
10763 | -> unit step\r | |
10764 | -> unit</programlisting>\r | |
10765 | <simpara>This example shows why we must eta expand uses of <literal>fold</literal> and <literal>step0</literal>\r | |
10766 | to work around the value restriction and make folders and steppers\r | |
10767 | polymorphic. The type of a fold function like <literal>f</literal> depends on the\r | |
10768 | number of arguments, and so will vary from use to use. Similarly,\r | |
10769 | each occurrence of an argument like <literal>a</literal> has a different type,\r | |
10770 | depending on the number of remaining arguments.</simpara>\r | |
10771 | <simpara>This example also shows that the type of a folder, when fully\r | |
10772 | expanded, is exponential in the number of arguments: there are as many\r | |
10773 | nested occurrences of the <literal>fold</literal> type constructor as there are\r | |
10774 | arguments, and each occurrence duplicates its type argument. One can\r | |
10775 | observe this exponential behavior in a type checker that doesn’t share\r | |
10776 | enough of the representation of types (e.g. one that represents types\r | |
10777 | as trees rather than directed acyclic graphs).</simpara>\r | |
10778 | <simpara>Generalizing this type derivation to uses of fold where the\r | |
10779 | accumulator and finisher are more interesting is straightforward. One\r | |
10780 | simply includes the type of the accumulator, which may change, for\r | |
10781 | each step, and the type of the finisher, which doesn’t change from\r | |
10782 | step 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 | |
10787 | causes problems if one wants to use a step in a first-class way.\r | |
10788 | Consider the following <literal>double</literal> function, which takes a step, <literal>s</literal>, and\r | |
10789 | produces a composite step that does <literal>s</literal> twice.</simpara>\r | |
10790 | <programlisting language="sml" linenumbering="unnumbered">fun double s = fn u => Fold.fold u s s</programlisting>\r | |
10791 | <simpara>The definition of <literal>double</literal> is not type correct. The problem is that\r | |
10792 | the type of a step depends on the number of remaining arguments but\r | |
10793 | that the parameter <literal>s</literal> is not polymorphic, and so can not be used in\r | |
10794 | two different positions.</simpara>\r | |
10795 | <simpara>Fortunately, we can define a function, <literal>lift0</literal>, that takes a monotyped\r | |
10796 | step function and <emphasis>lifts</emphasis> it into a polymorphic step function. This\r | |
10797 | is 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 | -> ('a1, 'a2, 'b, 'c, 'd) step0\r | |
10800 | fun lift0 (s: ('a1, 'a2, 'a2, 'a2, 'a2) step0)\r | |
10801 | (a: 'a1, f: 'b -> '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 | |
10804 | wrapped, to fix the problem.</simpara>\r | |
10805 | <programlisting language="sml" linenumbering="unnumbered">fun double s =\r | |
10806 | let\r | |
10807 | val s = fn z => Fold.lift0 s z\r | |
10808 | in\r | |
10809 | fn u => 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 | |
10812 | following example.</simpara>\r | |
10813 | <programlisting language="sml" linenumbering="unnumbered">val f = fn z => Fold.fold ((), fn () => ()) z\r | |
10814 | val a = fn z => Fold.step0 (fn () => ()) z\r | |
10815 | val a2 = fn z => double a z\r | |
10816 | val () = 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 | |
10818 | result, 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 | |
10823 | of the accumulator in a fold. Reworking the simple variable-argument\r | |
10824 | example to do this leads to the following.</simpara>\r | |
10825 | <programlisting language="sml" linenumbering="unnumbered">structure S:>\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 => Fold.fold ((), fn () => ()) z\r | |
10834 | val s = fn z => Fold.step0 (fn () => ()) z\r | |
10835 | end</programlisting>\r | |
10836 | <simpara>The idea is to name the accumulator type and use opaque signature\r | |
10837 | matching to make it abstract. This can prevent improper manipulation\r | |
10838 | of the accumulator by client code and ensure invariants that the\r | |
10839 | folder 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 | |
10901 | function that combines multiple arguments together using a binary\r | |
10902 | function. It is slightly tricky to do this directly using fold,\r | |
10903 | because of the special treatment required for the case of zero or one\r | |
10904 | argument. Here is a structure, <literal>Fold01N</literal>, that solves the problem\r | |
10905 | once 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 () => zero, start),\r | |
10910 | fn (finish, _, p, _) => finish (p ()))\r | |
10911 | \r | |
10912 | fun step0 {combine, input} =\r | |
10913 | Fold.step0 (fn (_, finish, _, f) =>\r | |
10914 | (finish,\r | |
10915 | finish,\r | |
10916 | fn () => f input,\r | |
10917 | fn x' => 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 | |
10923 | then one can define a variable-arity function <literal>f</literal> and stepper\r | |
10924 | <literal>`</literal> as follows.</simpara>\r | |
10925 | <programlisting language="sml" linenumbering="unnumbered">val f = fn z => Fold01N.fold {finish = finish, start = start, zero = zero} z\r | |
10926 | val ` = fn z => 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 | |
10929 | f `a1 $ = finish (start a1)\r | |
10930 | f `a1 `a2 $ = finish (c (start a1, a2))\r | |
10931 | f `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 | |
10937 | to duplicate the definition of some rather complex types in both the\r | |
10938 | signature and the structure. We first define the types in a\r | |
10939 | structure. Then, we define them via type re-definitions in the\r | |
10940 | signature, 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 -> 'zero)\r | |
10946 | * ('accum2 -> 'answer)\r | |
10947 | * (unit -> 'zero)\r | |
10948 | * ('input -> 'accum1),\r | |
10949 | ('a -> 'b) * 'c * (unit -> '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 -> 'accum1),\r | |
10956 | 'b * 'b * (unit -> 'accum1) * ('input2 -> '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 -> 'accum1),\r | |
10963 | 'c * 'c * (unit -> 'accum1) * ('input -> 'accum2),\r | |
10964 | 'e, 'f, 'g) Fold.step1\r | |
10965 | end\r | |
10966 | \r | |
10967 | signature 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 -> 'answer,\r | |
10978 | start: 'input -> 'accum1,\r | |
10979 | zero: 'zero}\r | |
10980 | -> ('input, 'accum1, 'accum2, 'answer, 'zero,\r | |
10981 | 'a, 'b, 'c, 'd, 'e) t\r | |
10982 | \r | |
10983 | val step0:\r | |
10984 | {combine: 'accum1 * 'input2 -> 'accum2,\r | |
10985 | input: 'input1}\r | |
10986 | -> ('input1, 'accum1, 'input2, 'accum2,\r | |
10987 | 'a, 'b, 'c, 'd, 'e, 'f) step0\r | |
10988 | \r | |
10989 | val step1:\r | |
10990 | {combine: 'accum1 * 'input -> 'accum2}\r | |
10991 | -> ('accum1, 'input, 'accum2,\r | |
10992 | 'a, 'b, 'c, 'd, 'e, 'f, 'g) step1\r | |
10993 | end\r | |
10994 | \r | |
10995 | structure 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 () => zero, start),\r | |
11001 | fn (finish, _, p, _) => finish (p ()))\r | |
11002 | \r | |
11003 | fun step0 {combine, input} =\r | |
11004 | Fold.step0 (fn (_, finish, _, f) =>\r | |
11005 | (finish,\r | |
11006 | finish,\r | |
11007 | fn () => f input,\r | |
11008 | fn x' => 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’s foreign function interface (FFI) extends Standard ML and makes\r | |
11019 | it easy to take the address of C global objects, access C global\r | |
11020 | variables, call from SML to C, and call from C to SML. MLton also\r | |
11021 | provides <link linkend="MLNLFFI">ML-NLFFI</link>, which is a higher-level FFI for calling\r | |
11022 | C 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 | |
11079 | syntax uses some abbreviations.</simpara>\r | |
11080 | <informaltable\r | |
11081 | frame="all"\r | |
11082 | rowsep="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> … <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>-></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 | |
11120 | of <link linkend="ForeignFunctionInterface">ForeignFunctionInterface</link> expressions. However, the type is\r | |
11121 | lexed, parsed, and elaborated as an SML type, so any type (including\r | |
11122 | type abbreviations) may be used, so long as it elaborates to a type of\r | |
11123 | the 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 -> cBaseTy) * (cBaseTy -> unit);</screen>\r | |
11151 | <simpara>Denotes the <emphasis>getter</emphasis> and <emphasis>setter</emphasis> for a C variable. The <emphasis>cBaseTy</emphasis>s\r | |
11152 | must 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 -> (unit -> cBaseTy) * (cBaseTy -> unit);</screen>\r | |
11177 | <simpara>Denotes the <emphasis>getter</emphasis> and <emphasis>setter</emphasis> for a C pointer to a variable.\r | |
11178 | The <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 | |
11184 | function. See <link linkend="CallingFromSMLToC">Calling from SML to C</link> for more\r | |
11185 | details.</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 -> cFuncTy;</screen>\r | |
11230 | <simpara>Denotes an SML function whose behavior is implemented by calling a C\r | |
11231 | function 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 | |
11262 | for more details.</simpara>\r | |
11263 | </section>\r | |
11264 | <section id="_export">\r | |
11265 | <title>Export</title>\r | |
11266 | <screen>_export "CFunctionName" attr... : cFuncTy -> unit;</screen>\r | |
11267 | <simpara>Exports a C function with the name <literal>CFunctionName</literal> that can be used to\r | |
11268 | call an SML function of the type <emphasis>cFuncTy</emphasis>. When the function denoted\r | |
11269 | by the export expression is applied to an SML function <literal>f</literal>, subsequent\r | |
11270 | C 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 | |
11272 | applied more than once, with each application replacing any previous\r | |
11273 | definition 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’s <link linkend="ForeignFunctionInterface">ForeignFunctionInterface</link> only allows values of certain SML\r | |
11304 | types to be passed between SML and C. The following types are\r | |
11305 | allowed: <literal>bool</literal>, <literal>char</literal>, <literal>int</literal>, <literal>real</literal>, <literal>word</literal>. All of the different\r | |
11306 | sizes of (fixed-sized) integers, reals, and words are supported as\r | |
11307 | well: <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 — see <link linkend="MLtonPointer">MLtonPointer</link> for\r | |
11311 | details.</simpara>\r | |
11312 | <simpara>Arrays, refs, and vectors of the above types are also allowed.\r | |
11313 | Because in MLton monomorphic arrays and vectors are exactly the same\r | |
11314 | as 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 | |
11316 | Strings are not null terminated, unless you manually do so from the\r | |
11317 | SML side.</simpara>\r | |
11318 | <simpara>Unfortunately, passing tuples or datatypes is not allowed because that\r | |
11319 | would 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 | |
11322 | the mapping between SML types and C types.</simpara>\r | |
11323 | <informaltable\r | |
11324 | frame="all"\r | |
11325 | rowsep="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 | |
11467 | types correspond to the default behavior.</simpara>\r | |
11468 | <simpara><anchor id="ForeignFunctionInterfaceTypes_ReadOnly" xreflabel="[ForeignFunctionInterfaceTypes_ReadOnly]"/>Note (read only): Because MLton assumes that\r | |
11469 | vectors and strings are read-only (and will perform optimizations\r | |
11470 | that, for instance, cause them to share space), you must not modify\r | |
11471 | the 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 | |
11473 | in reality, the object has the natural C representation. Your C code\r | |
11474 | should cast to the appropriate C type if you want to keep the C\r | |
11475 | compiler from complaining.</simpara>\r | |
11476 | <simpara>When calling an <link linkend="CallingFromSMLToC">imported C function from SML</link>\r | |
11477 | that 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 | |
11479 | array, ref, or string argument, then the object must be an ML object\r | |
11480 | allocated on the ML heap. (Although an array, ref, or vector object\r | |
11481 | has the natural C representation, the object also has an additional\r | |
11482 | header 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 | |
11484 | which provides structure aliases for various C types:</simpara>\r | |
11485 | <informaltable\r | |
11486 | frame="all"\r | |
11487 | rowsep="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 | |
11623 | target 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 | |
11631 | integers that denote indices of some sort. For example, in <link linkend="OCaml">OCaml</link>\r | |
11632 | a <literal>for</literal>-loop takes either the form</simpara>\r | |
11633 | <screen>for <name> = <lower> to <upper> do <body> done</screen>\r | |
11634 | <simpara>or the form</simpara>\r | |
11635 | <screen>for <name> = <upper> downto <lower> do <body> 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 | |
11639 | for <literal>while</literal>-loops, but not for <literal>for</literal>-loops. Indeed, in SML, many uses\r | |
11640 | of <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 | |
11643 | arrays. However, the Basis Library does not provide a function for\r | |
11644 | iterating over a range of integer values. Fortunately, it is very\r | |
11645 | easy 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 | |
11649 | the 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 | |
11653 | infix to downto\r | |
11654 | \r | |
11655 | val for =\r | |
11656 | fn lo to up =>\r | |
11657 | (fn f => let fun loop lo = if lo > up then ()\r | |
11658 | else (f lo; loop (lo+1))\r | |
11659 | in loop lo end)\r | |
11660 | | up downto lo =>\r | |
11661 | (fn f => let fun loop up = if up < 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 => 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 => 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 =>\r | |
11674 | for (c to d)\r | |
11675 | (fn j =>\r | |
11676 | ...))</programlisting>\r | |
11677 | <simpara>is fairly readable, but tends to cause the body of the loop to be\r | |
11678 | indented 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 | |
11683 | bound of the iterated range is almost always excluded and most loops\r | |
11684 | would subtract one from the upper bound:</simpara>\r | |
11685 | <programlisting language="sml" linenumbering="unnumbered">for (0 to n-1) ...\r | |
11686 | for (n-1 downto 0) ...</programlisting>\r | |
11687 | <simpara>It is probably better to break convention and exclude the upper bound\r | |
11688 | by default, because it leads to more concise code and becomes\r | |
11689 | idiomatic with very little practice. The iterator combinators\r | |
11690 | described 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 | |
11695 | probably good enough for many uses, it is a bit cumbersome when one\r | |
11696 | needs to iterate over a Cartesian product. One might also want to\r | |
11697 | iterate over more than just consecutive integers. It turns out that\r | |
11698 | one can provide a library of iterator combinators that allow one to\r | |
11699 | implement iterators more flexibly.</simpara>\r | |
11700 | <simpara>Since the types of the combinators may be a bit difficult to infer\r | |
11701 | from their implementations, let’s first take a look at a signature of\r | |
11702 | the iterator combinator library:</simpara>\r | |
11703 | <programlisting language="sml" linenumbering="unnumbered">signature ITER =\r | |
11704 | sig\r | |
11705 | type 'a t = ('a -> unit) -> unit\r | |
11706 | \r | |
11707 | val return : 'a -> 'a t\r | |
11708 | val >>= : 'a t * ('a -> 'b t) -> 'b t\r | |
11709 | \r | |
11710 | val none : 'a t\r | |
11711 | \r | |
11712 | val to : int * int -> int t\r | |
11713 | val downto : int * int -> int t\r | |
11714 | \r | |
11715 | val inList : 'a list -> 'a t\r | |
11716 | val inVector : 'a vector -> 'a t\r | |
11717 | val inArray : 'a array -> 'a t\r | |
11718 | \r | |
11719 | val using : ('a, 'b) StringCvt.reader -> 'b -> 'a t\r | |
11720 | \r | |
11721 | val when : 'a t * ('a -> bool) -> 'a t\r | |
11722 | val by : 'a t * ('a -> 'b) -> 'b t\r | |
11723 | val @@ : 'a t * 'a t -> 'a t\r | |
11724 | val ** : 'a t * 'b t -> ('a, 'b) product t\r | |
11725 | \r | |
11726 | val for : 'a -> 'a\r | |
11727 | end</programlisting>\r | |
11728 | <simpara>Several of the above combinators are meant to be used as infix\r | |
11729 | operators. Here is a set of suitable infix declarations:</simpara>\r | |
11730 | <programlisting language="sml" linenumbering="unnumbered">infix 2 to downto\r | |
11731 | infix 1 @@ when by\r | |
11732 | infix 0 >>= **</programlisting>\r | |
11733 | <simpara>A few notes are in order:</simpara>\r | |
11734 | <itemizedlist>\r | |
11735 | <listitem>\r | |
11736 | <simpara>\r | |
11737 | The <literal>'a t</literal> type constructor with the <literal>return</literal> and <literal>>>=</literal> operators forms a monad.\r | |
11738 | </simpara>\r | |
11739 | </listitem>\r | |
11740 | <listitem>\r | |
11741 | <simpara>\r | |
11742 | The <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 | |
11752 | The <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 | |
11757 | The <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 | |
11762 | See <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 | |
11769 | The <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 | |
11784 | following basic combinators:</simpara>\r | |
11785 | <programlisting language="sml" linenumbering="unnumbered">fun const x _ = x\r | |
11786 | fun flip f x y = f y x\r | |
11787 | fun id x = x\r | |
11788 | fun opt fno fso = fn NONE => fno () | SOME ? => fso ?\r | |
11789 | fun 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 :> ITER =\r | |
11792 | struct\r | |
11793 | type 'a t = ('a -> unit) -> unit\r | |
11794 | \r | |
11795 | val return = pass\r | |
11796 | fun (iA >>= 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<u then (f l; `(l+1)) else () in `l end\r | |
11801 | fun (u downto l) f = let fun `u = if u>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) => (f x; `s)) (get s) in `s end\r | |
11808 | \r | |
11809 | fun (iA when p) f = iA (fn a => 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 => iB (fn b => f (a & 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 | |
11817 | in terms of the other combinators, most notably <literal>return</literal> and <literal>>>=</literal>.\r | |
11818 | Another implementation issue worth mentioning is that <literal>downto</literal> is\r | |
11819 | written 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 | |
11824 | operators 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 => x mod 3 <> 0) ** inList ["a", "b"] ** 2 downto 1 by real)\r | |
11827 | (fn x & y & z =>\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 | |
11830 | iterators. For example, here is an iterator over a "triangle":</simpara>\r | |
11831 | <programlisting language="sml" linenumbering="unnumbered">fun triangle (l, u) = l to u >>= (fn i => i to u >>= (fn j => 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 | |
11842 | tree.</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 | |
11867 | since 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 | |
11874 | is a functional programming language developed at Microsoft Research.\r | |
11875 | F# was partly inspired by the <link linkend="OCaml">OCaml</link> language and shares some\r | |
11876 | common core constructs with it. F# is integrated with Visual Studio\r | |
11877 | 2010 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 | |
11883 | the values of some of the fields. <link linkend="StandardML">Standard ML</link> does not\r | |
11884 | have explicit syntax for functional record update. We will show below\r | |
11885 | how to implement functional record update in SML, with a little\r | |
11886 | boilerplate 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 | |
11892 | updates. 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 | |
11896 | functional 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 | |
11899 | replaced 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 | |
11901 | functional record update directly. We first give a simple\r | |
11902 | implementation that has a number of problems. We then give an\r | |
11903 | advanced implementation, that, while complex underneath, is a reusable\r | |
11904 | library 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 | |
11911 | fun withB ({a, b = _, c}, b) = {a = a, b = b, c = c}\r | |
11912 | fun 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 | |
11920 | code is quadratic in the number of record fields. Furthermore,\r | |
11921 | changing, adding, or deleting a field requires time proportional to\r | |
11922 | the number of fields (because each <literal>with<emphasis><L></emphasis></literal> function must be\r | |
11923 | changed). It is also annoying to have to define a <literal>with<emphasis><L></emphasis></literal>\r | |
11924 | function, 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><N></emphasis></literal>\r | |
11930 | functions and single <emphasis>update</emphasis> operator <literal>U</literal> so that one can define a\r | |
11931 | functional record update function for any record type simply by\r | |
11932 | specifying a (trivial) isomorphism between that type and function\r | |
11933 | argument list. For example, suppose that we would like to do\r | |
11934 | functional record update on records with fields <literal>a</literal> and <literal>b</literal>. Then one\r | |
11935 | defines a function <literal>updateAB</literal> as follows.</simpara>\r | |
11936 | <programlisting language="sml" linenumbering="unnumbered">val updateAB =\r | |
11937 | fn z =>\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 | |
11947 | records and function arguments. There is a second use of <literal>from</literal> to\r | |
11948 | work 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 | |
11951 | are valid.</simpara>\r | |
11952 | <programlisting language="sml" linenumbering="unnumbered">updateAB {a = 13, b = "hello"} (set#b "goodbye") $\r | |
11953 | updateAB {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 | |
11955 | update on records with fields <literal>b</literal>, <literal>c</literal>, and <literal>d</literal>. Then one defines a\r | |
11956 | function <literal>updateBCD</literal> as follows.</simpara>\r | |
11957 | <programlisting language="sml" linenumbering="unnumbered">val updateBCD =\r | |
11958 | fn z =>\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 | |
11967 | is 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 | |
11970 | be updated multiple times. Further note that the same <literal>set</literal> operator\r | |
11971 | is used for all update functions (in the above, for both <literal>updateAB</literal>\r | |
11972 | and <literal>updateBCD</literal>).</simpara>\r | |
11973 | <simpara>In general, to define a functional-record-update function on records\r | |
11974 | with fields <literal>f1</literal>, <literal>f2</literal>, …, <literal>fN</literal>, use the following template.</simpara>\r | |
11975 | <programlisting language="sml" linenumbering="unnumbered">val update =\r | |
11976 | fn z =>\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, _) => 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)) => (fn out => vars (s (ops ()) (out, f)), ops)) z\r | |
12017 | fun set z = Fold.step2 (fn (s, v, (vars, ops)) => (fn out => vars (s (ops ()) (out, fn _ => 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 | |
12021 | replace the contents of one argument out of a list of arguments. The\r | |
12022 | functions <literal>f<emphasis><X></emphasis></literal> replace the 0th, 1st, … argument with their\r | |
12023 | argument <literal>z</literal>. The <literal>c<emphasis><X></emphasis></literal> functions pass the first <emphasis>X</emphasis> <literal>f</literal>\r | |
12024 | functions to the record constructor.</simpara>\r | |
12025 | <simpara>The <literal>#field</literal> notation of Standard ML allows us to select the map\r | |
12026 | function which replaces the corresponding argument. By converting the\r | |
12027 | record to an argument list, feeding that list through the selected map\r | |
12028 | function and piping the list into the record constructor, functional\r | |
12029 | record 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 | |
12034 | expect with the special syntax. Namely a sequence of updates will be\r | |
12035 | optimized into a single record construction that copies the unchanged\r | |
12036 | fields 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 | |
12038 | of <link linkend="FunctionalRecordUpdate">FunctionalRecordUpdate</link>. However, the old structure caused\r | |
12039 | exponentially increasing compile times. We advise you to switch to\r | |
12040 | the 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 | |
12052 | parser 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 | |
12055 | to 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’s garbage collector uses copying, mark-compact, and generational\r | |
12063 | collection, automatically switching between them at run time based on\r | |
12064 | the amount of live data relative to the amount of RAM. The runtime\r | |
12065 | system tries to keep the heap within RAM if at all possible.</simpara>\r | |
12066 | <simpara>MLton’s copying collector is a simple, two-space, breadth-first,\r | |
12067 | Cheney-style collector. The design for the generational and\r | |
12068 | mark-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 | |
12096 | it yields a new type. Thus, any attempt to mix the types will lead to\r | |
12097 | a type error at compile-time. The following program, which does not\r | |
12098 | type 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 | |
12103 | structure S1 = F ()\r | |
12104 | structure S2 = F ()\r | |
12105 | val _: S1.t -> S2.t = fn x => x</programlisting>\r | |
12106 | <simpara>Generativity also means that two different datatype declarations\r | |
12107 | define different types, even if they define identical constructors.\r | |
12108 | The following program does not type check due to this.</simpara>\r | |
12109 | <programlisting language="sml" linenumbering="unnumbered">datatype t = A | B\r | |
12110 | val a1 = A\r | |
12111 | datatype t = A | B\r | |
12112 | val a2 = A\r | |
12113 | val _ = 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 | |
12130 | it 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 | |
12133 | val e1 = E\r | |
12134 | fun isE1 (e: exn): bool =\r | |
12135 | case e of\r | |
12136 | E => true\r | |
12137 | | _ => false\r | |
12138 | exception E\r | |
12139 | val e2 = E\r | |
12140 | fun isE2 (e: exn): bool =\r | |
12141 | case e of\r | |
12142 | E => true\r | |
12143 | | _ => false\r | |
12144 | fun pb (b: bool): unit =\r | |
12145 | print (concat [Bool.toString b, "\n"])\r | |
12146 | val () = (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 | |
12151 | exception <literal>E</literal> and a corresponding function that returns <literal>true</literal> only on\r | |
12152 | that exception. Although declared by syntactically identical\r | |
12153 | exception declarations, <literal>e1</literal> and <literal>e2</literal> are different exceptions. The\r | |
12154 | program, 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 | |
12156 | exception declaration yields a new exception each time it is\r | |
12157 | evaluated.</simpara>\r | |
12158 | <programlisting language="sml" linenumbering="unnumbered">fun f (): exn * (exn -> bool) =\r | |
12159 | let\r | |
12160 | exception E\r | |
12161 | in\r | |
12162 | (E, fn E => true | _ => false)\r | |
12163 | end\r | |
12164 | val (e1, isE1) = f ()\r | |
12165 | val (e2, isE2) = f ()\r | |
12166 | fun pb (b: bool): unit =\r | |
12167 | print (concat [Bool.toString b, "\n"])\r | |
12168 | val () = (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 | |
12178 | following valid SML program.</simpara>\r | |
12179 | <programlisting language="sml" linenumbering="unnumbered">fun f (): ('a -> exn) * (exn -> 'a) =\r | |
12180 | let\r | |
12181 | exception E of 'a\r | |
12182 | in\r | |
12183 | (E, fn E x => x | _ => raise Fail "f")\r | |
12184 | end\r | |
12185 | fun cast (a: 'a): 'b =\r | |
12186 | let\r | |
12187 | val (make: 'a -> exn, _) = f ()\r | |
12188 | val (_, get: exn -> 'b) = f ()\r | |
12189 | in\r | |
12190 | get (make a)\r | |
12191 | end\r | |
12192 | val _ = ((cast 13): int -> int) 14</programlisting>\r | |
12193 | <simpara>If exceptions weren’t generative, then each call <literal>f ()</literal> would yield\r | |
12194 | the same exception constructor <literal>E</literal>. Then, our <literal>cast</literal> function could\r | |
12195 | use <literal>make: 'a -> exn</literal> to convert any value into an exception and then\r | |
12196 | <literal>get: exn -> 'b</literal> to convert that exception to a value of arbitrary\r | |
12197 | type. If <literal>cast</literal> worked, then we could cast an integer as a function\r | |
12198 | and apply. Of course, because of generative exceptions, this program\r | |
12199 | raises <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 | |
12220 | MLton 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 | |
12240 | Gtk user interfaces.</simpara>\r | |
12241 | <simpara><link linkend="WesleyTerpstra">WesleyTerpstra</link> is working on a Glade→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 | |
12258 | to move them out to the top level so they are only evaluated once and\r | |
12259 | do 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 | |
12285 | arithmetic library) is a library for arbitrary precision integer\r | |
12286 | arithmetic. 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 | |
12293 | There is a known problem with the GnuMP library (prior to version\r | |
12294 | 4.2.x), where it requires a lot of stack space for some computations,\r | |
12295 | e.g. <literal>IntInf.toString</literal> of a million digit number. If you run with\r | |
12296 | stack size limited, you may see a segfault in such programs. This\r | |
12297 | problem is mentioned in the <ulink url="http://gmplib.org/#FAQ">GnuMP FAQ</ulink>, where\r | |
12298 | they describe two solutions.\r | |
12299 | </simpara>\r | |
12300 | <itemizedlist>\r | |
12301 | <listitem>\r | |
12302 | <simpara>\r | |
12303 | Increase (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 | |
12309 | Configure and rebuild <literal>libgmp</literal> with <literal>--disable-alloca</literal>, which will\r | |
12310 | cause it to allocate temporaries using <literal>malloc</literal> instead of on the\r | |
12311 | stack.\r | |
12312 | </simpara>\r | |
12313 | </listitem>\r | |
12314 | </itemizedlist>\r | |
12315 | </listitem>\r | |
12316 | <listitem>\r | |
12317 | <simpara>\r | |
12318 | On some platforms, the GnuMP library may be configured to use one of\r | |
12319 | multiple ABIs (Application Binary Interfaces). For example, on some\r | |
12320 | 32-bit architectures, GnuMP may be configured to represent a limb as\r | |
12321 | either a 32-bit <literal>long</literal> or as a 64-bit <literal>long long</literal>. Similarly, GnuMP\r | |
12322 | may 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’s\r | |
12326 | representation of a limb. Hence, it is important that MLton and the\r | |
12327 | GnuMP library agree upon the representation of a limb.</simpara>\r | |
12328 | <itemizedlist>\r | |
12329 | <listitem>\r | |
12330 | <simpara>\r | |
12331 | When using a source package of MLton, building will detect the\r | |
12332 | GnuMP library’s representation of a limb.\r | |
12333 | </simpara>\r | |
12334 | </listitem>\r | |
12335 | <listitem>\r | |
12336 | <simpara>\r | |
12337 | When using a binary package of MLton that is dynamically linked\r | |
12338 | against the GnuMP library, the build machine and the install machine\r | |
12339 | must have the GnuMP library configured with the same representation of\r | |
12340 | a limb. (On the other hand, the build machine need not have the GnuMP\r | |
12341 | library configured with CPU features compatible with the install\r | |
12342 | machine.)\r | |
12343 | </simpara>\r | |
12344 | </listitem>\r | |
12345 | <listitem>\r | |
12346 | <simpara>\r | |
12347 | When using a binary package of MLton that is statically linked\r | |
12348 | against the GnuMP library, the build machine and the install machine\r | |
12349 | need not have the GnuMP library configured with the same\r | |
12350 | representation of a limb. (On the other hand, the build machine must\r | |
12351 | have the GnuMP library configured with CPU features compatible with\r | |
12352 | the install machine.)\r | |
12353 | </simpara>\r | |
12354 | <simpara>However, MLton will be configured with the representation of a limb\r | |
12355 | from the GnuMP library of the build machine. Executables produced by\r | |
12356 | MLton will be incompatible with the GnuMP library of the install\r | |
12357 | machine. To <emphasis>reconfigure</emphasis> MLton with the representation of a limb\r | |
12358 | from 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 | |
12366 | structure C_MPLimb = struct open Word?? type t = word end\r | |
12367 | functor 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 | |
12404 | removes operations that are redundant on some, but not necessarily all\r | |
12405 | paths, through the program. PRE can subsume both common subexpression\r | |
12406 | elimination and loop-invariant code motion, and is therefore a\r | |
12407 | potentially powerful optimization. However, a naïve\r | |
12408 | implementation of PRE on a program in static single assignment (SSA)\r | |
12409 | form is unlikely to be effective. This project aims to adapt and\r | |
12410 | implement the SSAPRE algorithm(s) of Thomas VanDrunen in MLton’s SSA\r | |
12411 | intermediate 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 | |
12440 | heap profile is concerned with the allocation, retention, and\r | |
12441 | deallocation (via garbage collection) of heap data during the\r | |
12442 | execution of a program. A heap profile can be used to diagnose\r | |
12443 | performance problems in a functional program that arise from space\r | |
12444 | leaks. This project aims to design and implement a heap profiler for\r | |
12445 | MLton 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ö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ö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 | |
12474 | functional languages. Garbage collect too often, and program\r | |
12475 | performance suffers due to the excessive time spent in the garbage\r | |
12476 | collector. Garbage collect not often enough, and program performance\r | |
12477 | suffers due to the excessive space used by the uncollected garbage.\r | |
12478 | One particular issue is ensuring that a program utilizing a garbage\r | |
12479 | collector "plays nice" with other processes on the system, by not\r | |
12480 | using too much or too little physical memory. While there are some\r | |
12481 | reasonable theoretical results about garbage collections with heaps of\r | |
12482 | fixed size, there seems to be insufficient work that really looks\r | |
12483 | carefully at the question of dynamically resizing the heap in response\r | |
12484 | to the live data demands of the application and, similarly, in\r | |
12485 | response to the behavior of the operating system and other processes.\r | |
12486 | This project aims to investigate improvements to the memory behavior of\r | |
12487 | MLton compiled programs through better tuning of the garbage\r | |
12488 | collector.</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 ML Language Features</title>\r | |
12521 | <simpara>Any programming language, including Standard ML, can be improved.\r | |
12522 | The community has identified a number of modest extensions and\r | |
12523 | revisions to the Standard ML programming language that would\r | |
12524 | likely prove useful in practice. This project aims to implement these\r | |
12525 | language 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 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 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 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 | |
12549 | implementations (including MLton) provide little to no source-level\r | |
12550 | debugging support. This project aims to add basic to intermediate\r | |
12551 | source-level debugging support to the MLton compiler. MLton already\r | |
12552 | supports source-level profiling, which can be used to attribute bytes\r | |
12553 | allocated or time spent in source functions. It should be relatively\r | |
12554 | straightforward to leverage this source-level information into basic\r | |
12555 | source-level debugging support, with the ability to set/unset\r | |
12556 | breakpoints and step through declarations and functions. It may be\r | |
12557 | possible to also provide intermediate source-level debugging support,\r | |
12558 | with the ability to inspect in-scope variables of basic types (e.g.,\r | |
12559 | types compatible with MLton’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 — 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 — 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 | |
12588 | Instruction, Multiple Data) operations, such as Intel’s MMX/SSE\r | |
12589 | instructions, AMD’s 3DNow! instructions, and IBM’s AltiVec. Such\r | |
12590 | instructions are particularly useful for multimedia, scientific, and\r | |
12591 | cryptographic applications. This project aims to add preliminary\r | |
12592 | support for vector data and vector operations to the MLton compiler.\r | |
12593 | Ideally, after surveying SIMD instruction sets and SIMD support in\r | |
12594 | other compilers, a core set of SIMD primitives with broad architecture\r | |
12595 | and compiler support can be identified. After adding SIMD primitives\r | |
12596 | to the core compiler and carrying them through to the various\r | |
12597 | backends, there will be opportunities to design and implement an SML\r | |
12598 | library that exposes the primitives to the SML programmer as well as\r | |
12599 | opportunities to design and implement auto-vectorization\r | |
12600 | optimizations.</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 | |
12624 | RTEMS, RT Linux, and FreeRTOS. The project will include modifications\r | |
12625 | to the MLton build and configuration process. Students will need to\r | |
12626 | extend the MLton configuration process for each of the RTOSs. The\r | |
12627 | MLton compilation process will need to be extended to invoke the C\r | |
12628 | cross compilers the RTOSs provide for embedded support. Test scripts\r | |
12629 | for validation will be necessary and these will need to be run in\r | |
12630 | emulators 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 | |
12636 | management scheme to garbage collection. Regions can be inferred by\r | |
12637 | the compiler (e.g., Cyclone and MLKit) or provided to the programmer\r | |
12638 | through a library. Since many students do not have extensive\r | |
12639 | experience with compilers we plan on adopting the later approach.\r | |
12640 | Creating a viable region based memory solution requires the removal of\r | |
12641 | the GC and changes to the allocator. Additionally, write barriers\r | |
12642 | will be necessary to ensure references between two ML objects is never\r | |
12643 | established if the left hand side of the assignment has a longer\r | |
12644 | lifetime than the right hand side. Students will need to come up with\r | |
12645 | an 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 | |
12651 | Cyclone\r | |
12652 | </simpara>\r | |
12653 | </listitem>\r | |
12654 | <listitem>\r | |
12655 | <simpara>\r | |
12656 | MLKit\r | |
12657 | </simpara>\r | |
12658 | </listitem>\r | |
12659 | <listitem>\r | |
12660 | <simpara>\r | |
12661 | RTSJ + 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 | |
12670 | environment that targets scalable multicore platforms. It is an\r | |
12671 | extension of MLton. It combines new language abstractions and\r | |
12672 | associated compiler analyses for expressing and implementing various\r | |
12673 | kinds of fine-grained parallelism (safe futures, speculation,\r | |
12674 | transactions, etc.), along with a sophisticated runtime system tuned\r | |
12675 | to efficiently handle large numbers of lightweight threads. The core\r | |
12676 | stable features of MultiMLton will need to be integrated with the\r | |
12677 | latest MLton public release. Certain experimental features, such as\r | |
12678 | support for the Intel SCC and distributed runtime will be omitted.\r | |
12679 | This project requires students to understand the delta between the\r | |
12680 | MultiMLton code base and the MLton code base. Students will need to\r | |
12681 | create build and configuration scripts for MLton to enable MultiMLton\r | |
12682 | features.</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 — 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 | |
12729 | removes operations that are redundant on some, but not necessarily all\r | |
12730 | paths, through the program. PRE can subsume both common subexpression\r | |
12731 | elimination and loop-invariant code motion, and is therefore a\r | |
12732 | potentially powerful optimization. However, a naïve\r | |
12733 | implementation of PRE on a program in static single assignment (SSA)\r | |
12734 | form is unlikely to be effective. This project aims to adapt and\r | |
12735 | implement the SSAPRE algorithm(s) of Thomas VanDrunen in MLton’s SSA\r | |
12736 | intermediate 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 | |
12765 | heap profile is concerned with the allocation, retention, and\r | |
12766 | deallocation (via garbage collection) of heap data during the\r | |
12767 | execution of a program. A heap profile can be used to diagnose\r | |
12768 | performance problems in a functional program that arise from space\r | |
12769 | leaks. This project aims to design and implement a heap profiler for\r | |
12770 | MLton 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ö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ö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 | |
12799 | functional languages. Garbage collect too often, and program\r | |
12800 | performance suffers due to the excessive time spent in the garbage\r | |
12801 | collector. Garbage collect not often enough, and program performance\r | |
12802 | suffers due to the excessive space used by the uncollected garbage.\r | |
12803 | One particular issue is ensuring that a program utilizing a garbage\r | |
12804 | collector "plays nice" with other processes on the system, by not\r | |
12805 | using too much or too little physical memory. While there are some\r | |
12806 | reasonable theoretical results about garbage collections with heaps of\r | |
12807 | fixed size, there seems to be insufficient work that really looks\r | |
12808 | carefully at the question of dynamically resizing the heap in response\r | |
12809 | to the live data demands of the application and, similarly, in\r | |
12810 | response to the behavior of the operating system and other processes.\r | |
12811 | This project aims to investigate improvements to the memory behavior of\r | |
12812 | MLton compiled programs through better tuning of the garbage\r | |
12813 | collector.</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 ML Language Features</title>\r | |
12846 | <simpara>Any programming language, including Standard ML, can be improved.\r | |
12847 | The community has identified a number of modest extensions and\r | |
12848 | revisions to the Standard ML programming language that would\r | |
12849 | likely prove useful in practice. This project aims to implement these\r | |
12850 | language 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 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 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 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 | |
12874 | implementations (including MLton) provide little to no source-level\r | |
12875 | debugging support. This project aims to add basic to intermediate\r | |
12876 | source-level debugging support to the MLton compiler. MLton already\r | |
12877 | supports source-level profiling, which can be used to attribute bytes\r | |
12878 | allocated or time spent in source functions. It should be relatively\r | |
12879 | straightforward to leverage this source-level information into basic\r | |
12880 | source-level debugging support, with the ability to set/unset\r | |
12881 | breakpoints and step through declarations and functions. It may be\r | |
12882 | possible to also provide intermediate source-level debugging support,\r | |
12883 | with the ability to inspect in-scope variables of basic types (e.g.,\r | |
12884 | types compatible with MLton’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 — 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 — 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 | |
12913 | management scheme to garbage collection. Regions can be inferred by\r | |
12914 | the compiler (e.g., Cyclone and MLKit) or provided to the programmer\r | |
12915 | through a library. Since many students do not have extensive\r | |
12916 | experience with compilers we plan on adopting the later approach.\r | |
12917 | Creating a viable region based memory solution requires the removal of\r | |
12918 | the GC and changes to the allocator. Additionally, write barriers\r | |
12919 | will be necessary to ensure references between two ML objects is never\r | |
12920 | established if the left hand side of the assignment has a longer\r | |
12921 | lifetime than the right hand side. Students will need to come up with\r | |
12922 | an 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 | |
12928 | Cyclone\r | |
12929 | </simpara>\r | |
12930 | </listitem>\r | |
12931 | <listitem>\r | |
12932 | <simpara>\r | |
12933 | MLKit\r | |
12934 | </simpara>\r | |
12935 | </listitem>\r | |
12936 | <listitem>\r | |
12937 | <simpara>\r | |
12938 | RTSJ + 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 | |
12947 | environment that targets scalable multicore platforms. It is an\r | |
12948 | extension of MLton. It combines new language abstractions and\r | |
12949 | associated compiler analyses for expressing and implementing various\r | |
12950 | kinds of fine-grained parallelism (safe futures, speculation,\r | |
12951 | transactions, etc.), along with a sophisticated runtime system tuned\r | |
12952 | to efficiently handle large numbers of lightweight threads. The core\r | |
12953 | stable features of MultiMLton will need to be integrated with the\r | |
12954 | latest MLton public release. Certain experimental features, such as\r | |
12955 | support for the Intel SCC and distributed runtime will be omitted.\r | |
12956 | This project requires students to understand the delta between the\r | |
12957 | MultiMLton code base and the MLton code base. Students will need to\r | |
12958 | create build and configuration scripts for MLton to enable MultiMLton\r | |
12959 | features.</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 — 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 ML Improvements</title>\r | |
12972 | <simpara><ulink url="http://cml.cs.uchicago.edu/">Concurrent ML</ulink> is an SML concurrency\r | |
12973 | library based on synchronous message passing. MLton has a partial\r | |
12974 | implementation of the CML message-passing primitives, but its use in\r | |
12975 | real-world applications has been stymied by the lack of completeness\r | |
12976 | and thread-safe I/O libraries. This project would aim to flesh out\r | |
12977 | the CML implementation in MLton to be fully compatible with the\r | |
12978 | "official" version distributed as part of SML/NJ. Furthermore, time\r | |
12979 | permitting, runtime system support could be added to allow use of\r | |
12980 | modern OS features, such as asynchronous I/O, in the implementation of\r | |
12981 | CML’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 | |
13028 | heap profile is concerned with the allocation, retention, and\r | |
13029 | deallocation (via garbage collection) of heap data during the\r | |
13030 | execution of a program. A heap profile can be used to diagnose\r | |
13031 | performance problems in a functional program that arise from space\r | |
13032 | leaks. This project aims to design and implement a heap profiler for\r | |
13033 | MLton 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ö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ö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 | |
13062 | functional languages. Garbage collect too often, and program\r | |
13063 | performance suffers due to the excessive time spent in the garbage\r | |
13064 | collector. Garbage collect not often enough, and program performance\r | |
13065 | suffers due to the excessive space used by the uncollected\r | |
13066 | garbage. One particular issue is ensuring that a program utilizing a\r | |
13067 | garbage collector "plays nice" with other processes on the system, by\r | |
13068 | not using too much or too little physical memory. While there are some\r | |
13069 | reasonable theoretical results about garbage collections with heaps of\r | |
13070 | fixed size, there seems to be insufficient work that really looks\r | |
13071 | carefully at the question of dynamically resizing the heap in response\r | |
13072 | to the live data demands of the application and, similarly, in\r | |
13073 | response to the behavior of the operating system and other\r | |
13074 | processes. This project aims to investigate improvements to the memory\r | |
13075 | behavior of MLton compiled programs through better tuning of the\r | |
13076 | garbage 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 | |
13125 | on a stack. This naturally corresponds to the call-return pattern of\r | |
13126 | function invocation. However, there are some disadvantages to\r | |
13127 | stack-allocated activation records. In a functional programming\r | |
13128 | language, functions may be deeply recursive, resulting in call stacks\r | |
13129 | that are much larger than typically supported by the operating system;\r | |
13130 | hence, a functional programming language implementation will typically\r | |
13131 | store its stack in its heap. Furthermore, a functional programming\r | |
13132 | language implementation must handle and recover from stack overflow,\r | |
13133 | by allocating a larger stack (again, in its heap) and copying\r | |
13134 | activation records from the old stack to the new stack. In the\r | |
13135 | presence of threads, stacks must be allocated in a heap and, in the\r | |
13136 | presence of a garbage collector, should be garbage collected when\r | |
13137 | unreachable. While heap-allocated activation records avoid many of\r | |
13138 | these disadvantages, they have not been widely implemented. This\r | |
13139 | project aims to implement and evaluate heap-allocated activation\r | |
13140 | records 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 | |
13165 | is the de facto representation for floating-point computation.\r | |
13166 | However, it is a <emphasis>binary</emphasis> (base 2) representation of floating-point\r | |
13167 | values, while many applications call for input and output of\r | |
13168 | floating-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 | |
13170 | representation (e.g., a string like <literal>"0.1"</literal>) and returns the best\r | |
13171 | binary floating-point representation of that number. The\r | |
13172 | <emphasis>binary-to-decimal</emphasis> conversion problem takes a binary floating-point\r | |
13173 | representation and returns a decimal floating-point representation\r | |
13174 | using the smallest number of digits that allow the decimal\r | |
13175 | floating-point representation to be converted to the original binary\r | |
13176 | floating-point representation. For both conversion routines, "best"\r | |
13177 | is dependent upon the current floating-point rounding mode.</simpara>\r | |
13178 | <simpara>MLton uses David Gay’s\r | |
13179 | <ulink url="http://www.netlib.org/fp/gdtoa.tgz">gdtoa library</ulink> for floating-point\r | |
13180 | conversions. While this is an exellent library, it generalizes the\r | |
13181 | decimal-to-binary and binary-to-decimal conversion routines beyond\r | |
13182 | what is required by the\r | |
13183 | <ulink url="http://standardml.org/Basis/">Standard ML Basis Library</ulink> and induces an\r | |
13184 | external dependency on the compiler. Native implementations of these\r | |
13185 | conversion 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 | |
13187 | ML features in the implementation (e.g., the published algorithms\r | |
13188 | often require use of infinite precision arithmetic, which is provided\r | |
13189 | by the <literal>IntInf</literal> structure in Standard ML, but is provided in an ad hoc\r | |
13190 | fasion in the <literal>gdtoa</literal> library).</simpara>\r | |
13191 | <simpara>This project aims to develop a native implementation of the conversion\r | |
13192 | routines 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 | |
13231 | implementations (including MLton) provide little to no source-level\r | |
13232 | debugging support. This project aims to add basic to intermediate\r | |
13233 | source-level debugging support to the MLton compiler. MLton already\r | |
13234 | supports source-level profiling, which can be used to attribute bytes\r | |
13235 | allocated or time spent in source functions. It should be relatively\r | |
13236 | straightforward to leverage this source-level information into basic\r | |
13237 | source-level debugging support, with the ability to set/unset\r | |
13238 | breakpoints and step through declarations and functions. It may be\r | |
13239 | possible to also provide intermediate source-level debugging support,\r | |
13240 | with the ability to inspect in-scope variables of basic types (e.g.,\r | |
13241 | types compatible with MLton’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 — 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 — 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 | |
13270 | management scheme to garbage collection. Regions can be inferred by\r | |
13271 | the compiler (e.g., Cyclone and MLKit) or provided to the programmer\r | |
13272 | through a library. Since many students do not have extensive\r | |
13273 | experience with compilers we plan on adopting the later approach.\r | |
13274 | Creating a viable region based memory solution requires the removal of\r | |
13275 | the GC and changes to the allocator. Additionally, write barriers\r | |
13276 | will be necessary to ensure references between two ML objects is never\r | |
13277 | established if the left hand side of the assignment has a longer\r | |
13278 | lifetime than the right hand side. Students will need to come up with\r | |
13279 | an 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 | |
13285 | Cyclone\r | |
13286 | </simpara>\r | |
13287 | </listitem>\r | |
13288 | <listitem>\r | |
13289 | <simpara>\r | |
13290 | MLKit\r | |
13291 | </simpara>\r | |
13292 | </listitem>\r | |
13293 | <listitem>\r | |
13294 | <simpara>\r | |
13295 | RTSJ + 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 | |
13304 | kernel 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 | |
13306 | to real-time threads that the RTOS provides. This will include\r | |
13307 | associating priorities with MLton threads and building priority based\r | |
13308 | scheduling algorithms. Additionally, support for perdioc, aperiodic,\r | |
13309 | and sporadic tasks should be supported. A real-time SML library will\r | |
13310 | need to be created to provide a forward facing interface for\r | |
13311 | programmers. Stretch goals include reworking the MLton <literal>atomic</literal>\r | |
13312 | statement and associated synchronization primitives built on top of\r | |
13313 | the 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 | |
13319 | real-time garbage collection. We will model the real-time GC on the\r | |
13320 | Schism RTGC. The first task will be to create a fixed size runtime\r | |
13321 | object representation. Large structures will need to be represented\r | |
13322 | as a linked lists of fixed sized objects. Arrays and vectors will be\r | |
13323 | transferred into dense trees. Compaction and copying can therefore be\r | |
13324 | removed from the GC algorithms that MLton currently supports. Lastly,\r | |
13325 | the GC will be made concurrent, allowing for the execution of the GC\r | |
13326 | threads as the lowest priority task in the system. Stretch goals\r | |
13327 | include a priority aware mechanism for the GC to signal to real-time\r | |
13328 | ML threads that it needs to scan their stack and identification of\r | |
13329 | places where the stack is shallow to bound priority inversion during\r | |
13330 | this 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 | |
13340 | intended as reference implementation of\r | |
13341 | <link linkend="DefinitionOfStandardML">The Definition of Standard ML (Revised)</link> and\r | |
13342 | not 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 | |
13348 | My background is a combination of mathematics and computer science.\r | |
13349 | Currently 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 | |
13355 | integrated it with SML/NJ. The defunctorizer used SML/NJ’s visible\r | |
13356 | compiler and operated on the <literal>Ast</literal> intermediate representation\r | |
13357 | produced by the SML/NJ front end. Experiments showed that\r | |
13358 | defunctorization gave a speedup of up to six times over separate\r | |
13359 | compilation and up to two times over batch compilation without functor\r | |
13360 | expansion.</simpara>\r | |
13361 | <simpara>In August 1997, we began development of an independent compiler for\r | |
13362 | SML. At the time the compiler was called <literal>smlc</literal>. By October, we had\r | |
13363 | a working monomorphiser. By November, we added a polyvariant\r | |
13364 | higher-order control-flow analysis. At that point, MLton was about\r | |
13365 | 10,000 lines of code.</simpara>\r | |
13366 | <simpara>Over the next year and half, <literal>smlc</literal> morphed into a full-fledged\r | |
13367 | compiler for SML. It was renamed MLton, and first released in March\r | |
13368 | 1999.</simpara>\r | |
13369 | <simpara>From the start, MLton has been driven by whole-program optimization\r | |
13370 | and an emphasis on performance. Also from the start, MLton has had a\r | |
13371 | fast C FFI and <literal>IntInf</literal> based on the GNU multiprecision library. At\r | |
13372 | its 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 | |
13374 | as we added a native code generator, mllex, mlyacc, a profiler, many\r | |
13375 | optimizations, and many libraries including threads and signal\r | |
13376 | handling.</simpara>\r | |
13377 | <simpara>During 2002, MLton grew to 112,204 lines and we had releases in April\r | |
13378 | and September. We added support for cross compilation and used this\r | |
13379 | to enable MLton to run on Cygwin/Windows and FreeBSD. We also made\r | |
13380 | improvements to the garbage collector, so that it now works with large\r | |
13381 | arrays and up to 4G of memory and so that it automatically uses\r | |
13382 | copying, mark-compact, or generational collection depending on heap\r | |
13383 | usage and RAM size. We also continued improvements to the optimizer\r | |
13384 | and libraries.</simpara>\r | |
13385 | <simpara>During 2003, MLton grew to 122,299 lines and we had releases in March\r | |
13386 | and July. We extended the profiler to support source-level profiling\r | |
13387 | of time and allocation and to display call graphs. We completed the\r | |
13388 | Basis Library implementation, and added new MLton-specific libraries\r | |
13389 | for weak pointers and finalization. We extended the FFI to allow\r | |
13390 | callbacks from C to SML. We added support for the Sparc/Solaris\r | |
13391 | platform, 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’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 | |
13398 | program 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 => (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 | |
13411 | name; 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 | |
13415 | operations that cause a call to be a nontail call are profiling\r | |
13416 | operations, and if so, moves them before the call, turning it into a\r | |
13417 | tail call. If you observe a program that has a tail call that appears\r | |
13418 | to 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 | |
13422 | the <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 | |
13424 | the profiler uses the <literal>Enter</literal>/<literal>Leave</literal> statements to infer the "local"\r | |
13425 | portion of the control stack at each program point. The profiler then\r | |
13426 | removes the <literal>Enter</literal>s/<literal>Leave</literal>s and inserts different information\r | |
13427 | depending 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 | |
13429 | code (i.e. each statement has a unique label in its basic block that\r | |
13430 | prefixes it) and associates each label with the local control stack.\r | |
13431 | For time profiling (with the <link linkend="CCodegen">CCodegen</link> and <link linkend="LLVMCodegen">LLVMCodegen</link>), the profiler\r | |
13432 | inserts code that sets a global field that records the local control\r | |
13433 | stack. For allocation profiling, the profiler inserts calls to a C\r | |
13434 | function that will maintain byte counts. With stack profiling, the\r | |
13435 | profiler also inserts a call to a C function at each nontail call in\r | |
13436 | order to maintain information at runtime about what SML functions are\r | |
13437 | on the stack.</simpara>\r | |
13438 | <simpara>At run time, the profiler associates counters (either clock ticks or\r | |
13439 | byte counts) with source functions. When the program finishes, the\r | |
13440 | profiler 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 | |
13442 | associate the counts in the <literal>mlmon.out</literal> file with source\r | |
13443 | functions.</simpara>\r | |
13444 | <simpara>For time profiling, the profiler catches the <literal>SIGPROF</literal> signal 100\r | |
13445 | times per second and increments the appropriate counter, determined by\r | |
13446 | looking at the label prefixing the current program counter and mapping\r | |
13447 | that 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 | |
13451 | end of the program after the data is written.</simpara>\r | |
13452 | <simpara>Profiling has not been tested with signals or threads. In particular,\r | |
13453 | stack 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 | |
13460 | identifiers.</simpara>\r | |
13461 | <itemizedlist>\r | |
13462 | <listitem>\r | |
13463 | <simpara>\r | |
13464 | Alphanumeric: 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 | |
13470 | Symbolic: a sequence of the following\r | |
13471 | </simpara>\r | |
13472 | <screen> ! % & $ # + - / : < = > ? @ | ~ ` ^ | *</screen>\r | |
13473 | <simpara>Examples: <literal>+=</literal>, <literal><=</literal>, <literal>>></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 | |
13478 | have additional syntactic rules.</simpara>\r | |
13479 | <itemizedlist>\r | |
13480 | <listitem>\r | |
13481 | <simpara>\r | |
13482 | Identifiers not starting with a prime.\r | |
13483 | </simpara>\r | |
13484 | <itemizedlist>\r | |
13485 | <listitem>\r | |
13486 | <simpara>\r | |
13487 | value identifier (includes variables and constructors)\r | |
13488 | </simpara>\r | |
13489 | </listitem>\r | |
13490 | <listitem>\r | |
13491 | <simpara>\r | |
13492 | type constructor\r | |
13493 | </simpara>\r | |
13494 | </listitem>\r | |
13495 | <listitem>\r | |
13496 | <simpara>\r | |
13497 | structure identifier\r | |
13498 | </simpara>\r | |
13499 | </listitem>\r | |
13500 | <listitem>\r | |
13501 | <simpara>\r | |
13502 | signature identifier\r | |
13503 | </simpara>\r | |
13504 | </listitem>\r | |
13505 | <listitem>\r | |
13506 | <simpara>\r | |
13507 | functor identifier\r | |
13508 | </simpara>\r | |
13509 | </listitem>\r | |
13510 | </itemizedlist>\r | |
13511 | </listitem>\r | |
13512 | <listitem>\r | |
13513 | <simpara>\r | |
13514 | Identifiers starting with a prime.\r | |
13515 | </simpara>\r | |
13516 | <itemizedlist>\r | |
13517 | <listitem>\r | |
13518 | <simpara>\r | |
13519 | type variable\r | |
13520 | </simpara>\r | |
13521 | </listitem>\r | |
13522 | </itemizedlist>\r | |
13523 | </listitem>\r | |
13524 | <listitem>\r | |
13525 | <simpara>\r | |
13526 | Identifiers not starting with a prime and numeric labels (<literal>1</literal>, <literal>2</literal>, …).\r | |
13527 | </simpara>\r | |
13528 | <itemizedlist>\r | |
13529 | <listitem>\r | |
13530 | <simpara>\r | |
13531 | record 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 | |
13543 | immutable. For example, constants, tuples, records, lists, and\r | |
13544 | vectors 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 | |
13550 | variable 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 | |
13552 | the <link linkend="ValueRestriction">ValueRestriction</link> in an earlier version of SML, but no longer play\r | |
13553 | a 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 | |
13635 | installs 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 | |
13650 | the function of type <literal>unit -> unit</literal> that should be called on program\r | |
13651 | exit.</simpara>\r | |
13652 | <itemizedlist>\r | |
13653 | <listitem>\r | |
13654 | <simpara>\r | |
13655 | The 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 =>\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 | |
13667 | val topLevelSuffixCell =\r | |
13668 | Ref_ref (z_0)</programlisting>\r | |
13669 | </listitem>\r | |
13670 | <listitem>\r | |
13671 | <simpara>\r | |
13672 | Any 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 | |
13682 | The 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 | |
13686 | val z_0 =\r | |
13687 | ()\r | |
13688 | val 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 | |
13699 | provides functions designed to be used as infix operators there are\r | |
13700 | several obvious alternatives:</simpara>\r | |
13701 | <itemizedlist>\r | |
13702 | <listitem>\r | |
13703 | <simpara>\r | |
13704 | Use only prefix applications. Unfortunately there are situations\r | |
13705 | where infix applications lead to considerably more readable code.\r | |
13706 | </simpara>\r | |
13707 | </listitem>\r | |
13708 | <listitem>\r | |
13709 | <simpara>\r | |
13710 | Make the fixity declarations at the top-level. This may lead to\r | |
13711 | collisions and may be unsustainable in a large project. Pollution of\r | |
13712 | the top-level should be avoided.\r | |
13713 | </simpara>\r | |
13714 | </listitem>\r | |
13715 | <listitem>\r | |
13716 | <simpara>\r | |
13717 | Make the fixity declarations at each scope where you want to use\r | |
13718 | infix applications. The duplication becomes inconvenient if the\r | |
13719 | operators are widely used. Duplication of code should be avoided.\r | |
13720 | </simpara>\r | |
13721 | </listitem>\r | |
13722 | <listitem>\r | |
13723 | <simpara>\r | |
13724 | Use non-standard extensions, such as the <link linkend="MLBasis">ML Basis system</link>\r | |
13725 | to control the scope of fixity declarations. This has the obvious\r | |
13726 | drawback of reduced portability.\r | |
13727 | </simpara>\r | |
13728 | </listitem>\r | |
13729 | <listitem>\r | |
13730 | <simpara>\r | |
13731 | Reuse existing infix operator symbols (<literal>^</literal>, <literal>+</literal>, <literal>-</literal>, …). This\r | |
13732 | can be convenient when the standard operators aren’t needed in the\r | |
13733 | same scope with the new operators. On the other hand, one is limited\r | |
13734 | to 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 | |
13739 | describes a slightly less obvious alternative that can sometimes be\r | |
13740 | useful. The idea is to approximate Haskell’s special syntax for\r | |
13741 | treating any identifier enclosed in grave accents (backquotes) as an\r | |
13742 | infix operator. In Haskell, instead of writing the prefix application\r | |
13743 | <literal>f x y</literal> one can write the infix application <literal>x `f` y</literal>.</simpara>\r | |
13744 | <section id="_infixing_operators">\r | |
13745 | <title>Infixing operators</title>\r | |
13746 | <simpara>Let’s first take a look at the definitions of the operators:</simpara>\r | |
13747 | <programlisting language="sml" linenumbering="unnumbered">infix 3 <\ fun x <\ f = fn y => f (x, y) (* Left section *)\r | |
13748 | infix 3 \> fun f \> y = f y (* Left application *)\r | |
13749 | infixr 3 /> fun f /> y = fn x => f (x, y) (* Right section *)\r | |
13750 | infixr 3 </ fun x </ f = f x (* Right application *)\r | |
13751 | \r | |
13752 | infix 2 o (* See motivation below *)\r | |
13753 | infix 0 :=</programlisting>\r | |
13754 | <simpara>The left and right sectioning operators, <literal><\</literal> and <literal>/></literal>, are useful in\r | |
13755 | SML for partial application of infix operators.\r | |
13756 | <link linkend="References_Paulson96">ML For the Working Programmer</link> describes curried\r | |
13757 | functions <literal>secl</literal> and <literal>secr</literal> for the same purpose on pages 179-181.\r | |
13758 | For example,</simpara>\r | |
13759 | <programlisting language="sml" linenumbering="unnumbered">List.map (op- /> 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 <\ 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>\></literal> and <literal></</literal>,\r | |
13764 | the 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 | |
13766 | general,</simpara>\r | |
13767 | <screen>x0 <\f1\> x1 <\f2\> x2 ... <\fN\> xN = fN (... f2 (f1 (x0, x1), x2) ..., xN)</screen>\r | |
13768 | <simpara>and</simpara>\r | |
13769 | <screen>xN </fN/> ... x2 </f2/> x1 </f1/> 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 | |
13773 | comparisons:</simpara>\r | |
13774 | <programlisting language="sml" linenumbering="unnumbered">structure Order (* ... *) =\r | |
13775 | struct\r | |
13776 | (* ... *)\r | |
13777 | val orWhenEq = fn (EQUAL, th) => th ()\r | |
13778 | | (other, _) => 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) <\Order.orWhenEq\> `fbe (b, e) <\Order.orWhenEq\> `fcf (c, f)</programlisting>\r | |
13785 | <simpara>where <literal>`</literal> is defined as</simpara>\r | |
13786 | <programlisting language="sml" linenumbering="unnumbered">fun `f x = fn () => f x</programlisting>\r | |
13787 | <simpara>Although <literal>orWhenEq</literal> can be convenient (try rewriting the above without\r | |
13788 | it), it is probably not useful enough to be defined at the top level\r | |
13789 | as an infix operator. Fortunately we can use the infixing operators\r | |
13790 | and don’t have to.</simpara>\r | |
13791 | <simpara>Another fairly realistic example would be to use the infixing operators with\r | |
13792 | the technique described on the <link linkend="Printf">Printf</link> page. Assuming that you would have\r | |
13793 | a <literal>Printf</literal> module binding <literal>printf</literal>, <literal>`</literal>, and formatting combinators\r | |
13794 | named <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 "<\int\>" and a string "<\string\>".") 13 "foo" end</programlisting>\r | |
13797 | <simpara>without having to duplicate the fixity declarations. Alternatively, you could\r | |
13798 | write</simpara>\r | |
13799 | <programlisting language="sml" linenumbering="unnumbered">P.printf (P.`"Here's an int "<\P.int\>" and a string "<\P.string\>".") 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 | |
13807 | convenience on their own. In general,</simpara>\r | |
13808 | <screen>f \> x1 \> ... \> xN = f x1 ... xN</screen>\r | |
13809 | <simpara>and</simpara>\r | |
13810 | <screen>xN </ ... </ x1 </ 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 \> 1 + 2</programlisting>\r | |
13813 | <simpara>The left and right application operators are related to operators\r | |
13814 | that could be described as the right and left piping operators:</simpara>\r | |
13815 | <programlisting language="sml" linenumbering="unnumbered">infix 1 >| val op>| = op</ (* Left pipe *)\r | |
13816 | infixr 1 |< val op|< = op\> (* Right pipe *)</programlisting>\r | |
13817 | <simpara>As you can see, the left and right piping operators, <literal>>|</literal> and <literal>|<</literal>,\r | |
13818 | are the same as the right and left application operators,\r | |
13819 | respectively, except the associativities are reversed and the binding\r | |
13820 | strength is lower. They are useful for piping data through a sequence\r | |
13821 | of operations. In general,</simpara>\r | |
13822 | <screen>x >| f1 >| ... >| fN = fN (... (f1 x) ...) = (fN o ... o f1) x</screen>\r | |
13823 | <simpara>and</simpara>\r | |
13824 | <screen>fN |< ... |< f1 |< x = fN (... (f1 x) ...) = (fN o ... o f1) x</screen>\r | |
13825 | <simpara>The right piping operator, <literal>|<</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 | |
13828 | strict language, like SML, eta-reduction is generally unsafe. Using\r | |
13829 | the left piping operator, parsing functions can be formatted\r | |
13830 | conveniently as</simpara>\r | |
13831 | <programlisting language="sml" linenumbering="unnumbered">fun parsingFunc input =\r | |
13832 | input >| (* ... *)\r | |
13833 | || (* ... *)\r | |
13834 | || (* ... *)</programlisting>\r | |
13835 | <simpara>where <literal>||</literal> is supposed to be a combinator provided by the parsing combinator\r | |
13836 | library.</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 | |
13843 | necessary, but can be convenient and should be relatively\r | |
13844 | safe. Consider the following motivating examples from\r | |
13845 | <link linkend="WesleyTerpstra">Wesley W. Terpstra</link> relying on the redefined\r | |
13846 | precedences:</simpara>\r | |
13847 | <programlisting language="sml" linenumbering="unnumbered">Word8.fromInt o Char.ord o s <\String.sub\r | |
13848 | (* Combining sectioning and composition *)\r | |
13849 | \r | |
13850 | x := s <\String.sub\> 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 | |
13855 | an expression of the form <literal>r := x</literal> always returns a unit, which makes\r | |
13856 | little sense to combine with anything. Dropping <literal>:=</literal> to the lowest\r | |
13857 | precedence level makes it behave more like in other imperative\r | |
13858 | languages.</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’t seem to make much sense to use <literal>o</literal> with any of the\r | |
13861 | operators defined by the <link linkend="BasisLibrary">Basis Library</link> in an\r | |
13862 | unparenthesized expression. This is simply because none of the other\r | |
13863 | operators 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 | |
13865 | without having any adverse effects with respect to other infix\r | |
13866 | operators 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’s <literal>x `f` y</literal> syntax\r | |
13871 | achievable in Standard ML would probably be something like\r | |
13872 | <literal>x `f^ y</literal>, but <literal>^</literal> is already used for string\r | |
13873 | concatenation by the <link linkend="BasisLibrary">Basis Library</link>. Other\r | |
13874 | combinations of the characters <literal>`</literal> and <literal>^</literal> would be\r | |
13875 | possible, but none seems clearly the best visually. The symbols <literal><\</literal>,\r | |
13876 | <literal>\></literal>, <literal></</literal>, and <literal>/></literal> are reasonably concise and have a certain\r | |
13877 | self-documenting appearance and symmetry, which can help to remember\r | |
13878 | them. As the names suggest, the symbols of the piping operators <literal>>|</literal>\r | |
13879 | and <literal>|<</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> — inline any function satisfying <literal>(numCalls - 1) * (size - small) <= 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> — 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> — 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 | |
13990 | binary 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 | |
13996 | via <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 | |
14067 | however, 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 | |
14092 | well as example SML programs (in the <literal>examples</literal> directory), and license\r | |
14093 | information.</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 | |
14099 | with 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 | |
14104 | small 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’s <literal>bash</literal> and\r | |
14109 | <literal>tar</literal>. The use of an archiving tool that is not aware of Cygwin’s\r | |
14110 | mounts 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 | |
14168 | position 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 | |
14226 | at 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 | |
14244 | constructor 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 [] => 0\r | |
14249 | | [x] => x\r | |
14250 | | _ :: l => last l\r | |
14251 | \r | |
14252 | val _ = 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 => L_73 | ::_0 => 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 => L_75 | _ => 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 => L_73 | ::_0 => 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 => L_75 | ::_0 => 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 | |
14299 | effect 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 | |
14307 | the 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 | |
14317 | to 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 | |
14338 | the 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 | |
14340 | Furthermore, for a <literal>Lambda</literal> bound in a <literal>Fun</literal> dec, <literal>lambdaRec</literal> gives\r | |
14341 | the 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 => ... y ... g ... f ...\r | |
14345 | and g = fn z => ... f ... w ...</screen>\r | |
14346 | <screen>lambdaFree(fn x =>) = [y, w]\r | |
14347 | lambdaFree(fn z =>) = [y, w]\r | |
14348 | lambdaRec(fn x =>) = [g, f]\r | |
14349 | lambdaRec(fn z =>) = [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 | |
14356 | compiles. In short, we are conservative about making such changes.\r | |
14357 | There 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 | |
14362 | extremely high standard of specification. The value of the Definition\r | |
14363 | would be significantly diluted by changes that are not specified at an\r | |
14364 | equally high level, and the dilution increases with the complexity of\r | |
14365 | the language change and its interaction with other language features.\r | |
14366 | </simpara>\r | |
14367 | </listitem>\r | |
14368 | <listitem>\r | |
14369 | <simpara>\r | |
14370 | The SML community is small and there are a number of\r | |
14371 | <link linkend="StandardMLImplementations">SML implementations</link>. Without an\r | |
14372 | agreed-upon standard, it becomes very difficult to port programs\r | |
14373 | between compilers, and the community would be balkanized.\r | |
14374 | </simpara>\r | |
14375 | </listitem>\r | |
14376 | <listitem>\r | |
14377 | <simpara>\r | |
14378 | Our main goal is to enable programmers to be as effective as\r | |
14379 | possible with MLton/SML. There are a number of improvements other\r | |
14380 | than language changes that we could spend our time on that would\r | |
14381 | provide more benefit to programmers.\r | |
14382 | </simpara>\r | |
14383 | </listitem>\r | |
14384 | <listitem>\r | |
14385 | <simpara>\r | |
14386 | The more the language that MLton compiles changes over time, the\r | |
14387 | more difficult it is to use MLton as a stable platform for serious\r | |
14388 | program 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 | |
14411 | that is impossible to achieve without them or have non-trivial\r | |
14412 | community support. The Definition does not define a foreign function\r | |
14413 | interface. So, we must either extend the language or greatly restrict\r | |
14414 | the class of programs that can be written. Similarly, the Definition\r | |
14415 | does not provide a mechanism for namespace control at the module\r | |
14416 | level, making it impossible to deliver packaged libraries and have a\r | |
14417 | hope of users using them without name clashes. The ML Basis system\r | |
14418 | addresses this problem. We have also provided a formal specification\r | |
14419 | of 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 | |
14440 | not evaluated before calling the function. Instead, the arguments are\r | |
14441 | suspended 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 | |
14443 | language. However, it is easy to delay evaluation of an expression in\r | |
14444 | SML by creating a <emphasis>thunk</emphasis>, which is a nullary function. In SML, a\r | |
14445 | thunk is written <literal>fn () => e</literal>. Another essential feature of laziness\r | |
14446 | is <emphasis>memoization</emphasis>, meaning that once a suspended argument is evaluated,\r | |
14447 | subsequent references look up the value. We can express this in SML\r | |
14448 | with 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 -> 'a) -> unit -> '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 -> 'a): unit -> 'a =\r | |
14457 | let\r | |
14458 | datatype 'a lazy_result = Unevaluated of (unit -> '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 () =>\r | |
14465 | case !r of\r | |
14466 | Unevaluated th => let\r | |
14467 | val a = th ()\r | |
14468 | handle x => (r := Failed x; raise x)\r | |
14469 | val () = r := Evaluated a\r | |
14470 | in\r | |
14471 | a\r | |
14472 | end\r | |
14473 | | Evaluated a => a\r | |
14474 | | Failed x => 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 | |
14482 | MLton. However, often large SML projects use implementation specific\r | |
14483 | features so some "porting" is required. Here is a partial list of\r | |
14484 | software that is known to run on MLton.</simpara>\r | |
14485 | <itemizedlist>\r | |
14486 | <listitem>\r | |
14487 | <simpara>\r | |
14488 | Utility 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 | |
14520 | Scanner 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 | |
14542 | Parser 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 | |
14564 | Concurrency: <link linkend="ConcurrentML">ConcurrentML</link> - distributed with MLton\r | |
14565 | </simpara>\r | |
14566 | </listitem>\r | |
14567 | <listitem>\r | |
14568 | <simpara>\r | |
14569 | Graphics\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 | |
14586 | Misc. 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 | |
14642 | PostgreSQL\r | |
14643 | </simpara>\r | |
14644 | <itemizedlist>\r | |
14645 | <listitem>\r | |
14646 | <simpara>\r | |
14647 | Moscow 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 | |
14652 | SML/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 | |
14659 | Web:\r | |
14660 | </simpara>\r | |
14661 | <itemizedlist>\r | |
14662 | <listitem>\r | |
14663 | <simpara>\r | |
14664 | ML 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 | |
14669 | Moscow 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 | |
14674 | SML/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 | |
14686 | While Standard ML libraries should be designed with the <link linkend="MLBasis">MLBasis</link> system to work with other Standard ML programs,\r | |
14687 | system-level library support allows MLton to create libraries for use by other programming languages.\r | |
14688 | Even more importantly, system-level library support allows MLton to access libraries from other languages.\r | |
14689 | This 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 | |
14693 | Executable programs and dynamic libraries are the two most common examples of a DSO.\r | |
14694 | They are called shared because if they are used more than once, they are only loaded once into main memory.\r | |
14695 | For 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 | |
14696 | A dynamic library, for example a graphical toolkit, might be used by several different executable programs, each possibly running multiple times.\r | |
14697 | Nevertheless, the dynamic library is only loaded once and it’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 | |
14699 | These are used in order to make the DSO do something useful, like execute.\r | |
14700 | For 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 | |
14701 | Dynamic libraries generally provide many symbols, corresponding to functions which can be called and variables which can be read or written.\r | |
14702 | Symbols 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 | |
14704 | If a DSO needs to use a symbol, this is called <emphasis>importing</emphasis>.\r | |
14705 | A DSO might need to use symbols defined within itself or perhaps from another DSO.\r | |
14706 | In both cases, it is importing that symbol, but the scope of the import differs.\r | |
14707 | Similarly, a DSO might export a symbol for use only within itself, or it might export a symbol for use by other DSOs.\r | |
14708 | Some 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 | |
14713 | The notation <literal>_import "symbolname"</literal> imports functions, <literal>_symbol "symbolname"</literal> imports variables, and <literal>_address "symbolname"</literal> imports an address.\r | |
14714 | To 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 | |
14715 | For details of the syntax and restrictions on the supported FFI types, read the <link linkend="ForeignFunctionInterface">ForeignFunctionInterface</link> page.\r | |
14716 | In 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 | |
14718 | If the symbol should only be used within the same DSO, that symbol has <emphasis><literal>private</literal></emphasis> scope.\r | |
14719 | Conversely, if the symbol should also be available to other DSOs the symbol has <emphasis><literal>public</literal></emphasis> scope.\r | |
14720 | Generally, one should have as few public exports as possible.\r | |
14721 | Since they are public, other DSOs will come to depend on them, limiting your ability to change them.\r | |
14722 | You specify the export scope in MLton by putting <literal>private</literal> or <literal>public</literal> after the symbol’s name in an FFI directive.\r | |
14723 | eg: <literal>_export "foo" private: int->int;</literal> or <literal>_export "bar" public: int->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 | |
14725 | If the symbol is exported by the same DSO, use <literal>public</literal> or <literal>private</literal> as appropriate.\r | |
14726 | If the symbol is exported by a different DSO, then the scope <emphasis><literal>external</literal></emphasis> should be used to import it.\r | |
14727 | Within a DSO, all references to a symbol must use the same scope.\r | |
14728 | MLton will check this at compile time, reporting: <literal>symbol "foo" redeclared as public (previously external)</literal>. This may cause linker errors.\r | |
14729 | However, MLton can only check usage within Standard ML.\r | |
14730 | All objects being linked into a resulting DSO must agree, and it is the programmer’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 | |
14750 | All 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 | |
14758 | To link a shared library, use <literal>-link-opt -l<dso_name></literal>.\r | |
14759 | The default output format is executable.</simpara>\r | |
14760 | <simpara>MLton can also create archives.\r | |
14761 | An archive is not a DSO, but it does have a collection of symbols.\r | |
14762 | When an archive is linked into a DSO, it is completely absorbed.\r | |
14763 | Other 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 | |
14764 | However, 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 | |
14766 | For this reason, MLton can create two types or archives.\r | |
14767 | A normal archive (<literal>-format archive</literal>) is appropriate for linking into an executable.\r | |
14768 | Conversely, 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 | |
14770 | The symbol <literal>libname_open</literal> is a function which must be called before any other symbols are accessed.\r | |
14771 | The <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> → <literal>foo</literal>, <literal>libfoo</literal> → <literal>foo</literal>).\r | |
14772 | The 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 | |
14808 | When the output format is not an executable, it creates one by default named <literal>libname.h</literal>.\r | |
14809 | This can be overridden with <literal>-export-header foo.h</literal>.\r | |
14810 | This 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 | |
14812 | then the C code should <literal>#define PART_OF_LIBNAME</literal> before it includes the header file.\r | |
14813 | This ensures that the C code is using the symbols with correct scope.\r | |
14814 | Any 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 | |
14815 | The 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 | |
14820 | PUBLIC int cFoo() {\r | |
14821 | return smlFoo();\r | |
14822 | }</programlisting>\r | |
14823 | <programlisting language="sml" linenumbering="unnumbered">val () = _export "smlFoo" private: unit -> int; (fn () => 5)\r | |
14824 | val cFoo = _import "cFoo" public: unit -> 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 | |
14829 | However, depending on this will lead to portability problems.\r | |
14830 | Windows is also especially sensitive to mixups of <emphasis><literal>public</literal></emphasis> and <emphasis><literal>external</literal></emphasis>.\r | |
14831 | If an archive is linked, make sure it’s symbols are imported as <literal>public</literal>.\r | |
14832 | If a DLL is linked, make sure it’s symbols are imported as <literal>external</literal>.\r | |
14833 | Using <literal>external</literal> instead of <literal>public</literal> will result in link errors that <literal>__imp__foo is undefined</literal>.\r | |
14834 | Using <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 | |
14836 | Libarchives are quite rare, but necessary if creating a library from an archive.\r | |
14837 | It is common for a library to provide both an archive and a dynamic library on this platform.\r | |
14838 | The linker will pick one or the other, usually preferring the dynamic library.\r | |
14839 | While a quirk of the operating system allows external import to work for both archives and libraries,\r | |
14840 | portable projects should not depend on this behaviour.\r | |
14841 | On 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 | |
14850 | content in this web site, we require that contributions to the web\r | |
14851 | site be dedicated to the public domain. That means that you can only\r | |
14852 | add works that are already in the public domain, or that you must hold\r | |
14853 | the copyright on the work that you agree to dedicate the work to the\r | |
14854 | public domain.</simpara>\r | |
14855 | <simpara>By contributing to this web site, you agree to dedicate your\r | |
14856 | contribution 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 | |
14861 | below. By contributing code to the project, you agree to release the\r | |
14862 | code under this license. Contributors can retain copyright to their\r | |
14863 | contributions by asserting copyright in their code. Contributors may\r | |
14864 | also 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 | |
14873 | as <ulink url="http://www.eecs.harvard.edu/%7Enr/noweb/">Noweb</ulink>, MLton supports\r | |
14874 | comments 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 | |
14877 | source file. The first character of a source file has the position\r | |
14878 | 1.1. A line directive causes the front end to believe that the\r | |
14879 | character following the right parenthesis is at the line and column of\r | |
14880 | the specified file. A line directive only affects the reporting of\r | |
14881 | error messages and does not affect program semantics (except for\r | |
14882 | functions like <literal>MLton.Exn.history</literal> that report source file positions).\r | |
14883 | Syntactically invalid line directives are ignored. To prevent\r | |
14884 | incompatibilities with SML, the file name may not contain the\r | |
14885 | character 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 | |
14891 | reusable 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 | |
14910 | further optimized and compiled to native object code by the <link linkend="LLVM">LLVM</link>\r | |
14911 | toolchain.</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 | |
14914 | code size with this generator is usually slightly smaller than either\r | |
14915 | the <link linkend="AMD64Codegen">native</link> or the <link linkend="CCodegen">C</link> code generators. Compile\r | |
14916 | time 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 | |
14918 | or <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 | |
14949 | there 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 | |
14977 | global <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’t escape)\r | |
14983 | are 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 | |
15002 | global <literal>ref</literal> can only be moved into a function that is executed at\r | |
15003 | most 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 | |
15008 | analysis — 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 | |
15018 | all 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 | |
15025 | transformation\r | |
15026 | </simpara>\r | |
15027 | <itemizedlist>\r | |
15028 | <listitem>\r | |
15029 | <simpara>\r | |
15030 | rewrites <literal>r = Ref_ref x</literal> to <literal>r = x</literal>\r | |
15031 | </simpara>\r | |
15032 | </listitem>\r | |
15033 | <listitem>\r | |
15034 | <simpara>\r | |
15035 | rewrites <literal>_ = Ref_assign (r, y)</literal> to <literal>r = y</literal>\r | |
15036 | </simpara>\r | |
15037 | </listitem>\r | |
15038 | <listitem>\r | |
15039 | <simpara>\r | |
15040 | rewrites <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> — 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 | |
15147 | invoked 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 | |
15195 | by <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 | |
15199 | to 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 | |
15221 | some 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 | |
15226 | configuration 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 | |
15233 | followed by a file name and a list of files to compile, assemble, and\r | |
15234 | link 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 | |
15237 | a valid SML program, in which case MLton compiles the program to\r | |
15238 | produce an executable <literal>foo</literal>. Since MLton does not support separate\r | |
15239 | compilation, the program must be the entire program you wish to\r | |
15240 | compile. However, the program may refer to signatures and structures\r | |
15241 | defined 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 | |
15244 | compile the complete SML program described by the basis <literal>foo.mlb</literal>,\r | |
15245 | which 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 | |
15266 | nested tree (or dag) of simple case expressions and tests.</simpara>\r | |
15267 | <simpara>MLton’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 | |
15302 | nested 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 -> Var.t) -> Exp.t)) vector,\r | |
15324 | conTycon: Con.t -> Tycon.t,\r | |
15325 | region: Region.t,\r | |
15326 | test: Var.t,\r | |
15327 | testType: Type.t,\r | |
15328 | tyconCons: Tycon.t -> {con: Con.t, hasArg: bool} vector}\r | |
15329 | -> Exp.t * (unit -> ((Layout.t * {isOnlyExns: bool}) vector) vector)</programlisting>\r | |
15330 | <simpara><literal>matchCompile</literal> is complicated by the desire for modularity between the\r | |
15331 | match compiler and its caller. Its caller is responsible for building\r | |
15332 | the right hand side of a rule <literal>p => e</literal>. On the other hand, the match\r | |
15333 | compiler is responsible for destructing the test and binding new\r | |
15334 | variables to the components. In order to connect the new variables\r | |
15335 | created by the match compiler with the variables in the pattern <literal>p</literal>,\r | |
15336 | the match compiler passes an environment back to its caller that maps\r | |
15337 | each variable in <literal>p</literal> to the corresponding variable introduced by the\r | |
15338 | match compiler.</simpara>\r | |
15339 | <simpara>The match compiler builds a tree of n-way case expressions by working\r | |
15340 | from 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) => e1\r | |
15343 | | (C2 b, C3 c) => 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 | |
15348 | in\r | |
15349 | case x of\r | |
15350 | (x1, x2) =>\r | |
15351 | (case x1 of\r | |
15352 | C2 b' => (case x2 of\r | |
15353 | C1 a' => f1 a'\r | |
15354 | | C3 c' => f2(b',c')\r | |
15355 | | _ => raise Match)\r | |
15356 | | _ => (case x2 of\r | |
15357 | C1 a_ => f1 a_\r | |
15358 | | _ => raise Match))\r | |
15359 | end</programlisting>\r | |
15360 | <simpara>Here you can see the necessity of abstracting out the ride hand sides\r | |
15361 | of the cases in order to avoid code duplication. Right hand sides are\r | |
15362 | always abstracted. The simplifier cleans things up. You can also see\r | |
15363 | the new (primed) variables introduced by the match compiler and how\r | |
15364 | the renaming works. Finally, you can see how the match compiler\r | |
15365 | introduces the necessary default clauses in order to make a match\r | |
15366 | exhaustive, i.e. cover all the cases.</simpara>\r | |
15367 | <simpara>The match compiler uses <literal>numCons</literal> and <literal>tyconCons</literal> to determine\r | |
15368 | the 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 | |
15379 | is 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 | |
15385 | general maintenance\r | |
15386 | </simpara>\r | |
15387 | </listitem>\r | |
15388 | <listitem>\r | |
15389 | <simpara>\r | |
15390 | release 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 | |
15399 | understand <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’t Posix\r | |
15442 | </simpara>\r | |
15443 | </listitem>\r | |
15444 | <listitem>\r | |
15445 | <simpara>\r | |
15446 | coordinate 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 | |
15458 | Intel Research bug: <literal>no tyconRep property</literal> (company won’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 | |
15470 | treatment 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 | |
15487 | representation 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 | |
15504 | John 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 | |
15511 | page 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’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 | |
15533 | It 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 | |
15540 | The <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 | |
15545 | PolySpace bug: <link linkend="Redundant">Redundant</link> optimization (company won’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 | |
15557 | treatment 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 | |
15579 | Use <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 | |
15596 | Implement 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 | |
15608 | Enrich 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 | |
15625 | PolySpace 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 | |
15637 | eliminate <literal>-build-constants</literal>\r | |
15638 | </simpara>\r | |
15639 | <itemizedlist>\r | |
15640 | <listitem>\r | |
15641 | <simpara>\r | |
15642 | all <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 | |
15647 | generate <literal>gen-constants.c</literal> from <literal>basis-ffi.def</literal>\r | |
15648 | </simpara>\r | |
15649 | </listitem>\r | |
15650 | <listitem>\r | |
15651 | <simpara>\r | |
15652 | generate <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 | |
15657 | similar 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 | |
15664 | eliminate "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 | |
15676 | extend IL type checkers to check for empty property lists\r | |
15677 | </simpara>\r | |
15678 | </listitem>\r | |
15679 | <listitem>\r | |
15680 | <simpara>\r | |
15681 | make (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 | |
15699 | but is available at the\r | |
15700 | <ulink url="http://sourceforge.net/project/showfiles.php?group_id=23226&package_id=16523">file\r | |
15701 | release page</ulink>. To test it, after unpacking, do <literal>cd examples; make\r | |
15702 | mlton</literal>, after which you should be able to run the many examples\r | |
15703 | (<literal>signup-mlton</literal>, <literal>listview-mlton</literal>, …).</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’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’s beginning to look as if one route forward will be to embed an SML interpreter into a MLton-compiled executable. I don’t know if an extensible interpreter of the kind we’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 | |
15738 | 1970s as a programming language to assist theorem proving in the logic\r | |
15739 | LCF. 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 | |
15741 | today.</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 | |
15747 | parser 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 | |
15768 | programming-in-the-very-large, namespace management at the module\r | |
15769 | level, separate delivery of library sources, and more. While Standard\r | |
15770 | ML modules are a sophisticated language for programming-in-the-large,\r | |
15771 | it is difficult, if not impossible, to accomplish a number of routine\r | |
15772 | namespace management operations when a program draws upon multiple\r | |
15773 | libraries provided by different vendors.</simpara>\r | |
15774 | <simpara>The ML Basis system is a simple, yet powerful, approach that builds\r | |
15775 | upon the programmer’s intuitive notion (and\r | |
15776 | <link linkend="DefinitionOfStandardML">The Definition of Standard ML (Revised)</link>'s\r | |
15777 | formal notion) of the top-level environment (a <emphasis>basis</emphasis>). The system\r | |
15778 | is designed as a natural extension of <link linkend="StandardML">Standard ML</link>; the\r | |
15779 | formal 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 | |
15781 | of 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 | |
15786 | Explicit file order: The order of files (and, hence, the order of\r | |
15787 | evaluation) in the program is explicit. The ML Basis system’s\r | |
15788 | semantics are structured in such a way that for any well-formed\r | |
15789 | project, there will be exactly one possible interpretation of the\r | |
15790 | project’s syntax, static semantics, and dynamic semantics.\r | |
15791 | </simpara>\r | |
15792 | </listitem>\r | |
15793 | <listitem>\r | |
15794 | <simpara>\r | |
15795 | Implicit dependencies: A source file (corresponding to an SML\r | |
15796 | top-level declaration) is elaborated in the environment described by\r | |
15797 | preceding declarations. It is not necessary to explicitly list the\r | |
15798 | dependencies of a file.\r | |
15799 | </simpara>\r | |
15800 | </listitem>\r | |
15801 | <listitem>\r | |
15802 | <simpara>\r | |
15803 | Scoping and renaming: The ML Basis system provides mechanisms for\r | |
15804 | limiting the scope of (i.e, hiding) and renaming identifiers.\r | |
15805 | </simpara>\r | |
15806 | </listitem>\r | |
15807 | <listitem>\r | |
15808 | <simpara>\r | |
15809 | No naming convention for finding the file that defines a module.\r | |
15810 | To import a module, its defining file must appear in some ML Basis\r | |
15811 | file.\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 | |
15853 | nonexhaustive patterns, relying on invariants of the generated code to\r | |
15854 | ensure that the pattern matchings never fail. A programmer may wish\r | |
15855 | to elide the nonexhaustive warnings from this code, in order that\r | |
15856 | legitimate warnings are not missed in a flurry of false positives. To\r | |
15857 | do so, the programmer simply annotates the generated code with the\r | |
15858 | <literal>nonexhaustiveBind ignore</literal> and <literal>nonexhaustiveMatch ignore</literal>\r | |
15859 | annotations:</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 | |
15869 | in\r | |
15870 | signature FOO\r | |
15871 | structure Foo\r | |
15872 | end</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 | |
15877 | such libraries should strive to be mindful of the ways in which\r | |
15878 | programmers may choose to compile their programs. For example,\r | |
15879 | although 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 | |
15881 | defaulted to <literal>warn</literal> and <literal>true</literal> can help uncover likely bugs. However,\r | |
15882 | a programmer is unlikely to be interested in unused modules from an\r | |
15883 | imported library, and the behavior of <literal>sequenceNonUnit error</literal> may be\r | |
15884 | incompatible with some libraries. Hence, a library author may choose\r | |
15885 | to 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 | |
15891 | in\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 | |
15904 | end</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 | |
15907 | warn</literal> have the obvious effect on elaboration. The annotations\r | |
15908 | <literal>warnUnused true</literal> and <literal>forceUsed</literal> work in conjunction — warning on\r | |
15909 | any identifiers that do not contribute to the exported modules, and\r | |
15910 | preventing warnings on exported modules that are not used in the\r | |
15911 | remainder of the program. Many of the\r | |
15912 | <link linkend="MLBasisAvailableLibraries">available libraries</link> are delivered with\r | |
15913 | these 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 | |
15920 | elaboration of SML source files. Conceptually, a basis file is\r | |
15921 | elaborated in a default annotation environment (just as it is\r | |
15922 | elaborated in an empty basis). The declaration\r | |
15923 | <literal>ann</literal> <literal>"</literal><emphasis>ann</emphasis><literal>"</literal> <literal>in</literal> <emphasis>basdec</emphasis> <literal>end</literal>\r | |
15924 | merges the annotation <emphasis>ann</emphasis> with the "current" annotation environment\r | |
15925 | for 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 | |
15927 | conveniently specify multiple annotations, the following derived form\r | |
15928 | is 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 | ⇒\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 | |
15935 | annotations that take an argument, the first value listed is the\r | |
15936 | default.</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 | |
15943 | expressions 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 | |
15951 | proxy 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 | |
15964 | proxy 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 | |
15992 | first function-value binding of a <literal>fun</literal> declaration, and allow a bar\r | |
15993 | to 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 | |
16001 | sequence 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 | |
16021 | signature.</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 | |
16028 | proxy 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 | |
16051 | be 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 | |
16058 | declarations (i.e., pattern-match failures that raise the <literal>Bind</literal>\r | |
16059 | exception). 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 | |
16066 | in <literal>val</literal> declarations that arise solely from unmatched exceptions.\r | |
16067 | If <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 | |
16074 | in <literal>fn</literal> expressions, <literal>case</literal> expressions, and <literal>fun</literal> declarations that\r | |
16075 | arise solely from unmatched exceptions. If <literal>default</literal>, follow the\r | |
16076 | behavior 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 | |
16083 | in <literal>handle</literal> expressions that arise solely from unmatched exceptions.\r | |
16084 | If <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 | |
16091 | expressions, <literal>case</literal> expressions, and <literal>fun</literal> declarations (i.e.,\r | |
16092 | pattern-match failures that raise the <literal>Match</literal> exception). An error\r | |
16093 | will 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 | |
16100 | expressions (i.e., pattern-match failures that implicitly (re)raise\r | |
16101 | the unmatched exception). An error will abort a compile, while a\r | |
16102 | warning 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 | |
16109 | An 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 | |
16117 | compile, 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 | |
16124 | expressions. 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 | |
16131 | to default types (if not otherwise resolved by type inference) and the\r | |
16132 | scope at which unresolved flexible record constraints are reported.</simpara>\r | |
16133 | <simpara>The syntactic-class argument means to perform resolution checks at the\r | |
16134 | smallest enclosing syntactic form of the given class. The default\r | |
16135 | behavior is to resolve at the smallest enclosing <emphasis>strdec</emphasis> (which is\r | |
16136 | equivalent to the largest enclosing <emphasis>dec</emphasis>). Other useful behaviors\r | |
16137 | are to resolve at the smallest enclosing <emphasis>topdec</emphasis> (which is equivalent\r | |
16138 | to 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 | |
16140 | correspond 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 | |
16147 | sequence expression <literal>(e1; e2)</literal>. This can be helpful in detecting\r | |
16148 | curried applications that are mistakenly not fully applied. To\r | |
16149 | silence 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 | |
16156 | redefines an identifier that previously had constructor status. An\r | |
16157 | error 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 | |
16269 | fragments of the <link linkend="BasisLibrary">Basis Library</link> that can not be\r | |
16270 | expressed 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><></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>, …,\r | |
16324 | <literal>filen.sml</literal>, which depend upon libraries <literal>lib1.mlb</literal>, …, <literal>libm.mlb</literal>.</simpara>\r | |
16325 | <screen>(* import libraries *)\r | |
16326 | lib1.mlb\r | |
16327 | ...\r | |
16328 | libm.mlb\r | |
16329 | \r | |
16330 | (* program files *)\r | |
16331 | file1.sml\r | |
16332 | ...\r | |
16333 | filen.sml</screen>\r | |
16334 | <simpara>The bases denoted by <literal>lib1.mlb</literal>, …, <literal>libm.mlb</literal> are merged (bindings\r | |
16335 | of names in later bases take precedence over bindings of the same name\r | |
16336 | in earlier bases), producing a basis in which <literal>file1.sml</literal>, …,\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 | |
16342 | functors from a collection of files.</simpara>\r | |
16343 | <screen>local\r | |
16344 | file1.sml\r | |
16345 | ...\r | |
16346 | filen.sml\r | |
16347 | in\r | |
16348 | (* export filter here *)\r | |
16349 | functor F\r | |
16350 | structure S\r | |
16351 | end</screen>\r | |
16352 | <simpara>While <literal>file1.sml</literal>, …, <literal>filen.sml</literal> may declare top-level identifiers\r | |
16353 | in addition to <literal>F</literal> and <literal>S</literal>, such names are not accessible to programs\r | |
16354 | and 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 | |
16359 | modules.</simpara>\r | |
16360 | <screen>local\r | |
16361 | file1.sml\r | |
16362 | ...\r | |
16363 | filen.sml\r | |
16364 | in\r | |
16365 | (* export filter, with renaming, here *)\r | |
16366 | functor F\r | |
16367 | structure S' = S\r | |
16368 | end</screen>\r | |
16369 | <simpara>Note that <literal>functor F</literal> is an abbreviation for <literal>functor F = F</literal>, which\r | |
16370 | simply 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 | |
16375 | structure <literal>S</literal> from another library.</simpara>\r | |
16376 | <screen>local\r | |
16377 | lib1.mlb\r | |
16378 | in\r | |
16379 | (* import filter here *)\r | |
16380 | functor F\r | |
16381 | end\r | |
16382 | local\r | |
16383 | lib2.mlb\r | |
16384 | in\r | |
16385 | (* import filter here *)\r | |
16386 | structure S\r | |
16387 | end\r | |
16388 | file1.sml\r | |
16389 | ...\r | |
16390 | filen.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 | |
16395 | another structure <literal>S</literal> from another library.</simpara>\r | |
16396 | <screen>local\r | |
16397 | lib1.mlb\r | |
16398 | in\r | |
16399 | (* import filter, with renaming, here *)\r | |
16400 | structure S1 = S\r | |
16401 | end\r | |
16402 | local\r | |
16403 | lib2.mlb\r | |
16404 | in\r | |
16405 | (* import filter, with renaming, here *)\r | |
16406 | structure S2 = S\r | |
16407 | end\r | |
16408 | file1.sml\r | |
16409 | ...\r | |
16410 | filen.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 | |
16415 | program and library components, MLB files provide convenient syntax\r | |
16416 | for renaming Modules level identifiers (in fact, renaming of functor\r | |
16417 | identifiers provides a mechanism that is not available in SML).\r | |
16418 | However, please note that <literal>.mlb</literal> files elaborate to full bases\r | |
16419 | including top-level types and values (including infix status), in\r | |
16420 | addition to structures, signatures, and functors. For example,\r | |
16421 | suppose 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 | |
16423 | and some operations should be available at the top-level;\r | |
16424 | additionally, a signature and structure provide the complete\r | |
16425 | interface.</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 & : ('a -> 'c) * ('b -> 'c) -> ('a, 'b) either -> 'c\r | |
16432 | val && : ('a -> 'c) * ('b -> 'd) -> ('a, 'b) either -> ('c, 'd) either\r | |
16433 | end\r | |
16434 | \r | |
16435 | signature EITHER =\r | |
16436 | sig\r | |
16437 | include EITHER_GLOBAL\r | |
16438 | val isLeft : ('a, 'b) either -> bool\r | |
16439 | val isRight : ('a, 'b) either -> 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 & g = fn x =>\r | |
16447 | case x of Left z => f z | Right z => g z\r | |
16448 | fun f && g = (Left o f) & (Right o g)\r | |
16449 | fun isLeft x = ((fn _ => true) & (fn _ => false)) x\r | |
16450 | fun isRight x = (not o isLeft) x\r | |
16451 | ...\r | |
16452 | end\r | |
16453 | structure EitherGlobal : EITHER_GLOBAL = Either</programlisting>\r | |
16454 | <simpara><literal>either-infixes.sml</literal></simpara>\r | |
16455 | <programlisting language="sml" linenumbering="unnumbered">infixr 3 & &&</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 | |
16460 | local\r | |
16461 | (* import Basis Library *)\r | |
16462 | $(SML_LIB)/basis/basis.mlb\r | |
16463 | either-sigs.sml\r | |
16464 | either-strs.sml\r | |
16465 | in\r | |
16466 | signature EITHER\r | |
16467 | structure Either\r | |
16468 | either-open.sml\r | |
16469 | end</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>&</literal> and <literal>&&</literal> (with infix status) in the\r | |
16473 | top-level environment. Note that <literal>either-infixes.sml</literal> is outside the\r | |
16474 | scope of the local, because we want the infixes available in the\r | |
16475 | implementation 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 | |
16482 | variables (of the form <literal>$(VAR)</literal>) to file system paths. ML Basis path\r | |
16483 | variables provide a flexible way to refer to libraries while allowing\r | |
16484 | them 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 | |
16486 | consists of two, white-space delimited tokens. The first token is a\r | |
16487 | path variable <literal>VAR</literal> and the second token is the path to which the\r | |
16488 | variable is mapped. The path may include path variables, which are\r | |
16489 | recursively expanded.</simpara>\r | |
16490 | <simpara>The mapping from path variables to paths is initialized by the compiler.\r | |
16491 | Additional path maps can be specified with <literal>-mlb-path-map</literal> and\r | |
16492 | individual path variable mappings can be specified with\r | |
16493 | <literal>-mlb-path-var</literal> (see <link linkend="CompileTimeOptions">CompileTimeOptions</link>). Configuration files are\r | |
16494 | processed from first to last and from top to bottom, later mappings\r | |
16495 | take precedence over earlier mappings.</simpara>\r | |
16496 | <simpara>The compiler and system-wide configuration file makes the following\r | |
16497 | path variables available.</simpara>\r | |
16498 | <informaltable\r | |
16499 | frame="all"\r | |
16500 | rowsep="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 | |
16544 | should 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> … <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 | |
16621 | directory containing the MLB file. Paths may include path variables\r | |
16622 | and are expanded according to a <link linkend="MLBasisPathMap">path map</link>. Unquoted\r | |
16623 | paths 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 | |
16626 | included by quoting the path with <literal>"</literal>. A quoted path is lexed as an\r | |
16627 | SML string constant.</simpara>\r | |
16628 | <simpara><link linkend="MLBasisAnnotations">Annotations</link> allow a library author to\r | |
16629 | control 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 | |
16634 | ML Basis files in the style of the\r | |
16635 | <link linkend="DefinitionOfStandardML">Definition</link>. Here, we give an informal\r | |
16636 | explanation.</simpara>\r | |
16637 | <simpara>An SML structure is a collection of types, values, and other\r | |
16638 | structures. Similarly, a basis is a collection, but of more kinds of\r | |
16639 | objects: types, values, structures, fixities, signatures, functors,\r | |
16640 | and other bases.</simpara>\r | |
16641 | <simpara>A basis declaration denotes a basis. A structure, signature, or\r | |
16642 | functor declaration denotes a basis containing the corresponding\r | |
16643 | module. Sequencing of basis declarations merges bases, with later\r | |
16644 | definitions taking precedence over earlier ones, just like sequencing\r | |
16645 | of SML declarations. Local declarations provide name hiding, just\r | |
16646 | like SML local declarations. A reference to an SML source file causes\r | |
16647 | the file to be elaborated in the basis extant at the point of\r | |
16648 | reference. A reference to an MLB file causes the basis denoted by\r | |
16649 | that MLB file to be imported — the basis at the point of reference\r | |
16650 | does <emphasis>not</emphasis> affect the imported basis.</simpara>\r | |
16651 | <simpara>Basis expressions and basis identifiers allow binding a basis to a\r | |
16652 | name.</simpara>\r | |
16653 | <simpara>An MLB file is elaborated starting in an empty basis. Each MLB file\r | |
16654 | is elaborated and evaluated only once, with the result being cached.\r | |
16655 | Subsequent references use the cached value. Thus, any observable\r | |
16656 | effects due to evaluation are not duplicated if the MLB file is\r | |
16657 | referred 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 | |
16665 | Java 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’97</link>\r | |
16693 | </simpara>\r | |
16694 | <itemizedlist>\r | |
16695 | <listitem>\r | |
16696 | <simpara>\r | |
16697 | including 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 | |
16710 | and 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 | |
16722 | and <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 | |
16729 | Multiple backends, including\r | |
16730 | </simpara>\r | |
16731 | <itemizedlist>\r | |
16732 | <listitem>\r | |
16733 | <simpara>\r | |
16734 | native x86,\r | |
16735 | </simpara>\r | |
16736 | </listitem>\r | |
16737 | <listitem>\r | |
16738 | <simpara>\r | |
16739 | bytecode, and\r | |
16740 | </simpara>\r | |
16741 | </listitem>\r | |
16742 | <listitem>\r | |
16743 | <simpara>\r | |
16744 | JavaScript (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 | |
16754 | concurrent programming / threads,\r | |
16755 | </simpara>\r | |
16756 | </listitem>\r | |
16757 | <listitem>\r | |
16758 | <simpara>\r | |
16759 | calling 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 | |
16768 | modeled 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 | |
16770 | distributed 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 | |
16774 | and 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 | |
16802 | Source 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 | |
16807 | DFA 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 | |
16812 | Output. 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 | |
16848 | is 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 | |
16850 | SML/NJ.</simpara>\r | |
16851 | <simpara>As of 20180119, MLton includes the ML-LPT Library synchronized with\r | |
16852 | SML/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 | |
16858 | You can import the ML-LPT Library into an MLB file with:\r | |
16859 | </simpara>\r | |
16860 | <informaltable\r | |
16861 | frame="all"\r | |
16862 | rowsep="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 | |
16884 | If you are porting a project from SML/NJ’s <link linkend="CompilationManager">CompilationManager</link> to\r | |
16885 | MLton’s <link linkend="MLBasis">ML Basis system</link> using <literal>cm2mlb</literal>, note that the\r | |
16886 | following 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 | |
16893 | output <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 | |
16922 | The string "<literal>MLton prof</literal>".\r | |
16923 | </simpara>\r | |
16924 | </listitem>\r | |
16925 | <listitem>\r | |
16926 | <simpara>\r | |
16927 | The string "<literal>alloc</literal>", "<literal>count</literal>", or "<literal>time</literal>", depending on the kind\r | |
16928 | of profiling information, corresponding to the command-line argument\r | |
16929 | supplied to <literal>mlton -profile</literal>.\r | |
16930 | </simpara>\r | |
16931 | </listitem>\r | |
16932 | <listitem>\r | |
16933 | <simpara>\r | |
16934 | The string "<literal>current</literal>" or "<literal>stack</literal>" depending on whether profiling\r | |
16935 | data was gathered for only the current function (the top of the stack)\r | |
16936 | or for all functions on the stack. This corresponds to whether the\r | |
16937 | executable was compiled with <literal>-profile-stack false</literal> or <literal>-profile-stack\r | |
16938 | true</literal>.\r | |
16939 | </simpara>\r | |
16940 | </listitem>\r | |
16941 | <listitem>\r | |
16942 | <simpara>\r | |
16943 | The magic number of the executable.\r | |
16944 | </simpara>\r | |
16945 | </listitem>\r | |
16946 | <listitem>\r | |
16947 | <simpara>\r | |
16948 | The number of non-gc ticks, followed by a space, then the number of\r | |
16949 | GC ticks.\r | |
16950 | </simpara>\r | |
16951 | </listitem>\r | |
16952 | <listitem>\r | |
16953 | <simpara>\r | |
16954 | The number of (split) functions for which data is recorded.\r | |
16955 | </simpara>\r | |
16956 | </listitem>\r | |
16957 | <listitem>\r | |
16958 | <simpara>\r | |
16959 | A line for each (split) function with counts. Each line contains an\r | |
16960 | integer count of the number of ticks while the function was current.\r | |
16961 | In addition, if stack data was gathered (<literal>-profile-stack true</literal>), then\r | |
16962 | the line contains two additional tick counts:\r | |
16963 | </simpara>\r | |
16964 | <itemizedlist>\r | |
16965 | <listitem>\r | |
16966 | <simpara>\r | |
16967 | the number of ticks while the function was on the stack.\r | |
16968 | </simpara>\r | |
16969 | </listitem>\r | |
16970 | <listitem>\r | |
16971 | <simpara>\r | |
16972 | the 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 | |
16980 | The number of (master) functions for which data is recorded.\r | |
16981 | </simpara>\r | |
16982 | </listitem>\r | |
16983 | <listitem>\r | |
16984 | <simpara>\r | |
16985 | A line for each (master) function with counts. The lines have the\r | |
16986 | same 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 | |
16996 | library for SML.</simpara>\r | |
16997 | <simpara>As of 20050212, MLton has an initial port of ML-NLFFI from SML/NJ to\r | |
16998 | MLton. 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 | |
17001 | details, the code generated by SML/NJ’s <literal>ml-nlffigen</literal> is not\r | |
17002 | compatible with MLton, and vice-versa. However, the generated code\r | |
17003 | has the same interface, so portable client code can be written.\r | |
17004 | MLton’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 | |
17011 | You can import the ML-NLFFI Library into an MLB file with\r | |
17012 | </simpara>\r | |
17013 | <informaltable\r | |
17014 | frame="all"\r | |
17015 | rowsep="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 | |
17037 | If you are porting a project from SML/NJ’s <link linkend="CompilationManager">CompilationManager</link> to\r | |
17038 | MLton’s <link linkend="MLBasis">ML Basis system</link> using <literal>cm2mlb</literal>, note that the\r | |
17039 | following 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 | |
17045 | file into a <literal>$(SML_LIB)/mlnlffi-lib/mlnlffi-lib.mlb</literal> import in the\r | |
17046 | output <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 | |
17075 | files. It is based on the <link linkend="CKitLibrary">CKitLibrary</link>, which is primarily designed\r | |
17076 | to handle standardized C and thus does not understand many (any?)\r | |
17077 | compiler extensions; however, it attempts to recover from errors when\r | |
17078 | seeing 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 | |
17082 | most portable libraries largely avoid the use of these types of\r | |
17083 | extensions in header files.</simpara>\r | |
17084 | <simpara><literal>mlnlffigen</literal> will normally not generate bindings for <literal>#included</literal>\r | |
17085 | files; 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’s implementation(s) of the <link linkend="MLNLFFI">MLNLFFI</link> library differs from the\r | |
17091 | SML/NJ implementation in two important ways:</simpara>\r | |
17092 | <itemizedlist>\r | |
17093 | <listitem>\r | |
17094 | <simpara>\r | |
17095 | MLton cannot utilize the <literal>Unsafe.cast</literal> "cheat" described in Section\r | |
17096 | 3.7 of <link linkend="References_Blume01">Blume01</link>. (MLton’s representation of\r | |
17097 | <link linkend="Closure">closures</link> and\r | |
17098 | <link linkend="PackedRepresentation">aggressive representation</link> optimizations make\r | |
17099 | an <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 | |
17105 | One solution is to utilize an additional type parameter (as\r | |
17106 | described 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 | |
17123 | end</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 | |
17125 | T.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 | |
17127 | will 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 | |
17132 | both the SML/NJ implementation and the MLton implementation, this\r | |
17133 | should not be a problem in practice. Tools, like <literal>ml-nlffigen</literal>, which\r | |
17134 | are 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 | |
17136 | parameter. Client code which uses such generated glue-code (e.g.,\r | |
17137 | Section 1 of <link linkend="References_Blume01">Blume01</link>) need rarely write type-annotations,\r | |
17138 | thanks to the magic of type inference.</simpara>\r | |
17139 | </listitem>\r | |
17140 | <listitem>\r | |
17141 | <simpara>\r | |
17142 | The above implementation suffers from two disadvantages.\r | |
17143 | </simpara>\r | |
17144 | <simpara>First, it changes the MLNLFFI Library interface, meaning that the same\r | |
17145 | program may not type-check under both the SML/NJ implementation and\r | |
17146 | the MLton implementation (though, in light of type inference and the\r | |
17147 | richer <literal>MLRep</literal> structure provided by MLton, this point is mostly\r | |
17148 | moot).</simpara>\r | |
17149 | <simpara>Second, it appears to unnecessarily duplicate type information. For\r | |
17150 | example, an external C variable of type <literal>int (* f[3])(int)</literal> (that is,\r | |
17151 | an array of three function pointers), would be represented by the SML\r | |
17152 | type <literal>(((sint -> sint) fptr, dec dg3) arr, sint -> sint, rw) obj</literal>.\r | |
17153 | One might well ask why the <literal>'f</literal> instantiation (<literal>sint -> sint</literal> in this\r | |
17154 | case) cannot be <emphasis>extracted</emphasis> from the <literal>'t</literal> instantiation\r | |
17155 | (<literal>((sint -> sint) fptr, dec dg3) arr</literal> in this case), obviating the\r | |
17156 | need for a separate <emphasis>function-type</emphasis> type argument. There are a number\r | |
17157 | of components to an complete answer to this question. Foremost is the\r | |
17158 | fact that <link linkend="StandardML">Standard ML</link> supports neither (general)\r | |
17159 | type-level functions nor intensional polymorphism.</simpara>\r | |
17160 | <simpara>A more direct answer for MLNLFFI is that in the SML/NJ implemention,\r | |
17161 | the definition of the types <literal>('t, 'c) obj</literal> and <literal>('t, 'c) ptr</literal> are made\r | |
17162 | in 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 | |
17164 | types <literal>((sint -> sint) fptr, rw) ptr</literal> and\r | |
17165 | <literal>((double -> double) fptr, rw) ptr</literal> necessarily carry distinct (and\r | |
17166 | type incompatible) run-time (C-)type information (RTTI), corresponding\r | |
17167 | to the different calling conventions of the two C functions. The\r | |
17168 | <literal>Unsafe.cast</literal> "cheat" overcomes the type incompatibility without\r | |
17169 | introducing 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 | |
17171 | the <literal>'t</literal> type variable instantiation is that the type of the\r | |
17172 | representation of RTTI doesn’t even <emphasis>see</emphasis> the (phantom) <literal>'t</literal> type\r | |
17173 | variable. The solution which presents itself is to give up on the\r | |
17174 | phantomness of the <literal>'t</literal> type variable, making it available to the\r | |
17175 | representation of RTTI.</simpara>\r | |
17176 | <simpara>This is not without some small drawbacks. Because many of the types\r | |
17177 | used to instantiate <literal>'t</literal> carry more structure than is strictly\r | |
17178 | necessary for <literal>'t</literal>'s RTTI, it is sometimes necessary to wrap and\r | |
17179 | unwrap RTTI to accommodate the additional structure. (In the other\r | |
17180 | implementations, the corresponding operations can pass along the RTTI\r | |
17181 | unchanged.) However, these coercions contribute minuscule overhead;\r | |
17182 | in fact, in a majority of cases, MLton’s optimizations will completely\r | |
17183 | eliminate 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’t one use a <link linkend="UniversalType">universal type</link>\r | |
17188 | to eliminate the use of <literal>Unsafe.cast</literal>?</simpara>\r | |
17189 | <itemizedlist>\r | |
17190 | <listitem>\r | |
17191 | <simpara>\r | |
17192 | Answer: ???\r | |
17193 | </simpara>\r | |
17194 | </listitem>\r | |
17195 | </itemizedlist>\r | |
17196 | </listitem>\r | |
17197 | <listitem>\r | |
17198 | <simpara>\r | |
17199 | MLton (in both of the above implementations) provides a richer\r | |
17200 | <literal>MLRep</literal> structure, utilizing <literal>Int<emphasis><N></emphasis></literal> and <literal>Word<emphasis><N></emphasis></literal>\r | |
17201 | structures.\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 <:SignedBitops:> = 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 <:SignedBitops:> = 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 <:SignedBitops:> = 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 <:SignedBitops:> = IntBitOps(structure I = Signed\r | |
17234 | structure W = Unsigned)\r | |
17235 | end\r | |
17236 | structure <:LongLong:> =\r | |
17237 | struct\r | |
17238 | structure Signed = Int64\r | |
17239 | structure Unsigned = Word64\r | |
17240 | (* word-style bit-operations on integers... *)\r | |
17241 | structure <:SignedBitops:> = IntBitOps(structure I = Signed\r | |
17242 | structure W = Unsigned)\r | |
17243 | end\r | |
17244 | structure Float = Real32\r | |
17245 | structure Double = Real64\r | |
17246 | end</programlisting>\r | |
17247 | <simpara>This would appear to be a better interface, even when an\r | |
17248 | implementation must choose <literal>Int32</literal> and <literal>Word32</literal> as the representation\r | |
17249 | for 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 | |
17257 | Library</ulink> is a framework for retargetable and optimizing compiler back\r | |
17258 | ends. The MLRISC Library is distributed with SML/NJ. Due to\r | |
17259 | differences between SML/NJ and MLton, this library will not work\r | |
17260 | out-of-the box with MLton.</simpara>\r | |
17261 | <simpara>As of 20180119, MLton includes a port of the MLRISC Library\r | |
17262 | synchronized 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 | |
17268 | You can import a sub-library of the MLRISC Library into an MLB file with:\r | |
17269 | </simpara>\r | |
17270 | <informaltable\r | |
17271 | frame="all"\r | |
17272 | rowsep="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 | |
17374 | If you are porting a project from SML/NJ’s <link linkend="CompilationManager">CompilationManager</link> to\r | |
17375 | MLton’s <link linkend="MLBasis">ML Basis system</link> using <literal>cm2mlb</literal>, note that the\r | |
17376 | following 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 | |
17381 | an input <literal>.cm</literal> file into a <literal>$(SML_LIB)/mlrisc-lib/mlb/MLRISC.mlb</literal>\r | |
17382 | import 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 | |
17389 | deriving the <literal>.mlb</literal> files from the <literal>.cm</literal> files:</simpara>\r | |
17390 | <itemizedlist>\r | |
17391 | <listitem>\r | |
17392 | <simpara>\r | |
17393 | eliminate 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 | |
17398 | eliminate 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 | |
17403 | eliminate <literal>where <str> = <str></literal>: Quite painful to expand out all the flexible types in the respective structures. Furthermore, many of the implied type equalities aren’t needed, but it’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’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’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 -> 'a * 'b) -> '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 | |
17442 | determined 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 -> 'a) -> 'a\r | |
17461 | val isolate: ('a -> unit) -> 'a t\r | |
17462 | val prepend: 'a t * ('b -> 'a) -> 'b t\r | |
17463 | val throw: 'a t * 'a -> 'b\r | |
17464 | val throw': 'a t * (unit -> 'a) -> '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 | |
17478 | stack; hence, <literal>callcc</literal> takes time proportional to the size of the\r | |
17479 | current 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 | |
17486 | is 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 | |
17493 | continuation that first does <literal>f</literal> and then does <literal>k</literal>. This is a\r | |
17494 | constant 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 | |
17509 | another 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’s primitive stack capture and copy operations. This isn’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 -> unit) -> 'a t =\r | |
17529 | fn (f: 'a -> unit) =>\r | |
17530 | callcc\r | |
17531 | (fn k1 =>\r | |
17532 | let\r | |
17533 | val x = callcc (fn k2 => throw (k1, k2))\r | |
17534 | val _ = (f x ; Exit.topLevelSuffix ())\r | |
17535 | handle exn => 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’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’s stack copying implementation of continuations and would arise in SML/NJ’s CPS-translation implementation); we are only assuming that the implementation can’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 | |
17544 | val base: (unit -> unit) t =\r | |
17545 | callcc\r | |
17546 | (fn k1 =>\r | |
17547 | let\r | |
17548 | val th = callcc (fn k2 => throw (k1, k2))\r | |
17549 | val _ = (th () ; Exit.topLevelSuffix ())\r | |
17550 | handle exn => MLtonExn.topLevelHandler exn\r | |
17551 | in\r | |
17552 | raise Fail "MLton.Cont.isolate: return from (wrapped) func"\r | |
17553 | end)\r | |
17554 | in\r | |
17555 | val isolate: ('a -> unit) -> 'a t =\r | |
17556 | fn (f: 'a -> unit) =>\r | |
17557 | callcc\r | |
17558 | (fn k1 =>\r | |
17559 | let\r | |
17560 | val x = callcc (fn k2 => throw (k1, k2))\r | |
17561 | in\r | |
17562 | throw (base, fn () => f x)\r | |
17563 | end)\r | |
17564 | end</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’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’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 | |
17569 | throws 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’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> — 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 | |
17571 | continuation 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’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 — the continuation isn’t retained, so neither is the <emphasis>semantic</emphasis>\r | |
17575 | garbage 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 | |
17578 | val base: (unit -> unit) t =\r | |
17579 | callcc\r | |
17580 | (fn k1 =>\r | |
17581 | let\r | |
17582 | val th = callcc (fn k2 => throw (k1, k2))\r | |
17583 | val _ = (th () ; Exit.topLevelSuffix ())\r | |
17584 | handle exn => MLtonExn.topLevelHandler exn\r | |
17585 | in\r | |
17586 | raise Fail "MLton.Cont.isolate: return from (wrapped) func"\r | |
17587 | end)\r | |
17588 | in\r | |
17589 | val isolate: ('a -> unit) -> 'a t =\r | |
17590 | fn (f: 'a -> unit) =>\r | |
17591 | callcc\r | |
17592 | (fn k1 =>\r | |
17593 | throw (base, fn () =>\r | |
17594 | let\r | |
17595 | val x = callcc (fn k2 => throw (k1, k2))\r | |
17596 | in\r | |
17597 | throw (base, fn () => f x)\r | |
17598 | end))\r | |
17599 | end</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’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 | |
17603 | val base: (unit -> unit) option t =\r | |
17604 | let\r | |
17605 | val baseRef: (unit -> unit) option t option ref = ref NONE\r | |
17606 | val th = callcc (fn k => (base := SOME k; NONE))\r | |
17607 | in\r | |
17608 | case th of\r | |
17609 | NONE => (case !baseRef of\r | |
17610 | NONE => raise Fail "MLton.Cont.isolate: missing base"\r | |
17611 | | SOME base => base)\r | |
17612 | | SOME th => let\r | |
17613 | val _ = (th () ; Exit.topLevelSuffix ())\r | |
17614 | handle exn => 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 | |
17620 | in\r | |
17621 | val isolate: ('a -> unit) -> 'a t =\r | |
17622 | fn (f: 'a -> unit) =>\r | |
17623 | callcc\r | |
17624 | (fn k1 =>\r | |
17625 | throw (base, SOME (fn () =>\r | |
17626 | let\r | |
17627 | val x = callcc (fn k2 => throw (k1, k2))\r | |
17628 | in\r | |
17629 | throw (base, SOME (fn () => f x))\r | |
17630 | end)))\r | |
17631 | end</programlisting>\r | |
17632 | <simpara>Now, to evaluate <literal>base</literal>, we only copy the stack once (instead of 3 times). Because we don’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 -> 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 | |
17634 | continuations is given by</simpara>\r | |
17635 | <programlisting language="sml" linenumbering="unnumbered">type 'a t = (unit -> 'a) -> 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 -> 'a): 'b =\r | |
17638 | (k v; raise Fail "MLton.Cont.throw': return from continuation")\r | |
17639 | \r | |
17640 | fun ('a, 'b) throw (k: 'a t, v: 'a): 'b = throw' (k, fn () => 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 | |
17643 | val base: (unit -> unit) option t =\r | |
17644 | let\r | |
17645 | val baseRef: (unit -> unit) option t ref =\r | |
17646 | ref (fn _ => raise Fail "MLton.Cont.isolate: missing base")\r | |
17647 | val th = callcc (fn k => (baseRef := k; NONE))\r | |
17648 | in\r | |
17649 | case th of\r | |
17650 | NONE => !baseRef\r | |
17651 | | SOME th => let\r | |
17652 | val _ = (th () ; Exit.topLevelSuffix ())\r | |
17653 | handle exn => 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 | |
17659 | in\r | |
17660 | val isolate: ('a -> unit) -> 'a t =\r | |
17661 | fn (f: 'a -> unit) =>\r | |
17662 | fn (v: unit -> 'a) =>\r | |
17663 | throw (base, SOME (f o v))\r | |
17664 | end</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’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 | |
17668 | val thRef: (unit -> unit) option ref = ref NONE\r | |
17669 | val base: unit t =\r | |
17670 | let\r | |
17671 | val baseRef: unit t ref =\r | |
17672 | ref (fn _ => raise Fail "MLton.Cont.isolate: missing base")\r | |
17673 | val () = callcc (fn k => baseRef := k)\r | |
17674 | in\r | |
17675 | case !thRef of\r | |
17676 | NONE => !baseRef\r | |
17677 | | SOME th =>\r | |
17678 | let\r | |
17679 | val _ = thRef := NONE\r | |
17680 | val _ = (th () ; Exit.topLevelSuffix ())\r | |
17681 | handle exn => MLtonExn.topLevelHandler exn\r | |
17682 | in\r | |
17683 | raise Fail "MLton.Cont.isolate: return from (wrapped) func"\r | |
17684 | end\r | |
17685 | end\r | |
17686 | in\r | |
17687 | val isolate: ('a -> unit) -> 'a t =\r | |
17688 | fn (f: 'a -> unit) =>\r | |
17689 | fn (v: unit -> 'a) =>\r | |
17690 | let\r | |
17691 | val () = thRef := SOME (f o v)\r | |
17692 | in\r | |
17693 | throw (base, ())\r | |
17694 | end\r | |
17695 | end</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’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’s primitive stack copying operations.</simpara>\r | |
17698 | <programlisting language="sml" linenumbering="unnumbered">local\r | |
17699 | val thRef: (unit -> unit) option ref = ref NONE\r | |
17700 | val base: Thread.preThread =\r | |
17701 | let\r | |
17702 | val () = Thread.copyCurrent ()\r | |
17703 | in\r | |
17704 | case !thRef of\r | |
17705 | NONE => Thread.savedPre ()\r | |
17706 | | SOME th =>\r | |
17707 | let\r | |
17708 | val () = thRef := NONE\r | |
17709 | val _ = (th () ; Exit.topLevelSuffix ())\r | |
17710 | handle exn => MLtonExn.topLevelHandler exn\r | |
17711 | in\r | |
17712 | raise Fail "MLton.Cont.isolate: return from (wrapped) func"\r | |
17713 | end\r | |
17714 | end\r | |
17715 | in\r | |
17716 | val isolate: ('a -> unit) -> 'a t =\r | |
17717 | fn (f: 'a -> unit) =>\r | |
17718 | fn (v: unit -> 'a) =>\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 | |
17725 | end</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 | |
17729 | val thRef: (unit -> unit) option ref = ref NONE\r | |
17730 | val base: Thread.preThread =\r | |
17731 | let\r | |
17732 | val () = Thread.copyCurrent ()\r | |
17733 | in\r | |
17734 | case !thRef of\r | |
17735 | NONE => Thread.savedPre ()\r | |
17736 | | SOME th =>\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 => MLtonExn.topLevelHandler exn\r | |
17742 | in\r | |
17743 | raise Fail "MLton.Cont.isolate: return from (wrapped) func"\r | |
17744 | end\r | |
17745 | end\r | |
17746 | in\r | |
17747 | val isolate: ('a -> unit) -> 'a t =\r | |
17748 | fn (f: 'a -> unit) =>\r | |
17749 | fn (v: unit -> 'a) =>\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 | |
17758 | end</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 -> unit) -> 'a t =\r | |
17761 | fn (f: 'a -> unit) =>\r | |
17762 | fn (v: unit -> 'a) =>\r | |
17763 | let\r | |
17764 | val th = (f (v ()) ; Exit.topLevelSuffix ())\r | |
17765 | handle exn => MLtonExn.topLevelHandler exn\r | |
17766 | val t = MLton.Thread.prepare (MLton.Thread.new th, ())\r | |
17767 | in\r | |
17768 | MLton.Thread.switch (fn _ => 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 | |
17777 | combination with the emdebian project, this allows a debian system to\r | |
17778 | compile 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 -> string option) -> unit\r | |
17879 | val history: exn -> string list\r | |
17880 | \r | |
17881 | val defaultTopLevelHandler: exn -> 'a\r | |
17882 | val getTopLevelHandler: unit -> (exn -> unit)\r | |
17883 | val setTopLevelHandler: (exn -> unit) -> unit\r | |
17884 | val topLevelHandler: exn -> '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 | |
17892 | converting exceptions to strings. Messagers are tried in order from\r | |
17893 | most 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 | |
17900 | element of the list is a file position. The elements are in reverse\r | |
17901 | chronological order, i.e. the function called last is at the front of\r | |
17902 | the 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 | |
17911 | out 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 | |
17924 | should 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 -> unit) -> unit\r | |
17942 | val finalizeBefore: 'a t * 'b t -> unit\r | |
17943 | val new: 'a -> 'a t\r | |
17944 | val touch: 'a t -> unit\r | |
17945 | val withValue: 'a t * ('a -> 'b) -> 'b\r | |
17946 | end</programlisting>\r | |
17947 | <simpara>A <emphasis>finalizable</emphasis> value is a container to which finalizers can be\r | |
17948 | attached. A container holds a value, which is reachable as long as\r | |
17949 | the container itself is reachable. A <emphasis>finalizer</emphasis> is a function that\r | |
17950 | runs at some point after garbage collection determines that the\r | |
17951 | container to which it is attached has become\r | |
17952 | <link linkend="Reachability">unreachable</link>. A finalizer is treated like a signal\r | |
17953 | handler, in that it runs asynchronously in a separate thread, with\r | |
17954 | signals 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 | |
17962 | last 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>, …, <literal>vn</literal> = <literal>v</literal> with <literal>finalizeBefore (vi, vi+1)</literal> will\r | |
17971 | result 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 | |
17978 | of <literal>v</literal> will run sometime after the last call to <literal>withValue</literal> on <literal>v</literal>\r | |
17979 | when 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 | |
17992 | that <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 -> t\r | |
18004 | val sing: int -> t\r | |
18005 | val sum: t -> int\r | |
18006 | end\r | |
18007 | \r | |
18008 | functor 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 -> P.t\r | |
18013 | val free: P.t -> unit\r | |
18014 | val sing: int -> P.t\r | |
18015 | val sum: P.t -> 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' =>\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 | |
18042 | functor Test (structure CList: CLIST\r | |
18043 | structure MLton: sig\r | |
18044 | structure GC:\r | |
18045 | sig\r | |
18046 | val collect: unit -> 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 => 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 | |
18077 | structure 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 -> P.t;\r | |
18083 | val free = _import "listFree": P.t -> unit;\r | |
18084 | val sing = _import "listSing": int -> P.t;\r | |
18085 | val sum = _import "listSum": P.t -> int;\r | |
18086 | end)\r | |
18087 | \r | |
18088 | structure 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 <stdio.h>\r | |
18092 | \r | |
18093 | typedef unsigned int uint;\r | |
18094 | \r | |
18095 | typedef struct Cons {\r | |
18096 | struct Cons *next;\r | |
18097 | int value;\r | |
18098 | } *Cons;\r | |
18099 | \r | |
18100 | Cons 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->next = c;\r | |
18106 | res->value = n;\r | |
18107 | return res;\r | |
18108 | }\r | |
18109 | \r | |
18110 | Cons 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->next = NULL;\r | |
18116 | res->value = n;\r | |
18117 | return res;\r | |
18118 | }\r | |
18119 | \r | |
18120 | void listFree (Cons p) {\r | |
18121 | fprintf (stderr, "listFree (0x%08x)\n", (uint)p);\r | |
18122 | free (p);\r | |
18123 | }\r | |
18124 | \r | |
18125 | int 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->next)\r | |
18131 | res += c->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 | |
18138 | 0x08072890 = listSing (2)\r | |
18139 | 0x080728a0 = listCons (2)\r | |
18140 | 0x080728b0 = listCons (2)\r | |
18141 | 0x080728c0 = listCons (2)\r | |
18142 | 0x080728d0 = listCons (2)\r | |
18143 | 0x080728e0 = listCons (2)\r | |
18144 | 0x080728f0 = listCons (2)\r | |
18145 | listSum\r | |
18146 | listSum(l) = 14\r | |
18147 | listFree (0x080728f0)\r | |
18148 | listFree (0x080728e0)\r | |
18149 | listFree (0x080728d0)\r | |
18150 | listFree (0x080728c0)\r | |
18151 | listFree (0x080728b0)\r | |
18152 | listFree (0x080728a0)\r | |
18153 | listFree (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 | |
18158 | unspecified time, interrupting the user program. It is also possible,\r | |
18159 | and sometimes useful, to have synchronous finalizers, where the user\r | |
18160 | program explicitly decides when to run enabled finalizers. We have\r | |
18161 | considered this in MLton, and it seems possible, but there are some\r | |
18162 | unresolved 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 -> unit\r | |
18188 | val pack: unit -> unit\r | |
18189 | val setMessages: bool -> unit\r | |
18190 | val setSummary: bool -> unit\r | |
18191 | val unpack: unit -> unit\r | |
18192 | structure Statistics :\r | |
18193 | sig\r | |
18194 | val bytesAllocated: unit -> IntInf.int\r | |
18195 | val lastBytesLive: unit -> IntInf.int\r | |
18196 | val numCopyingGCs: unit -> IntInf.int\r | |
18197 | val numMarkCompactGCs: unit -> IntInf.int\r | |
18198 | val numMinorGCs: unit -> IntInf.int\r | |
18199 | val maxBytesLive: unit -> 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 | |
18214 | available 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 | |
18221 | end of each garbage collection. It is the same as the <literal>gc-messages</literal>\r | |
18222 | runtime 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 | |
18229 | upon termination of the program. It is the same as the <literal>gc-summary</literal>\r | |
18230 | runtime 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 | |
18255 | the 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 | |
18269 | recent 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 -> bool\r | |
18287 | val gcd: t * t -> t\r | |
18288 | val isSmall: t -> 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 -> rep\r | |
18296 | val fromRep : rep -> t option\r | |
18297 | end</programlisting>\r | |
18298 | <simpara>MLton represents an arbitrary precision integer either as an unboxed\r | |
18299 | word with the bottom bit set to 1 and the top bits representing a\r | |
18300 | small signed integer, or as a pointer to a vector of words, where the\r | |
18301 | first 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’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 | |
18333 | platforms, <literal>BigWord</literal> is likely to be equivalent to <literal>Word32</literal>, and on\r | |
18334 | 64-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 | |
18341 | platforms, <literal>SmallInt</literal> is likely to be equivalent to <literal>Int32</literal>, and on\r | |
18342 | 64-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 | |
18361 | If <literal>fromRep r</literal> is given anything besides the valid result of <literal>rep i</literal>\r | |
18362 | for 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 -> Posix.IO.file_desc\r | |
18375 | val mkstemp: string -> string * outstream\r | |
18376 | val mkstemps: {prefix: string, suffix: string} -> string * outstream\r | |
18377 | val newIn: Posix.IO.file_desc * string -> instream\r | |
18378 | val newOut: Posix.IO.file_desc * string -> outstream\r | |
18379 | val outFd: outstream -> Posix.IO.file_desc\r | |
18380 | val tempPrefix: string -> 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 | |
18394 | with 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 | |
18407 | any <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 | |
18414 | any <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 | |
18427 | files.</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} -> unit\r | |
18442 | val signal: t -> 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 | |
18450 | given <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 | |
18464 | that 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 | |
18469 | to 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 | |
18479 | Stephen’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 | |
18484 | versioning. Each library has an "unstable" subdirectory in which work\r | |
18485 | happens. When one is happy with a library, one tags it by copying it\r | |
18486 | to a stable version directory. Stable libraries are immutable — when\r | |
18487 | one refers to a stable library, one always gets exactly the same code.\r | |
18488 | No one has actually made a stable library yet, but, when I’m ready to\r | |
18489 | tag 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 | |
18498 | MLton’s <link linkend="License">License</link>. We haven’t decided on whether that will be a\r | |
18499 | requirement to be in the repository or not. For the sake of\r | |
18500 | simplicity (a single license) and encouraging widest use of code,\r | |
18501 | contributors are encouraged to use that license. But it may be too\r | |
18502 | strict to require it.</simpara>\r | |
18503 | <simpara>If someone wants to contribute a new library to our repository or to\r | |
18504 | work on an old one, they can make a pull request. If people want to\r | |
18505 | work in their own repository, they can do so — that’s the point of\r | |
18506 | using domain names to prevent clashes. The idea is that a user should\r | |
18507 | be able to bring library collections in from many different\r | |
18508 | repositories without problems. And those libraries could even work\r | |
18509 | with each other.</simpara>\r | |
18510 | <simpara>At some point we may want to settle on an <link linkend="MLBasisPathMap">MLBasisPathMap</link> variable\r | |
18511 | for the root of the library project. Or, we could reuse <literal>SML_LIB</literal>,\r | |
18512 | and migrate what we currently keep there into the library\r | |
18513 | infrastructure.</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 -> t\r | |
18523 | val toPoly: t -> 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 | |
18543 | argument 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 | |
18550 | argument 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 -> t\r | |
18562 | val toPoly: t -> 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 | |
18582 | MLton, 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 | |
18589 | MLton, 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 -> t option\r | |
18604 | val host: t\r | |
18605 | val toString: t -> 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 -> t option\r | |
18614 | val host: t\r | |
18615 | val toString: t -> 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 -> t\r | |
18677 | val compare: t * t -> order\r | |
18678 | val diff: t * t -> word\r | |
18679 | val getInt8: t * int -> Int8.int\r | |
18680 | val getInt16: t * int -> Int16.int\r | |
18681 | val getInt32: t * int -> Int32.int\r | |
18682 | val getInt64: t * int -> Int64.int\r | |
18683 | val getPointer: t * int -> t\r | |
18684 | val getReal32: t * int -> Real32.real\r | |
18685 | val getReal64: t * int -> Real64.real\r | |
18686 | val getWord8: t * int -> Word8.word\r | |
18687 | val getWord16: t * int -> Word16.word\r | |
18688 | val getWord32: t * int -> Word32.word\r | |
18689 | val getWord64: t * int -> Word64.word\r | |
18690 | val null: t\r | |
18691 | val setInt8: t * int * Int8.int -> unit\r | |
18692 | val setInt16: t * int * Int16.int -> unit\r | |
18693 | val setInt32: t * int * Int32.int -> unit\r | |
18694 | val setInt64: t * int * Int64.int -> unit\r | |
18695 | val setPointer: t * int * t -> unit\r | |
18696 | val setReal32: t * int * Real32.real -> unit\r | |
18697 | val setReal64: t * int * Real64.real -> unit\r | |
18698 | val setWord8: t * int * Word8.word -> unit\r | |
18699 | val setWord16: t * int * Word16.word -> unit\r | |
18700 | val setWord32: t * int * Word32.word -> unit\r | |
18701 | val setWord64: t * int * Word64.word -> unit\r | |
18702 | val sizeofPointer: word\r | |
18703 | val sub: t * word -> 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 | |
18717 | overflow.</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 | |
18730 | not check for overflow.</simpara>\r | |
18731 | </listitem>\r | |
18732 | <listitem>\r | |
18733 | <simpara>\r | |
18734 | <literal>get<emphasis><X></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 | |
18737 | pointed to by <literal>p</literal>. For example, <literal>getWord32 (p, 7)</literal> returns the 32-bit\r | |
18738 | word 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><X></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 | |
18751 | objects pointed to by <literal>p</literal>. For example, <literal>setWord32 (p, 7, w)</literal> stores\r | |
18752 | the 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 | |
18765 | overflow.</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} -> unit\r | |
18777 | val setgroups: gid list -> 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 | |
18785 | be 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} -> pid\r | |
18803 | val spawne: {args: string list, env: string list, path: string} -> pid\r | |
18804 | val spawnp: {args: string list, file: string} -> 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 -> BinIO.instream\r | |
18823 | val binOut: (BinIO.outstream, output) t -> BinIO.outstream\r | |
18824 | val fd: (Posix.FileSys.file_desc, 'dir) t -> Posix.FileSys.file_desc\r | |
18825 | val remember: (any, 'dir) t -> ('use, 'dir) t\r | |
18826 | val textIn: (TextIO.instream, input) t -> TextIO.instream\r | |
18827 | val textOut: (TextIO.outstream, output) t -> 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 -> (none, 'dir) t\r | |
18835 | val fd: Posix.FileSys.file_desc -> (none, 'dir) t\r | |
18836 | val file: string -> (none, 'dir) t\r | |
18837 | val forget: ('use, 'dir) t -> (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 | -> ('stdin, 'stdout, 'stderr) t\r | |
18851 | val getStderr: ('stdin, 'stdout, 'stderr) t -> ('stderr, input) Child.t\r | |
18852 | val getStdin: ('stdin, 'stdout, 'stderr) t -> ('stdin, output) Child.t\r | |
18853 | val getStdout: ('stdin, 'stdout, 'stderr) t -> ('stdout, input) Child.t\r | |
18854 | val kill: ('stdin, 'stdout, 'stderr) t * Posix.Signal.signal -> unit\r | |
18855 | val reap: ('stdin, 'stdout, 'stderr) t -> 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 | |
18861 | process. On most platforms, the <literal>spawn</literal> functions are simple\r | |
18862 | wrappers 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 | |
18864 | the process id of the spawned process. They differ in how the\r | |
18865 | executable 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 | |
18872 | with 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 | |
18879 | the 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 | |
18887 | and 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 | |
18896 | output, and error streams. In addition, <literal>create</literal> works on all\r | |
18897 | platforms, including Cygwin and MinGW (Windows) where <literal>Posix.fork</literal> is\r | |
18898 | unavailable. For greatest portability programs should still use the\r | |
18899 | standard <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 | |
18901 | function. 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’s standard streams. The\r | |
18910 | <literal>'dir</literal> is viewed with respect to the parent. Thus a <literal>('a, input)\r | |
18911 | Child.t</literal> handle means that the parent may input the output from the\r | |
18912 | child.</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 | |
18919 | type. The type system will detect attempts to reverse the direction\r | |
18920 | of 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 | |
18927 | stream. However, it does not enforce that you read or write from the\r | |
18928 | handle. If you use the descriptor in an inappropriate direction, the\r | |
18929 | behavior is undefined. Furthermore, this function may potentially be\r | |
18930 | unavailable 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 | |
18937 | stream so that the stream may be used by <literal>Child.*</literal>. An <literal>any</literal> stream\r | |
18938 | may have had use <literal>none</literal> or <literal>'use</literal> prior to calling <literal>Param.forget</literal>. If\r | |
18939 | the 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 | |
18951 | created child process. The <literal>'dir</literal> is relative to the child process.\r | |
18952 | Input 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 | |
18959 | previously created child process. A single child stream should be\r | |
18960 | connected to only one child process or else <literal>DoublyRedirected</literal> will be\r | |
18961 | raised.</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 | |
18968 | closed when <literal>create</literal> is called. This function may not be available on\r | |
18969 | future 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 | |
18976 | if you are implementing an application which conditionally attaches\r | |
18977 | the child process to files or pipes. However, you must ensure that\r | |
18978 | your 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 | |
18985 | file will be opened only when <literal>create</literal> is called. So any exceptions\r | |
18986 | will be raised there and not by this function. If used for <literal>input</literal>,\r | |
18987 | the file is opened read-only. If used for <literal>output</literal>, the file is opened\r | |
18988 | read-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 | |
18995 | discarded. The <literal>null</literal> param when passed as <literal>stdout</literal> or <literal>stderr</literal> does\r | |
18996 | this. 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 | |
19004 | which the parent process holds. This may later form the input to one\r | |
19005 | of 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 | |
19012 | corresponding 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 | |
19024 | how 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 | |
19031 | want 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’s stream was connected via a pipe to the\r | |
19039 | parent process. The parent process may pass this pipe in turn to\r | |
19040 | another 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’s stream my not be used by the parent\r | |
19054 | process. This happens when the child process is connected directly to\r | |
19055 | some 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 | |
19058 | with 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 | |
19065 | bypass the normal type checking. This exception will only be raised\r | |
19066 | in cases where the <literal>forget</literal> mechanism allows a misuse that would be\r | |
19067 | impossible 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 | |
19074 | separate 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 | |
19082 | the program name). <literal>path</literal> should be an absolute path to the executable\r | |
19083 | run in the new child process; relative paths work, but are less\r | |
19084 | robust. Optionally, the environment may be overridden with <literal>env</literal>\r | |
19085 | where each string element has the form <literal>"key=value"</literal>. The <literal>std*</literal>\r | |
19086 | options 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 | |
19095 | child process may result in runtime dead-lock and elicits a compiler\r | |
19096 | warning.</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 | |
19103 | mean 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 | |
19118 | it is important to ensure that there are no cycles in the undirected\r | |
19119 | pipe graph. If this property is not maintained, deadlocks are a very\r | |
19120 | serious potential bug which may only appear under difficult to\r | |
19121 | reproduce conditions.</simpara>\r | |
19122 | <simpara>The danger lies in that most operating systems implement pipes with a\r | |
19123 | fixed buffer size. If process A has two output pipes which process B\r | |
19124 | reads, it can happen that process A blocks writing to pipe 2 because\r | |
19125 | it is full while process B blocks reading from pipe 1 because it is\r | |
19126 | empty. This same situation can happen with any undirected cycle formed\r | |
19127 | between processes (vertexes) and pipes (undirected edges) in the\r | |
19128 | graph.</simpara>\r | |
19129 | <simpara>It is possible to make this safe using low-level I/O primitives for\r | |
19130 | polling. However, these primitives are not very portable and\r | |
19131 | difficult to use properly. A far better approach is to make sure you\r | |
19132 | never create a cycle in the first place.</simpara>\r | |
19133 | <simpara>For these reasons, the <literal>Unix.executeInEnv</literal> is a very dangerous\r | |
19134 | function. Be careful when using it to ensure that the child process\r | |
19135 | only 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 | |
19140 | its output through <literal>grep</literal>, and then reads the result back into the\r | |
19141 | program.</simpara>\r | |
19142 | <programlisting language="sml" linenumbering="unnumbered">open MLton.Process\r | |
19143 | val 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 | |
19150 | val 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 | |
19157 | fun suck h =\r | |
19158 | case TextIO.inputLine h of\r | |
19159 | NONE => ()\r | |
19160 | | SOME s => (print ("'" ^ s ^ "'\n"); suck h)\r | |
19161 | \r | |
19162 | val () = 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 -> bool\r | |
19175 | val free: t -> unit\r | |
19176 | val malloc: unit -> t\r | |
19177 | val write: t * string -> unit\r | |
19178 | end\r | |
19179 | \r | |
19180 | val isOn: bool\r | |
19181 | val withData: Data.t * (unit -> 'a) -> 'a\r | |
19182 | end</programlisting>\r | |
19183 | <simpara><literal>MLton.Profile</literal> provides <link linkend="Profiling">Profiling</link> control from within the\r | |
19184 | program, allowing you to profile individual portions of your\r | |
19185 | program. With <literal>MLton.Profile</literal>, you can create many units of profiling\r | |
19186 | data (essentially, mappings from functions to counts) during a run of\r | |
19187 | a program, switch between them while the program is running, and\r | |
19188 | output 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 | |
19201 | execute non-profiled programs, when compiling <literal>-profile no</literal> (the\r | |
19202 | default), <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 | |
19215 | is an error to free the current unit of profiling data or to free a\r | |
19216 | previously 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 | |
19224 | allocated from the process address space (but is <emphasis>not</emphasis> in the MLton\r | |
19225 | heap) and consumes memory proportional to the number of source\r | |
19226 | functions. When compiling <literal>-profile no</literal>, <literal>Data.malloc ()</literal> is\r | |
19227 | equivalent 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 | |
19235 | data. When compiling <literal>-profile no</literal>, <literal>write (x, f)</literal> is a no-op. A\r | |
19236 | profiled program will always write the current unit of profiling data\r | |
19237 | at 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 | |
19244 | result of <literal>f</literal> after restoring the current unit of profiling data.\r | |
19245 | When 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 | |
19252 | showing how to profile the executions of the <literal>fib</literal> and <literal>tak</literal> functions\r | |
19253 | separately. 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 | |
19256 | val fibData = Profile.Data.malloc ()\r | |
19257 | val takData = Profile.Data.malloc ()\r | |
19258 | \r | |
19259 | fun wrap (f, d) x =\r | |
19260 | Profile.withData (d, fn () => f x)\r | |
19261 | \r | |
19262 | val rec fib =\r | |
19263 | fn 0 => 0\r | |
19264 | | 1 => 1\r | |
19265 | | n => fib (n - 1) + fib (n - 2)\r | |
19266 | val fib = wrap (fib, fibData)\r | |
19267 | \r | |
19268 | fun tak (x,y,z) =\r | |
19269 | if not (y < 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 | |
19274 | val tak = wrap (tak, takData)\r | |
19275 | \r | |
19276 | val rec f =\r | |
19277 | fn 0 => ()\r | |
19278 | | n => (fib 38; f (n-1))\r | |
19279 | val _ = f 2\r | |
19280 | \r | |
19281 | val rec g =\r | |
19282 | fn 0 => ()\r | |
19283 | | n => (tak (18,12,6); g (n-1))\r | |
19284 | val _ = g 500\r | |
19285 | \r | |
19286 | fun done (data, file) =\r | |
19287 | (Profile.Data.write (data, file)\r | |
19288 | ; Profile.Data.free data)\r | |
19289 | \r | |
19290 | val _ = done (fibData, "mlmon.fib.out")\r | |
19291 | val _ = 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 | |
19297 | 5.77 seconds of CPU time (0.00 seconds GC)\r | |
19298 | function cur\r | |
19299 | --------- -----\r | |
19300 | fib 96.9%\r | |
19301 | <unknown> 3.1%</screen>\r | |
19302 | <simpara>and for <literal>tak</literal></simpara>\r | |
19303 | <screen>% mlprof fib-tak mlmon.tak.out\r | |
19304 | 0.68 seconds of CPU time (0.00 seconds GC)\r | |
19305 | function cur\r | |
19306 | -------- ------\r | |
19307 | tak 100.0%</screen>\r | |
19308 | <simpara>Combine the data for <literal>fib</literal> and <literal>tak</literal> by calling <literal>mlprof</literal>\r | |
19309 | with multiple <literal>mlmon.out</literal> files.</simpara>\r | |
19310 | <screen>% mlprof fib-tak mlmon.fib.out mlmon.tak.out mlmon.out\r | |
19311 | 6.45 seconds of CPU time (0.00 seconds GC)\r | |
19312 | function cur\r | |
19313 | --------- -----\r | |
19314 | fib 86.7%\r | |
19315 | tak 10.5%\r | |
19316 | <unknown> 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 -> char\r | |
19325 | val alphaNumString: int -> string\r | |
19326 | val rand: unit -> word\r | |
19327 | val seed: unit -> word option\r | |
19328 | val srand: word -> unit\r | |
19329 | val useed: unit -> 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 | |
19357 | available.</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 — it will instead return\r | |
19372 | lower 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 -> t\r | |
19384 | val fromLargeWord: LargeWord.word -> t\r | |
19385 | val toWord: IEEEReal.rounding_mode -> t -> word\r | |
19386 | val toLargeWord: IEEEReal.rounding_mode -> t -> 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 | |
19394 | for <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 | |
19407 | than (the appropriate) <literal>REAL.maxFinite</literal>, then infinity is returned.\r | |
19408 | If <literal>w</literal> cannot be exactly represented as a real value, then the current\r | |
19409 | rounding 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 | |
19421 | mode. They raise <literal>Overflow</literal> if the result is not representable, in\r | |
19422 | particular, 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 -> t\r | |
19456 | val castToSysWord: t -> 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 -> {hard: rlim, soft: rlim}\r | |
19475 | val set: t * {hard: rlim, soft: rlim} -> 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 -> unit\r | |
19523 | val rusage: unit -> {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 | |
19537 | program 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 | |
19540 | either <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 | |
19548 | usage of the exited children, the garbage collector, and the process\r | |
19549 | itself. The <literal>self</literal> component includes the usage of the <literal>gc</literal>\r | |
19550 | component, 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 | |
19553 | the 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 -> Thread.Runnable.t) -> t\r | |
19571 | val ignore: t\r | |
19572 | val isDefault: t -> bool\r | |
19573 | val isIgnore: t -> bool\r | |
19574 | val simple: (unit -> unit) -> 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 -> t\r | |
19583 | val block: t -> unit\r | |
19584 | val getBlocked: unit -> t\r | |
19585 | val isMember: t * signal -> bool\r | |
19586 | val none: t\r | |
19587 | val setBlocked: t -> unit\r | |
19588 | val some: signal list -> t\r | |
19589 | val unblock: t -> unit\r | |
19590 | end\r | |
19591 | \r | |
19592 | val getHandler: t -> Handler.t\r | |
19593 | val handled: unit -> Mask.t\r | |
19594 | val prof: t\r | |
19595 | val restart: bool ref\r | |
19596 | val setHandler: t * Handler.t -> unit\r | |
19597 | val suspend: Mask.t -> unit\r | |
19598 | val vtalrm: t\r | |
19599 | end</programlisting>\r | |
19600 | <simpara>Signals handlers are functions from (runnable) threads to (runnable)\r | |
19601 | threads. When a signal arrives, the corresponding signal handler is\r | |
19602 | invoked, its argument being the thread that was interrupted by the\r | |
19603 | signal. The signal handler runs asynchronously, in its own thread.\r | |
19604 | The signal handler returns the thread that it would like to resume\r | |
19605 | execution (this is often the thread that it was passed). It is an\r | |
19606 | error for a signal handler to raise an exception that is not handled\r | |
19607 | within the signal handler itself.</simpara>\r | |
19608 | <simpara>A signal handler is never invoked while the running thread is in a\r | |
19609 | critical section (see <link linkend="MLtonThread">MLtonThread</link>). Invoking a signal handler\r | |
19610 | implicitly enters a critical section and the normal return of a signal\r | |
19611 | handler implicitly exits the critical section; hence, a signal handler\r | |
19612 | is 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 | |
19638 | return 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 | |
19693 | is 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 | |
19712 | it 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 | |
19737 | signals; 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 | |
19751 | interrupted 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 | |
19764 | signal is received and handled, at which point <literal>suspend</literal> resets the\r | |
19765 | mask 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 | |
19777 | the <link linkend="BasisLibrary">Basis Library</link> that correspond directly to\r | |
19778 | interruptible 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 | |
19780 | predictable semantics. The principal concerns are:</simpara>\r | |
19781 | <orderedlist numeration="arabic">\r | |
19782 | <listitem>\r | |
19783 | <simpara>\r | |
19784 | System calls that are interrupted by signals should, by default, be\r | |
19785 | restarted; 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 | |
19793 | Signal handlers should always get a chance to run (when outside a\r | |
19794 | critical region). If a system call is interrupted by a signal, then\r | |
19795 | the 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 | |
19801 | A system call that must be restarted while in a critical section\r | |
19802 | will be restarted with the handled signals blocked (and the previously\r | |
19803 | blocked signals remembered). This encourages the system call to\r | |
19804 | complete, allowing the program to make progress towards leaving the\r | |
19805 | critical section where the signal can be handled. If the system call\r | |
19806 | completes, the set of blocked signals are restored to those previously\r | |
19807 | blocked.\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 | |
19817 | available in the <link linkend="BasisLibrary">Basis Library</link>. As a warning,\r | |
19818 | please keep in mind that the <literal>MLton</literal> structure and its\r | |
19819 | substructures 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 -> bool\r | |
19823 | val equal: 'a * 'a -> bool\r | |
19824 | val hash: 'a -> Word32.word\r | |
19825 | val isMLton: bool\r | |
19826 | val share: 'a -> unit\r | |
19827 | val shareAll: unit -> unit\r | |
19828 | val size: 'a -> 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 -> t\r | |
19854 | val castToWord: t -> 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 -> t\r | |
19859 | val castToWord: t -> 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 | |
20028 | like <literal>char</literal>, <literal>int</literal>, and <literal>word</literal>, this is the same as equals. For\r | |
20029 | arrays, datatypes, strings, tuples, and vectors, this is a simple\r | |
20030 | pointer 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 | |
20037 | types, this is the same as <link linkend="PolymorphicEquality">PolymorphicEquality</link>. For other types,\r | |
20038 | it 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 | |
20045 | between execution of the same program, but may not be consistent\r | |
20046 | between 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 | |
20053 | stub 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 | |
20066 | immutable objects. A call to <literal>shareAll</literal> performs a major garbage\r | |
20067 | collection, 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 | |
20074 | including all objects reachable from <literal>x</literal> by following pointers. It\r | |
20075 | takes 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 | |
20082 | to 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 | |
20090 | val l = [1, 2, 3, 4]\r | |
20091 | \r | |
20092 | val _ =\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 _ => 0))\r | |
20097 | ; printSize ("a double array of length 10",\r | |
20098 | Array.tabulate (10, fn _ => 0.0))\r | |
20099 | ; printSize ("an array of length 10 of 2-ples of ints",\r | |
20100 | Array.tabulate (10, fn i => (i, i + 1)))\r | |
20101 | ; printSize ("a useless function", fn _ => 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 | |
20108 | val _ = if 10 = foldl (op +) 0 l\r | |
20109 | then ()\r | |
20110 | else raise Fail "bug"\r | |
20111 | \r | |
20112 | local\r | |
20113 | open MLton.Cont\r | |
20114 | in\r | |
20115 | val rc: int option t option ref = ref NONE\r | |
20116 | val _ =\r | |
20117 | case callcc (fn k: int option t => (rc := SOME k; throw (k, NONE))) of\r | |
20118 | NONE => ()\r | |
20119 | | SOME i => print (concat [Int.toString i, "\n"])\r | |
20120 | end\r | |
20121 | \r | |
20122 | val _ = printSize ("a continuation option ref", rc)\r | |
20123 | \r | |
20124 | val _ =\r | |
20125 | case !rc of\r | |
20126 | NONE => ()\r | |
20127 | | SOME k => (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 | |
20131 | The size of an int list of length 4 is 48 bytes.\r | |
20132 | The size of a string of length 10 is 24 bytes.\r | |
20133 | The size of an int array of length 10 is 52 bytes.\r | |
20134 | The size of a double array of length 10 is 92 bytes.\r | |
20135 | The size of an array of length 10 of 2-ples of ints is 92 bytes.\r | |
20136 | The size of a useless function is 0 bytes.\r | |
20137 | The size of a continuation option ref is 4544 bytes.\r | |
20138 | 13\r | |
20139 | The 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 | |
20141 | optimizations.</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 -> unit\r | |
20191 | val log: loglevel * string -> unit\r | |
20192 | val openlog: string * openflag list * facility -> unit\r | |
20193 | end</programlisting>\r | |
20194 | <simpara><literal>MLton.Syslog</literal> is a complete interface to the system logging\r | |
20195 | facilities. 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 | |
20214 | each 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 -> 'a) -> 'a\r | |
20235 | val atomicBegin: unit -> unit\r | |
20236 | val atomicEnd: unit -> unit\r | |
20237 | val atomicState: unit -> 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 -> Runnable.t) -> 'a\r | |
20247 | val new: ('a -> unit) -> 'a t\r | |
20248 | val prepend: 'a t * ('b -> 'a) -> 'b t\r | |
20249 | val prepare: 'a t * 'a -> Runnable.t\r | |
20250 | val switch: ('a t -> Runnable.t) -> 'a\r | |
20251 | end</programlisting>\r | |
20252 | <simpara><literal>MLton.Thread</literal> provides access to MLton’s user-level thread\r | |
20253 | implementation (i.e. not OS-level threads). Threads are lightweight\r | |
20254 | data structures that represent a paused computation. Runnable threads\r | |
20255 | are 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 | |
20257 | can 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 | |
20307 | performed.</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 | |
20314 | the thread. <literal>f</literal> must terminate by `switch`ing to another thread or\r | |
20315 | exiting 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 | |
20322 | applies <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 | |
20330 | will 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 | |
20337 | thread <literal>rt</literal>. It is an error for <literal>f</literal> to perform another <literal>switch</literal>. <literal>f</literal>\r | |
20338 | is 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 -> 'a t\r | |
20348 | val enque: 'a t * 'a -> unit\r | |
20349 | val deque: 'a t -> '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 | [] => (case !back of\r | |
20361 | [] => NONE\r | |
20362 | | l => let val l = rev l\r | |
20363 | in case l of\r | |
20364 | [] => raise Fail "deque"\r | |
20365 | | x :: l => (back := []; front := l; SOME x)\r | |
20366 | end)\r | |
20367 | | x :: l => (front := l; SOME x)\r | |
20368 | end\r | |
20369 | \r | |
20370 | structure Thread:\r | |
20371 | sig\r | |
20372 | val exit: unit -> 'a\r | |
20373 | val run: unit -> unit\r | |
20374 | val spawn: (unit -> unit) -> unit\r | |
20375 | val yield: unit -> 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 => valOf (!topLevel)\r | |
20391 | | SOME t => t\r | |
20392 | end\r | |
20393 | \r | |
20394 | fun 'a exit (): 'a = switch (fn _ => next ())\r | |
20395 | \r | |
20396 | fun new (f: unit -> unit): Thread.Runnable.t =\r | |
20397 | Thread.prepare\r | |
20398 | (Thread.new (fn () => ((f () handle _ => 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 => 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 =>\r | |
20410 | (topLevel := SOME (Thread.prepare (t, ()))\r | |
20411 | ; next()))\r | |
20412 | ; topLevel := NONE)\r | |
20413 | end\r | |
20414 | \r | |
20415 | val rec loop =\r | |
20416 | fn 0 => ()\r | |
20417 | | n => (print(concat[Int.toString n, "\n"])\r | |
20418 | ; Thread.yield()\r | |
20419 | ; loop(n - 1))\r | |
20420 | \r | |
20421 | val rec loop' =\r | |
20422 | fn 0 => ()\r | |
20423 | | n => (Thread.spawn (fn () => loop n); loop' (n - 2))\r | |
20424 | \r | |
20425 | val _ = Thread.spawn (fn () => loop' 10)\r | |
20426 | \r | |
20427 | val _ = Thread.run ()\r | |
20428 | \r | |
20429 | val _ = 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 -> 'a t\r | |
20438 | val enque: 'a t * 'a -> unit\r | |
20439 | val deque: 'a t -> '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 | [] => (case !back of\r | |
20451 | [] => NONE\r | |
20452 | | l => let val l = rev l\r | |
20453 | in case l of\r | |
20454 | [] => raise Fail "deque"\r | |
20455 | | x :: l => (back := []; front := l; SOME x)\r | |
20456 | end)\r | |
20457 | | x :: l => (front := l; SOME x)\r | |
20458 | end\r | |
20459 | \r | |
20460 | structure Thread:\r | |
20461 | sig\r | |
20462 | val exit: unit -> 'a\r | |
20463 | val run: unit -> unit\r | |
20464 | val spawn: (unit -> unit) -> unit\r | |
20465 | val yield: unit -> 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 => valOf (!topLevel)\r | |
20482 | | SOME t => t\r | |
20483 | end\r | |
20484 | \r | |
20485 | fun 'a exit (): 'a = switch (fn _ => next ())\r | |
20486 | \r | |
20487 | fun new (f: unit -> unit): Thread.Runnable.t =\r | |
20488 | Thread.prepare\r | |
20489 | (Thread.new (fn () => ((f () handle _ => 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 => 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 =>\r | |
20506 | (topLevel := SOME (Thread.prepare (t, ()))\r | |
20507 | ; new (fn () => (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 | |
20514 | val rec delay =\r | |
20515 | fn 0 => ()\r | |
20516 | | n => delay (n - 1)\r | |
20517 | \r | |
20518 | val rec loop =\r | |
20519 | fn 0 => ()\r | |
20520 | | n => (delay 500000; loop (n - 1))\r | |
20521 | \r | |
20522 | val rec loop' =\r | |
20523 | fn 0 => ()\r | |
20524 | | n => (Thread.spawn (fn () => loop n); loop' (n - 1))\r | |
20525 | \r | |
20526 | val _ = Thread.spawn (fn () => loop' 10)\r | |
20527 | \r | |
20528 | val _ = Thread.run ()\r | |
20529 | \r | |
20530 | val _ = 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 -> {done: unit -> 'a vector,\r | |
20539 | sub: int -> 'a,\r | |
20540 | update: int * 'a -> unit}\r | |
20541 | val unfoldi: int * 'b * (int * 'b -> 'a * 'b) -> '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 | |
20549 | functions to manipulate the vector. The <literal>done</literal> function may be called\r | |
20550 | to return the created vector; it is an error to call <literal>done</literal> before all\r | |
20551 | entries have been initialized; it is an error to call <literal>done</literal> after\r | |
20552 | having called <literal>done</literal>. The <literal>sub</literal> function may be called to return an\r | |
20553 | initialized vector entry; it is not an error to call <literal>sub</literal> after\r | |
20554 | having called <literal>done</literal>. The <literal>update</literal> function may be called to\r | |
20555 | initialize a vector entry; it is an error to call <literal>update</literal> after\r | |
20556 | having called <literal>done</literal>. One must initialize vector entries in order\r | |
20557 | from lowest to highest; that is, before calling <literal>update (i, x)</literal>, one\r | |
20558 | must 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 | |
20560 | operations.</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 | |
20567 | determined 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 -> 'a option\r | |
20580 | val new: 'a -> '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 | |
20583 | becomes <link linkend="Reachability">unreachable</link> due to garbage collection. The\r | |
20584 | weak pointer does not itself cause the object it points to be retained\r | |
20585 | by the garbage collector — only other strong pointers can do that.\r | |
20586 | For objects that are not allocated in the heap, like integers, a weak\r | |
20587 | pointer 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 | |
20601 | Otherwise, 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 -> t\r | |
20619 | val rol: t * word -> t\r | |
20620 | val ror: t * word -> 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 | |
20628 | for <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 -> 'a\r | |
20661 | val save: string -> status\r | |
20662 | val saveThread: string * Thread.Runnable.t -> 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 | |
20682 | computation can then be restarted at a later time using <literal>World.load</literal>\r | |
20683 | or 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 | |
20685 | the 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 | |
20692 | resume 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 | |
20698 | Executables 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 | |
20700 | of the executable (though, not of shared libraries). The state of a\r | |
20701 | computation includes addresses into the code and data segments of the\r | |
20702 | executable (e.g., static runtime-system data, return addresses); such\r | |
20703 | addresses are invalid when interpreted by the executable loaded at a\r | |
20704 | different base address.</simpara>\r | |
20705 | <simpara>Executables that save and load worlds should be compiled with an\r | |
20706 | option 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 | |
20720 | val _ =\r | |
20721 | case save "world" of\r | |
20722 | Original => print "I am the original\n"\r | |
20723 | | Clone => 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 | |
20725 | branch 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 | |
20728 | I 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 | |
20732 | I 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 | |
20739 | scanner 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 | |
20765 | after the Yacc parser generator.</simpara>\r | |
20766 | <simpara>A version of MLYacc, ported from the <link linkend="SMLNJ">SML/NJ</link> sources, is\r | |
20767 | distributed 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 | |
20802 | declarations 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 | |
20805 | fun 'a f (x: 'a) = T x\r | |
20806 | val a = f 1\r | |
20807 | val b = f 2\r | |
20808 | val 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 | |
20811 | datatype t2 = T2 of int * int\r | |
20812 | fun f1 (x: int) = T1 x\r | |
20813 | fun f2 (x: int * int) = T2 x\r | |
20814 | val a = f1 1\r | |
20815 | val b = f1 2\r | |
20816 | val 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 | |
20836 | On the way down, it creates a cache for each variable declared in a\r | |
20837 | polymorphic declaration that maps a lists of type arguments to a new\r | |
20838 | variable name. At a variable reference, it consults the cache (based\r | |
20839 | on the types the variable is applied to). If there is already an\r | |
20840 | entry in the cache, it is used. If not, a new entry is created. On\r | |
20841 | the way up, the monomorphiser duplicates a variable declaration for\r | |
20842 | each entry in the cache.</simpara>\r | |
20843 | <simpara>As with variables, the monomorphiser records all of the type at which\r | |
20844 | constructors are used. After the entire program is processed, the\r | |
20845 | monomorphiser duplicates each datatype declaration and its associated\r | |
20846 | constructors.</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 | |
20850 | and g (y: 'a) = f y\r | |
20851 | val a = f 13\r | |
20852 | val b = g 14\r | |
20853 | val 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 | |
20856 | and g1 (y: int) = f1 y\r | |
20857 | fun f2 (x : int * int) = g2 x\r | |
20858 | and g2 (y : int * int) = f2 y\r | |
20859 | val a = f1 13\r | |
20860 | val b = g1 14\r | |
20861 | val 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 | |
20866 | recursive uses of the defined type constructor are applied to\r | |
20867 | different type arguments than the definition. This has been\r | |
20868 | disallowed by others on type theoretic grounds. A canonical example\r | |
20869 | is the following.</simpara>\r | |
20870 | <programlisting language="sml" linenumbering="unnumbered">datatype 'a t = A of 'a | B of ('a * 'a) t\r | |
20871 | val 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 | |
20873 | to cause the need for the monomorphiser to create an infinite number\r | |
20874 | of types. However, due to the absence of polymorphic recursion in\r | |
20875 | SML, there are in fact only a finite number of instances of such types\r | |
20876 | in any given program. The monomorphiser translates the above program\r | |
20877 | to the following one.</simpara>\r | |
20878 | <programlisting language="sml" linenumbering="unnumbered">datatype t1 = B1 of t2\r | |
20879 | datatype t2 = B2 of t3\r | |
20880 | datatype t3 = A3 of (int * int) * (int * int)\r | |
20881 | val 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 | |
20883 | constructors from datatype declarations in order for the translation\r | |
20884 | to 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 | |
20892 | byte-code compiler, so it compiles code quickly, but the code runs\r | |
20893 | slowly. 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 | |
20904 | which <link linkend="SSA">SSA</link> functions and blocks might be executed more than once or\r | |
20905 | by more than one thread. It also determines when a program uses\r | |
20906 | threads 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 | |
20934 | other 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 | |
20943 | Bug in transparent signature match:\r | |
20944 | </simpara>\r | |
20945 | <itemizedlist>\r | |
20946 | <listitem>\r | |
20947 | <simpara>\r | |
20948 | What 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 | |
20963 | SVN 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 | |
20970 | Bug in <link linkend="DeepFlatten">DeepFlatten</link> pass:\r | |
20971 | </simpara>\r | |
20972 | <itemizedlist>\r | |
20973 | <listitem>\r | |
20974 | <simpara>\r | |
20975 | Should we allow argument to <literal>Weak_new</literal> to be flattened?\r | |
20976 | </simpara>\r | |
20977 | </listitem>\r | |
20978 | <listitem>\r | |
20979 | <simpara>\r | |
20980 | SVN 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 | |
20985 | SVN 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 | |
20996 | decimal or hexadecimal notation. Sometimes it can be convenient to\r | |
20997 | write numbers down in other bases. Fortunately, using <link linkend="Fold">Fold</link>, it is\r | |
20998 | possible to define a concise syntax for numeric literals that allows\r | |
20999 | one 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 | |
21002 | that, 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) =>\r | |
21019 | if 0 <= i andalso i < 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)) =>\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 | |
21047 | result one digit at a time, with each stepper multiplying the previous\r | |
21048 | result by the base and adding the next digit. The code is abstracted\r | |
21049 | in two different ways for extra generality. First, the <literal>make</literal>\r | |
21050 | function abstracts over the various primitive operations (addition,\r | |
21051 | multiplication, etc) that are needed to construct a number. This\r | |
21052 | allows the same code to be shared for constants <literal>I</literal>, <literal>II</literal>, <literal>W</literal> used to\r | |
21053 | write down the various numeric types. It also allows users to add new\r | |
21054 | constants for additional numeric types, by supplying the necessary\r | |
21055 | arguments to make.</simpara>\r | |
21056 | <simpara>Second, the step function, <literal>`</literal>, is abstracted over the actual\r | |
21057 | construction operation, which is created by make, and passed along the\r | |
21058 | fold. This allows the same constant, <literal>`</literal>, to be used for all\r | |
21059 | numeric types. The alternative approach, having a different step\r | |
21060 | function 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 | |
21062 | to ensure they are valid for the base. However, MLton will simplify\r | |
21063 | everything away at compile time, leaving just the final numeric\r | |
21064 | constant.</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 | |
21070 | object-oriented programming. Here are some papers that show how to\r | |
21071 | express 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 | |
21095 | The following discusses a simple object-oriented (OO) programming\r | |
21096 | technique in Standard ML. The reader is assumed to be able to read\r | |
21097 | Java and SML code.</simpara>\r | |
21098 | <section id="_motivation">\r | |
21099 | <title>Motivation</title>\r | |
21100 | <simpara>SML doesn’t provide subtyping, but it does provide parametric\r | |
21101 | polymorphism, which can be used to encode some forms of subtyping.\r | |
21102 | Most articles on OO programming in SML concentrate on such encoding\r | |
21103 | techniques. While those techniques are interesting — and it is\r | |
21104 | recommended to read such articles — and sometimes useful, it seems\r | |
21105 | that basically all OO gurus agree that (deep) subtyping (or\r | |
21106 | inheritance) hierarchies aren’t as practical as they were thought to\r | |
21107 | be in the early OO days. "Good", flexible, "OO" designs tend to have\r | |
21108 | a 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 | |
21119 | ClassB\r | |
21120 | ^\r | |
21121 | |\r | |
21122 | ClassC\r | |
21123 | ^\r | |
21124 | |</screen>\r | |
21125 | <simpara>tend to be signs of design mistakes. There are good underlying\r | |
21126 | reasons for this, but a thorough discussion is not in the scope of\r | |
21127 | this article. However, the point is that perhaps the encoding of\r | |
21128 | subtyping is not as important as one might believe. In the following\r | |
21129 | we ignore subtyping and rather concentrate on a very simple and basic\r | |
21130 | dynamic 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 | |
21135 | table" using a record that is wrapped inside a (possibly recursive)\r | |
21136 | datatype. Let’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 -> unit, get : unit -> int}</programlisting>\r | |
21144 | <simpara>Each value of type <literal>counter</literal> can be thought of as an object that\r | |
21145 | responds to two messages <literal>inc</literal> and <literal>get</literal>. To actually send messages\r | |
21146 | to 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 | |
21149 | in\r | |
21150 | val cGet = mk#get\r | |
21151 | val cInc = mk#inc\r | |
21152 | end</programlisting>\r | |
21153 | <simpara>that basically extract the "function table" <literal>t</literal> from a counter object\r | |
21154 | and then select the specified method <literal>m</literal> from the table.</simpara>\r | |
21155 | <simpara>Let’s then implement a simple function that increments a counter until a\r | |
21156 | given maximum is reached:</simpara>\r | |
21157 | <programlisting language="sml" linenumbering="unnumbered">fun incUpto counter max = while cGet counter < max do cInc counter</programlisting>\r | |
21158 | <simpara>You can easily verify that the above code compiles even without any\r | |
21159 | concrete implementation of a counter, thus it is clear that it doesn’t\r | |
21160 | depend on a particular counter implementation.</simpara>\r | |
21161 | <simpara>Let’s then implement a couple of counters. First consider the\r | |
21162 | following 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 () => cnt := !cnt + 1,\r | |
21174 | get = fn () => !cnt}\r | |
21175 | end</programlisting>\r | |
21176 | <simpara>The SML function <literal>newBasicCounter</literal> can be described as a constructor\r | |
21177 | function for counter objects of the <literal>BasicCounter</literal> "class". We can\r | |
21178 | also have other counter implementations. Here is the constructor for\r | |
21179 | a counter decorator that logs messages:</simpara>\r | |
21180 | <programlisting language="sml" linenumbering="unnumbered">fun newLoggedCounter counter =\r | |
21181 | Counter {inc = fn () => (print "inc\n" ; cInc counter),\r | |
21182 | get = fn () => (print "get\n" ; cGet counter)}</programlisting>\r | |
21183 | <simpara>The <literal>incUpto</literal> function works just as well with objects of either\r | |
21184 | class:</simpara>\r | |
21185 | <programlisting language="sml" linenumbering="unnumbered">val aCounter = newBasicCounter 0\r | |
21186 | val () = incUpto aCounter 5\r | |
21187 | val () = print (Int.toString (cGet aCounter) ^"\n")\r | |
21188 | \r | |
21189 | val aCounter = newLoggedCounter (newBasicCounter 0)\r | |
21190 | val () = incUpto aCounter 5\r | |
21191 | val () = print (Int.toString (cGet aCounter) ^"\n")</programlisting>\r | |
21192 | <simpara>In general, a dynamic dispatch interface is represented as a record\r | |
21193 | type wrapped inside a datatype. Each field of the record corresponds\r | |
21194 | to a public method or field of the object:</simpara>\r | |
21195 | <programlisting language="sml" linenumbering="unnumbered">datatype interface =\r | |
21196 | Interface of {method : t1 -> 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 | |
21200 | in SML, can not be recursive. However, SML datatypes can be\r | |
21201 | recursive. A record wrapped in a datatype can contain fields that\r | |
21202 | contain 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 -> 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 | |
21206 | instantiated to produce objects. To be able to instantiate objects,\r | |
21207 | the constructors of a concrete class are needed. In SML, we can\r | |
21208 | implement constructors as simple functions from arbitrary arguments to\r | |
21209 | values of the interface type. Such a constructor function can\r | |
21210 | encapsulate arbitrary private state and functions using lexical\r | |
21211 | closure. It is also easy to share implementations of methods between\r | |
21212 | two or more constructors.</simpara>\r | |
21213 | <simpara>While the <literal>Counter</literal> example is rather trivial, it should not be\r | |
21214 | difficult to see that this technique quite simply doesn’t require a huge\r | |
21215 | amount 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 | |
21220 | technique work together. Let’s investigate! Let’s use a simple\r | |
21221 | dispenser framework as a concrete example. (Note that this isn’t\r | |
21222 | intended 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 | |
21226 | dispensers. Here is a signature for an "abstract" functional (as\r | |
21227 | opposed 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 -> bool\r | |
21231 | val push : 'a * 'a t -> 'a t\r | |
21232 | val pop : 'a t -> ('a * 'a t) option\r | |
21233 | end</programlisting>\r | |
21234 | <simpara>The term "abstract" in the name of the signature refers to the fact that\r | |
21235 | the signature gives no way to instantiate a dispenser. It has nothing to\r | |
21236 | do with the concept of abstract data types.</simpara>\r | |
21237 | <simpara>Using SML functors we can write "generic" algorithms that manipulate\r | |
21238 | dispensers of an unknown type. Here are a couple of very simple\r | |
21239 | algorithms:</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 | |
21253 | end</programlisting>\r | |
21254 | <simpara>As one can easily verify, the above compiles even without any concrete\r | |
21255 | dispenser structure. Functors essentially provide a form a static\r | |
21256 | dispatch 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 | |
21261 | end</programlisting>\r | |
21262 | <simpara>and write any number of concrete structures implementing the signature.\r | |
21263 | For example, we could implement stacks</simpara>\r | |
21264 | <programlisting language="sml" linenumbering="unnumbered">structure Stack :> 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 | |
21270 | end</programlisting>\r | |
21271 | <simpara>and queues</simpara>\r | |
21272 | <programlisting language="sml" linenumbering="unnumbered">structure Queue :> DISPENSER = struct\r | |
21273 | datatype 'a t = T of 'a list * 'a list\r | |
21274 | val empty = T ([], [])\r | |
21275 | val isEmpty = fn T ([], _) => true | _ => false\r | |
21276 | val normalize = fn ([], ys) => (rev ys, []) | q => q\r | |
21277 | fun push (y, T (xs, ys)) = T (normalize (xs, y::ys))\r | |
21278 | val pop = fn (T (x::xs, ys)) => SOME (x, T (normalize (xs, ys))) | _ => NONE\r | |
21279 | end</programlisting>\r | |
21280 | <simpara>One can now write code that uses either the <literal>Stack</literal> or the <literal>Queue</literal>\r | |
21281 | dispenser. One can also instantiate the previously defined functor to\r | |
21282 | create functions for manipulating dispensers of a type:</simpara>\r | |
21283 | <programlisting language="sml" linenumbering="unnumbered">structure S = DispenserAlgs (Stack)\r | |
21284 | val [4,3,2,1] = S.popAll (S.pushAll ([1,2,3,4], Stack.empty))\r | |
21285 | \r | |
21286 | structure Q = DispenserAlgs (Queue)\r | |
21287 | val [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 | |
21289 | attempt 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’s then combine SML modules and the dynamic dispatch technique\r | |
21296 | introduced in this article. First we define an interface for\r | |
21297 | dispensers:</simpara>\r | |
21298 | <programlisting language="sml" linenumbering="unnumbered">structure Dispenser = struct\r | |
21299 | datatype 'a t =\r | |
21300 | I of {isEmpty : unit -> bool,\r | |
21301 | push : 'a -> 'a t,\r | |
21302 | pop : unit -> ('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 | |
21309 | end</programlisting>\r | |
21310 | <simpara>The <literal>Dispenser</literal> module, which we can think of as an interface for\r | |
21311 | dispensers, implements the <literal>ABSTRACT_DISPENSER</literal> signature using\r | |
21312 | the dynamic dispatch technique, but we leave the signature ascription\r | |
21313 | until later.</simpara>\r | |
21314 | <simpara>Then we define a <literal>DispenserClass</literal> functor that makes a "class" out of\r | |
21315 | a 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 () => D.isEmpty d,\r | |
21321 | push = fn x => make (D.push (x, d)),\r | |
21322 | pop = fn () =>\r | |
21323 | case D.pop d of\r | |
21324 | NONE => NONE\r | |
21325 | | SOME (x, d) => SOME (x, make d)}\r | |
21326 | \r | |
21327 | val empty =\r | |
21328 | I {isEmpty = fn () => true,\r | |
21329 | push = fn x => make (D.push (x, D.empty)),\r | |
21330 | pop = fn () => NONE}\r | |
21331 | end</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’t necessary for type safety, because the unsealed <literal>Dispenser</literal>\r | |
21335 | module does not allow one to break encapsulation, but makes sure that\r | |
21336 | only 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 | |
21339 | module into a dispenser class:</simpara>\r | |
21340 | <programlisting language="sml" linenumbering="unnumbered">structure StackClass = DispenserClass (Stack)\r | |
21341 | structure QueueClass = DispenserClass (Queue)</programlisting>\r | |
21342 | <simpara>Each dispenser class implements the same dynamic dispatch interface\r | |
21343 | and 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 | |
21349 | any 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 | |
21351 | val [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’s a comparison of some aspects of the OCaml and SML languages.</simpara>\r | |
21363 | <itemizedlist>\r | |
21364 | <listitem>\r | |
21365 | <simpara>\r | |
21366 | Standard ML has a formal <link linkend="DefinitionOfStandardML">Definition</link>, while\r | |
21367 | OCaml is specified by its lone implementation and informal\r | |
21368 | documentation.\r | |
21369 | </simpara>\r | |
21370 | </listitem>\r | |
21371 | <listitem>\r | |
21372 | <simpara>\r | |
21373 | Standard ML has a number of <link linkend="StandardMLImplementations">compilers</link>,\r | |
21374 | while OCaml has only one.\r | |
21375 | </simpara>\r | |
21376 | </listitem>\r | |
21377 | <listitem>\r | |
21378 | <simpara>\r | |
21379 | OCaml has built-in support for object-oriented programming, while\r | |
21380 | Standard ML does not (however, see <link linkend="ObjectOrientedProgramming">ObjectOrientedProgramming</link>).\r | |
21381 | </simpara>\r | |
21382 | </listitem>\r | |
21383 | <listitem>\r | |
21384 | <simpara>\r | |
21385 | Andreas Rossberg has a\r | |
21386 | <ulink url="http://www.mpi-sws.org/%7Erossberg/sml-vs-ocaml.html">side-by-side\r | |
21387 | comparison</ulink> of the syntax of SML and OCaml.\r | |
21388 | </simpara>\r | |
21389 | </listitem>\r | |
21390 | <listitem>\r | |
21391 | <simpara>\r | |
21392 | Adam Chlipala has a\r | |
21393 | <ulink url="http://adam.chlipala.net/mlcomp">point-by-point comparison</ulink> of OCaml\r | |
21394 | and 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’s a comparison of some aspects of OCaml and MLton.</simpara>\r | |
21402 | <itemizedlist>\r | |
21403 | <listitem>\r | |
21404 | <simpara>\r | |
21405 | Performance\r | |
21406 | </simpara>\r | |
21407 | <itemizedlist>\r | |
21408 | <listitem>\r | |
21409 | <simpara>\r | |
21410 | Both OCaml and MLton have excellent performance.\r | |
21411 | </simpara>\r | |
21412 | </listitem>\r | |
21413 | <listitem>\r | |
21414 | <simpara>\r | |
21415 | MLton performs extensive <link linkend="WholeProgramOptimization">WholeProgramOptimization</link>, which can\r | |
21416 | provide substantial improvements in large, modular programs.\r | |
21417 | </simpara>\r | |
21418 | </listitem>\r | |
21419 | <listitem>\r | |
21420 | <simpara>\r | |
21421 | MLton uses native types, like 32-bit integers, without any penalty\r | |
21422 | due to tagging or boxing. OCaml uses 31-bit integers with a penalty\r | |
21423 | due 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 | |
21428 | MLton uses native types, like 64-bit floats, without any penalty\r | |
21429 | due to boxing. OCaml, in some situations, boxes 64-bit floats.\r | |
21430 | </simpara>\r | |
21431 | </listitem>\r | |
21432 | <listitem>\r | |
21433 | <simpara>\r | |
21434 | MLton represents arrays of all types unboxed. In OCaml, only\r | |
21435 | arrays of 64-bit floats are unboxed, and then only when it is\r | |
21436 | syntactically apparent.\r | |
21437 | </simpara>\r | |
21438 | </listitem>\r | |
21439 | <listitem>\r | |
21440 | <simpara>\r | |
21441 | MLton represents records compactly by reordering and packing the\r | |
21442 | fields.\r | |
21443 | </simpara>\r | |
21444 | </listitem>\r | |
21445 | <listitem>\r | |
21446 | <simpara>\r | |
21447 | In MLton, polymorphic and monomorphic code have the same\r | |
21448 | performance. In OCaml, polymorphism can introduce a performance\r | |
21449 | penalty.\r | |
21450 | </simpara>\r | |
21451 | </listitem>\r | |
21452 | <listitem>\r | |
21453 | <simpara>\r | |
21454 | In MLton, module boundaries have no impact on performance. In\r | |
21455 | OCaml, moving code between modules can cause a performance penalty.\r | |
21456 | </simpara>\r | |
21457 | </listitem>\r | |
21458 | <listitem>\r | |
21459 | <simpara>\r | |
21460 | MLton’s <link linkend="ForeignFunctionInterface">ForeignFunctionInterface</link> is simpler than OCaml’s.\r | |
21461 | </simpara>\r | |
21462 | </listitem>\r | |
21463 | </itemizedlist>\r | |
21464 | </listitem>\r | |
21465 | <listitem>\r | |
21466 | <simpara>\r | |
21467 | Tools\r | |
21468 | </simpara>\r | |
21469 | <itemizedlist>\r | |
21470 | <listitem>\r | |
21471 | <simpara>\r | |
21472 | OCaml has a debugger, while MLton does not.\r | |
21473 | </simpara>\r | |
21474 | </listitem>\r | |
21475 | <listitem>\r | |
21476 | <simpara>\r | |
21477 | OCaml supports separate compilation, while MLton does not.\r | |
21478 | </simpara>\r | |
21479 | </listitem>\r | |
21480 | <listitem>\r | |
21481 | <simpara>\r | |
21482 | OCaml compiles faster than MLton.\r | |
21483 | </simpara>\r | |
21484 | </listitem>\r | |
21485 | <listitem>\r | |
21486 | <simpara>\r | |
21487 | MLton 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 | |
21494 | Libraries\r | |
21495 | </simpara>\r | |
21496 | <itemizedlist>\r | |
21497 | <listitem>\r | |
21498 | <simpara>\r | |
21499 | OCaml has more available libraries.\r | |
21500 | </simpara>\r | |
21501 | </listitem>\r | |
21502 | </itemizedlist>\r | |
21503 | </listitem>\r | |
21504 | <listitem>\r | |
21505 | <simpara>\r | |
21506 | Community\r | |
21507 | </simpara>\r | |
21508 | <itemizedlist>\r | |
21509 | <listitem>\r | |
21510 | <simpara>\r | |
21511 | OCaml has a larger community than MLton.\r | |
21512 | </simpara>\r | |
21513 | </listitem>\r | |
21514 | <listitem>\r | |
21515 | <simpara>\r | |
21516 | MLton 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 | |
21529 | which 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 | |
21534 | many of the functions, covering GL, GLU, and GLUT. This is available\r | |
21535 | in 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 | |
21537 | contains a number of small, standard OpenGL examples translated to\r | |
21538 | SML.\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 | |
21544 | possibly 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 | |
21556 | these 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 | |
21562 | certain symbols. Every program that includes the\r | |
21563 | <link linkend="BasisLibrary">Basis Library</link> automatically gets the following infix\r | |
21564 | declarations. Higher number indicates higher precedence.</simpara>\r | |
21565 | <programlisting language="sml" linenumbering="unnumbered">infix 7 * / mod div\r | |
21566 | infix 6 + - ^\r | |
21567 | infixr 5 :: @\r | |
21568 | infix 4 = <> > >= < <=\r | |
21569 | infix 3 := o\r | |
21570 | infix 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 | |
21576 | arguments. Nevertheless, using <link linkend="Fold">Fold</link>, it is easy to define\r | |
21577 | functions that take optional arguments.</simpara>\r | |
21578 | <simpara>For example, suppose that we have the following definition of a\r | |
21579 | function <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 | |
21583 | function <literal>f'</literal>, an optionalized version of <literal>f</literal>, that takes 0, 1, 2, or\r | |
21584 | 3 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 | |
21586 | used. If <literal>f'</literal> gets one argument, then that will be used for <literal>i</literal>. Two\r | |
21587 | arguments will be used for <literal>i</literal> and <literal>r</literal> respectively. Three arguments\r | |
21588 | will override all default values. Calls to <literal>f'</literal> will look like the\r | |
21589 | following.</simpara>\r | |
21590 | <programlisting language="sml" linenumbering="unnumbered">f' $\r | |
21591 | f' `2 $\r | |
21592 | f' `2 `3.0 $\r | |
21593 | f' `2 `3.0 `"four" $</programlisting>\r | |
21594 | <simpara>The optional argument indicator, <literal>`</literal>, is not special syntax ---\r | |
21595 | it is a normal SML value, defined in the <literal>OptionalArg</literal> structure\r | |
21596 | below.</simpara>\r | |
21597 | <simpara>Here is the definition of <literal>f'</literal> using the <literal>OptionalArg</literal> structure, in\r | |
21598 | particular, <literal>OptionalArg.make</literal> and <literal>OptionalArg.D</literal>.</simpara>\r | |
21599 | <programlisting language="sml" linenumbering="unnumbered">val f' =\r | |
21600 | fn z =>\r | |
21601 | let open OptionalArg in\r | |
21602 | make (D 1) (D 2.0) (D "three") $\r | |
21603 | end (fn i & r & s => 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 | |
21606 | call to <literal>OptionalArg.make</literal> is supplied with a variable number of\r | |
21607 | defaults (in this case, three), the end-of-arguments terminator, <literal>$</literal>,\r | |
21608 | and 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 | |
21610 | the product to an ordinary tuple and calls <literal>f</literal>. Often, the function\r | |
21611 | body will simply be written directly.</simpara>\r | |
21612 | <simpara>In general, the definition of an optional-argument function looks like\r | |
21613 | the following.</simpara>\r | |
21614 | <programlisting language="sml" linenumbering="unnumbered">val f =\r | |
21615 | fn z =>\r | |
21616 | let open OptionalArg in\r | |
21617 | make (D <default1>) (D <default2>) ... (D <defaultn>) $\r | |
21618 | end (fn x1 & x2 & ... & xn =>\r | |
21619 | <function code goes here>)\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 =>\r | |
21626 | Fold.fold\r | |
21627 | ((id, fn (f, x) => f x),\r | |
21628 | fn (d, r) => fn func =>\r | |
21629 | Fold.fold ((id, d ()), fn (f, d) =>\r | |
21630 | let\r | |
21631 | val d & () = 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) =>\r | |
21638 | (fn ds => f (d & ds),\r | |
21639 | fn (f, a & b) => r (fn x => f a & x, b)))\r | |
21640 | \r | |
21641 | val ` =\r | |
21642 | fn z =>\r | |
21643 | Fold.step1 (fn (x, (f, _ & d)) => (fn d => f (x & 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 | |
21647 | the default values in a product, associated to the right, and a\r | |
21648 | reversal function that converts a product (of the same arity as the\r | |
21649 | number of defaults) from right associativity to left associativity.\r | |
21650 | The accumulated defaults are used by the second fold, which recurs\r | |
21651 | over the product, replacing the appropriate component as it encounters\r | |
21652 | optional arguments. The second fold also constructs a "fill"\r | |
21653 | function, <literal>f</literal>, that is used to reconstruct the product once the\r | |
21654 | end-of-arguments is reached. Finally, the finisher reconstructs the\r | |
21655 | product and uses the reversal function to convert the product from\r | |
21656 | right associative to left associative, at which point it is passed to\r | |
21657 | the user-supplied function.</simpara>\r | |
21658 | <simpara>Much of the complexity comes from the fact that while recurring over a\r | |
21659 | product from left to right, one wants it to be right-associative,\r | |
21660 | e.g., look like</simpara>\r | |
21661 | <programlisting language="sml" linenumbering="unnumbered">a & (b & (c & d))</programlisting>\r | |
21662 | <simpara>but the user function in the end wants the product to be left\r | |
21663 | associative, so that the product argument pattern can be written\r | |
21664 | without parentheses (since <literal>&</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 | |
21668 | is sometimes useful to have labelled optional arguments. These allow\r | |
21669 | one to define a function, <literal>f</literal>, with defaults, say <literal>a</literal> and <literal>b</literal>. Then,\r | |
21670 | a caller of <literal>f</literal> can supply values for <literal>a</literal> and <literal>b</literal> by name. If no\r | |
21671 | value 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 | |
21674 | example, that one wants a function <literal>f</literal> with labelled optional\r | |
21675 | arguments <literal>a</literal> and <literal>b</literal> with default values <literal>0</literal> and <literal>0.0</literal> respectively.\r | |
21676 | If one has a functional-record-update function <literal>updateAB</literal> for records\r | |
21677 | with <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 =>\r | |
21680 | Fold.post\r | |
21681 | (updateAB {a = 0, b = 0.0},\r | |
21682 | fn {a, b} => 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 | |
21686 | the actual code for the function with a functional-record updater that\r | |
21687 | starts 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 | |
21690 | val () = f (U#a 13) $\r | |
21691 | val () = f (U#a 13) (U#b 17.5) $\r | |
21692 | val () = 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 | |
21694 | the arguments, or both of the arguments, and in either order. All\r | |
21695 | that matter is that the arguments be labelled correctly (and of the\r | |
21696 | right 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 =>\r | |
21700 | Fold.post\r | |
21701 | (updateBCD {b = 0, c = 0.0, d = "<>"},\r | |
21702 | fn {b, c, d} =>\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 | |
21709 | val () = f (U#d "goodbye") $\r | |
21710 | val () = 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 | |
21717 | are overloaded, meaning that they can denote a constant of the\r | |
21718 | appropriate type as determined by context. SML defines the\r | |
21719 | overloading classes <emphasis>Int</emphasis>, <emphasis>Real</emphasis>, and <emphasis>Word</emphasis>, which denote the sets\r | |
21720 | of types that integer, real, and word constants may take on. In\r | |
21721 | MLton, these are defined as follows.</simpara>\r | |
21722 | <informaltable\r | |
21723 | frame="all"\r | |
21724 | rowsep="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>, … <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>, … <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 | |
21746 | much context is used to resolve overloading. It says that the context\r | |
21747 | is <emphasis>no larger than the smallest enclosing structure-level\r | |
21748 | declaration</emphasis>, but that <emphasis>an implementation may require that a smaller\r | |
21749 | context determines the type</emphasis>. MLton uses the largest possible context\r | |
21750 | allowed by SML in resolving overloading. If the type of a constant is\r | |
21751 | not determined by context, then it takes on a default type. In MLton,\r | |
21752 | these are defined as follows.</simpara>\r | |
21753 | <informaltable\r | |
21754 | frame="all"\r | |
21755 | rowsep="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 | |
21777 | types.</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 | |
21793 | The 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 | |
21804 | which 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 | |
21817 | representation 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 | |
21848 | parallel 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 | |
21874 | range 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 | |
21908 | RAM. The benchmarks were compiled with the default settings for all\r | |
21909 | the compilers, except for Moscow ML, which was passed the\r | |
21910 | <literal>-orthodox -standalone -toplevel</literal> switches. The Poly/ML executables\r | |
21911 | were produced using <literal>polyc</literal>.\r | |
21912 | The SML/NJ executables were produced by wrapping the entire program in\r | |
21913 | a <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 | |
21915 | please 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 | |
21918 | of the benchmarks were obtained from the SML/NJ benchmark suite. Some\r | |
21919 | of 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 | |
21947 | when compiled by another compiler to the run time when compiled by\r | |
21948 | MLton. That is, the larger the number, the slower the generated code\r | |
21949 | runs. A number larger than one indicates that the corresponding\r | |
21950 | compiler produces code that runs more slowly than MLton. A * in an\r | |
21951 | entry means the compiler failed to compile the benchmark or that the\r | |
21952 | benchmark failed to run.</simpara>\r | |
21953 | <informaltable\r | |
21954 | frame="all"\r | |
21955 | rowsep="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 | |
22339 | Note: 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 | |
22341 | benchmark 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 | |
22346 | The size for MLton and the ML Kit is the sum of text and data for the\r | |
22347 | standalone executable as reported by <literal>size</literal>. The size for Moscow\r | |
22348 | ML is the size in bytes of the executable <literal>a.out</literal>. The size for\r | |
22349 | Poly/ML is the difference in size of the database before the session\r | |
22350 | start and after the commit. The size for SML/NJ is the size of the\r | |
22351 | heap file created by <literal>exportFn</literal> and does not include the size of\r | |
22352 | the SML/NJ runtime system (approximately 100K). A * in an entry means\r | |
22353 | that the compiler failed to compile the benchmark.</simpara>\r | |
22354 | <informaltable\r | |
22355 | frame="all"\r | |
22356 | rowsep="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 | |
22743 | seconds. A * in an entry means that the compiler failed to compile\r | |
22744 | the benchmark.</simpara>\r | |
22745 | <informaltable\r | |
22746 | frame="all"\r | |
22747 | rowsep="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 | |
23136 | used to force the type checker to ensure invariants at compile time.\r | |
23137 | This is done by augmenting a type with additional arguments (phantom\r | |
23138 | type variables) and expressing constraints by choosing phantom types\r | |
23139 | to 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 | |
23150 | dimensions\r | |
23151 | </simpara>\r | |
23152 | </listitem>\r | |
23153 | <listitem>\r | |
23154 | <simpara>\r | |
23155 | C 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 | |
23167 | subtyping\r | |
23168 | </simpara>\r | |
23169 | </listitem>\r | |
23170 | </itemizedlist>\r | |
23171 | </listitem>\r | |
23172 | <listitem>\r | |
23173 | <simpara>\r | |
23174 | socket 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 | |
23307 | function and translates calls to <literal>MLton_equal</literal> into calls to that\r | |
23308 | function.</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 | |
23311 | a separate equality function for each tuple type.</simpara>\r | |
23312 | <simpara>All equality functions are created only if necessary, i.e., if\r | |
23313 | equality is actually used at a type.</simpara>\r | |
23314 | <simpara>Optimizations:</simpara>\r | |
23315 | <itemizedlist>\r | |
23316 | <listitem>\r | |
23317 | <simpara>\r | |
23318 | for datatypes that are enumerations, do not build a case dispatch,\r | |
23319 | just 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 | |
23324 | deep equality always does an <literal>MLton_eq</literal> test first\r | |
23325 | </simpara>\r | |
23326 | </listitem>\r | |
23327 | <listitem>\r | |
23328 | <simpara>\r | |
23329 | If one argument to <literal>=</literal> is a constant and the type will get\r | |
23330 | translated to an <literal>IntOrPointer</literal>, then just use <literal>eq</literal> instead of the\r | |
23331 | full equality. This is important for implementing code like the\r | |
23332 | following 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 | |
23338 | Also convert pointer equality on scalar types to type specific\r | |
23339 | primitives.\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 | |
23367 | function and translates calls to <literal>MLton_hash</literal> into calls to that\r | |
23368 | function.</simpara>\r | |
23369 | <simpara>For tuples, it does the equality test inline; i.e., it does not create\r | |
23370 | a separate equality function for each tuple type.</simpara>\r | |
23371 | <simpara>All equality functions are created only if necessary, i.e., if\r | |
23372 | equality 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 | |
23396 | for equality. It is specified as</simpara>\r | |
23397 | <programlisting language="sml" linenumbering="unnumbered">val = : ''a * ''a -> 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 | |
23400 | polymorphic 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 | |
23403 | equality.</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 | |
23407 | of 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 | |
23414 | reals for equality, but beware that this has different algebraic\r | |
23415 | properties 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 | |
23426 | tuples, 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 | |
23432 | that values are compared by recursively descending the data structure\r | |
23433 | until ground types are reached, at which point the ground types are\r | |
23434 | compared with primitive equality tests (like comparison of\r | |
23435 | characters). 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 | |
23438 | different locations in memory.</simpara>\r | |
23439 | <simpara>Because of structural equality, immutable values can only be compared\r | |
23440 | if their components can be compared. For example, <literal>[1, 2, 3]</literal> can be\r | |
23441 | compared, 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 | |
23443 | only 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 | |
23449 | pointer 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 | |
23452 | same contents.</simpara>\r | |
23453 | <simpara>Because equality of mutable values is not structural, arrays and refs\r | |
23454 | can be compared <emphasis>even if their components are not equality types</emphasis>.\r | |
23455 | Hence, 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 | |
23458 | in\r | |
23459 | r = r\r | |
23460 | end</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 | |
23465 | same datatype are equal if they are of the same <link linkend="Variant">variant</link> and\r | |
23466 | if the <link linkend="Variant">variant</link>'s arguments are equal (recursively). So,\r | |
23467 | with 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 | |
23470 | and <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 | |
23472 | pointer equality whenever it reaches a mutable value. So, with the\r | |
23473 | datatype</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 | |
23476 | because 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 | |
23478 | the special property of the <literal>ref</literal> and <literal>array</literal> type constructors that\r | |
23479 | allows them to be compared regardless of their component type. For\r | |
23480 | example, 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 | |
23483 | because pointer comparison on a ref cell would suffice.\r | |
23484 | Unfortunately, the type system can only express that a user-defined\r | |
23485 | datatype <link linkend="AdmitsEquality">admits equality</link> or not. In this case, <literal>t</literal>\r | |
23486 | admits 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 | |
23489 | fun 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: [<equality>] t * [<equality>] 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 | |
23500 | values being compared, stopping as soon as they are determined to be\r | |
23501 | unequal, or exploring the entire values to determine that they are\r | |
23502 | equal. Hence, polymorphic equality can take time proportional to the\r | |
23503 | size 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 | |
23508 | When computing structural equality, first do a pointer comparison.\r | |
23509 | If the comparison yields <literal>true</literal>, then stop and return <literal>true</literal>, since\r | |
23510 | the structural comparison is guaranteed to do so. If the pointer\r | |
23511 | comparison fails, then recursively descend the values.\r | |
23512 | </simpara>\r | |
23513 | </listitem>\r | |
23514 | <listitem>\r | |
23515 | <simpara>\r | |
23516 | If a datatype is an enum (e.g. <literal>datatype t = A | B | C</literal>), then a\r | |
23517 | single comparison suffices to compare values of the datatype. No case\r | |
23518 | dispatch is required to determine whether the two values are of the\r | |
23519 | same <link linkend="Variant">variant</link>.\r | |
23520 | </simpara>\r | |
23521 | </listitem>\r | |
23522 | <listitem>\r | |
23523 | <simpara>\r | |
23524 | When comparing a known constant non-value-carrying\r | |
23525 | <link linkend="Variant">variant</link>, use a single comparison. For example, the\r | |
23526 | following 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 | |
23529 | fun f x = ... if A = x then ...</programlisting>\r | |
23530 | </listitem>\r | |
23531 | <listitem>\r | |
23532 | <simpara>\r | |
23533 | When 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 | |
23535 | dispatch 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 | |
23569 | variable 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 | |
23590 | development environment that includes implementations of a number of\r | |
23591 | languages, 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’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 | |
23611 | the following steps.</simpara>\r | |
23612 | <orderedlist numeration="arabic">\r | |
23613 | <listitem>\r | |
23614 | <simpara>\r | |
23615 | Make 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 | |
23621 | Get 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 | |
23631 | are porting to another architecture, you must use the C code\r | |
23632 | generator. These notes do not cover building a new native code\r | |
23633 | generator.</simpara>\r | |
23634 | <simpara>Some of the following steps will not be necessary if MLton already\r | |
23635 | supports 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 | |
23641 | Scripts.\r | |
23642 | </simpara>\r | |
23643 | <itemizedlist>\r | |
23644 | <listitem>\r | |
23645 | <simpara>\r | |
23646 | In <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 | |
23653 | Runtime 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 | |
23660 | In <literal>platform.h</literal>, add a new case to include <literal>platform/<arch>.h</literal> and <literal>platform/<os>.h</literal>.\r | |
23661 | </simpara>\r | |
23662 | </listitem>\r | |
23663 | <listitem>\r | |
23664 | <simpara>\r | |
23665 | In <literal>platform/<arch>.h</literal>:\r | |
23666 | </simpara>\r | |
23667 | <itemizedlist>\r | |
23668 | <listitem>\r | |
23669 | <simpara>\r | |
23670 | define <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 | |
23677 | In <literal>platform/<os>.h</literal>:\r | |
23678 | </simpara>\r | |
23679 | <itemizedlist>\r | |
23680 | <listitem>\r | |
23681 | <simpara>\r | |
23682 | include platform-specific includes.\r | |
23683 | </simpara>\r | |
23684 | </listitem>\r | |
23685 | <listitem>\r | |
23686 | <simpara>\r | |
23687 | define <literal>MLton_Platform_OS_host</literal>.\r | |
23688 | </simpara>\r | |
23689 | </listitem>\r | |
23690 | <listitem>\r | |
23691 | <simpara>\r | |
23692 | define 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 | |
23699 | In <literal>platform/<os>.c</literal> implement any platform-dependent functions that the runtime needs.\r | |
23700 | </simpara>\r | |
23701 | </listitem>\r | |
23702 | <listitem>\r | |
23703 | <simpara>\r | |
23704 | Add 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 | |
23709 | Compile and install the <link linkend="GnuMP">GnuMP</link>. This varies from platform to platform. In <literal>platform/<os>.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 | |
23716 | Basis Library implementation (<literal>basis-library/*</literal>)\r | |
23717 | </simpara>\r | |
23718 | <itemizedlist>\r | |
23719 | <listitem>\r | |
23720 | <simpara>\r | |
23721 | In <literal>primitive/prim-mlton.sml</literal>:\r | |
23722 | </simpara>\r | |
23723 | <itemizedlist>\r | |
23724 | <listitem>\r | |
23725 | <simpara>\r | |
23726 | Add 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 | |
23731 | modify 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/<arch>.h</literal>.\r | |
23732 | </simpara>\r | |
23733 | </listitem>\r | |
23734 | <listitem>\r | |
23735 | <simpara>\r | |
23736 | Add 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 | |
23741 | modify 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/<os>.h</literal>.\r | |
23742 | </simpara>\r | |
23743 | </listitem>\r | |
23744 | </itemizedlist>\r | |
23745 | </listitem>\r | |
23746 | <listitem>\r | |
23747 | <simpara>\r | |
23748 | In <literal>mlton/platform.{sig,sml}</literal> add a new variant.\r | |
23749 | </simpara>\r | |
23750 | </listitem>\r | |
23751 | <listitem>\r | |
23752 | <simpara>\r | |
23753 | In <literal>sml-nj/sml-nj.sml</literal>, modify <literal>getOSKind</literal>.\r | |
23754 | </simpara>\r | |
23755 | </listitem>\r | |
23756 | <listitem>\r | |
23757 | <simpara>\r | |
23758 | Look 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 | |
23767 | Compiler.\r | |
23768 | </simpara>\r | |
23769 | <itemizedlist>\r | |
23770 | <listitem>\r | |
23771 | <simpara>\r | |
23772 | In <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 | |
23777 | In <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 | |
23784 | system must be the same (except for possibly case of letters) in the\r | |
23785 | scripts, runtime, Basis Library implementation, and compiler (stubs).\r | |
23786 | In <literal>mlton/main/main.fun</literal>, MLton itself uses the conversions to and\r | |
23787 | from 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 | |
23795 | many as possible) of the regressions working before moving to a self\r | |
23796 | compile. It is easiest to do this by modifying and rebuilding the\r | |
23797 | compiler on a working machine and then running the regressions with a\r | |
23798 | cross compiler. It is not easy to build a gcc cross compiler, so we\r | |
23799 | recommend generating the C and assembly on a working machine (using\r | |
23800 | MLton’s <literal>-target</literal> and <literal>-stop g</literal> flags, copying the generated files to\r | |
23801 | the target machine, then compiling and linking there.</simpara>\r | |
23802 | <orderedlist numeration="arabic">\r | |
23803 | <listitem>\r | |
23804 | <simpara>\r | |
23805 | Remake the compiler on a working machine.\r | |
23806 | </simpara>\r | |
23807 | </listitem>\r | |
23808 | <listitem>\r | |
23809 | <simpara>\r | |
23810 | Use <literal>bin/add-cross</literal> to add support for the new target. In particular, this should create <literal>build/lib/mlton/targets/<target>/</literal> with the platform-specific necessary cross-compilation information.\r | |
23811 | </simpara>\r | |
23812 | </listitem>\r | |
23813 | <listitem>\r | |
23814 | <simpara>\r | |
23815 | Run the regression tests with the cross-compiler. To cross-compile all the tests, do\r | |
23816 | </simpara>\r | |
23817 | <screen>bin/regression -cross <target></screen>\r | |
23818 | <simpara>This will create all the executables. Then, copy <literal>bin/regression</literal> and\r | |
23819 | the <literal>regression</literal> directory to the target machine, and do</simpara>\r | |
23820 | <screen>bin/regression -run-only <target></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 | |
23825 | until all the regressions pass.</simpara>\r | |
23826 | </section>\r | |
23827 | <section id="_bootstrap">\r | |
23828 | <title>Bootstrap</title>\r | |
23829 | <simpara>Once you’ve got all the regressions working, you can build MLton for\r | |
23830 | the new target. As with the regressions, the idea for bootstrapping\r | |
23831 | is to generate the C and assembly on a working machine, copy it to the\r | |
23832 | target machine, and then compile and link there. Here’s the sequence\r | |
23833 | of steps.</simpara>\r | |
23834 | <orderedlist numeration="arabic">\r | |
23835 | <listitem>\r | |
23836 | <simpara>\r | |
23837 | On 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 <target> mlton.mlb</screen>\r | |
23840 | </listitem>\r | |
23841 | <listitem>\r | |
23842 | <simpara>\r | |
23843 | Copy to the target machine.\r | |
23844 | </simpara>\r | |
23845 | </listitem>\r | |
23846 | <listitem>\r | |
23847 | <simpara>\r | |
23848 | On 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 | |
23851 | mv <target> 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 | |
23856 | On 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 | |
23859 | gcc -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 | |
23867 | At 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 | |
23873 | Making 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 | |
23878 | directories were clean so that the tools are rebuilt on the new\r | |
23879 | platform, but hopefully this structure works. Once you’ve got a\r | |
23880 | compiler on the target machine, you should test it by running all the\r | |
23881 | regressions normally (i.e. without the <literal>-cross</literal> flag) and by running a\r | |
23882 | couple 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 | |
23887 | MLton 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 | |
23910 | to 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 | |
23937 | However, it is possible to implement your own version with only a few\r | |
23938 | lines of code.</simpara>\r | |
23939 | <simpara>Here is a definition for <literal>printf</literal> and <literal>fprintf</literal>, along with format\r | |
23940 | specifiers 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 => p ()) ignore\r | |
23944 | fun fprintf out f = f (out, id)\r | |
23945 | val printf = fn z => fprintf TextIO.stdOut z\r | |
23946 | fun one ((out, f), make) g =\r | |
23947 | g (out, fn r =>\r | |
23948 | f (fn p =>\r | |
23949 | make (fn s =>\r | |
23950 | r (fn () => (p (); TextIO.output (out, s))))))\r | |
23951 | fun ` x s = one (x, fn f => f s)\r | |
23952 | fun spec to x = one (x, fn f => f o to)\r | |
23953 | val B = fn z => spec Bool.toString z\r | |
23954 | val I = fn z => spec Int.toString z\r | |
23955 | val R = fn z => spec Real.toString z\r | |
23956 | end</programlisting>\r | |
23957 | <simpara>Here’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 <spec1> ... <specn> $ <arg1> ... <argm></screen>\r | |
23963 | <simpara>where each <literal><speci></literal> is either a specifier like <literal>B</literal>, <literal>I</literal>, or <literal>R</literal>, or\r | |
23964 | is an inline string, like <literal>`"foo"</literal>. A backtick (<literal>`</literal>)\r | |
23965 | must precede each inline string. Each <literal><argi></literal> must be of the\r | |
23966 | appropriate 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 | |
23968 | ways. In particular, the function produced by <literal>printf</literal> is a perfectly\r | |
23969 | ordinary SML function, and can be passed around, used multiple times,\r | |
23970 | etc. For example:</simpara>\r | |
23971 | <programlisting language="sml" linenumbering="unnumbered">val f: int -> bool -> unit = printf `"Int="I`" Bool="B`"\n" $\r | |
23972 | val () = f 1 true\r | |
23973 | val () = f 2 false</programlisting>\r | |
23974 | <simpara>The definition of <literal>printf</literal> is even careful to not print anything until\r | |
23975 | it is fully applied. So, examples like the following will work as\r | |
23976 | expected.</simpara>\r | |
23977 | <screen>val f: int -> bool -> unit = printf `"Int="I`" Bool="B`"\n" $ 13\r | |
23978 | val () = f true\r | |
23979 | val () = f false</screen>\r | |
23980 | <simpara>It is also easy to define new format specifiers. For example, suppose\r | |
23981 | we wanted format specifiers for characters and strings.</simpara>\r | |
23982 | <screen>val C = fn z => spec Char.toString z\r | |
23983 | val S = fn z => spec (fn s => s) z</screen>\r | |
23984 | <simpara>One can define format specifiers for more complex types, e.g. pairs of\r | |
23985 | integers.</simpara>\r | |
23986 | <screen>val I2 =\r | |
23987 | fn z =>\r | |
23988 | spec (fn (i, j) =>\r | |
23989 | concat ["(", Int.toString i, ", ", Int.toString j, ")"])\r | |
23990 | z</screen>\r | |
23991 | <simpara>Here’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 | |
23997 | arguments. Here is the definition of a <literal>Printf</literal> structure in terms of\r | |
23998 | fold. The structure is equivalent to the above one, except that it\r | |
23999 | uses 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) => f (fn p => p ()) ignore)\r | |
24004 | \r | |
24005 | val printf = fn z => fprintf TextIO.stdOut z\r | |
24006 | \r | |
24007 | fun one ((out, f), make) =\r | |
24008 | (out, fn r =>\r | |
24009 | f (fn p =>\r | |
24010 | make (fn s =>\r | |
24011 | r (fn () => (p (); TextIO.output (out, s))))))\r | |
24012 | \r | |
24013 | val ` =\r | |
24014 | fn z => Fold.step1 (fn (s, x) => one (x, fn f => f s)) z\r | |
24015 | \r | |
24016 | fun spec to = Fold.step0 (fn x => one (x, fn f => f o to))\r | |
24017 | \r | |
24018 | val B = fn z => spec Bool.toString z\r | |
24019 | val I = fn z => spec Int.toString z\r | |
24020 | val R = fn z => 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 | |
24023 | example, one can name parts of format strings using the fold idiom for\r | |
24024 | naming sequences of steps.</simpara>\r | |
24025 | <screen>val IB = fn u => Fold.fold u `"Int="I`" Bool="B\r | |
24026 | val () = 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 => Fold.fold u `"X="X`" Bool="B\r | |
24029 | val () = 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 | |
24051 | with 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 | |
24056 | val () = 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’t work, because SML functions take a fixed number\r | |
24059 | of arguments. Actually they take one argument, but if that’s a tuple,\r | |
24060 | it 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 | |
24066 | val () = 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 -> int -> real -> unit\r | |
24069 | val printf: string -> int -> real -> real -> unit</screen>\r | |
24070 | <simpara>This can’t work, because <literal>printf</literal> can only have one type. SML doesn’t\r | |
24071 | support 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 | |
24076 | problem. 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 | |
24078 | val () = 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 -> int -> real -> unit\r | |
24081 | val printf: string -> real -> int -> unit</screen>\r | |
24082 | <simpara>Again, this can’t possibly working because SML doesn’t have\r | |
24083 | overloading, and types can’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 | |
24088 | uses 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 | |
24090 | val printf: 'a t -> 'a\r | |
24091 | infix D F\r | |
24092 | val fs1: (int -> real -> unit) t = "here's an int "D" and a real "F".\n"\r | |
24093 | val fs2: (int -> real -> real -> unit) t =\r | |
24094 | "here's three values ("D", "F", "F").\n"\r | |
24095 | val () = printf fs1 13 17.0\r | |
24096 | val () = 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 | |
24098 | string 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 | |
24103 | character requires an additional argument of the appropriate type to\r | |
24104 | be 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 | |
24106 | string 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 | |
24108 | val ` : string -> ('a, 'a) t (* guess the type, which must be verified *)\r | |
24109 | val D: (int -> 'a, 'b) t * string -> ('a, 'b) t (* consume an int *)\r | |
24110 | val F: (real -> 'a, 'b) t * string -> ('a, 'b) t (* consume a real *)\r | |
24111 | val printf: (unit, 'a) t -> 'a</programlisting>\r | |
24112 | <simpara>Don’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’s build up a format string and a specialized <literal>printf</literal>.</simpara>\r | |
24117 | <programlisting language="sml" linenumbering="unnumbered">infix D F\r | |
24118 | val f0 = `"here's an int "\r | |
24119 | val f1 = f0 D " and a real "\r | |
24120 | val f2 = f1 F ".\n"\r | |
24121 | val p = printf f2</programlisting>\r | |
24122 | <simpara>These definitions yield the following types.</simpara>\r | |
24123 | <programlisting language="sml" linenumbering="unnumbered">val f0: (int -> real -> unit, int -> real -> unit) t\r | |
24124 | val f1: (real -> unit, int -> real -> unit) t\r | |
24125 | val f2: (unit, int -> real -> unit) t\r | |
24126 | val p: int -> real -> unit</programlisting>\r | |
24127 | <simpara>So, <literal>p</literal> is a specialized <literal>printf</literal> function. We could use it as\r | |
24128 | follows</simpara>\r | |
24129 | <programlisting language="sml" linenumbering="unnumbered">val () = p 13 17.0\r | |
24130 | val () = 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 -> ('a, 'a) t\r | |
24138 | val D: (int -> 'a, 'b) t * string -> ('a, 'b) t\r | |
24139 | val F: (real -> 'a, 'b) t * string -> ('a, 'b) t\r | |
24140 | val printf: (unit, 'a) t -> 'a\r | |
24141 | end\r | |
24142 | \r | |
24143 | functor 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 | |
24155 | formatter for the part of the format string before it and transforms\r | |
24156 | it into a new formatter that first does the left hand bit, then does\r | |
24157 | its 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 -> 'a) -> 'b\r | |
24161 | \r | |
24162 | fun printf (T f) = f (fn () => ())\r | |
24163 | \r | |
24164 | fun ` s = T (fn a => (print s; a ()))\r | |
24165 | \r | |
24166 | fun D (T f, s) =\r | |
24167 | T (fn g => f (fn () => fn i =>\r | |
24168 | (print (Int.toString i); print s; g ())))\r | |
24169 | \r | |
24170 | fun F (T f, s) =\r | |
24171 | T (fn g => f (fn () => fn i =>\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 | |
24182 | Within the <literal>Printf</literal> structure we can define a format character\r | |
24183 | generator.</simpara>\r | |
24184 | <programlisting language="sml" linenumbering="unnumbered">val newFormat: ('a -> string) -> ('a -> 'b, 'c) t * string -> ('b, 'c) t =\r | |
24185 | fn toString => fn (T f, s) =>\r | |
24186 | T (fn th => f (fn () => fn a => (print (toString a); print s ; th ())))\r | |
24187 | val D = fn z => newFormat Int.toString z\r | |
24188 | val F = fn z => 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 | |
24193 | the 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 -> ('a, 'a) t\r | |
24198 | val newFormat: ('a -> string) -> ('a -> 'b, 'c) t * string -> ('b, 'c) t\r | |
24199 | val printf: (unit, 'a) t -> 'a\r | |
24200 | end\r | |
24201 | \r | |
24202 | structure Printf: PRINTF =\r | |
24203 | struct\r | |
24204 | datatype ('a, 'b) t = T of (unit -> 'a) -> 'b\r | |
24205 | \r | |
24206 | fun printf (T f) = f (fn () => ())\r | |
24207 | \r | |
24208 | fun ` s = T (fn a => (print s; a ()))\r | |
24209 | \r | |
24210 | fun newFormat toString (T f, s) =\r | |
24211 | T (fn th =>\r | |
24212 | f (fn () => fn a =>\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 | |
24221 | transformers.</simpara>\r | |
24222 | <programlisting language="sml" linenumbering="unnumbered">signature PRINTF =\r | |
24223 | sig\r | |
24224 | type ('a, 'b) t\r | |
24225 | val ` : string -> ('a, 'a) t\r | |
24226 | val fprintf: (unit, 'a) t * TextIO.outstream -> 'a\r | |
24227 | val newFormat: ('a -> string) -> ('a -> 'b, 'c) t * string -> ('b, 'c) t\r | |
24228 | val printf: (unit, 'a) t -> 'a\r | |
24229 | end\r | |
24230 | \r | |
24231 | structure 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 -> 'a) -> out -> 'b\r | |
24237 | \r | |
24238 | fun fprintf (T f, out) = f (fn _ => ()) out\r | |
24239 | \r | |
24240 | fun printf t = fprintf (t, TextIO.stdOut)\r | |
24241 | \r | |
24242 | fun ` s = T (fn a => fn out => (output (out, s); a out))\r | |
24243 | \r | |
24244 | fun newFormat toString (T f, s) =\r | |
24245 | T (fn g =>\r | |
24246 | f (fn out => fn a =>\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 | |
24257 | Lesson: instead of using dependent types for a function, express the\r | |
24258 | the dependency in the type of the argument.\r | |
24259 | </simpara>\r | |
24260 | </listitem>\r | |
24261 | <listitem>\r | |
24262 | <simpara>\r | |
24263 | If <literal>printf</literal> is partially applied, it will do the printing then and\r | |
24264 | there. 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 | |
24267 | either be eager (as above) or lazy (as below). A lazy formatter\r | |
24268 | accumulates enough state to print the entire string. The simplest\r | |
24269 | lazy 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 -> 'a) -> string -> 'b\r | |
24273 | \r | |
24274 | fun printf (T f) = f print ""\r | |
24275 | \r | |
24276 | fun ` s = T (fn th => fn s' => th (s' ^ s))\r | |
24277 | \r | |
24278 | fun newFormat toString (T f, s) =\r | |
24279 | T (fn th =>\r | |
24280 | f (fn s' => fn a =>\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 -> 'a) -> string list -> '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 => fn ss => th (s::ss))\r | |
24291 | \r | |
24292 | fun newFormat toString (T f, s) =\r | |
24293 | T (fn th =>\r | |
24294 | f (fn ss => fn a =>\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 | |
24320 | product 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 | |
24325 | situations where the syntax is cumbersome. There are also situations\r | |
24326 | in which it is useful to construct and destruct n-ary products\r | |
24327 | inductively, 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 | |
24329 | with an infix constructor defined as follows.</simpara>\r | |
24330 | <programlisting language="sml" linenumbering="unnumbered">datatype ('a, 'b) product = & of 'a * 'b\r | |
24331 | infix &</programlisting>\r | |
24332 | <simpara>With these definitions, one can write an n-ary product as a nested\r | |
24333 | binary product quite conveniently.</simpara>\r | |
24334 | <programlisting language="sml" linenumbering="unnumbered">x1 & x2 & ... & xn</programlisting>\r | |
24335 | <simpara>Because of left associativity, this is the same as</simpara>\r | |
24336 | <programlisting language="sml" linenumbering="unnumbered">(((x1 & x2) & ...) & xn)</programlisting>\r | |
24337 | <simpara>Because <literal>&</literal> is a constructor, the syntax can also be used for\r | |
24338 | patterns.</simpara>\r | |
24339 | <simpara>The symbol <literal>&</literal> is inspired by the Curry-Howard isomorphism: the proof\r | |
24340 | of a conjunction <literal>(A & 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 | |
24344 | type of the form.</simpara>\r | |
24345 | <programlisting language="sml" linenumbering="unnumbered">'a parser * 'b parser -> ('a * 'b) parser</programlisting>\r | |
24346 | <simpara>and produces a parser for the concatenation of two parsers. When more\r | |
24347 | than two parsers are concatenated, the result of the resulting parser\r | |
24348 | is 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 | |
24352 | becomes</simpara>\r | |
24353 | <programlisting language="sml" linenumbering="unnumbered">'a parser * 'b parser -> ('a, 'b) product parser</programlisting>\r | |
24354 | <simpara>While this doesn’t stop the nesting, it makes the pattern significantly\r | |
24355 | easier 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 & p2 & p3 & ... & 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 | |
24381 | bytes allocated, execution counts, or time spent in each function. To\r | |
24382 | profile you program, compile with <literal>-profile <emphasis>kind</emphasis></literal>, where <emphasis>kind</emphasis>\r | |
24383 | is one of <literal>alloc</literal>, <literal>count</literal>, or <literal>time</literal>. Then, run the executable,\r | |
24384 | which will write an <literal>mlmon.out</literal> file when it finishes. You can then\r | |
24385 | run <literal>mlprof</literal> on the executable and the <literal>mlmon.out</literal> file to see the\r | |
24386 | performance 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 | |
24445 | find out how many bytes each function allocates. To do so, compile\r | |
24446 | your 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 | [] => l2\r | |
24451 | | x :: l1 => x :: append (l1, l2)\r | |
24452 | \r | |
24453 | fun rev l =\r | |
24454 | case l of\r | |
24455 | [] => []\r | |
24456 | | x :: l => append (rev l, [x])\r | |
24457 | \r | |
24458 | val l = List.tabulate (1000, fn i => i)\r | |
24459 | val _ = 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 | |
24464 | 6,030,136 bytes allocated (108,336 bytes by GC)\r | |
24465 | function cur\r | |
24466 | ----------------------- -----\r | |
24467 | append list-rev.sml: 1 97.6%\r | |
24468 | <gc> 1.8%\r | |
24469 | <main> 0.4%\r | |
24470 | rev 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 | |
24472 | function defined on line 1 of <literal>list-rev.sml</literal>. The table also shows\r | |
24473 | how special functions like <literal>gc</literal> and <literal>main</literal> are handled: they are\r | |
24474 | printed with surrounding brackets. C functions are displayed\r | |
24475 | similarly. In this example, the allocation done by the garbage\r | |
24476 | collector 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 | |
24478 | because 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 | |
24480 | much 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 | |
24487 | find out how many times each function is called and how many times\r | |
24488 | each 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 >= 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 >= 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 | |
24512 | val rec f =\r | |
24513 | fn 0 => ()\r | |
24514 | | ~1 => print "this branch is not taken\n"\r | |
24515 | | n => (Tak.tak1 (18, 12, 6) ; f (n-1))\r | |
24516 | \r | |
24517 | val _ = f 5000\r | |
24518 | \r | |
24519 | fun 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 | |
24525 | 623,610,002 ticks\r | |
24526 | function cur raw\r | |
24527 | --------------------------------- ----- -------------\r | |
24528 | Tak.tak1.tak2 tak.sml: 5 38.2% (238,530,000)\r | |
24529 | Tak.tak1.tak2.<true> tak.sml: 7 27.5% (171,510,000)\r | |
24530 | Tak.tak1 tak.sml: 3 10.7% (67,025,000)\r | |
24531 | Tak.tak1.<true> tak.sml: 14 10.7% (67,025,000)\r | |
24532 | Tak.tak1.tak2.<false> tak.sml: 9 10.7% (67,020,000)\r | |
24533 | Tak.tak1.<false> tak.sml: 16 2.0% (12,490,000)\r | |
24534 | f tak.sml: 23 0.0% (5,001)\r | |
24535 | f.<branch> tak.sml: 25 0.0% (5,000)\r | |
24536 | f.<branch> tak.sml: 23 0.0% (1)\r | |
24537 | uncalled tak.sml: 29 0.0% (0)\r | |
24538 | f.<branch> tak.sml: 24 0.0% (0)</screen>\r | |
24539 | <simpara>Branches are displayed with lexical nesting followed by <literal><branch></literal>\r | |
24540 | where the function name would normally be, or <literal><true></literal> or <literal><false></literal>\r | |
24541 | for if-expressions. It is best to run <literal>mlprof</literal> with <literal>-show-line true</literal>\r | |
24542 | to 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 | |
24544 | code in your program that hasn’t been tested. For this reason,\r | |
24545 | <literal>mlprof</literal> displays functions and branches even if they have a count of\r | |
24546 | zero. As the above output shows, the branch on line 24 was never\r | |
24547 | taken and the function defined on line 29 was never called. To see\r | |
24548 | zero counts, it is best to run <literal>mlprof</literal> with <literal>-raw true</literal>, since some\r | |
24549 | code (e.g. the branch on line 23 above) will show up with <literal>0.0%</literal> but\r | |
24550 | may 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 | |
24556 | functions on the stack, not just the currently executing function. To\r | |
24557 | do so, compile your program with <literal>-profile-stack true</literal>. For example,\r | |
24558 | suppose 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 | [] => l2\r | |
24562 | | x :: l1 => x :: append (l1, l2)\r | |
24563 | \r | |
24564 | fun rev l =\r | |
24565 | case l of\r | |
24566 | [] => []\r | |
24567 | | x :: l => append (rev l, [x])\r | |
24568 | \r | |
24569 | val l = List.tabulate (1000, fn i => i)\r | |
24570 | val _ = 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 | |
24576 | 6,030,136 bytes allocated (108,336 bytes by GC)\r | |
24577 | function cur stack GC\r | |
24578 | ----------------------- ----- ----- ----\r | |
24579 | append list-rev.sml: 1 97.6% 97.6% 1.4%\r | |
24580 | <gc> 1.8% 0.0% 1.8%\r | |
24581 | <main> 0.4% 98.2% 1.8%\r | |
24582 | rev 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 | |
24585 | on the stack while 97.6% of the allocation is done by the user program\r | |
24586 | and 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 | |
24588 | noticeable since there is some extra bookkeeping at every nontail call\r | |
24589 | and 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 | |
24595 | find out how much time is spent in each function over an entire run of\r | |
24596 | the program. To do so, compile your program with <literal>-profile time</literal>.\r | |
24597 | For 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 >= 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 >= 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 | |
24619 | val rec f =\r | |
24620 | fn 0 => ()\r | |
24621 | | ~1 => print "this branch is not taken\n"\r | |
24622 | | n => (Tak.tak1 (18, 12, 6) ; f (n-1))\r | |
24623 | \r | |
24624 | val _ = f 5000\r | |
24625 | \r | |
24626 | fun 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 | |
24632 | 6.00 seconds of CPU time (0.00 seconds GC)\r | |
24633 | function cur\r | |
24634 | ------------- -----\r | |
24635 | Tak.tak1.tak2 75.8%\r | |
24636 | Tak.tak1 24.2%</screen>\r | |
24637 | <simpara>This example shows how <literal>mlprof</literal> indicates lexical nesting: as a\r | |
24638 | sequence of period-separated names indicating the structures and\r | |
24639 | functions in which a function definition is nested. The profiling\r | |
24640 | data 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 | |
24644 | 6.00 seconds of CPU time (0.00 seconds GC)\r | |
24645 | function cur raw\r | |
24646 | ------------- ----- -------\r | |
24647 | Tak.tak1.tak2 75.8% (4.55s)\r | |
24648 | Tak.tak1 24.2% (1.45s)</screen>\r | |
24649 | <simpara>Display the file name and line number for each function in addition to\r | |
24650 | its name with <literal>-show-line true</literal>.</simpara>\r | |
24651 | <screen>% mlprof -show-line true tak mlmon.out\r | |
24652 | 6.00 seconds of CPU time (0.00 seconds GC)\r | |
24653 | function cur\r | |
24654 | ------------------------- -----\r | |
24655 | Tak.tak1.tak2 tak.sml: 5 75.8%\r | |
24656 | Tak.tak1 tak.sml: 3 24.2%</screen>\r | |
24657 | <simpara>Time profiling is designed to have a very small performance impact.\r | |
24658 | However, in some cases there will be a run-time performance cost,\r | |
24659 | which may perturb the results. There is more likely to be an impact\r | |
24660 | with <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 | |
24662 | out 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 | |
24667 | a run-time error, since they would interfere with the profiler signal\r | |
24668 | handler.</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 | |
24682 | time</literal>, it is best to have a long running program (at least tens of\r | |
24683 | seconds) 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 | |
24690 | do not have time to implement, or at least haven’t started on yet.\r | |
24691 | Here is a list of some of those improvements, ranging from the easy (1\r | |
24692 | week) to the difficult (several months). If you have any interest in\r | |
24693 | working on one of these, or some other improvement to MLton not listed\r | |
24694 | here, 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 | |
24699 | Port to new platform: Windows (native, not Cygwin or MinGW), …\r | |
24700 | </simpara>\r | |
24701 | </listitem>\r | |
24702 | <listitem>\r | |
24703 | <simpara>\r | |
24704 | Source-level debugger\r | |
24705 | </simpara>\r | |
24706 | </listitem>\r | |
24707 | <listitem>\r | |
24708 | <simpara>\r | |
24709 | Heap profiler\r | |
24710 | </simpara>\r | |
24711 | </listitem>\r | |
24712 | <listitem>\r | |
24713 | <simpara>\r | |
24714 | Interfaces to libraries: OpenGL, Gtk+, D-BUS, …\r | |
24715 | </simpara>\r | |
24716 | </listitem>\r | |
24717 | <listitem>\r | |
24718 | <simpara>\r | |
24719 | More 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 | |
24724 | Additional constant types: <literal>structure Real80: REAL</literal>, …\r | |
24725 | </simpara>\r | |
24726 | </listitem>\r | |
24727 | <listitem>\r | |
24728 | <simpara>\r | |
24729 | An IDE (possibly integrated with <link linkend="Eclipse">Eclipse</link>)\r | |
24730 | </simpara>\r | |
24731 | </listitem>\r | |
24732 | <listitem>\r | |
24733 | <simpara>\r | |
24734 | Port MLRISC and use for code generation\r | |
24735 | </simpara>\r | |
24736 | </listitem>\r | |
24737 | <listitem>\r | |
24738 | <simpara>\r | |
24739 | Optimizations\r | |
24740 | </simpara>\r | |
24741 | <itemizedlist>\r | |
24742 | <listitem>\r | |
24743 | <simpara>\r | |
24744 | Improved closure representation\r | |
24745 | </simpara>\r | |
24746 | <simpara>Right now, MLton’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 | |
24767 | Elimination of array bounds checks in loops\r | |
24768 | </simpara>\r | |
24769 | </listitem>\r | |
24770 | <listitem>\r | |
24771 | <simpara>\r | |
24772 | Elimination of overflow checks on array index computations\r | |
24773 | </simpara>\r | |
24774 | </listitem>\r | |
24775 | <listitem>\r | |
24776 | <simpara>\r | |
24777 | Common-subexpression elimination of repeated array subscripts\r | |
24778 | </simpara>\r | |
24779 | </listitem>\r | |
24780 | <listitem>\r | |
24781 | <simpara>\r | |
24782 | Loop-invariant code motion, especially for tuple selects\r | |
24783 | </simpara>\r | |
24784 | </listitem>\r | |
24785 | <listitem>\r | |
24786 | <simpara>\r | |
24787 | Partial 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 | |
24799 | Loop unrolling, especially for small loops\r | |
24800 | </simpara>\r | |
24801 | </listitem>\r | |
24802 | <listitem>\r | |
24803 | <simpara>\r | |
24804 | Auto-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 | |
24809 | Optimize <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 | |
24816 | Analyses\r | |
24817 | </simpara>\r | |
24818 | <itemizedlist>\r | |
24819 | <listitem>\r | |
24820 | <simpara>\r | |
24821 | Uncaught 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 | |
24833 | syllable. 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 | |
24840 | properties (name-value pairs) can be inserted and from which\r | |
24841 | properties can be looked up by name. The term comes from the Lisp\r | |
24842 | language, where every symbol has a property list for storing\r | |
24843 | information, and where the names are typically symbols and keys can be\r | |
24844 | any type of value.</simpara>\r | |
24845 | <simpara>Here is an SML signature for property lists such that for any type of\r | |
24846 | value a new property can be dynamically created to manipulate that\r | |
24847 | type 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 -> t\r | |
24853 | val newProperty: unit -> {add: t * 'a -> unit,\r | |
24854 | peek: t -> 'a option}\r | |
24855 | end</programlisting>\r | |
24856 | <simpara>Here is a functor demonstrating the use of property lists. It first\r | |
24857 | creates a property list, then two new properties (of different types),\r | |
24858 | and 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 -> unit, peek = peekInt} = P.newProperty ()\r | |
24864 | val {add = addReal: P.t * real -> 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 | |
24873 | functor 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 | |
24878 | implementation requires a <link linkend="UniversalType">UniversalType</link>. Given that, a property\r | |
24879 | list is simply a list of elements of the universal type. Adding a\r | |
24880 | property adds to the front of the list, and looking up a property\r | |
24881 | scans 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 | |
24901 | handle duplicate insertions of the same property, as well as the\r | |
24902 | removal 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 | |
24909 | MLton relies heavily on property lists for attaching information to\r | |
24910 | syntax 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 | |
24917 | The <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> — 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 | |
24940 | Checkout 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 | |
24948 | Invoke <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 | |
24962 | similar, please contact me. GreyLensman on #sml on IRC or rracine at\r | |
24963 | this 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 | |
24968 | Pretty solid, high performance Rete implementation - base functionality is complete.\r | |
24969 | </simpara>\r | |
24970 | </listitem>\r | |
24971 | <listitem>\r | |
24972 | <simpara>\r | |
24973 | N3 parser - mostly complete\r | |
24974 | </simpara>\r | |
24975 | </listitem>\r | |
24976 | <listitem>\r | |
24977 | <simpara>\r | |
24978 | RDF parser based on fxg - not started.\r | |
24979 | </simpara>\r | |
24980 | </listitem>\r | |
24981 | <listitem>\r | |
24982 | <simpara>\r | |
24983 | Swerve HTTP server - 1/2 done.\r | |
24984 | </simpara>\r | |
24985 | </listitem>\r | |
24986 | <listitem>\r | |
24987 | <simpara>\r | |
24988 | SPARQL implementation - not started.\r | |
24989 | </simpara>\r | |
24990 | </listitem>\r | |
24991 | <listitem>\r | |
24992 | <simpara>\r | |
24993 | Persistent engine based on BerkelyDB - not started.\r | |
24994 | </simpara>\r | |
24995 | </listitem>\r | |
24996 | <listitem>\r | |
24997 | <simpara>\r | |
24998 | Native implementation of Postgresql protocol - underway, ways to go.\r | |
24999 | </simpara>\r | |
25000 | </listitem>\r | |
25001 | <listitem>\r | |
25002 | <simpara>\r | |
25003 | I also have a small change to the MLton compiler to add <literal>PackWord<emphasis><N></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 | |
25012 | maintained at runtime. Nodes in the graph are heap objects and edges\r | |
25013 | correspond to the pointers between heap objects. As the program runs,\r | |
25014 | it allocates new objects (adds nodes to the graph), and those new\r | |
25015 | objects can contain pointers to other objects (new edges in the\r | |
25016 | graph). If the program uses mutable objects (refs or arrays), it can\r | |
25017 | also 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 | |
25019 | nodes, and can only ever access nodes that are reachable by following\r | |
25020 | edges from these root nodes. Nodes that are <emphasis>unreachable</emphasis> can be\r | |
25021 | garbage 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 | |
25046 | arguments; an argument of a function or label is redundant if it is\r | |
25047 | always the same as another argument of the same function or label.\r | |
25048 | The analysis finds an equivalence relation on the arguments of a\r | |
25049 | function or label, such that all arguments in an equivalence class are\r | |
25050 | redundant with respect to the other arguments in the equivalence\r | |
25051 | class; the transformation selects one representative of each\r | |
25052 | equivalence class and drops the binding occurrence of\r | |
25053 | non-representative variables and renames use occurrences of the\r | |
25054 | non-representative variables to the representative variable. The\r | |
25055 | analysis finds the equivalence classes via a fixed-point analysis.\r | |
25056 | Each vector of arguments to a function or label is initialized to\r | |
25057 | equivalence classes that equate all arguments of the same type; one\r | |
25058 | could start with an equivalence class that equates all arguments, but\r | |
25059 | arguments of different type cannot be redundant. Variables bound in\r | |
25060 | statements are initialized to singleton equivalence classes. The\r | |
25061 | fixed-point analysis repeatedly refines these equivalence classes on\r | |
25062 | the 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 | |
25078 | components of it, were passed around in several places. That may have\r | |
25079 | been more relevant with polyvariant analyses (which are long gone).\r | |
25080 | But it still seems possibly relevant, especially with more aggressive\r | |
25081 | flattening, which should reveal some fields in nested closure records\r | |
25082 | that 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 | |
25093 | previous 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 | |
25108 | adding or subtracting 1. In particular, it will eliminate it in the\r | |
25109 | following cases:</simpara>\r | |
25110 | <programlisting language="sml" linenumbering="unnumbered">if x < y\r | |
25111 | then ... x + 1 ...\r | |
25112 | else ... 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&type=ISBN&location=10000&state=&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&type=ISBN&location=10000&state=&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 | |
25256 | that it yields nice speedups in SML.NET’s compile times. There are\r | |
25257 | also benchmarks showing that SML.NET when compiled by MLton runs\r | |
25258 | roughly 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&rep=rep1&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’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 | |
25333 | design 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’s closure-conversion algorithm, which translates from\r | |
25350 | its simply-typed higher-order intermediate language to its\r | |
25351 | simply-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 | |
25424 | X 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 | |
25460 | functions 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&tid=4787">The Little MLer</ulink>\r | |
25493 | (<ulink url="http://www3.addall.com/New/submitNew.cgi?query=026256114X&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 | |
25516 | elimination that is an optimization operating on MLton’s static single\r | |
25517 | assignment (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’CAML, which has an approach to ad-hoc\r | |
25537 | polymorphism based on <link linkend="References_Dubois95">Dubois95</link>, the differences being in how\r | |
25538 | type checking works an an improved compilation approach for typecase\r | |
25539 | that 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&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 | |
25566 | followed by a detailed description of each module. The module\r | |
25567 | descriptions 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&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 | |
25635 | the Ped text editor. Argues that using large numbers of threads and\r | |
25636 | message passing style is a practical and effective way of\r | |
25637 | modularizing 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’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 | |
25665 | encountered 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&type=ISBN">addall</ulink>).\r | |
25683 | ISBN 0471941484.\r | |
25684 | Richard Jones.\r | |
25685 | John Wiley & 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 | |
25705 | published 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’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&rep=rep1&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’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 | |
25772 | compiler and interpreter for ML with a machine model aimed at\r | |
25773 | efficient 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 | |
25805 | another, and is useful for the receiving thread to treat as an\r | |
25806 | exception so that it can clean up locks or other state relevant to its\r | |
25807 | current 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 | |
25850 | to four times over Moscow ML’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—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&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&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 | |
25896 | Accompanied 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&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’s syntax and\r | |
25910 | semantics. 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&rep=rep1&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 | |
25958 | an 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&rep=rep1&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&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 | |
26055 | different native x86 compilers (including MLton) and their register\r | |
26056 | usage 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’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 | |
26117 | processor.</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&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&rep=rep1&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 | |
26186 | match-compilation heuristics and showed that choice of heuristic\r | |
26187 | usually 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 | |
26230 | for 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&rep=rep1&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’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&rep=rep1&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 | |
26320 | algorithm uses a unification-based flow analysis followed by\r | |
26321 | defunctionalization 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 | |
26334 | is similar in structure to MLton, using monomorphisation,\r | |
26335 | defunctionalization, 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&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 | |
26379 | collector 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 | |
26391 | collector 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 | |
26402 | benchmarks 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 | |
26613 | The 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 | |
26632 | object for the <literal>ref</literal>, which in the above case saves two words. We\r | |
26633 | also save the time and code for the extra indirection at each get and\r | |
26634 | set. There are lots of useful data structures (singly-linked and\r | |
26635 | doubly-linked lists, union-find, Fibonacci heaps, …) that I believe\r | |
26636 | we are paying through the nose right now because of the absence of ref\r | |
26637 | flattening.</simpara>\r | |
26638 | <simpara>The idea is to compute for each occurrence of a <literal>ref</literal> type in the\r | |
26639 | program whether or not that <literal>ref</literal> can be represented as an offset of\r | |
26640 | some object (constructor or tuple). As before, a unification-based\r | |
26641 | whole-program with deep abstract values makes sure the analysis is\r | |
26642 | consistent.</simpara>\r | |
26643 | <simpara>The only syntactic part of the analysis that remains is the part that\r | |
26644 | checks 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 | |
26648 | the object allocation is in the same block. This is pretty\r | |
26649 | draconian, and it would be nice to generalize it some day to allow\r | |
26650 | flattening as long as the <literal>ref</literal> allocation and object allocation "line\r | |
26651 | up one-to-one" in the same loop-free chunk of code.\r | |
26652 | </simpara>\r | |
26653 | </listitem>\r | |
26654 | <listitem>\r | |
26655 | <simpara>\r | |
26656 | updates occur in the same block (and hence it is safe-for-space\r | |
26657 | because the containing object is still alive). It would be nice to\r | |
26658 | relax this to allow updates as long as it can be provedthat the\r | |
26659 | container 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 | |
26665 | being 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 | |
26667 | each point the <literal>ref</literal> is live, then the containing object is live too.\r | |
26668 | I 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 | |
26675 | collection of regions into which objects are allocated. At compile\r | |
26676 | time, either in the source program or through automatic inference,\r | |
26677 | allocation points are annotated with the region in which the\r | |
26678 | allocation will occur. Typically, although not always, the regions\r | |
26679 | are 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 | |
26682 | MLton, but in our opinion it is far from clear that regions would\r | |
26683 | provide MLton with improved performance, while they would certainly\r | |
26684 | add a lot of complexity to the compiler and complicate reasoning about\r | |
26685 | and achieving <link linkend="SpaceSafety">SpaceSafety</link>. Region-based memory management and\r | |
26686 | garbage collection have different strengths and weaknesses; it’s\r | |
26687 | pretty easy to come up with programs that do significantly better\r | |
26688 | under regions than under GC, and vice versa. We believe that it is\r | |
26689 | the case that common SML idioms tend to work better under GC than\r | |
26690 | under regions.</simpara>\r | |
26691 | <simpara>One common argument for regions is that the region operations can all\r | |
26692 | be done in (approximately) constant time; therefore, you eliminate GC\r | |
26693 | pause times, leading to a real-time GC. However, because of space\r | |
26694 | safety concerns (see below), we believe that region-based memory\r | |
26695 | management for SML must also include a traditional garbage collector.\r | |
26696 | Hence, to achieve real-time memory management for MLton/SML, we\r | |
26697 | believe that it would be both easier and more efficient to implement a\r | |
26698 | traditional real-time garbage collector than it would be to implement\r | |
26699 | a 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 | |
26703 | Standard ML. The ML Kit maintains a stack of regions at run time. At\r | |
26704 | compile time, it uses region inference to decide when data can be\r | |
26705 | allocated in a stack-like manner, assigning it to an appropriate\r | |
26706 | region. The ML Kit has put a lot of effort into improving the\r | |
26707 | supporting analyses and representations of regions, which are all\r | |
26708 | necessary to improve the performance.</simpara>\r | |
26709 | <simpara>Unfortunately, under a pure stack-based region system, space leaks are\r | |
26710 | inevitable in theory, and costly in practice. Data for which region\r | |
26711 | inference can not determine the lifetime is moved into the "global\r | |
26712 | region" whose lifetime is the entire program. There are two ways in\r | |
26713 | which region inference will place an object to the global region.</simpara>\r | |
26714 | <itemizedlist>\r | |
26715 | <listitem>\r | |
26716 | <simpara>\r | |
26717 | When the inference is too conservative, that is, when the data is\r | |
26718 | used in a stack-like manner but the region inference can’t figure it\r | |
26719 | out.\r | |
26720 | </simpara>\r | |
26721 | </listitem>\r | |
26722 | <listitem>\r | |
26723 | <simpara>\r | |
26724 | When data is not used in a stack-like manner. In this case,\r | |
26725 | correctness 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 | |
26730 | system you use, there are some programs such that the global region\r | |
26731 | must exist, and its size will grow to an unbounded multiple of the\r | |
26732 | live data size. For these programs one must have a GC to achieve\r | |
26733 | space safety.</simpara>\r | |
26734 | <simpara>To solve this problem, the ML Kit has undergone work to combine\r | |
26735 | garbage 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 | |
26737 | of a garbage collector to the ML Kit’s region-based system. These\r | |
26738 | papers provide convincing evidence for space leaks in the global\r | |
26739 | region. They show a number of benchmarks where the memory usage of\r | |
26740 | the program running with just regions is a large multiple (2, 10, 50,\r | |
26741 | even 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 | |
26743 | regions does better than either a system with just GC or a combined\r | |
26744 | system. Unfortunately, a pure region system isn’t practical because\r | |
26745 | of the lack of space safety. And the other performance numbers are\r | |
26746 | not so convincing, because they compare to an old version of SML/NJ\r | |
26747 | and not at all with MLton. It would be interesting to see a\r | |
26748 | comparison 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’s approach, and provide both\r | |
26753 | region-based memory management and garbage collection, but at the\r | |
26754 | programmer’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 — i.e., provide a\r | |
26756 | <literal>MLton.Regions</literal> structure with explicit region based memory\r | |
26757 | management operations, so that the programmer could use them when\r | |
26758 | appropriate. <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 | |
26767 | to support this option, although there might be a "poor-man’s" version\r | |
26768 | with 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 | |
26780 | New platforms:\r | |
26781 | </simpara>\r | |
26782 | <itemizedlist>\r | |
26783 | <listitem>\r | |
26784 | <simpara>\r | |
26785 | x86: FreeBSD 5.x, OpenBSD\r | |
26786 | </simpara>\r | |
26787 | </listitem>\r | |
26788 | <listitem>\r | |
26789 | <simpara>\r | |
26790 | PowerPC: Darwin (MacOSX)\r | |
26791 | </simpara>\r | |
26792 | </listitem>\r | |
26793 | </itemizedlist>\r | |
26794 | </listitem>\r | |
26795 | <listitem>\r | |
26796 | <simpara>\r | |
26797 | Support 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 | |
26802 | Support for dynamic libraries.\r | |
26803 | </simpara>\r | |
26804 | </listitem>\r | |
26805 | <listitem>\r | |
26806 | <simpara>\r | |
26807 | Support for <link linkend="ConcurrentML">ConcurrentML</link> (CML).\r | |
26808 | </simpara>\r | |
26809 | </listitem>\r | |
26810 | <listitem>\r | |
26811 | <simpara>\r | |
26812 | New structures: <literal>Int2</literal>, <literal>Int3</literal>, …, <literal>Int31</literal> and <literal>Word2</literal>, <literal>Word3</literal>, …, <literal>Word31</literal>.\r | |
26813 | </simpara>\r | |
26814 | </listitem>\r | |
26815 | <listitem>\r | |
26816 | <simpara>\r | |
26817 | Front-end bug fixes and improvements.\r | |
26818 | </simpara>\r | |
26819 | </listitem>\r | |
26820 | <listitem>\r | |
26821 | <simpara>\r | |
26822 | A 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 | |
26827 | A bytecode generator, available via <literal>-codegen bytecode</literal>.\r | |
26828 | </simpara>\r | |
26829 | </listitem>\r | |
26830 | <listitem>\r | |
26831 | <simpara>\r | |
26832 | Representation improvements:\r | |
26833 | </simpara>\r | |
26834 | <itemizedlist>\r | |
26835 | <listitem>\r | |
26836 | <simpara>\r | |
26837 | Tuples and datatypes are packed to decrease space usage.\r | |
26838 | </simpara>\r | |
26839 | </listitem>\r | |
26840 | <listitem>\r | |
26841 | <simpara>\r | |
26842 | Ref cells may be unboxed into their containing object.\r | |
26843 | </simpara>\r | |
26844 | </listitem>\r | |
26845 | <listitem>\r | |
26846 | <simpara>\r | |
26847 | Arrays 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 | |
26876 | The <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 | |
26881 | New platforms: <link linkend="RunningOnMinGW">X86/MinGW</link> and HPPA/Linux.\r | |
26882 | </simpara>\r | |
26883 | </listitem>\r | |
26884 | <listitem>\r | |
26885 | <simpara>\r | |
26886 | Improved and expanded documentation, based on the MLton wiki.\r | |
26887 | </simpara>\r | |
26888 | </listitem>\r | |
26889 | <listitem>\r | |
26890 | <simpara>\r | |
26891 | Compiler.\r | |
26892 | </simpara>\r | |
26893 | <itemizedlist>\r | |
26894 | <listitem>\r | |
26895 | <simpara>\r | |
26896 | improved 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 | |
26906 | Added: <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 | |
26911 | Removed: <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 | |
26920 | Language.\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 | |
26930 | Added: <literal>_symbol</literal>.\r | |
26931 | </simpara>\r | |
26932 | </listitem>\r | |
26933 | <listitem>\r | |
26934 | <simpara>\r | |
26935 | Changed: <literal>_export</literal>, <literal>_import</literal>.\r | |
26936 | </simpara>\r | |
26937 | </listitem>\r | |
26938 | <listitem>\r | |
26939 | <simpara>\r | |
26940 | Removed: <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 | |
26952 | Added: <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 | |
26957 | Deprecated: <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 | |
26966 | Libraries.\r | |
26967 | </simpara>\r | |
26968 | <itemizedlist>\r | |
26969 | <listitem>\r | |
26970 | <simpara>\r | |
26971 | Basis Library.\r | |
26972 | </simpara>\r | |
26973 | <itemizedlist>\r | |
26974 | <listitem>\r | |
26975 | <simpara>\r | |
26976 | Added: <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 | |
26988 | Added: <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 | |
26993 | Changed: <literal>MLton.Platform.Arch</literal>.\r | |
26994 | </simpara>\r | |
26995 | </listitem>\r | |
26996 | </itemizedlist>\r | |
26997 | </listitem>\r | |
26998 | <listitem>\r | |
26999 | <simpara>\r | |
27000 | Other libraries.\r | |
27001 | </simpara>\r | |
27002 | <itemizedlist>\r | |
27003 | <listitem>\r | |
27004 | <simpara>\r | |
27005 | Added: <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 | |
27014 | Tools.\r | |
27015 | </simpara>\r | |
27016 | <itemizedlist>\r | |
27017 | <listitem>\r | |
27018 | <simpara>\r | |
27019 | Updates of <literal>mllex</literal> and <literal>mlyacc</literal> from SML/NJ.\r | |
27020 | </simpara>\r | |
27021 | </listitem>\r | |
27022 | <listitem>\r | |
27023 | <simpara>\r | |
27024 | Added <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 | |
27045 | x86\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 | |
27060 | Linux\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 | |
27104 | PowerPC\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 | |
27116 | Sparc\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 | |
27138 | Debian <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 | |
27143 | RedHat <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&version=all&exact=1&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&stype=all">FreeBSD</ulink>\r | |
27159 | </simpara>\r | |
27160 | </listitem>\r | |
27161 | <listitem>\r | |
27162 | <simpara>\r | |
27163 | Fedora 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 | |
27199 | New 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 | |
27226 | Compiler.\r | |
27227 | </simpara>\r | |
27228 | <itemizedlist>\r | |
27229 | <listitem>\r | |
27230 | <simpara>\r | |
27231 | Support for 64-bit platforms.\r | |
27232 | </simpara>\r | |
27233 | <itemizedlist>\r | |
27234 | <listitem>\r | |
27235 | <simpara>\r | |
27236 | Native 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 | |
27248 | Added: <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 | |
27253 | Changed: <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 | |
27260 | Bytecode codegen.\r | |
27261 | </simpara>\r | |
27262 | <itemizedlist>\r | |
27263 | <listitem>\r | |
27264 | <simpara>\r | |
27265 | Support for exception history.\r | |
27266 | </simpara>\r | |
27267 | </listitem>\r | |
27268 | <listitem>\r | |
27269 | <simpara>\r | |
27270 | Support 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 | |
27279 | Language.\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 | |
27289 | Removed: <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 | |
27298 | Libraries.\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 | |
27308 | Added: <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 | |
27313 | Bug 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 | |
27325 | Added: <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 | |
27330 | Changed: <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 | |
27335 | Deprecated: <literal>MLton.Socket</literal>.\r | |
27336 | </simpara>\r | |
27337 | </listitem>\r | |
27338 | </itemizedlist>\r | |
27339 | </listitem>\r | |
27340 | <listitem>\r | |
27341 | <simpara>\r | |
27342 | Other libraries.\r | |
27343 | </simpara>\r | |
27344 | <itemizedlist>\r | |
27345 | <listitem>\r | |
27346 | <simpara>\r | |
27347 | Added: <link linkend="MLRISCLibrary">MLRISC library</link>.\r | |
27348 | </simpara>\r | |
27349 | </listitem>\r | |
27350 | <listitem>\r | |
27351 | <simpara>\r | |
27352 | Updated: <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 | |
27361 | Tools.\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 | |
27375 | AMD64\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 | |
27387 | HPPA\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 | |
27399 | PowerPC\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 | |
27421 | Sparc\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 | |
27433 | X86\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 | |
27500 | Debian <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&searchon=names&suite=all&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&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&searchon=names&version=all&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 | |
27558 | New 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 | |
27580 | Compiler.\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 | |
27590 | Added: <literal>-mlb-path-var <emphasis><name> <value></emphasis></literal>\r | |
27591 | </simpara>\r | |
27592 | </listitem>\r | |
27593 | <listitem>\r | |
27594 | <simpara>\r | |
27595 | Removed: <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 | |
27602 | Improved constant folding of floating-point operations.\r | |
27603 | </simpara>\r | |
27604 | </listitem>\r | |
27605 | <listitem>\r | |
27606 | <simpara>\r | |
27607 | Experimental: 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 | |
27612 | Extended <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 | |
27617 | Deprecated features (to be removed in a future release)\r | |
27618 | </simpara>\r | |
27619 | <itemizedlist>\r | |
27620 | <listitem>\r | |
27621 | <simpara>\r | |
27622 | Bytecode 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 | |
27627 | Support 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 | |
27634 | Bug 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 | |
27641 | Runtime.\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 | |
27651 | Added: <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 | |
27663 | Bug 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 | |
27670 | Language.\r | |
27671 | </simpara>\r | |
27672 | <itemizedlist>\r | |
27673 | <listitem>\r | |
27674 | <simpara>\r | |
27675 | Allow 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 | |
27682 | Libraries.\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 | |
27692 | Bug 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 | |
27704 | Added: <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 | |
27709 | Changed:\r | |
27710 | </simpara>\r | |
27711 | </listitem>\r | |
27712 | <listitem>\r | |
27713 | <simpara>\r | |
27714 | Deprecated: <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 | |
27726 | Added 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 | |
27733 | Other libraries.\r | |
27734 | </simpara>\r | |
27735 | <itemizedlist>\r | |
27736 | <listitem>\r | |
27737 | <simpara>\r | |
27738 | Updated: <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 | |
27747 | Tools.\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 | |
27757 | Eliminated top-level <literal>type int = Int.int</literal> in output.\r | |
27758 | </simpara>\r | |
27759 | </listitem>\r | |
27760 | <listitem>\r | |
27761 | <simpara>\r | |
27762 | Include <literal>(*#line line:col "file.lex" *)</literal> directives in output.\r | |
27763 | </simpara>\r | |
27764 | </listitem>\r | |
27765 | <listitem>\r | |
27766 | <simpara>\r | |
27767 | Added <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 | |
27779 | Added 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 | |
27784 | Deprecated command-line switch <literal>-linkage static</literal>.\r | |
27785 | </simpara>\r | |
27786 | </listitem>\r | |
27787 | <listitem>\r | |
27788 | <simpara>\r | |
27789 | Added 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 | |
27801 | Eliminated top-level <literal>type int = Int.int</literal> in output.\r | |
27802 | </simpara>\r | |
27803 | </listitem>\r | |
27804 | <listitem>\r | |
27805 | <simpara>\r | |
27806 | Include <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 | |
27816 | and <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 | |
27823 | AMD64 (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 | |
27848 | Windows 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 | |
27855 | X86\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 | |
27885 | Windows 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&searchon=names&suite=all&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&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&section=all&arch=any&searchon=names&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 | |
27953 | Compiler.\r | |
27954 | </simpara>\r | |
27955 | <itemizedlist>\r | |
27956 | <listitem>\r | |
27957 | <simpara>\r | |
27958 | Cosmetic improvements to type-error messages.\r | |
27959 | </simpara>\r | |
27960 | </listitem>\r | |
27961 | <listitem>\r | |
27962 | <simpara>\r | |
27963 | Removed features:\r | |
27964 | </simpara>\r | |
27965 | <itemizedlist>\r | |
27966 | <listitem>\r | |
27967 | <simpara>\r | |
27968 | Bytecode 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 | |
27973 | Support 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 | |
27980 | Bug 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 | |
27987 | Runtime.\r | |
27988 | </simpara>\r | |
27989 | <itemizedlist>\r | |
27990 | <listitem>\r | |
27991 | <simpara>\r | |
27992 | Bug 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 | |
27999 | Language.\r | |
28000 | </simpara>\r | |
28001 | <itemizedlist>\r | |
28002 | <listitem>\r | |
28003 | <simpara>\r | |
28004 | Interpret <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 | |
28014 | Added: <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 | |
28023 | Libraries.\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 | |
28033 | Improved performance of <literal>String.concatWith</literal>.\r | |
28034 | </simpara>\r | |
28035 | </listitem>\r | |
28036 | <listitem>\r | |
28037 | <simpara>\r | |
28038 | Use 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 | |
28043 | Support additional variables with <literal>Posix.ProcEnv.sysconf</literal>.\r | |
28044 | </simpara>\r | |
28045 | </listitem>\r | |
28046 | <listitem>\r | |
28047 | <simpara>\r | |
28048 | Bug 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 | |
28060 | Removed: <literal>MLton.Socket</literal>\r | |
28061 | </simpara>\r | |
28062 | </listitem>\r | |
28063 | </itemizedlist>\r | |
28064 | </listitem>\r | |
28065 | <listitem>\r | |
28066 | <simpara>\r | |
28067 | Other libraries.\r | |
28068 | </simpara>\r | |
28069 | <itemizedlist>\r | |
28070 | <listitem>\r | |
28071 | <simpara>\r | |
28072 | Updated: <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 | |
28077 | Added: <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 | |
28086 | Tools.\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 | |
28096 | Generate <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 | |
28108 | Generate <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 | |
28113 | Fixed 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 | |
28131 | AMD64 (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 | |
28154 | X86\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&searchon=names&suite=all&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&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&section=all&arch=any&searchon=names&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 | |
28228 | Compiler.\r | |
28229 | </simpara>\r | |
28230 | <itemizedlist>\r | |
28231 | <listitem>\r | |
28232 | <simpara>\r | |
28233 | Added an experimental LLVM codegen (<literal>-codegen llvm</literal>); requires LLVM tools\r | |
28234 | (<literal>llvm-as</literal>, <literal>opt</literal>, <literal>llc</literal>) version ≥ 3.7.\r | |
28235 | </simpara>\r | |
28236 | </listitem>\r | |
28237 | <listitem>\r | |
28238 | <simpara>\r | |
28239 | Made 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 | |
28249 | Fixed 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 | |
28255 | Made 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 | |
28262 | Updated <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 | |
28269 | Forced 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 | |
28276 | Runtime.\r | |
28277 | </simpara>\r | |
28278 | <itemizedlist>\r | |
28279 | <listitem>\r | |
28280 | <simpara>\r | |
28281 | Added <literal>gc-summary-file file</literal> runtime option.\r | |
28282 | </simpara>\r | |
28283 | </listitem>\r | |
28284 | <listitem>\r | |
28285 | <simpara>\r | |
28286 | Reorganized 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 | |
28292 | Changed 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 | |
28301 | Language.\r | |
28302 | </simpara>\r | |
28303 | <itemizedlist>\r | |
28304 | <listitem>\r | |
28305 | <simpara>\r | |
28306 | Added 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 | |
28312 | Added <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 | |
28318 | FFI:\r | |
28319 | </simpara>\r | |
28320 | <itemizedlist>\r | |
28321 | <listitem>\r | |
28322 | <simpara>\r | |
28323 | Added <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 | |
28335 | ML Basis annotations.\r | |
28336 | </simpara>\r | |
28337 | <itemizedlist>\r | |
28338 | <listitem>\r | |
28339 | <simpara>\r | |
28340 | Added <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 | |
28347 | Split <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 | |
28357 | Added <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 | |
28368 | Libraries.\r | |
28369 | </simpara>\r | |
28370 | <itemizedlist>\r | |
28371 | <listitem>\r | |
28372 | <simpara>\r | |
28373 | Basis Library.\r | |
28374 | </simpara>\r | |
28375 | <itemizedlist>\r | |
28376 | <listitem>\r | |
28377 | <simpara>\r | |
28378 | Improved 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 | |
28392 | Added 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 | |
28400 | Other libraries.\r | |
28401 | </simpara>\r | |
28402 | <itemizedlist>\r | |
28403 | <listitem>\r | |
28404 | <simpara>\r | |
28405 | Updated: 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 | |
28414 | Tools.\r | |
28415 | </simpara>\r | |
28416 | <itemizedlist>\r | |
28417 | <listitem>\r | |
28418 | <simpara>\r | |
28419 | mlnlffigen\r | |
28420 | </simpara>\r | |
28421 | <itemizedlist>\r | |
28422 | <listitem>\r | |
28423 | <simpara>\r | |
28424 | Updated 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 | |
28443 | AMD64 (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 | |
28505 | Update <literal>./CHANGELOG.adoc</literal>.\r | |
28506 | </simpara>\r | |
28507 | <itemizedlist>\r | |
28508 | <listitem>\r | |
28509 | <simpara>\r | |
28510 | Write entries for missing notable commits.\r | |
28511 | </simpara>\r | |
28512 | </listitem>\r | |
28513 | <listitem>\r | |
28514 | <simpara>\r | |
28515 | Write summary of changes from previous release.\r | |
28516 | </simpara>\r | |
28517 | </listitem>\r | |
28518 | <listitem>\r | |
28519 | <simpara>\r | |
28520 | Update with estimated release date.\r | |
28521 | </simpara>\r | |
28522 | </listitem>\r | |
28523 | </itemizedlist>\r | |
28524 | </listitem>\r | |
28525 | <listitem>\r | |
28526 | <simpara>\r | |
28527 | Update <literal>./README.adoc</literal>.\r | |
28528 | </simpara>\r | |
28529 | <itemizedlist>\r | |
28530 | <listitem>\r | |
28531 | <simpara>\r | |
28532 | Check features and description.\r | |
28533 | </simpara>\r | |
28534 | </listitem>\r | |
28535 | </itemizedlist>\r | |
28536 | </listitem>\r | |
28537 | <listitem>\r | |
28538 | <simpara>\r | |
28539 | Update <literal>man/{mlton,mlprof}.1</literal>.\r | |
28540 | </simpara>\r | |
28541 | <itemizedlist>\r | |
28542 | <listitem>\r | |
28543 | <simpara>\r | |
28544 | Check 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 | |
28549 | Check options in <literal>man/mlprof.1</literal>.\r | |
28550 | </simpara>\r | |
28551 | </listitem>\r | |
28552 | <listitem>\r | |
28553 | <simpara>\r | |
28554 | Update with estimated release date.\r | |
28555 | </simpara>\r | |
28556 | </listitem>\r | |
28557 | </itemizedlist>\r | |
28558 | </listitem>\r | |
28559 | <listitem>\r | |
28560 | <simpara>\r | |
28561 | Update <literal>doc/guide</literal>.\r | |
28562 | </simpara>\r | |
28563 | <itemizedlist>\r | |
28564 | <listitem>\r | |
28565 | <simpara>\r | |
28566 | Synchronize <link linkend="Features">Features</link> page with <literal>./README.adoc</literal>.\r | |
28567 | </simpara>\r | |
28568 | </listitem>\r | |
28569 | <listitem>\r | |
28570 | <simpara>\r | |
28571 | Update <link linkend="Credits">Credits</link> page with acknowledgements.\r | |
28572 | </simpara>\r | |
28573 | </listitem>\r | |
28574 | <listitem>\r | |
28575 | <simpara>\r | |
28576 | Create <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 | |
28581 | Update summary from <literal>./CHANGELOG.adoc</literal>.\r | |
28582 | </simpara>\r | |
28583 | </listitem>\r | |
28584 | <listitem>\r | |
28585 | <simpara>\r | |
28586 | Update links to estimated release date.\r | |
28587 | </simpara>\r | |
28588 | </listitem>\r | |
28589 | </itemizedlist>\r | |
28590 | </listitem>\r | |
28591 | <listitem>\r | |
28592 | <simpara>\r | |
28593 | Create <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 | |
28598 | Update links to estimated release date.\r | |
28599 | </simpara>\r | |
28600 | </listitem>\r | |
28601 | </itemizedlist>\r | |
28602 | </listitem>\r | |
28603 | <listitem>\r | |
28604 | <simpara>\r | |
28605 | Spell check pages.\r | |
28606 | </simpara>\r | |
28607 | </listitem>\r | |
28608 | </itemizedlist>\r | |
28609 | </listitem>\r | |
28610 | <listitem>\r | |
28611 | <simpara>\r | |
28612 | Ensure 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 | |
28622 | Update <literal>./CHANGELOG.adoc</literal>.\r | |
28623 | </simpara>\r | |
28624 | <itemizedlist>\r | |
28625 | <listitem>\r | |
28626 | <simpara>\r | |
28627 | Update with proper release date.\r | |
28628 | </simpara>\r | |
28629 | </listitem>\r | |
28630 | </itemizedlist>\r | |
28631 | </listitem>\r | |
28632 | <listitem>\r | |
28633 | <simpara>\r | |
28634 | Update <literal>man/{mlton,mlprof}.1</literal>.\r | |
28635 | </simpara>\r | |
28636 | <itemizedlist>\r | |
28637 | <listitem>\r | |
28638 | <simpara>\r | |
28639 | Update with proper release date.\r | |
28640 | </simpara>\r | |
28641 | </listitem>\r | |
28642 | </itemizedlist>\r | |
28643 | </listitem>\r | |
28644 | <listitem>\r | |
28645 | <simpara>\r | |
28646 | Update <literal>doc/guide</literal>.\r | |
28647 | </simpara>\r | |
28648 | <itemizedlist>\r | |
28649 | <listitem>\r | |
28650 | <simpara>\r | |
28651 | Rename <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 | |
28656 | Update links with proper release date.\r | |
28657 | </simpara>\r | |
28658 | </listitem>\r | |
28659 | </itemizedlist>\r | |
28660 | </listitem>\r | |
28661 | <listitem>\r | |
28662 | <simpara>\r | |
28663 | Rename <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 | |
28668 | Update links with proper release date.\r | |
28669 | </simpara>\r | |
28670 | </listitem>\r | |
28671 | </itemizedlist>\r | |
28672 | </listitem>\r | |
28673 | <listitem>\r | |
28674 | <simpara>\r | |
28675 | Update <emphasis role="strong">ReleaseXXXXLLCC</emphasis>.\r | |
28676 | </simpara>\r | |
28677 | <itemizedlist>\r | |
28678 | <listitem>\r | |
28679 | <simpara>\r | |
28680 | Change 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 | |
28687 | Update <link linkend="Home">Home</link> with note of new release.\r | |
28688 | </simpara>\r | |
28689 | <itemizedlist>\r | |
28690 | <listitem>\r | |
28691 | <simpara>\r | |
28692 | Change <literal>What's new?</literal> text to <literal>Please try out our new release, <:ReleaseYYYYMMDD:MLton YYYYMMDD></literal>.\r | |
28693 | </simpara>\r | |
28694 | </listitem>\r | |
28695 | <listitem>\r | |
28696 | <simpara>\r | |
28697 | Update <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 | |
28704 | Update <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 | |
28711 | Ensure 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 | |
28721 | Shell commands:\r | |
28722 | </simpara>\r | |
28723 | <screen>git clone http://github.com/MLton/mlton mlton.git\r | |
28724 | cd mlton.git\r | |
28725 | git checkout master\r | |
28726 | git tag -a -m "Tagging YYYYMMDD release" on-YYYYMMDD-release master\r | |
28727 | git 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 | |
28738 | Create <emphasis role="strong">YYYYMMDD</emphasis> directory:\r | |
28739 | </simpara>\r | |
28740 | <screen>sftp user@frs.sourceforge.net:/home/frs/project/mlton/mlton\r | |
28741 | sftp> mkdir YYYYMMDD\r | |
28742 | sftp> 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 | |
28751 | Create <literal>mlton-YYYYMMDD.src.tgz</literal>:\r | |
28752 | </simpara>\r | |
28753 | <screen>git clone http://github.com/MLton/mlton mlton\r | |
28754 | cd mlton\r | |
28755 | git checkout on-YYYYMMDD-release\r | |
28756 | make MLTON_VERSION=YYYYMMDD source-release\r | |
28757 | cd ..</screen>\r | |
28758 | <simpara>or</simpara>\r | |
28759 | <screen>wget https://github.com/MLton/mlton/archive/on-YYYYMMDD-release.tar.gz\r | |
28760 | tar xzvf on-YYYYMMDD-release.tar.gz\r | |
28761 | cd mlton-on-YYYYMMDD-release\r | |
28762 | make MLTON_VERSION=YYYYMMDD source-release\r | |
28763 | cd ..</screen>\r | |
28764 | </listitem>\r | |
28765 | <listitem>\r | |
28766 | <simpara>\r | |
28767 | Upload <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 | |
28773 | Update <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 | |
28783 | Build 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 | |
28786 | tar xzvf mlton-YYYYMMDD.src.tgz\r | |
28787 | cd mlton-YYYYMMDD\r | |
28788 | make binary-release\r | |
28789 | cd ..</screen>\r | |
28790 | </listitem>\r | |
28791 | <listitem>\r | |
28792 | <simpara>\r | |
28793 | Upload <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 | |
28799 | Update <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 | |
28815 | Shell commands:\r | |
28816 | </simpara>\r | |
28817 | <screen>wget http://sourceforge.net/projects/mlton/files/mlton/YYYYMMDD/mlton-YYYYMMDD.src.tgz\r | |
28818 | tar xzvf mlton-YYYYMMDD.src.tgz\r | |
28819 | cd mlton-YYYYMMDD\r | |
28820 | cd doc/guide\r | |
28821 | cp -prf localhost YYYYMMDD\r | |
28822 | tar czvf guide-YYYYMMDD.tgz YYYYMMDD\r | |
28823 | rsync -avzP --delete -e ssh YYYYMMDD user@web.sourceforge.net:/home/project-web/mlton/htdocs/guide/\r | |
28824 | rsync -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 | |
28833 | Mail 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 | |
28855 | Generate 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 | |
28898 | Release20040227\r | |
28899 | </simpara>\r | |
28900 | </listitem>\r | |
28901 | <listitem>\r | |
28902 | <simpara>\r | |
28903 | Release20030716\r | |
28904 | </simpara>\r | |
28905 | </listitem>\r | |
28906 | <listitem>\r | |
28907 | <simpara>\r | |
28908 | Release20030711\r | |
28909 | </simpara>\r | |
28910 | </listitem>\r | |
28911 | <listitem>\r | |
28912 | <simpara>\r | |
28913 | Release20030312\r | |
28914 | </simpara>\r | |
28915 | </listitem>\r | |
28916 | <listitem>\r | |
28917 | <simpara>\r | |
28918 | Release20020923\r | |
28919 | </simpara>\r | |
28920 | </listitem>\r | |
28921 | <listitem>\r | |
28922 | <simpara>\r | |
28923 | Release20020410\r | |
28924 | </simpara>\r | |
28925 | </listitem>\r | |
28926 | <listitem>\r | |
28927 | <simpara>\r | |
28928 | Release20011006\r | |
28929 | </simpara>\r | |
28930 | </listitem>\r | |
28931 | <listitem>\r | |
28932 | <simpara>\r | |
28933 | Release20010806\r | |
28934 | </simpara>\r | |
28935 | </listitem>\r | |
28936 | <listitem>\r | |
28937 | <simpara>\r | |
28938 | Release20010706\r | |
28939 | </simpara>\r | |
28940 | </listitem>\r | |
28941 | <listitem>\r | |
28942 | <simpara>\r | |
28943 | Release20000906\r | |
28944 | </simpara>\r | |
28945 | </listitem>\r | |
28946 | <listitem>\r | |
28947 | <simpara>\r | |
28948 | Release20000712\r | |
28949 | </simpara>\r | |
28950 | </listitem>\r | |
28951 | <listitem>\r | |
28952 | <simpara>\r | |
28953 | Release19990712\r | |
28954 | </simpara>\r | |
28955 | </listitem>\r | |
28956 | <listitem>\r | |
28957 | <simpara>\r | |
28958 | Release19990319\r | |
28959 | </simpara>\r | |
28960 | </listitem>\r | |
28961 | <listitem>\r | |
28962 | <simpara>\r | |
28963 | Release19980826\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 | |
28980 | datatypes\r | |
28981 | </simpara>\r | |
28982 | </listitem>\r | |
28983 | <listitem>\r | |
28984 | <simpara>\r | |
28985 | datatype constructors\r | |
28986 | </simpara>\r | |
28987 | </listitem>\r | |
28988 | <listitem>\r | |
28989 | <simpara>\r | |
28990 | datatype constructor arguments\r | |
28991 | </simpara>\r | |
28992 | </listitem>\r | |
28993 | <listitem>\r | |
28994 | <simpara>\r | |
28995 | functions\r | |
28996 | </simpara>\r | |
28997 | </listitem>\r | |
28998 | <listitem>\r | |
28999 | <simpara>\r | |
29000 | function arguments\r | |
29001 | </simpara>\r | |
29002 | </listitem>\r | |
29003 | <listitem>\r | |
29004 | <simpara>\r | |
29005 | function returns\r | |
29006 | </simpara>\r | |
29007 | </listitem>\r | |
29008 | <listitem>\r | |
29009 | <simpara>\r | |
29010 | blocks\r | |
29011 | </simpara>\r | |
29012 | </listitem>\r | |
29013 | <listitem>\r | |
29014 | <simpara>\r | |
29015 | block arguments\r | |
29016 | </simpara>\r | |
29017 | </listitem>\r | |
29018 | <listitem>\r | |
29019 | <simpara>\r | |
29020 | statements (variable bindings)\r | |
29021 | </simpara>\r | |
29022 | </listitem>\r | |
29023 | <listitem>\r | |
29024 | <simpara>\r | |
29025 | handlers from non-tail calls (mayRaise analysis)\r | |
29026 | </simpara>\r | |
29027 | </listitem>\r | |
29028 | <listitem>\r | |
29029 | <simpara>\r | |
29030 | continuations 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 | |
29067 | passes 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 | |
29099 | variables, which is used to predicate the insertion of phi arguments.\r | |
29100 | This is due to the algorithm’s bias towards imperative languages, for\r | |
29101 | which it makes the assumption that all variables are defined in the\r | |
29102 | start block and all variables are "used" at exit.</simpara>\r | |
29103 | <simpara>This is "optimized" for restoration of functions with small numbers of\r | |
29104 | violating variables — use bool vectors to represent sets of violating\r | |
29105 | variables.</simpara>\r | |
29106 | <simpara>Also, we use a <literal>Promise.t</literal> to suspend part of the dominance frontier\r | |
29107 | computation.</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 | |
29114 | as C, Java, and Python, often ask how one can translate functions that\r | |
29115 | return early into SML. This page briefly describes a number of ways\r | |
29116 | to 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 | |
29122 | or\r | |
29123 | <ulink url="http://www.standardml.org/Basis/list.html#SIG:LIST.all:VAL"><literal>List.all</literal></ulink>\r | |
29124 | is probably what you want in most cases. Unfortunately, it might be\r | |
29125 | the case that the particular conditional iteration pattern that you\r | |
29126 | want isn’t provided for your data structure. Usually the best\r | |
29127 | alternative in such a case is to implement the desired iteration\r | |
29128 | pattern 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 | |
29131 | one 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 | |
29140 | in\r | |
29141 | loop 0\r | |
29142 | end</programlisting>\r | |
29143 | <simpara>Of course, this technique, while probably the most common case in\r | |
29144 | practice, applies only if you are essentially iterating over some data\r | |
29145 | structure.</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 | |
29150 | statements is to basically implement <literal>return</literal> using exception\r | |
29151 | handling. The mechanism can be packaged into a reusable module with\r | |
29152 | the 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 | |
29163 | signature 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 | *> Exit.within\r | |
29174 | *> (fn l =>\r | |
29175 | *> if condition then\r | |
29176 | *> Exit.to l 1\r | |
29177 | *> else\r | |
29178 | *> 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 -> 'a -> '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 -> '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 | |
29203 | end</programlisting>\r | |
29204 | <simpara>(<link linkend="References_HarperEtAl93">Typing First-Class Continuations in ML</link>\r | |
29205 | discusses 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 | |
29207 | is straightforward:</simpara>\r | |
29208 | <programlisting language="sml" linenumbering="unnumbered">structure Exit :> EXIT = struct\r | |
29209 | type 'a t = 'a -> 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 => 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 | |
29221 | end</programlisting>\r | |
29222 | <simpara>Here is an example of how one could implement a <literal>find</literal> function given\r | |
29223 | an <literal>app</literal> function:</simpara>\r | |
29224 | <programlisting language="sml" linenumbering="unnumbered">fun appToFind (app : ('a -> unit) -> 'b -> unit)\r | |
29225 | (predicate : 'a -> bool)\r | |
29226 | (data : 'b) =\r | |
29227 | Exit.call\r | |
29228 | (fn return =>\r | |
29229 | (app (fn x =>\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 | |
29243 | instead of returning normally, functions invoke a function passed as\r | |
29244 | an argument. In general, multiple continuation functions may be\r | |
29245 | passed as arguments and the ordinary return continuation may also be\r | |
29246 | used. As an example, here is a function that finds the leftmost\r | |
29247 | element 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 | |
29250 | fun find predicate = let\r | |
29251 | fun recurse continue =\r | |
29252 | fn LEAF =>\r | |
29253 | continue ()\r | |
29254 | | BRANCH (lhs, elem, rhs) =>\r | |
29255 | recurse\r | |
29256 | (fn () =>\r | |
29257 | if predicate elem then\r | |
29258 | SOME elem\r | |
29259 | else\r | |
29260 | recurse continue rhs)\r | |
29261 | lhs\r | |
29262 | in\r | |
29263 | recurse (fn () => NONE)\r | |
29264 | end</programlisting>\r | |
29265 | <simpara>Note that the above function returns as soon as the leftmost element\r | |
29266 | satisfying 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 | |
29278 | decisions 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 | |
29298 | layout and associated packing of data representations. There are\r | |
29299 | singleton types that denote constants, other atomic types for things\r | |
29300 | like integers and reals, and arbitrary sum types and sequence (tuple)\r | |
29301 | types. The big change to the type system is that type checking is now\r | |
29302 | based on subtyping, not type equality. So, for example, the singleton\r | |
29303 | type <literal>0xFFFFEEBB</literal> whose only inhabitant is the eponymous constant is a\r | |
29304 | subtype 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 | |
29323 | constant folding, copy propagation\r | |
29324 | </simpara>\r | |
29325 | </listitem>\r | |
29326 | <listitem>\r | |
29327 | <simpara>\r | |
29328 | inline 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 | |
29352 | collected 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 <pass></literal> — keep diagnostic info for pass\r | |
29391 | </simpara>\r | |
29392 | </listitem>\r | |
29393 | <listitem>\r | |
29394 | <simpara>\r | |
29395 | <literal>-drop-pass <pass></literal> — omit optimization pass\r | |
29396 | </simpara>\r | |
29397 | </listitem>\r | |
29398 | <listitem>\r | |
29399 | <simpara>\r | |
29400 | <literal>-keep-pass <pass></literal> — 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 | |
29434 | When compiling for Alpha, MLton doesn’t support native code\r | |
29435 | generation (<literal>-codegen native</literal>). Hence, performance is not as good as\r | |
29436 | it might be and compile times are longer. Also, the quality of code\r | |
29437 | generated by <literal>gcc</literal> is important. By default, MLton calls <literal>gcc -O1</literal>.\r | |
29438 | You 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 | |
29443 | When 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 | |
29458 | When compiling for AMD64, MLton targets the 64-bit ABI.\r | |
29459 | </simpara>\r | |
29460 | </listitem>\r | |
29461 | <listitem>\r | |
29462 | <simpara>\r | |
29463 | On 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 | |
29468 | When 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 | |
29470 | library, 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 | |
29472 | details.)\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 | |
29487 | When compiling for ARM, MLton doesn’t support native code generation\r | |
29488 | (<literal>-codegen native</literal>). Hence, performance is not as good as it might be\r | |
29489 | and 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 | |
29491 | change 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 | |
29501 | which provides a Posix-like environment while running on Windows. To\r | |
29502 | run MLton with Cygwin, you must first install Cygwin on your Windows\r | |
29503 | machine. To do this, visit the Cygwin site from your Windows machine\r | |
29504 | and run their <literal>setup.exe</literal> script. Then, you can unpack the MLton\r | |
29505 | binary <literal>tgz</literal> in your Cygwin environment.</simpara>\r | |
29506 | <simpara>To run MLton cross-compiled executables on Windows, you must install\r | |
29507 | the 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 | |
29513 | Time profiling is disabled.\r | |
29514 | </simpara>\r | |
29515 | </listitem>\r | |
29516 | <listitem>\r | |
29517 | <simpara>\r | |
29518 | Cygwin’s <literal>mmap</literal> emulation is less than perfect. Sometimes it\r | |
29519 | interacts badly with <literal>Posix.Process.fork</literal>.\r | |
29520 | </simpara>\r | |
29521 | </listitem>\r | |
29522 | <listitem>\r | |
29523 | <simpara>\r | |
29524 | The <ulink url="https://raw.github.com/MLton/mlton/master/regression/socket.sml"><literal>socket.sml</literal></ulink> regression\r | |
29525 | test fails. We suspect this is not a bug and is simply due to our\r | |
29526 | test relying on a certain behavior when connecting to a socket that\r | |
29527 | has not yet accepted, which is handled differently on Cygwin than\r | |
29528 | other platforms. Any help in understanding and resolving this issue\r | |
29529 | is 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 | |
29554 | MLton 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 | |
29561 | For Intel-based Macs, MLton targets the <link linkend="RunningOnAMD64">AMD64 architecture</link> on Darwin 10 (Mac OS X Snow Leopard) and higher and\r | |
29562 | targets the <link linkend="RunningOnX86">x86 architecture</link> on Darwin 8 (Mac OS X\r | |
29563 | Tiger) 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 | |
29573 | Executables that save and load worlds on Darwin 11 (Mac OS X Lion)\r | |
29574 | and 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 | |
29581 | machines. The <literal>SIGPROF</literal> signal, used to sample the profiled program,\r | |
29582 | is supposed to be delivered 100 times a second (i.e., at 10000us\r | |
29583 | intervals), but there can be delays of over 1 minute between the\r | |
29584 | delivery of consecutive <literal>SIGPROF</literal> signals. A more complete\r | |
29585 | description may be found\r | |
29586 | <ulink url="http://lists.apple.com/archives/Unix-porting/2007/Aug/msg00000.html">here</ulink>\r | |
29587 | and\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 | |
29623 | MLton 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&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 | |
29634 | Executables often run more slowly than on a comparable Linux\r | |
29635 | machine. We conjecture that part of this is due to costs due to heap\r | |
29636 | resizing and kernel zeroing of pages. Any help in solving the problem\r | |
29637 | would be appreciated.\r | |
29638 | </simpara>\r | |
29639 | </listitem>\r | |
29640 | <listitem>\r | |
29641 | <simpara>\r | |
29642 | FreeBSD defaults to a datasize limit of 512M, even if you have more\r | |
29643 | than that amount of memory in the computer. Hence, your MLton process\r | |
29644 | will be limited in the amount of memory it has. To fix this problem,\r | |
29645 | turn up the datasize and the default datasize available to a process:\r | |
29646 | Edit <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 | |
29652 | and 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 | |
29666 | When compiling for HPPA, MLton targets the 32-bit HPPA architecture.\r | |
29667 | </simpara>\r | |
29668 | </listitem>\r | |
29669 | <listitem>\r | |
29670 | <simpara>\r | |
29671 | When compiling for HPPA, MLton doesn’t support native code\r | |
29672 | generation (<literal>-codegen native</literal>). Hence, performance is not as good as\r | |
29673 | it might be and compile times are longer. Also, the quality of code\r | |
29674 | generated by <literal>gcc</literal> is important. By default, MLton calls <literal>gcc -O1</literal>.\r | |
29675 | You 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 | |
29680 | When compiling for HPPA, MLton uses <literal>-align 8</literal> by default. While\r | |
29681 | this speeds up reals, it also may increase object sizes. If your\r | |
29682 | program does not make significant use of reals, you might see a\r | |
29683 | speedup 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 | |
29713 | When compiling for IA64, MLton targets the 64-bit ABI.\r | |
29714 | </simpara>\r | |
29715 | </listitem>\r | |
29716 | <listitem>\r | |
29717 | <simpara>\r | |
29718 | When compiling for IA64, MLton doesn’t support native code\r | |
29719 | generation (<literal>-codegen native</literal>). Hence, performance is not as good as\r | |
29720 | it might be and compile times are longer. Also, the quality of code\r | |
29721 | generated by <literal>gcc</literal> is important. By default, MLton calls <literal>gcc -O1</literal>.\r | |
29722 | You 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 | |
29727 | When compiling for IA64, MLton uses <literal>-align 8</literal> by default.\r | |
29728 | </simpara>\r | |
29729 | </listitem>\r | |
29730 | <listitem>\r | |
29731 | <simpara>\r | |
29732 | On 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 | |
29748 | applications to Windows. Some library functionality is missing or\r | |
29749 | changed.</simpara>\r | |
29750 | <section id="_notes_11">\r | |
29751 | <title>Notes</title>\r | |
29752 | <itemizedlist>\r | |
29753 | <listitem>\r | |
29754 | <simpara>\r | |
29755 | To compile MLton on MinGW:\r | |
29756 | </simpara>\r | |
29757 | <itemizedlist>\r | |
29758 | <listitem>\r | |
29759 | <simpara>\r | |
29760 | The <link linkend="GnuMP">GnuMP</link> library is required.\r | |
29761 | </simpara>\r | |
29762 | </listitem>\r | |
29763 | <listitem>\r | |
29764 | <simpara>\r | |
29765 | The Bash shell is required. If you are using a prebuilt MSYS, you\r | |
29766 | probably 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 | |
29778 | Many 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 | |
30113 | pkgsrc. This is a tree of Makefiles which when invoked downloads the\r | |
30114 | source code, builds a package and installs it on the system. In order\r | |
30115 | to run MLton on NetBSD, you will have to install several packages for\r | |
30116 | it 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 | |
30135 | will 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 | |
30144 | package</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 | |
30156 | 640Mb of RAM ought to be enough to self-compile MLton one might want\r | |
30157 | to do some tuning to the NetBSD VM subsystem in order to succeed. The\r | |
30158 | notes presented here is what <link linkend="JesperLouisAndersen">JesperLouisAndersen</link> uses for\r | |
30159 | compiling 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 | |
30165 | can 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 | |
30170 | need to tune up the default of 80 for anonymous pages. Setting</simpara>\r | |
30171 | <screen>sysctl -w vm.anonmax=95\r | |
30172 | sysctl -w vm.anonmin=50\r | |
30173 | sysctl -w vm.filemin=2\r | |
30174 | sysctl -w vm.execmin=2\r | |
30175 | sysctl -w vm.filemax=4\r | |
30176 | sysctl -w vm.execmax=4</screen>\r | |
30177 | <simpara>makes it less likely for the VM system to swap out anonymous pages.\r | |
30178 | For 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 | |
30180 | a 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 | |
30193 | The <ulink url="https://raw.github.com/MLton/mlton/master/regression/socket.sml"><literal>socket.sml</literal></ulink> regression\r | |
30194 | test fails. We suspect this is not a bug and is simply due to our\r | |
30195 | test relying on a certain behavior when connecting to a socket that\r | |
30196 | has not yet accepted, which is handled differently on OpenBSD than\r | |
30197 | other platforms. Any help in understanding and resolving this issue\r | |
30198 | is 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 | |
30213 | When compiling for PowerPC, MLton targets the 32-bit PowerPC\r | |
30214 | architecture.\r | |
30215 | </simpara>\r | |
30216 | </listitem>\r | |
30217 | <listitem>\r | |
30218 | <simpara>\r | |
30219 | When compiling for PowerPC, MLton doesn’t support native code\r | |
30220 | generation (<literal>-codegen native</literal>). Hence, performance is not as good as\r | |
30221 | it might be and compile times are longer. Also, the quality of code\r | |
30222 | generated by <literal>gcc</literal> is important. By default, MLton calls <literal>gcc -O1</literal>.\r | |
30223 | You 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 | |
30228 | On the PowerPC, the <link linkend="GnuMP">GnuMP</link> library supports multiple ABIs. See\r | |
30229 | the <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 | |
30244 | When compiling for PowerPC64, MLton targets the 64-bit PowerPC\r | |
30245 | architecture.\r | |
30246 | </simpara>\r | |
30247 | </listitem>\r | |
30248 | <listitem>\r | |
30249 | <simpara>\r | |
30250 | When compiling for PowerPC64, MLton doesn’t support native code\r | |
30251 | generation (<literal>-codegen native</literal>). Hence, performance is not as good as\r | |
30252 | it might be and compile times are longer. Also, the quality of code\r | |
30253 | generated by <literal>gcc</literal> is important. By default, MLton calls <literal>gcc -O1</literal>.\r | |
30254 | You 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 | |
30259 | On the PowerPC64, the <link linkend="GnuMP">GnuMP</link> library supports multiple ABIs. See\r | |
30260 | the <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 | |
30275 | When compiling for S390, MLton doesn’t support native code\r | |
30276 | generation (<literal>-codegen native</literal>). Hence, performance is not as good as\r | |
30277 | it might be and compile times are longer. Also, the quality of code\r | |
30278 | generated by <literal>gcc</literal> is important. By default, MLton calls <literal>gcc -O1</literal>.\r | |
30279 | You 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 | |
30294 | You must install the <literal>binutils</literal>, <literal>gcc</literal>, and <literal>make</literal> packages. You\r | |
30295 | can 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 | |
30301 | Making 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 | |
30312 | Bootstrapping on the <link linkend="RunningOnSparc">Sparc architecture</link> is so slow\r | |
30313 | as to be impractical (many hours on a 500MHz UltraSparc). For this\r | |
30314 | reason, 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 | |
30350 | When compiling for Sparc, MLton targets the 32-bit Sparc\r | |
30351 | architecture (i.e., Sparc V8).\r | |
30352 | </simpara>\r | |
30353 | </listitem>\r | |
30354 | <listitem>\r | |
30355 | <simpara>\r | |
30356 | When compiling for Sparc, MLton doesn’t support native code\r | |
30357 | generation (<literal>-codegen native</literal>). Hence, performance is not as good as\r | |
30358 | it might be and compile times are longer. Also, the quality of code\r | |
30359 | generated by <literal>gcc</literal> is important. By default, MLton calls <literal>gcc -O1</literal>.\r | |
30360 | You can change this by calling MLton with <literal>-cc-opt -O2</literal>. We have seen\r | |
30361 | this speed up some programs by as much as 30%, especially those\r | |
30362 | involving floating point; however, it can also more than double\r | |
30363 | compile times.\r | |
30364 | </simpara>\r | |
30365 | </listitem>\r | |
30366 | <listitem>\r | |
30367 | <simpara>\r | |
30368 | When compiling for Sparc, MLton uses <literal>-align 8</literal> by default. While\r | |
30369 | this speeds up reals, it also may increase object sizes. If your\r | |
30370 | program does not make significant use of reals, you might see a\r | |
30371 | speedup 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 | |
30381 | Bootstrapping on the <link linkend="RunningOnSparc">Sparc architecture</link> is so slow\r | |
30382 | as to be impractical (many hours on a 500MHz UltraSparc). For this\r | |
30383 | reason, 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 | |
30409 | On 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 | |
30420 | the runtime system. These arguments are optional, and occur before\r | |
30421 | the executable’s usual arguments. To use these options, the first\r | |
30422 | argument to the executable must be <literal>@MLton</literal>. The optional arguments\r | |
30423 | then follow, must be terminated by <literal>--</literal>, and are followed by any\r | |
30424 | arguments to the program. The optional arguments are <emphasis>not</emphasis> made\r | |
30425 | available to the SML program via <literal>CommandLine.arguments</literal>. For\r | |
30426 | example, 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 | |
30442 | trailing letter indicates its units.</simpara>\r | |
30443 | <informaltable\r | |
30444 | frame="all"\r | |
30445 | rowsep="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 | |
30468 | SML code, including memory for the stack (or stacks, if there are\r | |
30469 | multiple threads). It does not, however, include any memory used for\r | |
30470 | code 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 | |
30483 | termination 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 | |
30490 | termination 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 | |
30497 | have been created by a call to <literal>MLton.World.save</literal> by the same\r | |
30498 | executable. 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 | |
30505 | larger than <emphasis>x</emphasis>, where <emphasis>x</emphasis> is a real number and the trailing letter\r | |
30506 | indicates 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 | |
30514 | desired 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 | |
30521 | via <literal>-runtime no-load-world</literal> to create executables that will not load\r | |
30522 | a world. This may be useful to ensure that set-uid executables do not\r | |
30523 | load 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 | |
30530 | runtime views as the amount of RAM it can use. Typically <emphasis>x</emphasis> is less\r | |
30531 | than 1, and is used to account for space used by other programs\r | |
30532 | running 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’t process any <literal>@MLton</literal>\r | |
30541 | arguments.</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 | |
30554 | declaration 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 | |
30564 | where it is bound. Scope inference is a direct implementation of the\r | |
30565 | specification given in section 4.6 of the\r | |
30566 | <link linkend="DefinitionOfStandardML">Definition</link>. Recall that a free occurrence\r | |
30567 | of a type variable <literal>'a</literal> in a declaration <literal>d</literal> is <emphasis>unguarded</emphasis>\r | |
30568 | in <literal>d</literal> if <literal>'a</literal> is not part of a smaller declaration. A type\r | |
30569 | variable <literal>'a</literal> is implicitly scoped at <literal>d</literal> if <literal>'a</literal> is\r | |
30570 | unguarded in <literal>d</literal> and <literal>'a</literal> does not occur unguarded in any\r | |
30571 | declaration containing <literal>d</literal>.</simpara>\r | |
30572 | <simpara>The first pass of scope inference walks down the tree and renames all\r | |
30573 | explicitly bound type variables in order to avoid name collisions. It\r | |
30574 | then walks up the tree and adds to each declaration the set of\r | |
30575 | unguarded type variables occurring in that declaration. At this\r | |
30576 | point, 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 | |
30579 | pass walks down the tree leaving a <literal>'a</literal> at the a declaration where\r | |
30580 | it 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 | |
30587 | can compile with either MLton or SML/NJ, but we strongly recommend\r | |
30588 | using MLton, since it generates a much faster and more robust\r | |
30589 | executable.</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 | |
30594 | safe, you should use the same version of MLton that you are building.\r | |
30595 | However, older versions may work, as long as they don’t go back too\r | |
30596 | far. To build MLton, run <literal>make</literal> from within the root directory of the\r | |
30597 | sources. This will build MLton first with the already installed\r | |
30598 | binary 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 | |
30600 | and parser, and then calls <literal>mlton</literal> to compile itself. When making\r | |
30601 | MLton 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 | |
30604 | MLton 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 | |
30606 | of compilation is essential in order to achieve a fast and robust\r | |
30607 | MLton.</simpara>\r | |
30608 | <simpara>Compiling MLton requires at least 1GB of RAM for 32-bit platforms (2GB is\r | |
30609 | preferable) and at least 2GB RAM for 64-bit platforms (4GB is preferable).\r | |
30610 | If your machine has less RAM, self-compilation will\r | |
30611 | likely fail, or at least take a very long time due to paging. Even if\r | |
30612 | you have enough memory, there simply may not be enough available, due\r | |
30613 | to 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 | |
30615 | slow. 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 | |
30621 | The 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 | |
30626 | install 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 | |
30631 | The following errors indicates that a binary version of MLton could\r | |
30632 | not 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 | |
30638 | look for a <literal>mlton</literal> in your path and in <literal>src/build/bin</literal>. It is OK if\r | |
30639 | the latter doesn’t exist when the build starts; it is the target being\r | |
30640 | built. 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 | |
30648 | root directory of the sources. You must use a recent version of\r | |
30649 | SML/NJ. First, the <literal>Makefile</literal> calls <literal>ml-lex</literal> and <literal>ml-yacc</literal> to build\r | |
30650 | the 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 | |
30652 | will rebuild MLton with this SML/NJ built MLton and then will rebuild\r | |
30653 | MLton with the MLton built MLton. Building with SML/NJ takes\r | |
30654 | significant time (particularly during the "<literal>parseAndElaborate</literal>" phase\r | |
30655 | when the SML/NJ built MLton is compiling MLton). Unless you are doing\r | |
30656 | compiler development and need rapid recompilation, we recommend\r | |
30657 | compiling 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 | |
30664 | serialization. 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 | |
30678 | library (see\r | |
30679 | <ulink url="https://github.com/MLton/mltonlib/blob/master/com/ssh/generic/unstable/README"><literal>README</literal></ulink>) that\r | |
30680 | includes 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 | |
30696 | heap space required for zero-length vectors among all vectors (of a given type).\r | |
30697 | It was claimed that this optimization is important, e.g., in a self-compile,\r | |
30698 | where vectors are used for lots of syntax tree elements and many of those\r | |
30699 | vectors 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 | |
30702 | time (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 | |
30705 | application of the <literal>Array_uninit</literal> (previously, the <literal>Array_array</literal>) primitive to\r | |
30706 | the zero constant. The hash-consing of globals, meant to create exactly one\r | |
30707 | global 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 | |
30709 | the identity may be supressed by a subsequent <literal>Array_toVector</literal>)), hence each\r | |
30710 | distinct <literal>Array_array0Const</literal> primitive in the program remained as distinct\r | |
30711 | globals. The limited amount of inlining prior to <link linkend="ConstantPropagation">ConstantPropagation</link> meant\r | |
30712 | that there were typically fewer than a dozen "copies" of the same empty vector\r | |
30713 | in a program for a given type.</simpara>\r | |
30714 | <simpara>As a "functional" primitive, a nullary <literal>Vector_vector</literal> is globalized by\r | |
30715 | ClosureConvert, but is further recognized by ConstantPropagation and hash-consed\r | |
30716 | into 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 | |
30719 | coercion-based optimizations of <literal>Useless</literal>. For example, consider the\r | |
30720 | following 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 =>\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) => (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) => w + w1 + w2 + w3) 0wx0 v1\r | |
30730 | val ans2 = Vector.foldl (fn ((_,w2,_),w) => w + w2) 0wx0 v2\r | |
30731 | val ans3 = Vector.foldl (fn ((_,w2,_),w) => 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 | |
30738 | the 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 | |
30741 | polyvariance and inlining remained a distinct\r | |
30742 | <literal>Array_uninit((word16 * word16 * word16)) (0x0)</literal> global, which\r | |
30743 | resulted 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 | |
30747 | flows 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 | |
30750 | polyvariance are globalized during <literal>ClosureConvert</literal>, those global\r | |
30751 | references may be further duplicated by inlining, but the distinct\r | |
30752 | occurrences of <literal>Vector_vector((word16 * word16 * word16)) ()</literal> are\r | |
30753 | merged to a single occurrence. Because this result flows to places\r | |
30754 | requiring 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 | |
30758 | value 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 | |
30760 | entirely. This costs some space (no sharing of empty vectors) and\r | |
30761 | some 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 | |
30763 | and associated <literal>ConstantPropagation</literal> treatment. But, the semantics\r | |
30764 | and purpose of <literal>Array_array0Const</literal> was poorly understood, resulting in\r | |
30765 | this break.</simpara>\r | |
30766 | <simpara>The <link linkend="ShareZeroVec">ShareZeroVec</link> pass pursues a different approach: perform the 0-element\r | |
30767 | vector "optimization" as a separate optimization, after\r | |
30768 | <literal>ConstantPropagation</literal> and <literal>Useless</literal>. A trivial static analysis is\r | |
30769 | used to match <literal>val v: t vector = Array_toVector(t) (a)</literal> with\r | |
30770 | corresponding <literal>val a: array = Array_uninit(t) (l)</literal> and the later are\r | |
30771 | expanded to\r | |
30772 | <literal>val a: t array = if 0 = l then zeroArr_[t] else Array_uninit(t) (l)</literal>\r | |
30773 | with a single global <literal>val zeroArr_[t] = Array_uninit(t) (0)</literal> created\r | |
30774 | for 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 | |
30776 | approach, is that <literal>Array_toVector</literal> is applied each time a vector\r | |
30777 | is created, even if it is being applied to the <literal>zeroArr_[t]</literal>\r | |
30778 | zero-length array. (Although, this was the behavior of the\r | |
30779 | <literal>Array_array0Const</literal> approach.) This updates the object header each\r | |
30780 | time, whereas the <literal>Vector_vector(t) ()</literal> approach would have updated\r | |
30781 | the 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 | |
30783 | join point.</simpara>\r | |
30784 | <simpara>It would be possible to properly share zero-length vectors, but doing\r | |
30785 | so is a more sophisticated analysis and transformation, because there\r | |
30786 | can 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 | |
30789 | nothing happens when a zero-length vector is created. It may be best\r | |
30790 | to pursue a more general "array to vector" optimization that\r | |
30791 | transforms creations of static-length vectors (e.g., all the\r | |
30792 | <literal>Vector.new<N></literal> functions) into <literal>Vector_vector</literal> primitives (some of\r | |
30793 | which 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 <file></literal>, that causes MLton to pretty\r | |
30814 | print to <emphasis>file</emphasis> the basis defined by the input program. For example,\r | |
30815 | if <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 | |
30818 | with the following contents.</simpara>\r | |
30819 | <screen>val f: int -> int</screen>\r | |
30820 | <simpara>If you only want to see the basis and do not wish to compile the\r | |
30821 | program, 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 | |
30825 | signature them with <literal>_sig.</literal> to distinguish them from types defined in the\r | |
30826 | environment. 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 -> 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 -> 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 | |
30840 | that name is used everywhere for that type, no matter what the input\r | |
30841 | signature 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 | |
30858 | even 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 | |
30888 | possible, combined with <literal>where type</literal> clauses to specify the meanings\r | |
30889 | of 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 | |
30895 | structure S: SIG =\r | |
30896 | struct\r | |
30897 | type t = int\r | |
30898 | val x = 13\r | |
30899 | end\r | |
30900 | structure S2:> 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 | |
30907 | structure S: SIG\r | |
30908 | where type t = int\r | |
30909 | structure 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 "<file>"*)</literal> is recognized as a directive to\r | |
30917 | save the current basis (i.e., environment) to <literal><file></literal> (in the same format as\r | |
30918 | the <literal>-show-basis <file></literal> <link linkend="CompileTimeOptions">compile-time option</link>). The\r | |
30919 | <literal><file></literal> is interpreted relative to the source file in which it appears. The\r | |
30920 | comment is lexed as a distinct token and is parsed as a structure-level\r | |
30921 | declaration. [Note that treating the directive as a top-level declaration would\r | |
30922 | prohibit using it inside a functor body, which would make the feature\r | |
30923 | significantly less useful in the context of the MLton compiler sources (with its\r | |
30924 | nearly 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 | |
30927 | tools.</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 | |
30933 | accepts a special command-line runtime system argument, <literal>show-prof</literal>,\r | |
30934 | that outputs information about the source functions that are profiled.\r | |
30935 | Normally, this information is used by <literal>mlprof</literal>. This page documents\r | |
30936 | the <literal>show-prof</literal> output format, and is intended for those working on\r | |
30937 | the 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 | |
30942 | The magic number of the executable.\r | |
30943 | </simpara>\r | |
30944 | </listitem>\r | |
30945 | <listitem>\r | |
30946 | <simpara>\r | |
30947 | The number of source names in the executable.\r | |
30948 | </simpara>\r | |
30949 | </listitem>\r | |
30950 | <listitem>\r | |
30951 | <simpara>\r | |
30952 | A line for each source name giving the name of the function, a tab,\r | |
30953 | the filename of the file containing the function, a colon, a space,\r | |
30954 | and the line number that the function starts on in that file.\r | |
30955 | </simpara>\r | |
30956 | </listitem>\r | |
30957 | <listitem>\r | |
30958 | <simpara>\r | |
30959 | The number of (split) source functions.\r | |
30960 | </simpara>\r | |
30961 | </listitem>\r | |
30962 | <listitem>\r | |
30963 | <simpara>\r | |
30964 | A line for each (split) source function, where each line consists of\r | |
30965 | a source-name index (into the array of source names) and a successors\r | |
30966 | index (into the array of split-source sequences, defined below).\r | |
30967 | </simpara>\r | |
30968 | </listitem>\r | |
30969 | <listitem>\r | |
30970 | <simpara>\r | |
30971 | The number of split-source sequences.\r | |
30972 | </simpara>\r | |
30973 | </listitem>\r | |
30974 | <listitem>\r | |
30975 | <simpara>\r | |
30976 | A line for each split-source sequence, where each line is a space\r | |
30977 | separated 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 | |
30982 | define 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> ⇒ <literal>a</literal>\r | |
30997 | </simpara>\r | |
30998 | </listitem>\r | |
30999 | <listitem>\r | |
31000 | <simpara>\r | |
31001 | <literal>case C x of C y => e</literal> ⇒ <literal>let y = x in e</literal>\r | |
31002 | </simpara>\r | |
31003 | </listitem>\r | |
31004 | <listitem>\r | |
31005 | <simpara>\r | |
31006 | constant folding, copy propagation\r | |
31007 | </simpara>\r | |
31008 | </listitem>\r | |
31009 | <listitem>\r | |
31010 | <simpara>\r | |
31011 | eta blocks\r | |
31012 | </simpara>\r | |
31013 | </listitem>\r | |
31014 | <listitem>\r | |
31015 | <simpara>\r | |
31016 | tuple 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 | |
31049 | optimization pass.</simpara>\r | |
31050 | <simpara>The <link linkend="Shrink">Shrink</link> implementation also includes functions to eliminate\r | |
31051 | unreachable blocks from a <link linkend="SSA">SSA</link> or <link linkend="SSA2">SSA2</link> program or function.\r | |
31052 | The <link linkend="Shrink">Shrink</link> pass does not guarantee to eliminate all unreachable\r | |
31053 | blocks. Doing so would unduly complicate the implementation, and it\r | |
31054 | is almost always the case that all unreachable blocks are eliminated.\r | |
31055 | However, a small number of optimization passes require that the input\r | |
31056 | have no unreachable blocks (essentially, when the analysis works on\r | |
31057 | the control flow graph and the rewrite iterates on the vector of\r | |
31058 | blocks). 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 | |
31060 | the continuation and handler only do <literal>Profile</literal> statements into a tail\r | |
31061 | call 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 | |
31072 | abstraction 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 | |
31091 | and removes:</simpara>\r | |
31092 | <itemizedlist>\r | |
31093 | <listitem>\r | |
31094 | <simpara>\r | |
31095 | components of tuples\r | |
31096 | </simpara>\r | |
31097 | </listitem>\r | |
31098 | <listitem>\r | |
31099 | <simpara>\r | |
31100 | function args\r | |
31101 | </simpara>\r | |
31102 | </listitem>\r | |
31103 | <listitem>\r | |
31104 | <simpara>\r | |
31105 | constructor 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 | |
31146 | it will make polymorphic equality faster because some types are simpler\r | |
31147 | </simpara>\r | |
31148 | </listitem>\r | |
31149 | <listitem>\r | |
31150 | <simpara>\r | |
31151 | it 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 | |
31156 | uses <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 | |
31159 | datatype and replace the lhs by the rhs, i.e. we must keep the\r | |
31160 | circularity 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 | |
31163 | something 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 | |
31167 | be 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 | |
31176 | libraries 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 | |
31178 | MLton implementation of SML and is supported on Linux, Mac OS X, and\r | |
31179 | Microsoft 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 | |
31187 | targets 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 | |
31205 | native code compiler that runs on a variety of platforms and has a\r | |
31206 | number of libraries and tools.</simpara>\r | |
31207 | <simpara>We maintain a list of SML/NJ’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 | |
31210 | between 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 | |
31239 | Some of these are documented in the\r | |
31240 | <ulink url="http://www.smlnj.org/doc/Conversion/index.html">SML '97 Conversion Guide</ulink>.\r | |
31241 | Since MLton does not deviate from the Definition, you should look here\r | |
31242 | if you are having trouble porting a program from MLton to SML/NJ or\r | |
31243 | vice versa. If you discover other deviations of SML/NJ that aren’t\r | |
31244 | listed 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 | |
31249 | SML/NJ allows spaces in long identifiers, as in <literal>S . x</literal>. Section\r | |
31250 | 2.5 of the Definition implies that <literal>S . x</literal> should be treated as three\r | |
31251 | separate lexical items.\r | |
31252 | </simpara>\r | |
31253 | </listitem>\r | |
31254 | <listitem>\r | |
31255 | <simpara>\r | |
31256 | SML/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 -> int\r | |
31260 | end</programlisting>\r | |
31261 | <simpara>The grammar on page 14 of the Definition does not allow it. Recent\r | |
31262 | versions of SML/NJ do give a warning.</simpara>\r | |
31263 | </listitem>\r | |
31264 | <listitem>\r | |
31265 | <simpara>\r | |
31266 | SML/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 | |
31273 | SML/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 | |
31277 | versions of SML/NJ do give a warning.</simpara>\r | |
31278 | </listitem>\r | |
31279 | <listitem>\r | |
31280 | <simpara>\r | |
31281 | SML/NJ allows rebinding <literal>true</literal>, <literal>false</literal>, <literal>nil</literal>, <literal>::</literal>, and <literal>ref</literal> by\r | |
31282 | the declarations:\r | |
31283 | </simpara>\r | |
31284 | <programlisting language="sml" linenumbering="unnumbered">fun true () = ()\r | |
31285 | fun false () = ()\r | |
31286 | fun nil () = ()\r | |
31287 | fun op :: () = ()\r | |
31288 | fun 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 | |
31293 | SML/NJ extends the syntax of the language to allow vector\r | |
31294 | expressions and patterns like the following:\r | |
31295 | </simpara>\r | |
31296 | <programlisting language="sml" linenumbering="unnumbered">val v = #[1,2,3]\r | |
31297 | val #[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 | |
31302 | SML/NJ extends the syntax of the language to allow <emphasis>or patterns</emphasis>\r | |
31303 | like the following:\r | |
31304 | </simpara>\r | |
31305 | <programlisting language="sml" linenumbering="unnumbered">datatype foo = Foo of int | Bar of int\r | |
31306 | val (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 | |
31311 | SML/NJ allows higher-order functors, that is, functors can be\r | |
31312 | components of structures and can be passed as functor arguments and\r | |
31313 | returned as functor results. As a consequence, SML/NJ allows\r | |
31314 | abbreviated 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 | |
31321 | functor 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 | |
31326 | functor G = F</programlisting>\r | |
31327 | </listitem>\r | |
31328 | <listitem>\r | |
31329 | <simpara>\r | |
31330 | SML/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 | |
31337 | SML/NJ allows duplicate type specifications in signatures when the\r | |
31338 | duplicates 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 | |
31345 | signature SIG2 =\r | |
31346 | sig\r | |
31347 | type t\r | |
31348 | type v\r | |
31349 | end\r | |
31350 | signature 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 | |
31359 | SML/NJ allows sharing constraints between type abbreviations in\r | |
31360 | signatures, 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 | |
31369 | SML/NJ correctly disallow sharing constraints between type\r | |
31370 | abbreviations in signatures.</simpara>\r | |
31371 | </listitem>\r | |
31372 | <listitem>\r | |
31373 | <simpara>\r | |
31374 | SML/NJ disallows multiple <literal>where type</literal> specifications of the same\r | |
31375 | type 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 | |
31387 | SML/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 | |
31400 | SML/NJ does not expand the <literal>withtype</literal> derived form as described by\r | |
31401 | the Definition. According to page 55 of the Definition, the type\r | |
31402 | bindings of a <literal>withtype</literal> declaration are substituted simultaneously in\r | |
31403 | the connected datatype. Consider the following program.\r | |
31404 | </simpara>\r | |
31405 | <programlisting language="sml" linenumbering="unnumbered">type u = real ;\r | |
31406 | datatype a =\r | |
31407 | A of t\r | |
31408 | | B of u\r | |
31409 | withtype u = int\r | |
31410 | and 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 | |
31413 | datatype a =\r | |
31414 | A of u\r | |
31415 | | B of int ;\r | |
31416 | type u = int\r | |
31417 | and t = u</programlisting>\r | |
31418 | <simpara>However, SML/NJ expands <literal>withtype</literal> bindings sequentially, meaning that\r | |
31419 | earlier bindings are expanded within later ones. Hence, the above\r | |
31420 | program is expanded to the following.</simpara>\r | |
31421 | <programlisting language="sml" linenumbering="unnumbered">type u = real ;\r | |
31422 | datatype a =\r | |
31423 | A of int\r | |
31424 | | B of int ;\r | |
31425 | type u = int\r | |
31426 | type t = int</programlisting>\r | |
31427 | </listitem>\r | |
31428 | <listitem>\r | |
31429 | <simpara>\r | |
31430 | SML/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 | |
31436 | SML/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 | |
31440 | signature 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 | |
31446 | signature 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 | |
31451 | similar to a definitional type specification. For example:</simpara>\r | |
31452 | <programlisting language="sml" linenumbering="unnumbered">structure S = struct type t = int end\r | |
31453 | signature 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 | |
31459 | signature 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 | |
31466 | SML/NJ disallows binding non-datatypes with datatype replication.\r | |
31467 | For example, it rejects the following program that should be allowed\r | |
31468 | according to the Definition.\r | |
31469 | </simpara>\r | |
31470 | <programlisting language="sml" linenumbering="unnumbered">type ('a, 'b) t = 'a * 'b\r | |
31471 | datatype u = datatype t</programlisting>\r | |
31472 | <simpara>This idiom can be useful when one wants to rename a type without\r | |
31473 | rewriting all the type arguments. For example, the above would have\r | |
31474 | to be written in SML/NJ as follows.</simpara>\r | |
31475 | <programlisting language="sml" linenumbering="unnumbered">type ('a, 'b) t = 'a * 'b\r | |
31476 | type ('a, 'b) u = ('a, 'b) t</programlisting>\r | |
31477 | </listitem>\r | |
31478 | <listitem>\r | |
31479 | <simpara>\r | |
31480 | SML/NJ disallows sharing a structure with one of its substructures.\r | |
31481 | For 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 | |
31496 | SML/NJ disallows polymorphic generalization of refutable\r | |
31497 | patterns. For example, SML/NJ disallows the following.\r | |
31498 | </simpara>\r | |
31499 | <programlisting language="sml" linenumbering="unnumbered">val [x] = [[]]\r | |
31500 | val _ = (1 :: x, "one" :: x)</programlisting>\r | |
31501 | <simpara>Recent versions of SML/NJ correctly allow polymorphic generalization\r | |
31502 | of refutable patterns.</simpara>\r | |
31503 | </listitem>\r | |
31504 | <listitem>\r | |
31505 | <simpara>\r | |
31506 | SML/NJ uses an overly restrictive context for type inference. For\r | |
31507 | example, SML/NJ rejects both of the following.\r | |
31508 | </simpara>\r | |
31509 | <programlisting language="sml" linenumbering="unnumbered">structure S =\r | |
31510 | struct\r | |
31511 | val z = (fn x => x) []\r | |
31512 | val y = z :: [true] :: nil\r | |
31513 | end</programlisting>\r | |
31514 | <programlisting language="sml" linenumbering="unnumbered">structure S : sig val z : bool list end =\r | |
31515 | struct\r | |
31516 | val z = (fn x => x) []\r | |
31517 | end</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 | |
31528 | SML/NJ exposes the equality of the <literal>vector</literal> type in structures such\r | |
31529 | as <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 | |
31531 | the 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 | |
31537 | SML/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 | |
31539 | values 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 | |
31544 | Under SML/NJ on Windows, <literal>OS.Path.validVolume</literal> incorrectly considers\r | |
31545 | absolute empty volumes to be valid. In other words, when the\r | |
31546 | expression\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 | |
31550 | the other hand, correctly follows the Basis Library Specification,\r | |
31551 | which 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 | |
31554 | differently. 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 | |
31557 | whereas under MLton on Windows, evaluating this expression (correctly)\r | |
31558 | causes 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 | |
31567 | collection of libraries that are distributed with SML/NJ. Due to\r | |
31568 | differences between SML/NJ and MLton, these libraries will not work\r | |
31569 | out-of-the box with MLton.</simpara>\r | |
31570 | <simpara>As of 20180119, MLton includes a port of the SML/NJ Library\r | |
31571 | synchronized 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 | |
31577 | You can import a sub-library of the SML/NJ Library into an MLB file with:\r | |
31578 | </simpara>\r | |
31579 | <informaltable\r | |
31580 | frame="all"\r | |
31581 | rowsep="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, …</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 | |
31651 | If you are porting a project from SML/NJ’s <link linkend="CompilationManager">CompilationManager</link> to\r | |
31652 | MLton’s <link linkend="MLBasis">ML Basis system</link> using <literal>cm2mlb</literal>, note that the\r | |
31653 | following 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 | |
31672 | the 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 | |
31679 | deriving 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’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 -> 'a) -> 'a\r | |
31743 | val isolate: ('a -> unit) -> 'a cont\r | |
31744 | val throw: 'a cont -> 'a -> '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 -> string\r | |
31752 | val getOSKind: unit -> os_kind\r | |
31753 | val getOSName: unit -> string\r | |
31754 | end\r | |
31755 | \r | |
31756 | val exnHistory: exn -> string list\r | |
31757 | val exportFn: string * (string * string list -> OS.Process.status) -> unit\r | |
31758 | val exportML: string -> bool\r | |
31759 | val getAllArgs: unit -> string list\r | |
31760 | val getArgs: unit -> string list\r | |
31761 | val getCmdName: unit -> string\r | |
31762 | end</programlisting>\r | |
31763 | <simpara><literal>SMLofNJ</literal> implements a subset of the structure of the same name\r | |
31764 | provided in <link linkend="SMLNJ">Standard ML of New Jersey</link>. It is included to\r | |
31765 | make it easier to port programs between the two systems. The\r | |
31766 | semantics 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 | |
31821 | the 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 | |
31829 | computation.</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 | |
31840 | including a pretty printer generator, a document generator, and a\r | |
31841 | regression 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 | |
31849 | them 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 | |
31861 | read-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 | |
31867 | changes 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 | |
31882 | that 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 | |
31888 | Chapter 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 | |
31908 | It 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 | |
31910 | a sequence of global statements, and a collection of functions, along\r | |
31911 | with a distinguished "main" function. Each function consists of a\r | |
31912 | collection of basic blocks, where each basic block is a sequence of\r | |
31913 | statements 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 | |
31944 | verifies the following:</simpara>\r | |
31945 | <itemizedlist>\r | |
31946 | <listitem>\r | |
31947 | <simpara>\r | |
31948 | no duplicate definitions (tycons, cons, vars, labels, funcs)\r | |
31949 | </simpara>\r | |
31950 | </listitem>\r | |
31951 | <listitem>\r | |
31952 | <simpara>\r | |
31953 | no out of scope references (tycons, cons, vars, labels, funcs)\r | |
31954 | </simpara>\r | |
31955 | </listitem>\r | |
31956 | <listitem>\r | |
31957 | <simpara>\r | |
31958 | variable definitions dominate variable uses\r | |
31959 | </simpara>\r | |
31960 | </listitem>\r | |
31961 | <listitem>\r | |
31962 | <simpara>\r | |
31963 | case 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 | |
32016 | declarations, a sequence of global statements, and a collection of\r | |
32017 | functions, along with a distinguished "main" function. Each function\r | |
32018 | consists of a collection of basic blocks, where each basic block is a\r | |
32019 | sequence 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 | |
32021 | the vector type constructor n-ary instead of unary. This allows\r | |
32022 | optimizations 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 | |
32053 | program verifies the following:</simpara>\r | |
32054 | <itemizedlist>\r | |
32055 | <listitem>\r | |
32056 | <simpara>\r | |
32057 | no duplicate definitions (tycons, cons, vars, labels, funcs)\r | |
32058 | </simpara>\r | |
32059 | </listitem>\r | |
32060 | <listitem>\r | |
32061 | <simpara>\r | |
32062 | no out of scope references (tycons, cons, vars, labels, funcs)\r | |
32063 | </simpara>\r | |
32064 | </listitem>\r | |
32065 | <listitem>\r | |
32066 | <simpara>\r | |
32067 | variable definitions dominate variable uses\r | |
32068 | </simpara>\r | |
32069 | </listitem>\r | |
32070 | <listitem>\r | |
32071 | <simpara>\r | |
32072 | case 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 | |
32096 | collected 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 <pass></literal> — keep diagnostic info for pass\r | |
32140 | </simpara>\r | |
32141 | </listitem>\r | |
32142 | <listitem>\r | |
32143 | <simpara>\r | |
32144 | <literal>-disable-pass <pass></literal> — skip optimization pass (if normally performed)\r | |
32145 | </simpara>\r | |
32146 | </listitem>\r | |
32147 | <listitem>\r | |
32148 | <simpara>\r | |
32149 | <literal>-enable-pass <pass></literal> — perform optimization pass (if normally skipped)\r | |
32150 | </simpara>\r | |
32151 | </listitem>\r | |
32152 | <listitem>\r | |
32153 | <simpara>\r | |
32154 | <literal>-keep-pass <pass></literal> — keep the results of pass\r | |
32155 | </simpara>\r | |
32156 | </listitem>\r | |
32157 | <listitem>\r | |
32158 | <simpara>\r | |
32159 | <literal>-loop-passes <n></literal> — loop optimization passes\r | |
32160 | </simpara>\r | |
32161 | </listitem>\r | |
32162 | <listitem>\r | |
32163 | <simpara>\r | |
32164 | <literal>-ssa2-passes <passes></literal> — 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 | |
32173 | collected 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 <pass></literal> — keep diagnostic info for pass\r | |
32320 | </simpara>\r | |
32321 | </listitem>\r | |
32322 | <listitem>\r | |
32323 | <simpara>\r | |
32324 | <literal>-disable-pass <pass></literal> — skip optimization pass (if normally performed)\r | |
32325 | </simpara>\r | |
32326 | </listitem>\r | |
32327 | <listitem>\r | |
32328 | <simpara>\r | |
32329 | <literal>-enable-pass <pass></literal> — perform optimization pass (if normally skipped)\r | |
32330 | </simpara>\r | |
32331 | </listitem>\r | |
32332 | <listitem>\r | |
32333 | <simpara>\r | |
32334 | <literal>-keep-pass <pass></literal> — keep the results of pass\r | |
32335 | </simpara>\r | |
32336 | </listitem>\r | |
32337 | <listitem>\r | |
32338 | <simpara>\r | |
32339 | <literal>-loop-passes <n></literal> — loop optimization passes\r | |
32340 | </simpara>\r | |
32341 | </listitem>\r | |
32342 | <listitem>\r | |
32343 | <simpara>\r | |
32344 | <literal>-ssa-passes <passes></literal> — 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 | |
32357 | Stabilizers 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 | |
32367 | Stabilizers 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 | |
32377 | Download and build a source copy of MLton\r | |
32378 | </simpara>\r | |
32379 | </listitem>\r | |
32380 | <listitem>\r | |
32381 | <simpara>\r | |
32382 | Extract the tar.gz file attached to this page\r | |
32383 | </simpara>\r | |
32384 | </listitem>\r | |
32385 | <listitem>\r | |
32386 | <simpara>\r | |
32387 | Some 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 | |
32397 | Please 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 | |
32402 | We are looking to expand the usability of stabilizers\r | |
32403 | </simpara>\r | |
32404 | </listitem>\r | |
32405 | <listitem>\r | |
32406 | <simpara>\r | |
32407 | Please 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 | |
32417 | This 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 | |
32422 | More 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 -> 'b) -> ('a -> 'b)\r | |
32434 | val stabilize: unit -> 'a\r | |
32435 | \r | |
32436 | val stableCP: (('a -> 'b) * (unit -> unit)) ->\r | |
32437 | (('a -> 'b) * checkpoint)\r | |
32438 | val stabilizeCP: checkpoint -> unit\r | |
32439 | \r | |
32440 | val unmonitoredAssign: ('a ref * 'a) -> unit\r | |
32441 | val monitoredAssign: ('a ref * 'a) -> 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 | |
32462 | nearest enclosing <emphasis>stable</emphasis> section. These effects may have propagated\r | |
32463 | to other threads, so all affected threads are returned to a globally\r | |
32464 | consistent previous state. The return is undefined because control\r | |
32465 | cannot 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 | |
32472 | identical to <literal>f</literal> but when applied will execute within a stable\r | |
32473 | section. <literal>comp</literal> will be executed if <literal>f'</literal> is later stabilized. <literal>cp</literal>\r | |
32474 | is 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 | |
32481 | stabilize 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 | |
32495 | stabilizers. <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 | |
32524 | support for rapid prototyping, modularity, and development of large\r | |
32525 | programs, 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 | |
32815 | confusion 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 | |
32817 | an interactive REPL (Read-Eval Print Loop) while trying to learn the\r | |
32818 | basics of the language. While writing your first SML programs, you\r | |
32819 | should keep the source code of your programs in a form that is\r | |
32820 | accepted 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 | |
32824 | to introduce mutually recursive definitions. The purpose of the <literal>and</literal>\r | |
32825 | keyword is to introduce mutually recursive definitions of functions\r | |
32826 | and 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 | |
32830 | and 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 | |
32839 | it 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 | |
32844 | in <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 | |
32850 | The pattern `h \r | |
32851 | </term>\r | |
32852 | <listitem>\r | |
32853 | <simpara>\r | |
32854 | t` 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 | |
32862 | multiple consecutive constructed patterns through currying.</simpara>\r | |
32863 | <simpara>The same applies to nonfix constructors. For example, the parentheses\r | |
32864 | in</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 | |
32869 | there is always just one constructed pattern. So, both</simpara>\r | |
32870 | <programlisting language="sml" linenumbering="unnumbered">val valOf = fn NONE => raise Option\r | |
32871 | | SOME x => x</programlisting>\r | |
32872 | <simpara>and</simpara>\r | |
32873 | <programlisting language="sml" linenumbering="unnumbered">fun valOf x = case x of\r | |
32874 | NONE => raise Option\r | |
32875 | | SOME x => 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 | |
32881 | Normally an SML source file should only contain declarations. The\r | |
32882 | following are declarations:</simpara>\r | |
32883 | <programlisting language="sml" linenumbering="unnumbered">datatype dt = ...\r | |
32884 | fun f ... = ...\r | |
32885 | functor Fn (...) = ...\r | |
32886 | infix ...\r | |
32887 | infixr ...\r | |
32888 | local ... in ... end\r | |
32889 | nonfix ...\r | |
32890 | open ...\r | |
32891 | signature SIG = ...\r | |
32892 | structure Struct = ...\r | |
32893 | type t = ...\r | |
32894 | val v = ...</programlisting>\r | |
32895 | <simpara>Note that</simpara>\r | |
32896 | <programlisting language="sml" linenumbering="unnumbered">let ... in ... end</programlisting>\r | |
32897 | <simpara>isn’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 | |
32905 | discussion.</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 | |
32910 | necessary 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 | |
32915 | Before SML’97, <literal>*)</literal> was considered a comment terminator in SML and\r | |
32916 | caused a syntax error. At the time of writing, <link linkend="SMLNJ">SML/NJ</link> still\r | |
32917 | rejects 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 | |
32919 | is 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><</literal>, <literal>></literal>, …) and\r | |
32924 | numeric 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 | |
32926 | overloaded operators such as</simpara>\r | |
32927 | <programlisting language="sml" linenumbering="unnumbered">fun min (x, y) = if y < x then y else x</programlisting>\r | |
32928 | <simpara>are not overloaded themselves. SML doesn’t really support\r | |
32929 | (user-defined) overloading or other forms of ad hoc polymorphism. In\r | |
32930 | cases such as the above where the context doesn’t resolve the\r | |
32931 | overloading, expressions using overloaded operators or constants get\r | |
32932 | assigned a default type. The above definition gets the type</simpara>\r | |
32933 | <programlisting language="sml" linenumbering="unnumbered">val min : int * int -> 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 | |
32939 | is probably caused by the fact that in an SML REPL, a semicolon (and\r | |
32940 | enter) is used to signal the REPL that it should evaluate the\r | |
32941 | preceding chunk of code as a unit. In SML source files, semicolons\r | |
32942 | are really needed in only two places. Namely, in expressions of the\r | |
32943 | form</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 | |
32948 | rather 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’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 | |
32979 | from interpreters, to byte-code compilers, to incremental compilers,\r | |
32980 | to 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 | |
33048 | MLWorks\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’97 as defined in the\r | |
33068 | <link linkend="DefinitionOfStandardML">Definition</link>\r | |
33069 | requires only a minimal initial basis, which, while including the\r | |
33070 | types <literal>int</literal>, <literal>real</literal>, <literal>char</literal>, and <literal>string</literal>, need have\r | |
33071 | no operations on those base types. Hence, the only observable output\r | |
33072 | of an SML’97 program is termination or raising an exception. Most SML\r | |
33073 | compilers should agree there, to the degree each agrees with the\r | |
33074 | Definition. See <link linkend="UnresolvedBugs">UnresolvedBugs</link> for MLton’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 | |
33077 | Within the Basis Library, there are numerous places where the behavior\r | |
33078 | is 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 | |
33082 | Int/Real/Word sizes are the biggest implementation dependent aspect;\r | |
33083 | so, one implementation may raise <literal>Overflow</literal> while another can\r | |
33084 | accommodate the result. Also, maximum array and vector lengths are\r | |
33085 | implementation dependent. Interfacing with the operating system is a\r | |
33086 | bit murky, and implementations surely differ in handling of errors\r | |
33087 | there.</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 | |
33096 | Andrew 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 | |
33102 | Stephen 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 | |
33108 | Robert 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 | |
33114 | Mads 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 | |
33120 | Mads 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 | |
33129 | depend on the values of their arguments, or so called dependently\r | |
33130 | typed functions, it is possible, and arguably commonplace, to write\r | |
33131 | functions whose types depend on the types of their arguments. Indeed,\r | |
33132 | the 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 | |
33134 | is less commonplace, however, is to write functions whose behavior\r | |
33135 | would depend on the types of their arguments. Nevertheless, there are\r | |
33136 | several techniques for writing such functions.\r | |
33137 | <link linkend="TypeIndexedValues">Type-indexed values</link> and <link linkend="Fold">fold</link> are two such\r | |
33138 | techniques. This page presents another such technique dubbed static\r | |
33139 | sums.</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 | |
33145 | end</programlisting>\r | |
33146 | <simpara>While a generic sum type such as defined above is very useful, it has\r | |
33147 | a 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 => a\r | |
33152 | | Sum.INR a => a</programlisting>\r | |
33153 | <simpara>As can be seen from the type of <literal>out</literal>, it is limited in the sense that\r | |
33154 | it requires both variants of the sum to have the same type. So, <literal>out</literal>\r | |
33155 | cannot be used to extract the value of a sum of two different types,\r | |
33156 | such as the type <literal>(int, real) Sum.t</literal>. As another example of a\r | |
33157 | limitation, 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 => i + 1\r | |
33161 | | Sum.INR r => Real.nextAfter (r, Real.posInf)</programlisting>\r | |
33162 | <simpara>The above definition of <literal>succ</literal> cannot be typed, because there is no\r | |
33163 | type 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 | |
33170 | match (inR x) (f, g) = g x</screen>\r | |
33171 | <simpara>and do not suffer from the same limitions. The definitions are\r | |
33172 | actually 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 | |
33177 | end</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 => i + 1,\r | |
33182 | fn r => 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 | |
33185 | succ (StaticSum.inR Real.maxFinite) = Real.posInf</programlisting>\r | |
33186 | <simpara>To better understand how this works, consider the following signature\r | |
33187 | for static sums:</simpara>\r | |
33188 | <programlisting language="sml" linenumbering="unnumbered">structure StaticSum :> sig\r | |
33189 | type ('dL, 'cL, 'dR, 'cR, 'c) t\r | |
33190 | val inL : 'dL -> ('dL, 'cL, 'dR, 'cR, 'cL) t\r | |
33191 | val inR : 'dR -> ('dL, 'cL, 'dR, 'cR, 'cR) t\r | |
33192 | val match : ('dL, 'cL, 'dR, 'cR, 'c) t -> ('dL -> 'cL) * ('dR -> 'cR) -> 'c\r | |
33193 | end = struct\r | |
33194 | type ('dL, 'cL, 'dR, 'cR, 'c) t = ('dL -> 'cL) * ('dR -> 'cR) -> 'c\r | |
33195 | open StaticSum\r | |
33196 | end</programlisting>\r | |
33197 | <simpara>Above, <literal>'d</literal> stands for domain and <literal>'c</literal> for codomain. The key\r | |
33198 | difference between an ordinary sum type, like <literal>(int, real) Sum.t</literal>, and\r | |
33199 | a static sum type, like <literal>(int, real, real, int, real) StaticSum.t</literal>, is\r | |
33200 | that the ordinary sum type says nothing about the type of the result\r | |
33201 | of 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 -> '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 | |
33206 | For 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 | |
33208 | argument type of <literal>succ</literal> gives the type <literal>(int, int, real, real, int)\r | |
33209 | StaticSum.t -> int</literal>.</simpara>\r | |
33210 | <simpara>The <literal>out</literal> function is quite useful on its own. Here is how it can be\r | |
33211 | defined:</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 -> 'c =\r | |
33215 | fn s => match s (fn x => x, fn x => x)\r | |
33216 | end</programlisting>\r | |
33217 | <simpara>Due to the value restriction, lack of first class polymorphism and\r | |
33218 | polymorphic recursion, the usefulness and convenience of static sums\r | |
33219 | is somewhat limited in SML. So, don’t throw away the ordinary sum\r | |
33220 | type 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 | |
33224 | result type would depend on some of the arguments. Traditionally such\r | |
33225 | functions have been thought to be impossible in SML and the solution\r | |
33226 | has 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 | |
33228 | Basis library defines 16 <literal>send</literal> and 16 <literal>recv</literal> functions. In contrast,\r | |
33229 | the 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 | |
33231 | Basic library designed by Stephen Weeks defines only a single <literal>send</literal>\r | |
33232 | and a single <literal>receive</literal> and the result types of the functions depend on\r | |
33233 | their 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 | |
33235 | static 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 | |
33241 | and returns their sum given a monadic parsing combinator library. A\r | |
33242 | part 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 | |
33250 | end</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 -> 'a t\r | |
33255 | val >>= : 'a t * ('a -> 'b t) -> 'b t\r | |
33256 | end\r | |
33257 | infix >>=</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 >>= (fn _ =>\r | |
33260 | int >>= (fn x =>\r | |
33261 | comma >>= (fn _ =>\r | |
33262 | int >>= (fn y =>\r | |
33263 | rparen >>= (fn _ =>\r | |
33264 | return (x + y))))))</programlisting>\r | |
33265 | <simpara>In Haskell, the parser could be written using the <literal>do</literal> notation\r | |
33266 | considerably less verbosely as:</simpara>\r | |
33267 | <programlisting language="haskell" linenumbering="unnumbered">p = do { lparen ; x <- int ; comma ; y <- int ; rparen ; return $ x + y }</programlisting>\r | |
33268 | <simpara>SML doesn’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 | |
33270 | us to write the parser as</simpara>\r | |
33271 | <programlisting language="sml" linenumbering="unnumbered">val p = `lparen ^ \int ^ `comma ^ \int ^ `rparen @ (fn x & y => x + y)</programlisting>\r | |
33272 | <simpara>using four auxiliary combinators: <literal>`</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>`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 | |
33297 | The type of the result of the concatenation depends on the types of\r | |
33298 | the arguments.</simpara>\r | |
33299 | <simpara>Using static sums and the <link linkend="ProductType">product type</link>, the pick\r | |
33300 | notation 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 | |
33303 | in\r | |
33304 | struct\r | |
33305 | fun `a = inL (a >>= (fn _ => return ()))\r | |
33306 | val \ = inR\r | |
33307 | fun a @ f = out a >>= (return o f)\r | |
33308 | fun a ^ b =\r | |
33309 | (match b o match a)\r | |
33310 | (fn a =>\r | |
33311 | (fn b => inL (a >>= (fn _ => b)),\r | |
33312 | fn b => inR (a >>= (fn _ => b))),\r | |
33313 | fn a =>\r | |
33314 | (fn b => inR (a >>= (fn a => b >>= (fn _ => return a))),\r | |
33315 | fn b => inR (a >>= (fn a => b >>= (fn b => return (a & b))))))\r | |
33316 | end\r | |
33317 | end</programlisting>\r | |
33318 | <simpara>The above implementation is inefficient, however. It uses many more\r | |
33319 | bind operations, <literal>>>=</literal>, than necessary. That can be solved with an\r | |
33320 | additional level of abstraction:</simpara>\r | |
33321 | <programlisting language="sml" linenumbering="unnumbered">functor MkMonadPick (include MONAD) = let\r | |
33322 | open StaticSum\r | |
33323 | in\r | |
33324 | struct\r | |
33325 | fun `a = inL (fn b => a >>= (fn _ => b ()))\r | |
33326 | fun \a = inR (fn b => a >>= 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 => (fn b => inL (fn c => a (fn () => b c)),\r | |
33331 | fn b => inR (fn c => a (fn () => b c))),\r | |
33332 | fn a => (fn b => inR (fn c => a (fn a => b (fn () => c a))),\r | |
33333 | fn b => inR (fn c => a (fn a => b (fn b => c (a & b))))))\r | |
33334 | end\r | |
33335 | end</programlisting>\r | |
33336 | <simpara>After instantiating and opening either of the above monad pick\r | |
33337 | implementations, the previously given definition of <literal>p</literal> can be\r | |
33338 | compiled and results in a parser whose result is of type <literal>int</literal>. Here\r | |
33339 | is 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 & y => x + y)\r | |
33347 | end\r | |
33348 | end</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 | |
33391 | The 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 | |
33406 | sML for short, is to provide a vehicle for the continued evolution of\r | |
33407 | ML, using Standard ML as a starting point. The intention is for\r | |
33408 | successor ML to be a living, evolving dialect of ML that is responsive\r | |
33409 | to community needs and advances in language design, implementation,\r | |
33410 | and 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 | |
33414 | The features are disabled by default, and may be enabled utilizing the\r | |
33415 | feature’s corresponding <link linkend="MLBasisAnnotations">ML Basis annotation</link>\r | |
33416 | which is listed directly after the feature name. In addition, the\r | |
33417 | <literal>allowSuccessorML {false|true}</literal> annotation can be used to\r | |
33418 | simultaneously 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 | |
33426 | side 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 | |
33434 | Extended 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 | |
33437 | proxy 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 | |
33442 | Extended 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 | |
33445 | integer and word constants.</simpara>\r | |
33446 | <simpara>Underscores in a numeric constant must occur between digits and\r | |
33447 | consecutive underscores are allowed.</simpara>\r | |
33448 | <simpara>Binary integer constants use the prefix <literal>0b</literal> and binary word constants\r | |
33449 | use the prefix <literal>0wb</literal>.</simpara>\r | |
33450 | <simpara>The following example uses extended numeric constants (although it may\r | |
33451 | be incorrectly syntax highlighted):</simpara>\r | |
33452 | <programlisting language="sml" linenumbering="unnumbered">val pb = 0b10101\r | |
33453 | val nb = ~0b10_10_10\r | |
33454 | val wb = 0wb1010\r | |
33455 | val i = 4__327__829\r | |
33456 | val 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 ≥ 128 and ≤ 247 that\r | |
33463 | correspond to syntactically well-formed UTF-8 byte sequences in text\r | |
33464 | constants.</simpara>\r | |
33465 | <simpara>Any 1, 2, 3, or 4 byte sequence that can be properly decoded to a\r | |
33466 | binary number according to the UTF-8 encoding/decoding scheme is\r | |
33467 | allowed in a text constant (but invalid sequences are not explicitly\r | |
33468 | rejected) and denotes the corresponding sequence of characters with\r | |
33469 | integer codes ≥ 128 and ≤ 247. This feature enables "UTF-8\r | |
33470 | convenience" (but not comprehensive Unicode support); in particular,\r | |
33471 | it allows one to copy text from a browser and paste it into a string\r | |
33472 | constant in an editor and, furthermore, if the string is printed to a\r | |
33473 | terminal, then will (typically) appear as the original text. The\r | |
33474 | following example uses UTF-8 byte sequences:</simpara>\r | |
33475 | <programlisting language="sml" linenumbering="unnumbered">val s1 : String.string = "\240\159\130\161"\r | |
33476 | val s2 : String.string = "🂡"\r | |
33477 | val _ = print ("s1 --> " ^ s1 ^ "\n")\r | |
33478 | val _ = print ("s2 --> " ^ s2 ^ "\n")\r | |
33479 | val _ = print ("String.size s1 --> " ^ Int.toString (String.size s1) ^ "\n")\r | |
33480 | val _ = print ("String.size s2 --> " ^ Int.toString (String.size s2) ^ "\n")\r | |
33481 | val _ = print ("s1 = s2 --> " ^ Bool.toString (s1 = s2) ^ "\n")</programlisting>\r | |
33482 | <simpara>and, when compiled and executed, will display:</simpara>\r | |
33483 | <screen>s1 --> 🂡\r | |
33484 | s2 --> 🂡\r | |
33485 | String.size s1 --> 4\r | |
33486 | String.size s2 --> 4\r | |
33487 | s1 = s2 --> true</screen>\r | |
33488 | <simpara>Note that the <literal>String.string</literal> type corresponds to any sequence of\r | |
33489 | 8-bit values, including invalid UTF-8 sequences; hence the string\r | |
33490 | constant <literal>"\192"</literal> (a UTF-8 leading byte with no UTF-8 continuation\r | |
33491 | byte) is valid. Similarly, the <literal>Char.char</literal> type corresponds to a\r | |
33492 | single 8-bit value; hence the char constant <literal>#"α"</literal> is not valid, as\r | |
33493 | the 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 | |
33500 | Line Comments: <literal>allowLineComments {false|true}</literal>\r | |
33501 | </simpara>\r | |
33502 | <simpara>Allow line comments beginning with the token <literal>(*)</literal>. The following\r | |
33503 | example 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 | |
33506 | example uses line comments nested within block comments:</simpara>\r | |
33507 | <programlisting language="sml" linenumbering="unnumbered">(*\r | |
33508 | val x = 4 (*) This is a line comment\r | |
33509 | *)\r | |
33510 | \r | |
33511 | (*\r | |
33512 | val 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 | |
33518 | Optional 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 | |
33521 | or <literal>handle</literal> expression, allow a bar to appear before the first\r | |
33522 | function-value binding of a <literal>fun</literal> declaration, and allow a bar to\r | |
33523 | appear before the first constructor binding or description of a\r | |
33524 | <literal>datatype</literal> declaration or specification. The following example uses\r | |
33525 | leading 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 | |
33532 | fun\r | |
33533 | | f NONE = 0\r | |
33534 | | f (SOME t) =\r | |
33535 | (case t of\r | |
33536 | | A => 1\r | |
33537 | | B => 2\r | |
33538 | | C => 3)</programlisting>\r | |
33539 | <simpara>By eliminating the special case of the first element, this feature\r | |
33540 | allows for simpler refactoring (e.g., sorting the lines of the\r | |
33541 | <literal>datatype</literal> declaration’s constructor bindings to put the constructors\r | |
33542 | in alphabetical order).</simpara>\r | |
33543 | </listitem>\r | |
33544 | <listitem>\r | |
33545 | <simpara>\r | |
33546 | <anchor id="SuccessorML_OptSemicolon" xreflabel="[SuccessorML_OptSemicolon]"/>\r | |
33547 | Optional 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 | |
33551 | semicolon 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 | |
33560 | allows for simpler refactoring.</simpara>\r | |
33561 | </listitem>\r | |
33562 | <listitem>\r | |
33563 | <simpara>\r | |
33564 | <anchor id="SuccessorML_OrPats" xreflabel="[SuccessorML_OrPats]"/>\r | |
33565 | Disjunctive (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 | |
33570 | patterns and constraint patterns, much as <literal>orelse</literal> expressions have\r | |
33571 | lower precedence than <literal>andalso</literal> expressions and constraint\r | |
33572 | expressions. Both sub-patterns of a disjunctive pattern must bind the\r | |
33573 | same variables with the same types. The following example uses\r | |
33574 | disjunctive 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 | |
33577 | fun f t =\r | |
33578 | case t of\r | |
33579 | A x | B x | C x => x + 1\r | |
33580 | | D (x, _) | E (_, x) => x * 2</programlisting>\r | |
33581 | </listitem>\r | |
33582 | <listitem>\r | |
33583 | <simpara>\r | |
33584 | <anchor id="SuccessorML_RecordPunExps" xreflabel="[SuccessorML_RecordPunExps]"/>\r | |
33585 | Record 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 | |
33588 | expression 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 | |
33590 | example uses record punning expressions (and also record punning\r | |
33591 | patterns):</simpara>\r | |
33592 | <programlisting language="sml" linenumbering="unnumbered">fun incB r =\r | |
33593 | case r of {a, b, c} => {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} => {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 | |
33604 | The 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 -> 'a u\r | |
33610 | end\r | |
33611 | structure Stream : STREAM =\r | |
33612 | struct\r | |
33613 | datatype 'a u = Nil | Cons of 'a * 'a t\r | |
33614 | withtype 'a t = unit -> '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 -> 'a u)\r | |
33620 | type 'a t = unit -> 'a u\r | |
33621 | end\r | |
33622 | structure Stream : STREAM =\r | |
33623 | struct\r | |
33624 | datatype 'a u = Nil | Cons of 'a * (unit -> 'a u)\r | |
33625 | type 'a t = unit -> '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 | |
33631 | Vector 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 | |
33634 | proxy 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 | |
33639 | Vector 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>, …, <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 | |
33646 | Vector 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>, …, <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 | |
33659 | My research focus is in programming language design and implementation, concurrency,\r | |
33660 | and distributed systems. I am interested in various aspects of MLton, mostly related to (in no particular order): (1) control-flow analysis (2) representation\r | |
33661 | strategies (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 | |
33668 | is 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 | |
33674 | and serving one html page with one gif image. Given that the original\r | |
33675 | code was throughly designed and implemented in a thoughtful manner and\r | |
33676 | I expect it is quite usable modulo a few minor bugs introduced by my\r | |
33677 | porting 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 | |
33719 | empty list of type variables. Second, <link linkend="SXML">SXML</link> variable references\r | |
33720 | always have an empty list of type arguments. Constructors uses can\r | |
33721 | only have a nonempty list of type arguments if the constructor is a\r | |
33722 | primitive.</simpara>\r | |
33723 | <simpara>Although we could rely on the type system to enforce these constraints\r | |
33724 | by parameterizing the <link linkend="XML">XML</link> signature, <link linkend="StephenWeeks">StephenWeeks</link> did so in a\r | |
33725 | previous version of the compiler, and the software engineering gains\r | |
33726 | were 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 | |
33762 | collected 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 <pass></literal> — keep diagnostic info for pass\r | |
33809 | </simpara>\r | |
33810 | </listitem>\r | |
33811 | <listitem>\r | |
33812 | <simpara>\r | |
33813 | <literal>-disable-pass <pass></literal> — skip optimization pass (if normally performed)\r | |
33814 | </simpara>\r | |
33815 | </listitem>\r | |
33816 | <listitem>\r | |
33817 | <simpara>\r | |
33818 | <literal>-enable-pass <pass></literal> — perform optimization pass (if normally skipped)\r | |
33819 | </simpara>\r | |
33820 | </listitem>\r | |
33821 | <listitem>\r | |
33822 | <simpara>\r | |
33823 | <literal>-keep-pass <pass></literal> — keep the results of pass\r | |
33824 | </simpara>\r | |
33825 | </listitem>\r | |
33826 | <listitem>\r | |
33827 | <simpara>\r | |
33828 | <literal>-sxml-passes <passes></literal> — 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 | |
33837 | SML.</simpara>\r | |
33838 | <section id="_general">\r | |
33839 | <title>General</title>\r | |
33840 | <itemizedlist>\r | |
33841 | <listitem>\r | |
33842 | <simpara>\r | |
33843 | A line of code never exceeds 80 columns.\r | |
33844 | </simpara>\r | |
33845 | </listitem>\r | |
33846 | <listitem>\r | |
33847 | <simpara>\r | |
33848 | Only split a syntactic entity across multiple lines if it doesn’t fit on one line within 80 columns.\r | |
33849 | </simpara>\r | |
33850 | </listitem>\r | |
33851 | <listitem>\r | |
33852 | <simpara>\r | |
33853 | Use alphabetical order wherever possible.\r | |
33854 | </simpara>\r | |
33855 | </listitem>\r | |
33856 | <listitem>\r | |
33857 | <simpara>\r | |
33858 | Avoid redundant parentheses.\r | |
33859 | </simpara>\r | |
33860 | </listitem>\r | |
33861 | <listitem>\r | |
33862 | <simpara>\r | |
33863 | When 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 | |
33873 | Variables, record labels and type constructors begin with and use\r | |
33874 | small letters, using capital letters to separate words.\r | |
33875 | </simpara>\r | |
33876 | <programlisting language="sml" linenumbering="unnumbered">cost\r | |
33877 | maxValue</programlisting>\r | |
33878 | </listitem>\r | |
33879 | <listitem>\r | |
33880 | <simpara>\r | |
33881 | Variables that represent collections of objects (lists, arrays,\r | |
33882 | vectors, …) are often suffixed with an <literal>s</literal>.\r | |
33883 | </simpara>\r | |
33884 | <programlisting language="sml" linenumbering="unnumbered">xs\r | |
33885 | employees</programlisting>\r | |
33886 | </listitem>\r | |
33887 | <listitem>\r | |
33888 | <simpara>\r | |
33889 | Constructors, structure identifiers, and functor identifiers begin\r | |
33890 | with a capital letter.\r | |
33891 | </simpara>\r | |
33892 | <programlisting language="sml" linenumbering="unnumbered">Queue\r | |
33893 | LinkedList</programlisting>\r | |
33894 | </listitem>\r | |
33895 | <listitem>\r | |
33896 | <simpara>\r | |
33897 | Signature identifiers are in all capitals, using <literal>_</literal> to separate\r | |
33898 | words.\r | |
33899 | </simpara>\r | |
33900 | <programlisting language="sml" linenumbering="unnumbered">LIST\r | |
33901 | BINARY_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 | |
33910 | Alphabetize record labels. In a record type, there are spaces after\r | |
33911 | colons and commas, but not before colons or commas, or at the\r | |
33912 | delimiters <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 | |
33918 | Only split a record type across multiple lines if it doesn’t fit on\r | |
33919 | one line. If a record type must be split over multiple lines, put one\r | |
33920 | field 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 | |
33928 | In 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 | |
33934 | Only split a tuple type across multiple lines if it doesn’t fit on\r | |
33935 | one line. In a tuple type split over multiple lines, there is one\r | |
33936 | type 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 | |
33942 | apparent.</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 | |
33949 | In an arrow type split over multiple lines, put the arrow at the\r | |
33950 | beginning of its line.\r | |
33951 | </simpara>\r | |
33952 | <programlisting language="sml" linenumbering="unnumbered">int * real\r | |
33953 | -> bool</programlisting>\r | |
33954 | <simpara>It may also be useful to parenthesize to make the grouping more\r | |
33955 | apparent.</simpara>\r | |
33956 | <programlisting language="sml" linenumbering="unnumbered">(int * real\r | |
33957 | -> bool)</programlisting>\r | |
33958 | </listitem>\r | |
33959 | <listitem>\r | |
33960 | <simpara>\r | |
33961 | Avoid redundant parentheses.\r | |
33962 | </simpara>\r | |
33963 | </listitem>\r | |
33964 | <listitem>\r | |
33965 | <simpara>\r | |
33966 | Arrow types associate to the right, so write\r | |
33967 | </simpara>\r | |
33968 | <programlisting language="sml" linenumbering="unnumbered">a -> b -> c</programlisting>\r | |
33969 | <simpara>not</simpara>\r | |
33970 | <programlisting language="sml" linenumbering="unnumbered">a -> (b -> c)</programlisting>\r | |
33971 | </listitem>\r | |
33972 | <listitem>\r | |
33973 | <simpara>\r | |
33974 | Type 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 | |
33982 | Type constructor application binds more tightly than a tuple type,\r | |
33983 | so 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 | |
33991 | Tuple types bind more tightly than arrow types, so write\r | |
33992 | </simpara>\r | |
33993 | <programlisting language="sml" linenumbering="unnumbered">int * bool -> real</programlisting>\r | |
33994 | <simpara>not</simpara>\r | |
33995 | <programlisting language="sml" linenumbering="unnumbered">(int * bool) -> 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 | |
34004 | A core expression or declaration split over multiple lines does not\r | |
34005 | contain any blank lines.\r | |
34006 | </simpara>\r | |
34007 | </listitem>\r | |
34008 | <listitem>\r | |
34009 | <simpara>\r | |
34010 | A record field selector has no space between the <literal>#</literal> and the record\r | |
34011 | label. 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 | |
34019 | A tuple has a space after each comma, but not before, and not at the\r | |
34020 | delimiters <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 | |
34026 | A tuple split over multiple lines has one element per line, and the\r | |
34027 | commas 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 | |
34035 | A list has a space after each comma, but not before, and not at the\r | |
34036 | delimiters <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 | |
34042 | A list split over multiple lines has one element per line, and the\r | |
34043 | commas 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 | |
34051 | A record has spaces before and after <literal>=</literal>, a space after each comma,\r | |
34052 | but not before, and not at the delimiters <literal>{</literal> and <literal>}</literal>. Field names\r | |
34053 | appear 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 | |
34059 | A 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 | |
34065 | A sequence expression split over multiple lines has one expression\r | |
34066 | per line, and the semicolons at the beginning of lines. Lisp and\r | |
34067 | Scheme 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 | |
34073 | expression, which becomes more valuable as the expressions themselves\r | |
34074 | are split across multiple lines.</simpara>\r | |
34075 | </listitem>\r | |
34076 | <listitem>\r | |
34077 | <simpara>\r | |
34078 | An application expression has a space between the function and the\r | |
34079 | argument. There are no parens unless the argument is a tuple (in\r | |
34080 | which case the parens are really part of the tuple, not the\r | |
34081 | application).\r | |
34082 | </simpara>\r | |
34083 | <programlisting language="sml" linenumbering="unnumbered">f a\r | |
34084 | f (a1, a2, a3)</programlisting>\r | |
34085 | </listitem>\r | |
34086 | <listitem>\r | |
34087 | <simpara>\r | |
34088 | Avoid redundant parentheses. Application associates to left, so\r | |
34089 | write\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 | |
34097 | Infix operators have a space before and after the operator.\r | |
34098 | </simpara>\r | |
34099 | <programlisting language="sml" linenumbering="unnumbered">x + y\r | |
34100 | x * y - z</programlisting>\r | |
34101 | </listitem>\r | |
34102 | <listitem>\r | |
34103 | <simpara>\r | |
34104 | Avoid 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 | |
34112 | An <literal>andalso</literal> expression split over multiple lines has the <literal>andalso</literal>\r | |
34113 | at the beginning of subsequent lines.\r | |
34114 | </simpara>\r | |
34115 | <programlisting language="sml" linenumbering="unnumbered">e1\r | |
34116 | andalso e2\r | |
34117 | andalso e3</programlisting>\r | |
34118 | </listitem>\r | |
34119 | <listitem>\r | |
34120 | <simpara>\r | |
34121 | A <literal>case</literal> expression is indented as follows\r | |
34122 | </simpara>\r | |
34123 | <programlisting language="sml" linenumbering="unnumbered">case e1 of\r | |
34124 | p1 => e1\r | |
34125 | | p2 => e2\r | |
34126 | | p3 => e3</programlisting>\r | |
34127 | </listitem>\r | |
34128 | <listitem>\r | |
34129 | <simpara>\r | |
34130 | A <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 | |
34136 | A <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 | |
34142 | A <literal>datatype</literal> split over multiple lines has one constructor per line,\r | |
34143 | with the <literal>|</literal> at the beginning of lines and the constructors beginning\r | |
34144 | 3 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 | |
34153 | A <literal>fun</literal> declaration may start its body on the subsequent line,\r | |
34154 | indented 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 | |
34165 | An <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 | |
34169 | else e3</programlisting>\r | |
34170 | </listitem>\r | |
34171 | <listitem>\r | |
34172 | <simpara>\r | |
34173 | A 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 | |
34177 | else if e3\r | |
34178 | then e4\r | |
34179 | else if e5\r | |
34180 | then e6\r | |
34181 | else e7</programlisting>\r | |
34182 | </listitem>\r | |
34183 | <listitem>\r | |
34184 | <simpara>\r | |
34185 | A <literal>let</literal> expression has the <literal>let</literal>, <literal>in</literal>, and <literal>end</literal> on their own\r | |
34186 | lines, starting in the same column. Declarations and the body are\r | |
34187 | indented 3 spaces.\r | |
34188 | </simpara>\r | |
34189 | <programlisting language="sml" linenumbering="unnumbered">let\r | |
34190 | val x = 13\r | |
34191 | val y = 14\r | |
34192 | in\r | |
34193 | x + y\r | |
34194 | end</programlisting>\r | |
34195 | </listitem>\r | |
34196 | <listitem>\r | |
34197 | <simpara>\r | |
34198 | A <literal>local</literal> declaration has the <literal>local</literal>, <literal>in</literal>, and <literal>end</literal> on their own\r | |
34199 | lines, starting in the same column. Declarations are indented 3\r | |
34200 | spaces.\r | |
34201 | </simpara>\r | |
34202 | <programlisting language="sml" linenumbering="unnumbered">local\r | |
34203 | val x = 13\r | |
34204 | in\r | |
34205 | val y = x\r | |
34206 | end</programlisting>\r | |
34207 | </listitem>\r | |
34208 | <listitem>\r | |
34209 | <simpara>\r | |
34210 | An <literal>orelse</literal> expression split over multiple lines has the <literal>orelse</literal> at\r | |
34211 | the beginning of subsequent lines.\r | |
34212 | </simpara>\r | |
34213 | <programlisting language="sml" linenumbering="unnumbered">e1\r | |
34214 | orelse e2\r | |
34215 | orelse e3</programlisting>\r | |
34216 | </listitem>\r | |
34217 | <listitem>\r | |
34218 | <simpara>\r | |
34219 | A <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 | |
34225 | A <literal>val</literal> declaration can start the expression on the subsequent line,\r | |
34226 | indented 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 | |
34238 | A <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 | |
34245 | indentation to save horizontal space.</simpara>\r | |
34246 | <programlisting language="sml" linenumbering="unnumbered">signature FOO =\r | |
34247 | sig\r | |
34248 | \r | |
34249 | val x: int\r | |
34250 | \r | |
34251 | end</programlisting>\r | |
34252 | <simpara>In this case, there should be a blank line after the <literal>sig</literal> and before\r | |
34253 | the <literal>end</literal>.</simpara>\r | |
34254 | </listitem>\r | |
34255 | <listitem>\r | |
34256 | <simpara>\r | |
34257 | A <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 | |
34261 | before the colon to avoid lexing the colon as part of the operator.</simpara>\r | |
34262 | <programlisting language="sml" linenumbering="unnumbered">val + : t * t -> t</programlisting>\r | |
34263 | </listitem>\r | |
34264 | <listitem>\r | |
34265 | <simpara>\r | |
34266 | Alphabetize 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 | |
34271 | end</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 | |
34280 | A <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 | |
34286 | A <literal>structure</literal> declaration split over multiple lines is indented as\r | |
34287 | follows.\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 | |
34294 | indentation to save horizontal space.</simpara>\r | |
34295 | <programlisting language="sml" linenumbering="unnumbered">structure S =\r | |
34296 | struct\r | |
34297 | \r | |
34298 | val x = 13\r | |
34299 | \r | |
34300 | end</programlisting>\r | |
34301 | <simpara>In this case, there should be a blank line after the <literal>struct</literal> and\r | |
34302 | before the <literal>end</literal>.</simpara>\r | |
34303 | </listitem>\r | |
34304 | <listitem>\r | |
34305 | <simpara>\r | |
34306 | Declarations 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 | |
34317 | end</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 | |
34326 | A <literal>functor</literal> declaration has spaces after each <literal>:</literal> (or <literal>:></literal>) but not\r | |
34327 | before, and a space before and after the <literal>=</literal>. It is indented as\r | |
34328 | follows.\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 | |
34335 | indentation to save horizontal space.</simpara>\r | |
34336 | <programlisting language="sml" linenumbering="unnumbered">functor Foo (S: FOO_ARG): FOO =\r | |
34337 | struct\r | |
34338 | \r | |
34339 | val x = S.x\r | |
34340 | \r | |
34341 | end</programlisting>\r | |
34342 | <simpara>In this case, there should be a blank line after the <literal>struct</literal>\r | |
34343 | and 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> <?asciidoc-br?>\r | |
34355 |  <?asciidoc-br?>\r | |
34356 |  <?asciidoc-br?></simpara>\r | |
34357 | <simpara><?asciidoc-hr?></simpara>\r | |
34358 | <informaltable\r | |
34359 | frame="all"\r | |
34360 | rowsep="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 | |
34383 | to <link linkend="Development">Development</link>\r | |
34384 | </simpara>\r | |
34385 | </listitem>\r | |
34386 | <listitem>\r | |
34387 | <simpara>\r | |
34388 | to <link linkend="Documentation">Documentation</link>\r | |
34389 | </simpara>\r | |
34390 | </listitem>\r | |
34391 | <listitem>\r | |
34392 | <simpara>\r | |
34393 | to <link linkend="Download">Download</link>\r | |
34394 | </simpara>\r | |
34395 | </listitem>\r | |
34396 | </itemizedlist>\r | |
34397 | <simpara> <?asciidoc-br?>\r | |
34398 |  <?asciidoc-br?>\r | |
34399 |  <?asciidoc-br?></simpara>\r | |
34400 | <simpara><?asciidoc-hr?></simpara>\r | |
34401 | <informaltable\r | |
34402 | frame="all"\r | |
34403 | rowsep="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 | |
34426 | Defunctorization and monomorphisation are feasible\r | |
34427 | </simpara>\r | |
34428 | </listitem>\r | |
34429 | <listitem>\r | |
34430 | <simpara>\r | |
34431 | Global control-flow analysis is feasible\r | |
34432 | </simpara>\r | |
34433 | </listitem>\r | |
34434 | <listitem>\r | |
34435 | <simpara>\r | |
34436 | Early closure conversion is feasible\r | |
34437 | </simpara>\r | |
34438 | </listitem>\r | |
34439 | </itemizedlist>\r | |
34440 | <simpara> <?asciidoc-br?>\r | |
34441 |  <?asciidoc-br?>\r | |
34442 |  <?asciidoc-br?></simpara>\r | |
34443 | <simpara><?asciidoc-hr?></simpara>\r | |
34444 | <informaltable\r | |
34445 | frame="all"\r | |
34446 | rowsep="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 | |
34469 | What issues arise when translating from Standard ML into an intermediate language?\r | |
34470 | </simpara>\r | |
34471 | </listitem>\r | |
34472 | </itemizedlist>\r | |
34473 | <simpara> <?asciidoc-br?>\r | |
34474 |  <?asciidoc-br?>\r | |
34475 |  <?asciidoc-br?></simpara>\r | |
34476 | <simpara><?asciidoc-hr?></simpara>\r | |
34477 | <informaltable\r | |
34478 | frame="all"\r | |
34479 | rowsep="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 | |
34502 | How does one represent SML’s higher-order functions?\r | |
34503 | </simpara>\r | |
34504 | </listitem>\r | |
34505 | <listitem>\r | |
34506 | <simpara>\r | |
34507 | MLton’s answer: defunctionalize\r | |
34508 | </simpara>\r | |
34509 | </listitem>\r | |
34510 | </itemizedlist>\r | |
34511 | <simpara> <?asciidoc-br?>\r | |
34512 |  <?asciidoc-br?></simpara>\r | |
34513 | <simpara>See <link linkend="ClosureConvert">ClosureConvert</link>.</simpara>\r | |
34514 | <simpara> <?asciidoc-br?>\r | |
34515 |  <?asciidoc-br?>\r | |
34516 |  <?asciidoc-br?></simpara>\r | |
34517 | <simpara><?asciidoc-hr?></simpara>\r | |
34518 | <informaltable\r | |
34519 | frame="all"\r | |
34520 | rowsep="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 | |
34543 | How does one represent SML’s modules?\r | |
34544 | </simpara>\r | |
34545 | </listitem>\r | |
34546 | <listitem>\r | |
34547 | <simpara>\r | |
34548 | MLton’s answer: defunctorize\r | |
34549 | </simpara>\r | |
34550 | </listitem>\r | |
34551 | </itemizedlist>\r | |
34552 | <simpara> <?asciidoc-br?>\r | |
34553 |  <?asciidoc-br?></simpara>\r | |
34554 | <simpara>See <link linkend="Elaborate">Elaborate</link>.</simpara>\r | |
34555 | <simpara> <?asciidoc-br?>\r | |
34556 |  <?asciidoc-br?>\r | |
34557 |  <?asciidoc-br?></simpara>\r | |
34558 | <simpara><?asciidoc-hr?></simpara>\r | |
34559 | <informaltable\r | |
34560 | frame="all"\r | |
34561 | rowsep="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 | |
34584 | How does one represent SML’s polymorphism?\r | |
34585 | </simpara>\r | |
34586 | </listitem>\r | |
34587 | <listitem>\r | |
34588 | <simpara>\r | |
34589 | MLton’s answer: monomorphise\r | |
34590 | </simpara>\r | |
34591 | </listitem>\r | |
34592 | </itemizedlist>\r | |
34593 | <simpara> <?asciidoc-br?>\r | |
34594 |  <?asciidoc-br?></simpara>\r | |
34595 | <simpara>See <link linkend="Monomorphise">Monomorphise</link>.</simpara>\r | |
34596 | <simpara> <?asciidoc-br?>\r | |
34597 |  <?asciidoc-br?>\r | |
34598 |  <?asciidoc-br?></simpara>\r | |
34599 | <simpara><?asciidoc-hr?></simpara>\r | |
34600 | <informaltable\r | |
34601 | frame="all"\r | |
34602 | rowsep="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’s Approach</title>\r | |
34622 | <itemizedlist>\r | |
34623 | <listitem>\r | |
34624 | <simpara>\r | |
34625 | whole-program optimization using a simply-typed, first-order intermediate language\r | |
34626 | </simpara>\r | |
34627 | </listitem>\r | |
34628 | <listitem>\r | |
34629 | <simpara>\r | |
34630 | ensures programs are not penalized for exploiting abstraction and modularity\r | |
34631 | </simpara>\r | |
34632 | </listitem>\r | |
34633 | </itemizedlist>\r | |
34634 | <simpara> <?asciidoc-br?>\r | |
34635 |  <?asciidoc-br?>\r | |
34636 |  <?asciidoc-br?></simpara>\r | |
34637 | <simpara><?asciidoc-hr?></simpara>\r | |
34638 | <informaltable\r | |
34639 | frame="all"\r | |
34640 | rowsep="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 | |
34663 | Supports full Standard ML language and Basis Library\r | |
34664 | </simpara>\r | |
34665 | </listitem>\r | |
34666 | <listitem>\r | |
34667 | <simpara>\r | |
34668 | Generates standalone executables\r | |
34669 | </simpara>\r | |
34670 | </listitem>\r | |
34671 | <listitem>\r | |
34672 | <simpara>\r | |
34673 | Extensions\r | |
34674 | </simpara>\r | |
34675 | <itemizedlist>\r | |
34676 | <listitem>\r | |
34677 | <simpara>\r | |
34678 | Foreign function interface (SML to C, C to SML)\r | |
34679 | </simpara>\r | |
34680 | </listitem>\r | |
34681 | <listitem>\r | |
34682 | <simpara>\r | |
34683 | ML Basis system for programming in the very large\r | |
34684 | </simpara>\r | |
34685 | </listitem>\r | |
34686 | <listitem>\r | |
34687 | <simpara>\r | |
34688 | Extension libraries\r | |
34689 | </simpara>\r | |
34690 | </listitem>\r | |
34691 | </itemizedlist>\r | |
34692 | </listitem>\r | |
34693 | </itemizedlist>\r | |
34694 | <simpara> <?asciidoc-br?>\r | |
34695 |  <?asciidoc-br?></simpara>\r | |
34696 | <simpara>See <link linkend="Features">Features</link>.</simpara>\r | |
34697 | <simpara> <?asciidoc-br?>\r | |
34698 |  <?asciidoc-br?>\r | |
34699 |  <?asciidoc-br?></simpara>\r | |
34700 | <simpara><?asciidoc-hr?></simpara>\r | |
34701 | <informaltable\r | |
34702 | frame="all"\r | |
34703 | rowsep="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 | |
34724 | frame="all"\r | |
34725 | rowsep="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> <?asciidoc-br?>\r | |
34771 |  <?asciidoc-br?></simpara>\r | |
34772 | <simpara>See <link linkend="History">History</link>.</simpara>\r | |
34773 | <simpara> <?asciidoc-br?>\r | |
34774 |  <?asciidoc-br?>\r | |
34775 |  <?asciidoc-br?></simpara>\r | |
34776 | <simpara><?asciidoc-hr?></simpara>\r | |
34777 | <informaltable\r | |
34778 | frame="all"\r | |
34779 | rowsep="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 | |
34802 | a high-level language makes\r | |
34803 | </simpara>\r | |
34804 | <itemizedlist>\r | |
34805 | <listitem>\r | |
34806 | <simpara>\r | |
34807 | a programmer’s life easier\r | |
34808 | </simpara>\r | |
34809 | </listitem>\r | |
34810 | <listitem>\r | |
34811 | <simpara>\r | |
34812 | a compiler writer’s life harder\r | |
34813 | </simpara>\r | |
34814 | </listitem>\r | |
34815 | </itemizedlist>\r | |
34816 | </listitem>\r | |
34817 | <listitem>\r | |
34818 | <simpara>\r | |
34819 | perceived overheads of features discourage their use\r | |
34820 | </simpara>\r | |
34821 | <itemizedlist>\r | |
34822 | <listitem>\r | |
34823 | <simpara>\r | |
34824 | higher-order functions\r | |
34825 | </simpara>\r | |
34826 | </listitem>\r | |
34827 | <listitem>\r | |
34828 | <simpara>\r | |
34829 | polymorphic datatypes\r | |
34830 | </simpara>\r | |
34831 | </listitem>\r | |
34832 | <listitem>\r | |
34833 | <simpara>\r | |
34834 | separate modules\r | |
34835 | </simpara>\r | |
34836 | </listitem>\r | |
34837 | </itemizedlist>\r | |
34838 | </listitem>\r | |
34839 | </itemizedlist>\r | |
34840 | <simpara> <?asciidoc-br?>\r | |
34841 |  <?asciidoc-br?></simpara>\r | |
34842 | <simpara>Also see <link linkend="StandardML">Standard ML</link>.</simpara>\r | |
34843 | <simpara> <?asciidoc-br?>\r | |
34844 |  <?asciidoc-br?>\r | |
34845 |  <?asciidoc-br?></simpara>\r | |
34846 | <simpara><?asciidoc-hr?></simpara>\r | |
34847 | <informaltable\r | |
34848 | frame="all"\r | |
34849 | rowsep="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 | |
34872 | Bullet\r | |
34873 | </simpara>\r | |
34874 | </listitem>\r | |
34875 | <listitem>\r | |
34876 | <simpara>\r | |
34877 | Bullet\r | |
34878 | </simpara>\r | |
34879 | </listitem>\r | |
34880 | </itemizedlist>\r | |
34881 | <simpara> <?asciidoc-br?>\r | |
34882 |  <?asciidoc-br?>\r | |
34883 |  <?asciidoc-br?></simpara>\r | |
34884 | <simpara><?asciidoc-hr?></simpara>\r | |
34885 | <informaltable\r | |
34886 | frame="all"\r | |
34887 | rowsep="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 | |
34910 | Each of these techniques requires whole-program analysis\r | |
34911 | </simpara>\r | |
34912 | </listitem>\r | |
34913 | <listitem>\r | |
34914 | <simpara>\r | |
34915 | But, additional benefits:\r | |
34916 | </simpara>\r | |
34917 | <itemizedlist>\r | |
34918 | <listitem>\r | |
34919 | <simpara>\r | |
34920 | eliminate (some) variability in programming styles\r | |
34921 | </simpara>\r | |
34922 | </listitem>\r | |
34923 | <listitem>\r | |
34924 | <simpara>\r | |
34925 | specialize representations\r | |
34926 | </simpara>\r | |
34927 | </listitem>\r | |
34928 | <listitem>\r | |
34929 | <simpara>\r | |
34930 | simplifies and improves runtime system\r | |
34931 | </simpara>\r | |
34932 | </listitem>\r | |
34933 | </itemizedlist>\r | |
34934 | </listitem>\r | |
34935 | </itemizedlist>\r | |
34936 | <simpara> <?asciidoc-br?>\r | |
34937 |  <?asciidoc-br?>\r | |
34938 |  <?asciidoc-br?></simpara>\r | |
34939 | <simpara><?asciidoc-hr?></simpara>\r | |
34940 | <informaltable\r | |
34941 | frame="all"\r | |
34942 | rowsep="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 | |
34967 | express things. This page contains miscellaneous tips (ideas not\r | |
34968 | rules) for writing concise SML. The metric that we are interested in\r | |
34969 | here is the number of tokens or words (rather than the number of\r | |
34970 | lines, 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 | |
34974 | definitions in signatures and structures. Actually, it isn’t\r | |
34975 | repetition 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 | |
34978 | end</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 | |
34983 | end\r | |
34984 | \r | |
34985 | structure AnotherExp : EXP = struct\r | |
34986 | datatype exp = Fn of id * exp | App of exp * exp | Var of id\r | |
34987 | end</programlisting>\r | |
34988 | <simpara>the types <literal>AnExp.exp</literal> and <literal>AnotherExp.exp</literal> are two distinct types. If\r | |
34989 | such <link linkend="GenerativeDatatype">generativity</link> isn’t desired or needed, you\r | |
34990 | can 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 | |
34993 | end\r | |
34994 | \r | |
34995 | signature EXP = sig\r | |
34996 | datatype exp = datatype Exp.exp\r | |
34997 | end\r | |
34998 | \r | |
34999 | structure Exp : EXP = struct\r | |
35000 | open Exp\r | |
35001 | end</programlisting>\r | |
35002 | <simpara>Keep in mind that this isn’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 | |
35007 | example,</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 => false\r | |
35013 | | SOME _ => 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’t less verbose than</simpara>\r | |
35019 | <programlisting language="sml" linenumbering="unnumbered">val rec fib =\r | |
35020 | fn 0 => 0\r | |
35021 | | 1 => 1\r | |
35022 | | n => fib (n-1) + fib (n-2)</programlisting>\r | |
35023 | <simpara>It is quite often the case that a curried function primarily examines\r | |
35024 | just one of its arguments. Such functions can be written particularly\r | |
35025 | concisely by making the examined argument last. For example, instead\r | |
35026 | of</simpara>\r | |
35027 | <programlisting language="sml" linenumbering="unnumbered">fun eval (Fn (v, b)) env => ...\r | |
35028 | | eval (App (f, a) env => ...\r | |
35029 | | eval (Var v) env => ...</programlisting>\r | |
35030 | <simpara>consider writing</simpara>\r | |
35031 | <programlisting language="sml" linenumbering="unnumbered">fun eval env =\r | |
35032 | fn Fn (v, b) => ...\r | |
35033 | | App (f, a) => ...\r | |
35034 | | Var v => ...</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 | |
35039 | parentheses. An important rule to know is that prefix function\r | |
35040 | application in SML has higher precedence than any infix operator. For\r | |
35041 | example, 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 | |
35045 | a number of places. In particular, the parentheses in the following\r | |
35046 | examples are practically always superfluous and are best avoided:</simpara>\r | |
35047 | <programlisting language="sml" linenumbering="unnumbered">if (condition) then ... else ...\r | |
35048 | while (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) => ...\r | |
35054 | | (A2, B2) => ...</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 & b of\r | |
35058 | A1 & B1 => ...\r | |
35059 | | A2 & B2 => ...</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 < y then ...\r | |
35065 | else if x = y then ...\r | |
35066 | else ...</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 => ...\r | |
35070 | | EQUAL => ...\r | |
35071 | | GREATER => ...</programlisting>\r | |
35072 | <simpara>For a custom comparison, you would then define an appropriate datatype\r | |
35073 | and a reification function. An alternative to using datatypes is to\r | |
35074 | use dispatch functions</simpara>\r | |
35075 | <programlisting language="sml" linenumbering="unnumbered">comparing (x, y)\r | |
35076 | {lt = fn () => ...,\r | |
35077 | eq = fn () => ...,\r | |
35078 | gt = fn () => ...}</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 => lt\r | |
35083 | | EQUAL => eq\r | |
35084 | | GREATER => gt) ()</programlisting>\r | |
35085 | <simpara>An advantage is that no datatype definition is needed. A disadvantage\r | |
35086 | is that you can’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 | |
35092 | Separation Principle</ulink>. Adhering to the principle, a signature for an\r | |
35093 | imperative stack might contain specifications</simpara>\r | |
35094 | <programlisting language="sml" linenumbering="unnumbered">val isEmpty : 'a t -> bool\r | |
35095 | val pop : 'a t -> '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 | |
35098 | then ... pop stack ...\r | |
35099 | else ...</programlisting>\r | |
35100 | <simpara>or, when the element needs to be named,</simpara>\r | |
35101 | <programlisting language="sml" linenumbering="unnumbered">if isEmpty stack\r | |
35102 | then let val elem = pop stack in ... end\r | |
35103 | else ...</programlisting>\r | |
35104 | <simpara>For efficiency, correctness, and conciseness, it is often better to\r | |
35105 | combine the query and command and return the result as an option:</simpara>\r | |
35106 | <programlisting language="sml" linenumbering="unnumbered">val pop : 'a t -> '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 => ...\r | |
35110 | | SOME elem => ...</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 | |
35141 | convenient to decide on stack layout <emphasis>before</emphasis> any <link linkend="Codegen">codegen</link> takes over.\r | |
35142 | In particular, we compute all the stack frame info for each <link linkend="RSSA">RSSA</link>\r | |
35143 | function, including stack size, <link linkend="GarbageCollection">garbage collector</link>\r | |
35144 | masks 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 | |
35146 | number of (pseudo-)registers of every size. A liveness analysis\r | |
35147 | determines, for each variable, whether or not it is live across a\r | |
35148 | point where the runtime system might take over (for example, any\r | |
35149 | garbage collection point) or a non-tail call to another <link linkend="RSSA">RSSA</link>\r | |
35150 | function. Those that are live go on the stack, while those that\r | |
35151 | aren’t live go into psuedo-registers. From this information, we know\r | |
35152 | all we need to about each stack frame. On the downside, nothing\r | |
35153 | further 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 | |
35205 | an <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’s type checker follows the <link linkend="DefinitionOfStandardML">Definition</link>\r | |
35244 | closely, so you may find differences between MLton and other SML\r | |
35245 | compilers that do not follow the Definition so closely. In\r | |
35246 | particular, SML/NJ has many deviations from the Definition — please\r | |
35247 | see <link linkend="SMLNJDeviations">SMLNJDeviations</link> for those that we are aware of.</simpara>\r | |
35248 | <simpara>In some respects MLton’s type checker is more powerful than other SML\r | |
35249 | compilers, so there are programs that MLton accepts that are rejected\r | |
35250 | by some other SML compilers. These kinds of programs fall into a few\r | |
35251 | simple categories.</simpara>\r | |
35252 | <itemizedlist>\r | |
35253 | <listitem>\r | |
35254 | <simpara>\r | |
35255 | MLton resolves flexible record patterns using a larger context than\r | |
35256 | many other SML compilers. For example, MLton accepts the\r | |
35257 | following.\r | |
35258 | </simpara>\r | |
35259 | <programlisting language="sml" linenumbering="unnumbered">fun f {x, ...} = x\r | |
35260 | val _ = f {x = 13, y = "foo"}</programlisting>\r | |
35261 | </listitem>\r | |
35262 | <listitem>\r | |
35263 | <simpara>\r | |
35264 | MLton uses as large a context as possible to resolve the type of\r | |
35265 | variables constrained by the value restriction to be monotypes. For\r | |
35266 | example, MLton accepts the following.\r | |
35267 | </simpara>\r | |
35268 | <programlisting language="sml" linenumbering="unnumbered">structure S:\r | |
35269 | sig\r | |
35270 | val f: int -> int\r | |
35271 | end =\r | |
35272 | struct\r | |
35273 | val f = (fn x => x) (fn y => 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’s type checker\r | |
35280 | displays type errors differently than other SML compilers. In\r | |
35281 | particular, when two types are different, it is important for the\r | |
35282 | programmer to easily understand why they are different. So, MLton\r | |
35283 | displays only the differences between two types that don’t match,\r | |
35284 | using underscores for the parts that match. For example, if a\r | |
35285 | function expects <literal>real * int</literal> but gets <literal>real * real</literal>, the type error\r | |
35286 | message would look like</simpara>\r | |
35287 | <screen>expects: _ * [int]\r | |
35288 | but got: _ * [real]</screen>\r | |
35289 | <simpara>As another aid to spotting differences, MLton places brackets <literal>[]</literal>\r | |
35290 | around the parts of the types that don’t match. A common situation is\r | |
35291 | when a function receives a different number of arguments than it\r | |
35292 | expects, in which case you might see an error like</simpara>\r | |
35293 | <screen>expects: [int * real]\r | |
35294 | but got: [int * real * string]</screen>\r | |
35295 | <simpara>The brackets make it easy to see that the problem is that the tuples\r | |
35296 | have different numbers of components — not that the components don’t\r | |
35297 | match. Contrast that with a case where a function receives the right\r | |
35298 | number of arguments, but in the wrong order, in which case you might\r | |
35299 | see an error like</simpara>\r | |
35300 | <screen>expects: [int] * [real]\r | |
35301 | but 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 | |
35304 | confusing, or suggestions you may have for improvements to error\r | |
35305 | messages.</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 | |
35310 | deciding what name to use for a type. For example, in the following\r | |
35311 | type-incorrect program</simpara>\r | |
35312 | <programlisting language="sml" linenumbering="unnumbered">type t = int\r | |
35313 | fun f (x: t) = x\r | |
35314 | val _ = 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 | |
35322 | However, MLton uses the shortest/most-recent rule in order to decide\r | |
35323 | what type name to display. This rule means that, at the point of the\r | |
35324 | error, MLton first looks for the shortest name for a type in terms of\r | |
35325 | number of structure identifiers (e.g. <literal>foobar</literal> is shorter than <literal>A.t</literal>).\r | |
35326 | Next, if there are multiple names of the same length, then MLton uses\r | |
35327 | the most recently defined name. It is this tiebreaker that causes\r | |
35328 | MLton 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 | |
35330 | all of the definitions introduced by the structure (since the matching\r | |
35331 | takes place outside the structure and before it is defined). For\r | |
35332 | example, 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 | |
35349 | matched, then the prefix <literal>_str.</literal> is used. For example, in the\r | |
35350 | following 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 | |
35373 | types to types. Type constructors can be <emphasis>nullary</emphasis>, meaning that\r | |
35374 | they take no arguments, as in <literal>char</literal>, <literal>int</literal>, and <literal>real</literal>.\r | |
35375 | Type constructors can be <emphasis>unary</emphasis>, meaning that they take one\r | |
35376 | argument, as in <literal>array</literal>, <literal>list</literal>, and <literal>vector</literal>. A program\r | |
35377 | can define a new type constructor in two ways: a <literal>type</literal> definition\r | |
35378 | or a <literal>datatype</literal> declaration. User-defined type constructors can\r | |
35379 | can take any number of arguments.</simpara>\r | |
35380 | <programlisting language="sml" linenumbering="unnumbered">datatype t = T of int * real (* 0 arguments *)\r | |
35381 | type 'a t = 'a * int (* 1 argument *)\r | |
35382 | datatype ('a, 'b) t = A | B of 'a * 'b (* 2 arguments *)\r | |
35383 | type ('a, 'b, 'c) t = 'a * ('b -> '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 | |
35388 | Type 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 | |
35394 | Unary 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 | |
35400 | Nullary 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 | |
35406 | N-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 | |
35412 | Type 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 | |
35422 | presents a challenge to programmers. The problem is that at first\r | |
35423 | glance there seems to be no practical way to implement something like\r | |
35424 | a function for converting a value of any type to a string or a\r | |
35425 | function for computing a hash value for a value of any type.\r | |
35426 | Fortunately there are ways to implement type-indexed values in SML as\r | |
35427 | discussed 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 | |
35430 | type-indexed values.</simpara>\r | |
35431 | <simpara><emphasis role="strong">NOTE:</emphasis> The technique used in the following example uses an early (and\r | |
35432 | somewhat broken) variation of the basic technique used in an\r | |
35433 | experimental 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 | |
35435 | be found from the MLton repository. The generic programming library\r | |
35436 | also 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 | |
35441 | presentation that matches the syntax of SML as closely as possible.\r | |
35442 | One solution is a type-indexed function that maps a given type to a\r | |
35443 | function that maps any value (of the type) to its textual\r | |
35444 | presentation. A type-indexed function like this can be useful for a\r | |
35445 | variety of purposes. For example, one could use it to show debugging\r | |
35446 | information. We’ll call this function "<literal>show</literal>".</simpara>\r | |
35447 | <simpara>We’ll do a fairly complete implementation of <literal>show</literal>. We do not\r | |
35448 | distinguish infix and nonfix constructors, but that is not an\r | |
35449 | intrinsic property of SML datatypes. We also don’t reconstruct a type\r | |
35450 | name for the value, although it would be particularly useful for\r | |
35451 | functional values. To reconstruct type names, some changes would be\r | |
35452 | needed and the reader is encouraged to consider how to do that. A\r | |
35453 | more realistic implementation would use some pretty printing\r | |
35454 | combinators to compute a layout for the result. This should be a\r | |
35455 | relatively easy change (given a suitable pretty printing library).\r | |
35456 | Cyclic values (through references and arrays) do not have a standard\r | |
35457 | textual presentation and it is impossible to convert arbitrary\r | |
35458 | functional values (within SML) to a meaningful textual presentation.\r | |
35459 | Finally, it would also make sense to show sharing of references and\r | |
35460 | arrays. We’ll leave these improvements to an actual library\r | |
35461 | implementation.</simpara>\r | |
35462 | <simpara>The following code uses the <link linkend="Fixpoints">fixpoint framework</link> and other\r | |
35463 | utilities 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’s consider the design of the <literal>SHOW</literal> signature:</simpara>\r | |
35468 | <programlisting language="sml" linenumbering="unnumbered">infixr -->\r | |
35469 | \r | |
35470 | signature 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 -> 'a -> string\r | |
35478 | \r | |
35479 | (* user-defined types *)\r | |
35480 | val inj : ('a -> 'b) -> 'b t -> 'a t\r | |
35481 | \r | |
35482 | (* tuples and records *)\r | |
35483 | val * : ('a, 'k) p * ('b, 'k) p -> (('a, 'b) product, 'k) p\r | |
35484 | \r | |
35485 | val U : 'a t -> ('a, u) p\r | |
35486 | val L : string -> 'a t -> ('a, l) p\r | |
35487 | \r | |
35488 | val tuple : ('a, u) p -> 'a t\r | |
35489 | val record : ('a, l) p -> 'a t\r | |
35490 | \r | |
35491 | (* datatypes *)\r | |
35492 | val + : 'a s * 'b s -> (('a, 'b) sum) s\r | |
35493 | \r | |
35494 | val C0 : string -> unit s\r | |
35495 | val C1 : string -> 'a t -> 'a s\r | |
35496 | \r | |
35497 | val data : 'a s -> '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 -> ('a * 'a s) option) -> unit\r | |
35504 | \r | |
35505 | (* some built-in type constructors *)\r | |
35506 | val refc : 'a t -> 'a ref t\r | |
35507 | val array : 'a t -> 'a array t\r | |
35508 | val list : 'a t -> 'a list t\r | |
35509 | val vector : 'a t -> 'a vector t\r | |
35510 | val --> : 'a t * 'b t -> ('a -> '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 | |
35520 | end</programlisting>\r | |
35521 | <simpara>While some details are shaped by the specific requirements of <literal>show</literal>,\r | |
35522 | there are a number of (design) patterns that translate to other\r | |
35523 | type-indexed values. The former kind of details are mostly shaped by\r | |
35524 | the syntax of SML values that <literal>show</literal> is designed to produce. To this\r | |
35525 | end, abstract types and phantom types are used to distinguish\r | |
35526 | incomplete record, tuple, and datatype type-indices from each other\r | |
35527 | and from complete type-indices. Also, names of record labels and\r | |
35528 | datatype 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 | |
35532 | arbitrary user-defined datatypes. A number of combinators together\r | |
35533 | conspire to provide the functionality. First of all, to support new\r | |
35534 | user-defined types, a combinator taking a conversion function to a\r | |
35535 | previously supported type is provided:</simpara>\r | |
35536 | <programlisting language="sml" linenumbering="unnumbered">val inj : ('a -> 'b) -> 'b t -> 'a t</programlisting>\r | |
35537 | <simpara>An injection function is sufficient in this case, but in the general\r | |
35538 | case, an embedding with injection and projection functions may be\r | |
35539 | needed.</simpara>\r | |
35540 | <simpara>To support products (tuples and records) a product combinator is\r | |
35541 | provided:</simpara>\r | |
35542 | <programlisting language="sml" linenumbering="unnumbered">val * : ('a, 'k) p * ('b, 'k) p -> (('a, 'b) product, 'k) p</programlisting>\r | |
35543 | <simpara>The second (phantom) type variable <literal>'k</literal> is there to distinguish\r | |
35544 | between labelled and unlabelled products and the type <literal>p</literal>\r | |
35545 | distinguishes 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 -> (('a, 'b) sum) s</programlisting>\r | |
35549 | <simpara>Again, the purpose of the type <literal>s</literal> is to distinguish incomplete sums\r | |
35550 | from complete type-indices of type <literal>t</literal>, which usually isn’t necessary.</simpara>\r | |
35551 | <simpara>Finally, to support recursive datatypes, including sets of mutually\r | |
35552 | recursive 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 | |
35556 | encode 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 | |
35561 | all types can be embedded. SML also allows a program to generate new\r | |
35562 | exception variants at run-time. Thus a mechanism is required to register\r | |
35563 | handlers for particular variants:</simpara>\r | |
35564 | <programlisting language="sml" linenumbering="unnumbered">val exn : exn t\r | |
35565 | val regExn : (exn -> ('a * 'a s) option) -> unit</programlisting>\r | |
35566 | <simpara>The universal <literal>exn</literal> type-index then makes use of the registered\r | |
35567 | handlers. The above particular form of handler, which converts an\r | |
35568 | exception 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 | |
35570 | write handlers. To write a handler, one can conveniently reuse\r | |
35571 | existing type-indices:</simpara>\r | |
35572 | <programlisting language="sml" linenumbering="unnumbered">exception Int of int\r | |
35573 | \r | |
35574 | local\r | |
35575 | open Show\r | |
35576 | in\r | |
35577 | val () = regExn (fn Int v => SOME (v, C1"Int" int)\r | |
35578 | | _ => NONE)\r | |
35579 | end</programlisting>\r | |
35580 | <simpara>Note that a single handler may actually handle an arbitrary number of\r | |
35581 | different 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 | |
35586 | due to their special nature. The most important of these are arrays\r | |
35587 | and references, because cyclic data (ignoring closures) and observable\r | |
35588 | sharing can only be constructed through them.</simpara>\r | |
35589 | <simpara>When arrow types are really supported, unlike in this case, they\r | |
35590 | usually 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 | |
35592 | because of their special syntax. This isn’t usually the case.</simpara>\r | |
35593 | <simpara>The set of base types to support also needs to be considered unless\r | |
35594 | one exports an interface for constructing type-indices for entirely\r | |
35595 | new 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’s look at some examples. For\r | |
35602 | the following examples, we’ll assume a structure binding\r | |
35603 | <literal>Show :> SHOW</literal>. If you want to try the examples immediately, just\r | |
35604 | skip 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 | |
35612 | type-index <literal>list (list char)</literal>, which has the type <literal>char list list\r | |
35613 | Show.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 | |
35618 | interesting to see how user-defined types can be handled. Although\r | |
35619 | the <literal>option</literal> datatype is a standard type, it requires no special\r | |
35620 | support, so we can treat it as a user-defined type. Options can be\r | |
35621 | encoded easily using a sum:</simpara>\r | |
35622 | <programlisting language="sml" linenumbering="unnumbered">fun option t = let\r | |
35623 | open Show\r | |
35624 | in\r | |
35625 | inj (fn NONE => INL ()\r | |
35626 | | SOME v => INR v)\r | |
35627 | (data (C0"NONE" + C1"SOME" t))\r | |
35628 | end\r | |
35629 | \r | |
35630 | val "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 | |
35634 | subexpression of the above example as an exercise. (Use a compiler to\r | |
35635 | check 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 | |
35639 | in\r | |
35640 | inj (fn {a, b, c} => a & b & c)\r | |
35641 | (record (L"a" (option int) *\r | |
35642 | L"b" real *\r | |
35643 | L"c" bool))\r | |
35644 | end\r | |
35645 | \r | |
35646 | val "{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 | |
35650 | types to the general purpose sum and product types.</simpara>\r | |
35651 | <simpara>Of particular interest is whether recursive datatypes and cyclic data\r | |
35652 | can be handled. For example, how does one write a type-index for a\r | |
35653 | recursive 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 | |
35655 | fun arcs (VTX (_, r)) = r</programlisting>\r | |
35656 | <simpara>Using the <literal>Show</literal> combinators, we could first write a new type-index\r | |
35657 | combinator for <literal>graph</literal>:</simpara>\r | |
35658 | <programlisting language="sml" linenumbering="unnumbered">fun graph a = let\r | |
35659 | open Tie Show\r | |
35660 | in\r | |
35661 | fix Y (fn graph_a =>\r | |
35662 | inj (fn VTX (x, y) => x & y)\r | |
35663 | (data (C1"VTX"\r | |
35664 | (tuple (U a *\r | |
35665 | U (refc (list graph_a)))))))\r | |
35666 | end</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 | |
35675 | in\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 | |
35683 | end</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 | |
35694 | val () = let\r | |
35695 | open Show\r | |
35696 | in\r | |
35697 | regExn (fn ExnArray a =>\r | |
35698 | SOME (a, C1"ExnArray" (array exn))\r | |
35699 | | _ => NONE)\r | |
35700 | end\r | |
35701 | \r | |
35702 | val a_cycle = let\r | |
35703 | val a = Array.fromList [Empty]\r | |
35704 | in\r | |
35705 | Array.update (a, 0, ExnArray a) ; a\r | |
35706 | end</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 | |
35715 | exception ExnArray of exn array\r | |
35716 | \r | |
35717 | val () = let\r | |
35718 | open Show\r | |
35719 | in\r | |
35720 | regExn (fn ExnArray a =>\r | |
35721 | SOME (a, C1"ExnArray" array_exn)\r | |
35722 | | _ => NONE)\r | |
35723 | end\r | |
35724 | \r | |
35725 | val a_cycle = let\r | |
35726 | val a = Array.fromList [Empty]\r | |
35727 | in\r | |
35728 | Array.update (a, 0, ExnArray a) ; a\r | |
35729 | end\r | |
35730 | \r | |
35731 | val "[|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 | |
35735 | constructed imperatively through arrays and references (combined with\r | |
35736 | exceptions or recursive datatypes). Before recursing to a reference\r | |
35737 | or an array, one needs to check whether that reference or array has\r | |
35738 | already been seen before. When <literal>ref</literal> or <literal>array</literal> is called with a\r | |
35739 | type-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 "!%&$#+-/:<=>?@\\~`^|*"\r | |
35748 | \r | |
35749 | fun isSymId s = 0 < size s andalso CV.all isSym s\r | |
35750 | \r | |
35751 | fun isAlphaNumId s =\r | |
35752 | 0 < size s\r | |
35753 | andalso C.isAlpha (CV.sub (s, 0))\r | |
35754 | andalso CV.all (fn c => C.isAlphaNum c\r | |
35755 | orelse #"'" = c\r | |
35756 | orelse #"_" = c) s\r | |
35757 | \r | |
35758 | fun isNumLabel s =\r | |
35759 | 0 < size s\r | |
35760 | andalso #"0" <> 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 (#"." <\ op =) s)\r | |
35766 | \r | |
35767 | fun isLabel s = isId s orelse isNumLabel s\r | |
35768 | end\r | |
35769 | end\r | |
35770 | \r | |
35771 | structure Show :> SHOW = struct\r | |
35772 | datatype 'a t = IN of exn list * 'a -> 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) => (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 & b) =>\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 => 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) => l (rs, a)\r | |
35806 | | (rs, INR b) => 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 => x, IN) ?\r | |
35816 | \r | |
35817 | (* exceptions *)\r | |
35818 | local\r | |
35819 | val handlers = ref ([] : (exn -> unit t option) list)\r | |
35820 | in\r | |
35821 | val exn = IN (fn (rs, e) => let\r | |
35822 | fun lp [] =\r | |
35823 | C0(concat ["<exn:",\r | |
35824 | General.exnName e,\r | |
35825 | ">"])\r | |
35826 | | lp (f::fs) =\r | |
35827 | case f e\r | |
35828 | of NONE => lp fs\r | |
35829 | | SOME t => 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) =>\r | |
35837 | IN (fn (rs, ()) =>\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) => let\r | |
35848 | val idx = Int.toString o length\r | |
35849 | fun lp (E (v', c)::rs) =\r | |
35850 | if v' <> 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) =>\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 _) --> (IN _) = IN (const (false, "<fn>"))\r | |
35881 | \r | |
35882 | (* some built-in base types *)\r | |
35883 | local\r | |
35884 | fun mk toS = (fn x => (false, x)) o toS o (fn (_, x) => 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 () => "()"))\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 | |
35896 | end\r | |
35897 | \r | |
35898 | (* Handlers for standard top-level exceptions *)\r | |
35899 | val () = let\r | |
35900 | open Show\r | |
35901 | fun E0 name = SOME ((), C0 name)\r | |
35902 | in\r | |
35903 | regExn (fn Bind => E0"Bind"\r | |
35904 | | Chr => E0"Chr"\r | |
35905 | | Div => E0"Div"\r | |
35906 | | Domain => E0"Domain"\r | |
35907 | | Empty => E0"Empty"\r | |
35908 | | Match => E0"Match"\r | |
35909 | | Option => E0"Option"\r | |
35910 | | Overflow => E0"Overflow"\r | |
35911 | | Size => E0"Size"\r | |
35912 | | Span => E0"Span"\r | |
35913 | | Subscript => E0"Subscript"\r | |
35914 | | _ => NONE)\r | |
35915 | ; regExn (fn Fail s => SOME (s, C1"Fail" string)\r | |
35916 | | _ => NONE)\r | |
35917 | end</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 | |
35940 | bound) at a particular point in the program. A type variable can be\r | |
35941 | either implicitly scoped or explicitly scoped. For example, <literal>'a</literal> is\r | |
35942 | implicitly scoped in</simpara>\r | |
35943 | <programlisting language="sml" linenumbering="unnumbered">val id: 'a -> 'a = fn x => x</programlisting>\r | |
35944 | <simpara>and is implicitly scoped in</simpara>\r | |
35945 | <programlisting language="sml" linenumbering="unnumbered">val id = fn x: 'a => 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 -> 'a = fn x => x</programlisting>\r | |
35948 | <simpara>and is explicitly scoped in</simpara>\r | |
35949 | <programlisting language="sml" linenumbering="unnumbered">val 'a id = fn x: 'a => x</programlisting>\r | |
35950 | <simpara>A type variable can be scoped at a <literal>val</literal> or <literal>fun</literal> declaration. An SML\r | |
35951 | type checker performs scope inference on each top-level declaration to\r | |
35952 | determine the scope of each implicitly scoped type variable. After\r | |
35953 | scope inference, every type variable is scoped at exactly one\r | |
35954 | enclosing <literal>val</literal> or <literal>fun</literal> declaration. Scope inference shows that the\r | |
35955 | first and second example above are equivalent to the third and fourth\r | |
35956 | example, respectively.</simpara>\r | |
35957 | <simpara>Section 4.6 of the <link linkend="DefinitionOfStandardML">Definition</link> specifies\r | |
35958 | precisely the scope of an implicitly scoped type variable. A free\r | |
35959 | occurrence 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 | |
35961 | type 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 | |
35969 | In this example,\r | |
35970 | </simpara>\r | |
35971 | <programlisting language="sml" linenumbering="unnumbered">val id: 'a -> 'a = fn x => x</programlisting>\r | |
35972 | <simpara><literal>'a</literal> is unguarded in <literal>val id</literal> and does not occur unguarded in any\r | |
35973 | containing declaration. Hence, <literal>'a</literal> is scoped at <literal>val id</literal> and the\r | |
35974 | declaration is equivalent to the following.</simpara>\r | |
35975 | <programlisting language="sml" linenumbering="unnumbered">val 'a id: 'a -> 'a = fn x => x</programlisting>\r | |
35976 | </listitem>\r | |
35977 | <listitem>\r | |
35978 | <simpara>\r | |
35979 | In this example,\r | |
35980 | </simpara>\r | |
35981 | <programlisting language="sml" linenumbering="unnumbered"> val f = fn x => 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 | |
35983 | containing declaration. Hence, <literal>'a</literal> is scoped at <literal>val f</literal> and the\r | |
35984 | declaration is equivalent to the following.</simpara>\r | |
35985 | <programlisting language="sml" linenumbering="unnumbered">val 'a f = fn x => let exception E of 'a in E x end</programlisting>\r | |
35986 | </listitem>\r | |
35987 | <listitem>\r | |
35988 | <simpara>\r | |
35989 | In this example (taken from the <link linkend="DefinitionOfStandardML">Definition</link>),\r | |
35990 | </simpara>\r | |
35991 | <programlisting language="sml" linenumbering="unnumbered">val x: int -> int = let val id: 'a -> 'a = fn z => 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 | |
35993 | implicitly scoped at <literal>val id</literal>, and the declaration is equivalent to\r | |
35994 | the following.</simpara>\r | |
35995 | <programlisting language="sml" linenumbering="unnumbered">val x: int -> int = let val 'a id: 'a -> 'a = fn z => z in id id end</programlisting>\r | |
35996 | </listitem>\r | |
35997 | <listitem>\r | |
35998 | <simpara>\r | |
35999 | In this example,\r | |
36000 | </simpara>\r | |
36001 | <programlisting language="sml" linenumbering="unnumbered">val f = (fn x: 'a => x) (fn y => y)</programlisting>\r | |
36002 | <simpara><literal>'a</literal> occurs unguarded in <literal>val f</literal> and does not occur unguarded in any\r | |
36003 | containing declaration. Hence, <literal>'a</literal> is implicitly scoped at <literal>val f</literal>,\r | |
36004 | and the declaration is equivalent to the following.</simpara>\r | |
36005 | <programlisting language="sml" linenumbering="unnumbered">val 'a f = (fn x: 'a => x) (fn y => 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 | |
36010 | In 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 | |
36019 | implicitly 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 | |
36027 | but the <literal>x</literal> occurs outside the scope of the type variable <literal>'a</literal>. MLton\r | |
36028 | reports 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 | |
36037 | constraint, as in <literal>fun f (x: 'a)</literal>, or by explicitly scoping <literal>'a</literal>, as\r | |
36038 | in <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 | |
36045 | which it is already in scope (see the last restriction listed on page\r | |
36046 | 9 of the <link linkend="DefinitionOfStandardML">Definition</link>). For example, the\r | |
36047 | following 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 | |
36059 | following 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 | |
36075 | sentences along the lines of "the characters with numbers 0 to 127\r | |
36076 | coincide 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 | |
36081 | editors of the Basis Library) is that the <literal>WideChar</literal> and <literal>WideString</literal>\r | |
36082 | structures 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 | |
36084 | programmer can not program against the largest supported character\r | |
36085 | size.</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 | |
36090 | sequences in text constants. This feature enables "UTF-8 convenience"\r | |
36091 | (but not comprehensive Unicode support); in particular, it allows one\r | |
36092 | to copy text from a browser and paste it into a string constant in an\r | |
36093 | editor and, furthermore, if the string is printed to a terminal, then\r | |
36094 | will (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 | |
36098 | internal 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 | |
36100 | to 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 | |
36105 | in MLton/SML. In December 2004, there was a discussion that led to\r | |
36106 | some 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 | |
36123 | some 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 | |
36135 | documents.</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 | |
36142 | Here’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 -> ('a -> t) * (t -> '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 | |
36152 | the value from the universal type. A pair <literal>(inject, project)</literal>\r | |
36153 | returned 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 | |
36155 | created by a different function <literal>inject'</literal>, then <literal>project</literal> returns\r | |
36156 | <literal>NONE</literal>.</simpara>\r | |
36157 | <simpara>Here’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 -> 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 => "NONE"\r | |
36165 | | SOME i => Int.toString i\r | |
36166 | val (realIn: real -> 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 => "NONE"\r | |
36171 | | SOME i => Int.toString i\r | |
36172 | val s3 =\r | |
36173 | case realOut (!r) of\r | |
36174 | NONE => "NONE"\r | |
36175 | | SOME x => 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 | |
36181 | different embeddings.</simpara>\r | |
36182 | <simpara>Standard ML does not have explicit support for universal types;\r | |
36183 | however, 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 | |
36187 | accidental feature of their design is that the <literal>exn</literal> type is a\r | |
36188 | universal type. The implementation relies on being able to declare\r | |
36189 | exceptions 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:> 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 => SOME a\r | |
36201 | | _ => 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:> UNIVERSAL_TYPE =\r | |
36210 | struct\r | |
36211 | datatype t = T of {clear: unit -> unit,\r | |
36212 | store: unit -> 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 () => r := NONE,\r | |
36219 | store = fn () => 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 | |
36233 | implementation 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 -> unit</literal>.</simpara>\r | |
36236 | <programlisting language="sml" linenumbering="unnumbered">structure U:> UNIVERSAL_TYPE =\r | |
36237 | struct\r | |
36238 | type t = unit -> 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 () => 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 | |
36250 | longer than necessary, which could cause a space leak. The problem is\r | |
36251 | in <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 | |
36253 | we do not clear <literal>r'</literal> before returning from <literal>project</literal>, then <literal>r'</literal> will\r | |
36254 | keep 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 | |
36272 | the <link linkend="BasisLibrary">Basis Library</link>. In general, MLton complies with\r | |
36273 | the <link linkend="DefinitionOfStandardML">Definition</link> quite closely, typically much\r | |
36274 | more closely than other SML compilers (see, e.g., our list of\r | |
36275 | <link linkend="SMLNJDeviations">SML/NJ’s deviations</link>). In fact, the four deviations\r | |
36276 | listed here are the only known deviations, and we have no immediate\r | |
36277 | plans to fix them. If you find a deviation not listed here, please\r | |
36278 | report a <link linkend="Bug">Bug</link>.</simpara>\r | |
36279 | <simpara>We don’t plan to fix these bugs because the first (parsing nested\r | |
36280 | cases) has historically never been accepted by any SML compiler, the\r | |
36281 | second clearly indicates a problem in the\r | |
36282 | <link linkend="DefinitionOfStandardML">Definition</link>, and the remaining are difficult\r | |
36283 | to resolve in the context of MLton’s implementaton of Standard ML (and\r | |
36284 | unlikely to be problematic in practice).</simpara>\r | |
36285 | <itemizedlist>\r | |
36286 | <listitem>\r | |
36287 | <simpara>\r | |
36288 | MLton does not correctly parse case expressions nested within other\r | |
36289 | matches. 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 => 2\r | |
36294 | | _ => 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 | |
36298 | would be a mistake, since using parentheses is clearer and no SML\r | |
36299 | compiler has ever allowed them. Furthermore, implementing this would\r | |
36300 | require serious yacc grammar rewriting followed by postprocessing.</simpara>\r | |
36301 | </listitem>\r | |
36302 | <listitem>\r | |
36303 | <simpara>\r | |
36304 | MLton does not raise the <literal>Bind</literal> exception at run time when\r | |
36305 | evaluating <literal>val rec</literal> (and <literal>fun</literal>) declarations that redefine\r | |
36306 | identifiers that previously had constructor status. (By default,\r | |
36307 | MLton does warn at compile time about <literal>val rec</literal> (and <literal>fun</literal>)\r | |
36308 | declarations that redefine identifiers that previously had\r | |
36309 | constructors status; see the <literal>valrecConstr</literal> <link linkend="MLBasisAnnotations">ML Basis annotation</link>.) For example, the Definition requires the\r | |
36310 | following program to type check, but also (bizarelly) requires it to\r | |
36311 | raise the <literal>Bind</literal> exception\r | |
36312 | </simpara>\r | |
36313 | <programlisting language="sml" linenumbering="unnumbered">val rec NONE = fn () => ()</programlisting>\r | |
36314 | <simpara>The Definition’s behavior is obviously an error, a mismatch between\r | |
36315 | the static semantics (rule 26) and the dynamic semantics (rule 126).\r | |
36316 | Given the comments on rule 26 in the Definition, it seems clear that\r | |
36317 | the authors meant for <literal>val rec</literal> to allow an identifier’s constructor\r | |
36318 | status to be overridden both statically and dynamically. Hence, MLton\r | |
36319 | and most SML compilers follow rule 26, but do not follow rule 126.</simpara>\r | |
36320 | </listitem>\r | |
36321 | <listitem>\r | |
36322 | <simpara>\r | |
36323 | MLton does not hide the equality aspect of types declared in\r | |
36324 | <literal>abstype</literal> declarations. So, MLton accepts programs like the following,\r | |
36325 | while the Definition rejects them.\r | |
36326 | </simpara>\r | |
36327 | <programlisting language="sml" linenumbering="unnumbered">abstype t = T with end\r | |
36328 | val _ = fn (t1, t2 : t) => t1 = t2\r | |
36329 | \r | |
36330 | abstype t = T with val a = T end\r | |
36331 | val _ = a = a</programlisting>\r | |
36332 | <simpara>One consequence of this choice is that MLton accepts the following\r | |
36333 | program, in accordance with the Definition.</simpara>\r | |
36334 | <programlisting language="sml" linenumbering="unnumbered">abstype t = T with val eq = op = end\r | |
36335 | val _ = fn (t1, t2 : t) => eq (t1, t2)</programlisting>\r | |
36336 | <simpara>Other implementations will typically reject this program, because they\r | |
36337 | make an early choice for the type of <literal>eq</literal> to be <literal>''a * ''a -> bool</literal>\r | |
36338 | instead of <literal>t * t -> bool</literal>. The choice is understandable, since the\r | |
36339 | Definition accepts the following program.</simpara>\r | |
36340 | <programlisting language="sml" linenumbering="unnumbered">abstype t = T with val eq = op = end\r | |
36341 | val _ = eq (1, 2)</programlisting>\r | |
36342 | </listitem>\r | |
36343 | <listitem>\r | |
36344 | <simpara>\r | |
36345 | MLton (re-)type checks each functor definition at every\r | |
36346 | corresponding functor application (the compilation technique of\r | |
36347 | defunctorization). One consequence of this implementation is that\r | |
36348 | MLton accepts the following program, while the Definition rejects\r | |
36349 | it.\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 | |
36353 | end\r | |
36354 | structure A = F (struct type t = int end)\r | |
36355 | structure B = F (struct type t = bool end)\r | |
36356 | val _ = A.f 10\r | |
36357 | val _ = B.f "dude"</programlisting>\r | |
36358 | <simpara>On the other hand, other implementations will typically reject the\r | |
36359 | following 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 | |
36362 | end\r | |
36363 | structure A = F (struct type t = int end)\r | |
36364 | structure B = F (struct type t = bool end)\r | |
36365 | val _ = A.f 10\r | |
36366 | val _ = 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 | |
36375 | with 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 -> array\r | |
36382 | val sub: array * int -> elem\r | |
36383 | val update: array * int * elem -> unit\r | |
36384 | end\r | |
36385 | \r | |
36386 | signature UNSAFE_MONO_VECTOR =\r | |
36387 | sig\r | |
36388 | type elem\r | |
36389 | type vector\r | |
36390 | \r | |
36391 | val sub: vector * int -> elem\r | |
36392 | end\r | |
36393 | \r | |
36394 | signature UNSAFE =\r | |
36395 | sig\r | |
36396 | structure Array:\r | |
36397 | sig\r | |
36398 | val create: int * 'a -> 'a array\r | |
36399 | val sub: 'a array * int -> 'a\r | |
36400 | val update: 'a array * int * 'a -> 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 -> '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 | |
36465 | removes components of tuples that are constants (use unification)\r | |
36466 | </simpara>\r | |
36467 | </listitem>\r | |
36468 | <listitem>\r | |
36469 | <simpara>\r | |
36470 | removes function arguments that are constants\r | |
36471 | </simpara>\r | |
36472 | </listitem>\r | |
36473 | <listitem>\r | |
36474 | <simpara>\r | |
36475 | builds some kind of dependence graph where\r | |
36476 | </simpara>\r | |
36477 | <itemizedlist>\r | |
36478 | <listitem>\r | |
36479 | <simpara>\r | |
36480 | a 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 | |
36485 | a tuple is useful if it contains a useful component\r | |
36486 | </simpara>\r | |
36487 | </listitem>\r | |
36488 | <listitem>\r | |
36489 | <simpara>\r | |
36490 | a 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 | |
36497 | their components must agree (exactly). It is trivial to convert a\r | |
36498 | useful 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 | |
36513 | components — 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 | |
36515 | components aren’t — then the components are converted to type <literal>unit</literal>,\r | |
36516 | and 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 | |
36518 | calling 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 | |
36525 | used MLton. If you use MLton and are not here, please add your\r | |
36526 | project 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 | |
36547 | various <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 | |
36684 | various 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 | |
36699 | infix 8 * / div mod (* +1 from Basis Library *)\r | |
36700 | infix 7 + - ^ (* +1 from Basis Library *)\r | |
36701 | infixr 6 :: @ (* +1 from Basis Library *)\r | |
36702 | infix 5 = <> > >= < <= (* +1 from Basis Library *)\r | |
36703 | infix 4 <\ \>\r | |
36704 | infixr 4 </ />\r | |
36705 | infix 3 o\r | |
36706 | infix 2 >|\r | |
36707 | infixr 2 |<\r | |
36708 | infix 1 := (* -2 from Basis Library *)\r | |
36709 | infix 0 before &\r | |
36710 | \r | |
36711 | (* Some basic combinators *)\r | |
36712 | fun const x _ = x\r | |
36713 | fun cross (f, g) (x, y) = (f x, g y)\r | |
36714 | fun curry f x y = f (x, y)\r | |
36715 | fun fail e _ = raise e\r | |
36716 | fun id x = x\r | |
36717 | \r | |
36718 | (* Product type *)\r | |
36719 | datatype ('a, 'b) product = & of 'a * 'b\r | |
36720 | \r | |
36721 | (* Sum type *)\r | |
36722 | datatype ('a, 'b) sum = INL of 'a | INR of 'b\r | |
36723 | \r | |
36724 | (* Some type shorthands *)\r | |
36725 | type 'a uop = 'a -> 'a\r | |
36726 | type 'a fix = 'a uop -> 'a\r | |
36727 | type 'a thunk = unit -> 'a\r | |
36728 | type 'a effect = 'a -> unit\r | |
36729 | type ('a, 'b) emb = ('a -> 'b) * ('b -> 'a)\r | |
36730 | \r | |
36731 | (* Infixing, sectioning, and application operators *)\r | |
36732 | fun x <\ f = fn y => f (x, y)\r | |
36733 | fun f \> y = f y\r | |
36734 | fun f /> y = fn x => f (x, y)\r | |
36735 | fun x </ f = f x\r | |
36736 | \r | |
36737 | (* Piping operators *)\r | |
36738 | val op>| = op</\r | |
36739 | val op|< = op\></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 | |
36745 | allowed to polymorphically generalize a value declaration. In short,\r | |
36746 | the value restriction says that generalization can only occur if the\r | |
36747 | right-hand side of an expression is syntactically a value. For\r | |
36748 | example, in</simpara>\r | |
36749 | <programlisting language="sml" linenumbering="unnumbered">val f = fn x => x\r | |
36750 | val _ = (f "foo"; f 13)</programlisting>\r | |
36751 | <simpara>the expression <literal>fn x => x</literal> is syntactically a value, so <literal>f</literal> has\r | |
36752 | polymorphic type <literal>'a -> 'a</literal> and both calls to <literal>f</literal> type check. On the\r | |
36753 | other hand, in</simpara>\r | |
36754 | <programlisting language="sml" linenumbering="unnumbered">val f = let in fn x => x end\r | |
36755 | val _ = (f "foo"; f 13)</programlisting>\r | |
36756 | <simpara>the expression <literal>let in fn x => end end</literal> is not syntactically a value\r | |
36757 | and so <literal>f</literal> can either have type <literal>int -> int</literal> or <literal>string -> string</literal>,\r | |
36758 | but not <literal>'a -> '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 | |
36760 | precisely which expressions are syntactic values (it refers to such\r | |
36761 | expressions as <emphasis>non-expansive</emphasis>). An expression is a value if it is of\r | |
36762 | one of the following forms.</simpara>\r | |
36763 | <itemizedlist>\r | |
36764 | <listitem>\r | |
36765 | <simpara>\r | |
36766 | a constant (<literal>13</literal>, <literal>"foo"</literal>, <literal>13.0</literal>, …)\r | |
36767 | </simpara>\r | |
36768 | </listitem>\r | |
36769 | <listitem>\r | |
36770 | <simpara>\r | |
36771 | a variable (<literal>x</literal>, <literal>y</literal>, …)\r | |
36772 | </simpara>\r | |
36773 | </listitem>\r | |
36774 | <listitem>\r | |
36775 | <simpara>\r | |
36776 | a function (<literal>fn x => e</literal>)\r | |
36777 | </simpara>\r | |
36778 | </listitem>\r | |
36779 | <listitem>\r | |
36780 | <simpara>\r | |
36781 | the 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 | |
36786 | a type constrained value (<literal>v: t</literal>)\r | |
36787 | </simpara>\r | |
36788 | </listitem>\r | |
36789 | <listitem>\r | |
36790 | <simpara>\r | |
36791 | a 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 | |
36796 | a 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 | |
36801 | a 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 | |
36808 | values of different types, which would allow a value of one type to be\r | |
36809 | cast to another and hence would break type safety. If the restriction\r | |
36810 | were 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 | |
36812 | val r1: string option ref = r\r | |
36813 | val r2: int option ref = r\r | |
36814 | val () = r1 := SOME "foo"\r | |
36815 | val v: int = valOf (!r2)</programlisting>\r | |
36816 | <simpara>The first line violates the value restriction because <literal>ref NONE</literal> is\r | |
36817 | not a value. All other lines are type correct. By its last line, the\r | |
36818 | program has cast the string <literal>"foo"</literal> to an integer. This breaks type\r | |
36819 | safety, because now we can add a string to an integer with an\r | |
36820 | expression like <literal>v + 13</literal>. We could even be more devious, by adding\r | |
36821 | the following two lines, which allow us to threat the string <literal>"foo"</literal>\r | |
36822 | as a function.</simpara>\r | |
36823 | <programlisting language="sml" linenumbering="unnumbered">val r3: (int -> int) option ref = r\r | |
36824 | val v: int -> int = valOf (!r3)</programlisting>\r | |
36825 | <simpara>Eliminating the explicit <literal>ref</literal> does nothing to fix the problem. For\r | |
36826 | example, we could replace the declaration of <literal>r</literal> with the following.</simpara>\r | |
36827 | <programlisting language="sml" linenumbering="unnumbered">val f: unit -> 'a option ref = fn () => ref NONE\r | |
36828 | val 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 | |
36830 | violates 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 | |
36835 | be accepted.</simpara>\r | |
36836 | <programlisting language="sml" linenumbering="unnumbered">val id: 'a -> 'a = fn x => x\r | |
36837 | val f: 'a -> 'a = id id</programlisting>\r | |
36838 | <simpara>The type constraint on <literal>f</literal> requires <literal>f</literal> to be polymorphic, which is\r | |
36839 | disallowed because <literal>id id</literal> is not a value. MLton reports the\r | |
36840 | following 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] -> ['a]\r | |
36844 | in: val 'a f: ('a -> 'a) = id id</screen>\r | |
36845 | <simpara>MLton indicates the inability to make <literal>f</literal> polymorphic by saying that\r | |
36846 | the type of <literal>f</literal> cannot be generalized (made polymorphic) its\r | |
36847 | declaration is expansive (not a value). MLton doesn’t explicitly\r | |
36848 | mention the value restriction, but that is the reason. If we leave\r | |
36849 | the type constraint off of <literal>f</literal></simpara>\r | |
36850 | <programlisting language="sml" linenumbering="unnumbered">val id: 'a -> 'a = fn x => x\r | |
36851 | val f = id id</programlisting>\r | |
36852 | <simpara>then the program succeeds; however, MLton gives us the following\r | |
36853 | warning.</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: ??? -> ???\r | |
36857 | in: val f = id id</screen>\r | |
36858 | <simpara>This warning indicates that MLton couldn’t polymorphically generalize\r | |
36859 | <literal>f</literal>, nor was there enough context using <literal>f</literal> to determine its type.\r | |
36860 | This in itself is not a type error, but it it is a hint that something\r | |
36861 | is wrong with our program. Using <literal>f</literal> provides enough context to\r | |
36862 | eliminate the warning.</simpara>\r | |
36863 | <programlisting language="sml" linenumbering="unnumbered">val id: 'a -> 'a = fn x => x\r | |
36864 | val f = id id\r | |
36865 | val _ = 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 -> 'a = fn x => x\r | |
36868 | val f = id id\r | |
36869 | val _ = f 13\r | |
36870 | val _ = 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 -> 'a = fn x => x\r | |
36881 | val f = id id</programlisting>\r | |
36882 | <simpara>One might think that the value restriction could be relaxed, and that\r | |
36883 | only types involving <literal>ref</literal> should be disallowed. Unfortunately, the\r | |
36884 | following example shows that even the type <literal>'a -> 'a</literal> can cause\r | |
36885 | problems. If this program were allowed, then we could cast an integer\r | |
36886 | to a string (or any other type).</simpara>\r | |
36887 | <programlisting language="sml" linenumbering="unnumbered">val f: 'a -> 'a =\r | |
36888 | let\r | |
36889 | val r: 'a option ref = ref NONE\r | |
36890 | in\r | |
36891 | fn x =>\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 => x\r | |
36898 | | SOME y => y\r | |
36899 | end\r | |
36900 | end\r | |
36901 | val _ = f 13\r | |
36902 | val _ = 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 | |
36905 | than the value restriction. It encoded information in the type system\r | |
36906 | about when ref cells would be created, and used this to prevent a ref\r | |
36907 | cell from holding multiple types. Although it allowed more programs\r | |
36908 | to be type checked, this approach had significant drawbacks. First,\r | |
36909 | it was significantly more complex, both for implementers and for\r | |
36910 | programmers. Second, it had an unfortunate interaction with the\r | |
36911 | modularity, because information about ref usage was exposed in module\r | |
36912 | signatures. This either prevented the use of references for\r | |
36913 | implementing a signature, or required information that one would like\r | |
36914 | to keep hidden to propagate across modules.</simpara>\r | |
36915 | <simpara>In the early nineties, Andrew Wright studied about 250,000 lines of\r | |
36916 | existing SML code and discovered that it did not make significant use\r | |
36917 | of the extended typing ability, and proposed the value restriction as\r | |
36918 | a simpler alternative (<link linkend="References_Wright95">Wright95</link>). This was adopted in the\r | |
36919 | revised <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 | |
36925 | example type check follows.</simpara>\r | |
36926 | <programlisting language="sml" linenumbering="unnumbered">val id: 'a -> 'a = fn x => x\r | |
36927 | val f: 'a -> 'a = fn z => (id id) z</programlisting>\r | |
36928 | <simpara>This solution means that the computation (in this case <literal>id id</literal>) will\r | |
36929 | be performed each time <literal>f</literal> is applied, instead of just once when <literal>f</literal>\r | |
36930 | is declared. In this case, that is not a problem, but it could be if\r | |
36931 | the declaration of <literal>f</literal> performs substantial computation or creates a\r | |
36932 | shared data structure.</simpara>\r | |
36933 | <simpara>Another technique that sometimes works is to move a monomorphic\r | |
36934 | computation prior to a (would-be) polymorphic declaration so that the\r | |
36935 | expression is a value. Consider the following program, which fails\r | |
36936 | due to the value restriction.</simpara>\r | |
36937 | <programlisting language="sml" linenumbering="unnumbered">datatype 'a t = A of string | B of 'a\r | |
36938 | val 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 | |
36941 | local\r | |
36942 | val s = if true then "yes" else "no"\r | |
36943 | in\r | |
36944 | val x: 'a t = A s\r | |
36945 | end</programlisting>\r | |
36946 | <simpara>The following example (taken from <link linkend="References_Wright95">Wright95</link>) creates a ref\r | |
36947 | cell to count the number of times a function is called.</simpara>\r | |
36948 | <programlisting language="sml" linenumbering="unnumbered">val count: ('a -> 'a) -> ('a -> 'a) * (unit -> int) =\r | |
36949 | fn f =>\r | |
36950 | let\r | |
36951 | val r = ref 0\r | |
36952 | in\r | |
36953 | (fn x => (r := 1 + !r; f x), fn () => !r)\r | |
36954 | end\r | |
36955 | val id: 'a -> 'a = fn x => x\r | |
36956 | val (countId: 'a -> 'a, numCalls) = count id</programlisting>\r | |
36957 | <simpara>The example does not type check, due to the value restriction.\r | |
36958 | However, it is easy to rewrite the program, staging the ref cell\r | |
36959 | creation before the polymorphic code.</simpara>\r | |
36960 | <programlisting language="sml" linenumbering="unnumbered">datatype t = T of int ref\r | |
36961 | val count1: unit -> t = fn () => T (ref 0)\r | |
36962 | val count2: t * ('a -> 'a) -> (unit -> int) * ('a -> 'a) =\r | |
36963 | fn (T r, f) => (fn () => !r, fn x => (r := 1 + !r; f x))\r | |
36964 | val id: 'a -> 'a = fn x => x\r | |
36965 | val t = count1 ()\r | |
36966 | val countId: 'a -> 'a = fn z => #2 (count2 (t, id)) z\r | |
36967 | val 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 | |
36969 | a 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 | |
36986 | provide a variable-arity polymorphic function. For example, suppose\r | |
36987 | one is defining a combinator library, e.g. for parsing or pickling.\r | |
36988 | The signature for such a library might look something like the\r | |
36989 | following.</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 -> ('a1 * 'a2) t\r | |
36999 | val tuple3: 'a1 t * 'a2 t * 'a3 t -> ('a1 * 'a2 * 'a3) t\r | |
37000 | val tuple4: 'a1 t * 'a2 t * 'a3 t * 'a4 t\r | |
37001 | -> ('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 | |
37005 | Traditionally, the only way to take a variable number of arguments in\r | |
37006 | SML is to put the arguments in a list (or vector) and pass that. So,\r | |
37007 | one might define a tuple combinator with the following signature.</simpara>\r | |
37008 | <programlisting language="sml" linenumbering="unnumbered">val tupleN: 'a list -> 'a list t</programlisting>\r | |
37009 | <simpara>The problem with this approach is that as soon as one places values in\r | |
37010 | a list, they must all have the same type. So, programmers often take\r | |
37011 | an alternative approach, and define a family of <literal>tuple<N></literal> functions,\r | |
37012 | as 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 | |
37014 | clutters the signature with a number of functions when there should\r | |
37015 | really only be one. Second, it is <emphasis>closed</emphasis>, in that there are a fixed\r | |
37016 | number of tuple combinators in the interface, and should a client need\r | |
37017 | a combinator for a large tuple, he is out of luck. Third, this\r | |
37018 | approach often requires a lot of duplicate code in the implementation\r | |
37019 | of the combinators.</simpara>\r | |
37020 | <simpara>Fortunately, using <link linkend="Fold01N">Fold01N</link> and <link linkend="ProductType">products</link>, one can\r | |
37021 | provide an interface and implementation that solves all these\r | |
37022 | problems. Here is a simple pickling module that converts values to\r | |
37023 | strings.</simpara>\r | |
37024 | <programlisting language="sml" linenumbering="unnumbered">structure Pickler =\r | |
37025 | struct\r | |
37026 | type 'a t = 'a -> string\r | |
37027 | \r | |
37028 | val unit = fn () => ""\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 -> string list\r | |
37037 | \r | |
37038 | val tuple =\r | |
37039 | fn z =>\r | |
37040 | Fold01N.fold\r | |
37041 | {finish = fn ps => fn x => concat (rev (ps (x, []))),\r | |
37042 | start = fn p => fn (x, l) => p x :: l,\r | |
37043 | zero = unit}\r | |
37044 | z\r | |
37045 | \r | |
37046 | val ` =\r | |
37047 | fn z =>\r | |
37048 | Fold01N.step1\r | |
37049 | {combine = (fn (p, p') => fn (x & x', l) => 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 | |
37054 | val p2: a2 Pickler.t\r | |
37055 | ...\r | |
37056 | val 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 & a2 & ... & an) Pickler.t</programlisting>\r | |
37059 | <simpara>For example, with <literal>Pickler</literal> in scope, one can prove the following\r | |
37060 | equations.</simpara>\r | |
37061 | <programlisting language="sml" linenumbering="unnumbered">"" = tuple $ ()\r | |
37062 | "1" = tuple `int $ 1\r | |
37063 | "1,2.0" = tuple `int `real $ (1 & 2.0)\r | |
37064 | "1,2.0,three" = tuple `int `real `string $ (1 & 2.0 & "three")</programlisting>\r | |
37065 | <simpara>Here is the signature for <literal>Pickler</literal>. It shows why the <literal>accum</literal> type is\r | |
37066 | useful.</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 | |
37083 | structure 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 | |
37089 | datatype</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 | |
37097 | His interests lie in programming techniques that allow complex programs to be expressed\r | |
37098 | clearly 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’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 | |
37111 | A practical tool for documenting libraries. Preferably one that is\r | |
37112 | based on extracting the documentation from source code comments.\r | |
37113 | </simpara>\r | |
37114 | </listitem>\r | |
37115 | <listitem>\r | |
37116 | <simpara>\r | |
37117 | A good IDE. Possibly an enhanced SML mode (<literal>esml-mode</literal>) for Emacs.\r | |
37118 | Google for <ulink url="http://www.google.com/search?&q=SLIME+video">SLIME video</ulink> to\r | |
37119 | get an idea of what he’d like to see. Some specific notes:\r | |
37120 | </simpara>\r | |
37121 | <itemizedlist>\r | |
37122 | <listitem>\r | |
37123 | <simpara>\r | |
37124 | show type at point\r | |
37125 | </simpara>\r | |
37126 | </listitem>\r | |
37127 | <listitem>\r | |
37128 | <simpara>\r | |
37129 | robust, consistent indentation\r | |
37130 | </simpara>\r | |
37131 | </listitem>\r | |
37132 | <listitem>\r | |
37133 | <simpara>\r | |
37134 | show documentation\r | |
37135 | </simpara>\r | |
37136 | </listitem>\r | |
37137 | <listitem>\r | |
37138 | <simpara>\r | |
37139 | jump 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 | |
37147 | Documented 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 | |
37149 | list of libraries, tools, and frameworks Vesa is or has been working\r | |
37150 | on:\r | |
37151 | </simpara>\r | |
37152 | <itemizedlist>\r | |
37153 | <listitem>\r | |
37154 | <simpara>\r | |
37155 | Asynchronous 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 | |
37160 | Extended 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 | |
37165 | Generic 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 | |
37170 | Pretty 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 | |
37175 | Random 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 | |
37180 | RPC (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 | |
37190 | Unit 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 | |
37195 | Use 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 | |
37200 | Windows 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 | |
37212 | to report unused identifiers. This can be useful for catching bugs\r | |
37213 | and for code maintenance (e.g., eliminating dead code). However, the\r | |
37214 | <literal>warnUnused</literal> annotation can sometimes behave in counter-intuitive\r | |
37215 | ways. This page gives some of the anomalies that have been reported.</simpara>\r | |
37216 | <itemizedlist>\r | |
37217 | <listitem>\r | |
37218 | <simpara>\r | |
37219 | Functions whose only uses are recursive uses within their bodies are\r | |
37220 | not warned as unused:\r | |
37221 | </simpara>\r | |
37222 | <programlisting language="sml" linenumbering="unnumbered">local\r | |
37223 | fun foo () = foo () : unit\r | |
37224 | val bar = let fun baz () = baz () : unit in baz end\r | |
37225 | in\r | |
37226 | end</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 | |
37232 | Components of actual functor argument that are necessary to match\r | |
37233 | the functor argument signature but are unused in the body of the\r | |
37234 | functor 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 | |
37238 | end\r | |
37239 | structure 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 | |
37245 | No component of a functor result is warned as unused. In the\r | |
37246 | following, the only uses of <literal>f2</literal> are to match the functor argument\r | |
37247 | signatures 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 | |
37255 | end\r | |
37256 | functor G(structure Y : sig\r | |
37257 | type t\r | |
37258 | val f1 : t -> unit\r | |
37259 | val f2 : t -> unit\r | |
37260 | val z : unit\r | |
37261 | end) = struct\r | |
37262 | fun g (x : Y.t) = Y.f1 x\r | |
37263 | end\r | |
37264 | functor H(structure Y : sig\r | |
37265 | type t\r | |
37266 | val f1 : t -> unit\r | |
37267 | val f2 : t -> unit\r | |
37268 | val z : unit\r | |
37269 | end) = struct\r | |
37270 | fun h (x : Y.t) = Y.f1 x\r | |
37271 | end\r | |
37272 | functor 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 | |
37276 | end\r | |
37277 | structure U = Z()\r | |
37278 | val _ = U.SG.g ()\r | |
37279 | val _ = 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 | |
37292 | Distributed systems (P2P)\r | |
37293 | </simpara>\r | |
37294 | </listitem>\r | |
37295 | <listitem>\r | |
37296 | <simpara>\r | |
37297 | Number 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 | |
37306 | Some better optimization of mathematical expressions\r | |
37307 | </simpara>\r | |
37308 | </listitem>\r | |
37309 | <listitem>\r | |
37310 | <simpara>\r | |
37311 | IPv6 and multicast support\r | |
37312 | </simpara>\r | |
37313 | </listitem>\r | |
37314 | <listitem>\r | |
37315 | <simpara>\r | |
37316 | A complete GUI toolkit like mGTK\r | |
37317 | </simpara>\r | |
37318 | </listitem>\r | |
37319 | <listitem>\r | |
37320 | <simpara>\r | |
37321 | More 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 | |
37330 | optimizations operate over the entire program. This allows the\r | |
37331 | compiler many optimization opportunities that are not available when\r | |
37332 | analyzing modules separately (as with separate compilation).</simpara>\r | |
37333 | <simpara>Most of MLton’s optimizations are whole-program optimizations.\r | |
37334 | Because MLton compiles the whole program at once, it can perform\r | |
37335 | optimization across module boundaries. As a consequence, MLton often\r | |
37336 | reduces or eliminates the run-time penalty that arises with separate\r | |
37337 | compilation of SML features such as functors, modules, polymorphism,\r | |
37338 | and higher-order functions. MLton takes advantage of having the\r | |
37339 | entire program to perform transformations such as: defunctorization,\r | |
37340 | monomorphisation, higher-order control-flow analysis, inlining,\r | |
37341 | unboxing, argument flattening, redundant-argument removal, constant\r | |
37342 | folding, and representation selection. Whole-program compilation is\r | |
37343 | an 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 | |
37349 | have a new feature request, you probably want to query interest on one\r | |
37350 | of the <link linkend="Contact">mailing lists</link> first.</simpara>\r | |
37351 | <simpara>Please be aware of MLton’s policy on\r | |
37352 | <link linkend="LanguageChanges">language changes</link>. Nonetheless, we hope to provide\r | |
37353 | support for some of the "immediate" <link linkend="SuccessorML">SuccessorML</link> proposals in a\r | |
37354 | future 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 | |
37358 | files. For example, generalizing a bit, a ML Basis declaration of the\r | |
37359 | form</simpara>\r | |
37360 | <screen>option "option"</screen>\r | |
37361 | <simpara>could be introduced whose semantics would be the same (as closely as\r | |
37362 | possible) as if the option string were specified on the compiler\r | |
37363 | command line.</simpara>\r | |
37364 | <simpara>The main motivation for this is that a MLton library that would\r | |
37365 | introduce bindings (through <link linkend="ForeignFunctionInterface">FFI</link>) to an\r | |
37366 | external library could be packaged conveniently as a single MLB file.\r | |
37367 | For example, to link with library <literal>foo</literal> the MLB file would simply\r | |
37368 | contain:</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 | |
37395 | generalization is made explicit through type variables annotating\r | |
37396 | <literal>val</literal> and <literal>fun</literal> declarations. Polymorphic instantiation is made\r | |
37397 | explicit by specifying type arguments at variable references. <link linkend="XML">XML</link>\r | |
37398 | patterns can not be nested and can not contain wildcards, constraints,\r | |
37399 | flexible 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 | |
37429 | type 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 | |
37435 | recursively descends the program, checking that the type annotating\r | |
37436 | each node is the same as the type synthesized from the types of the\r | |
37437 | expressions 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 | |
37443 | attached to them. Finally, <link linkend="XML">XML</link> has a simplifier (<link linkend="XMLShrink">XMLShrink</link>),\r | |
37444 | which 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 | |
37448 | constructors. There are many utility functions for constructing and\r | |
37449 | destructing types involving built-in type constructors.</simpara>\r | |
37450 | <simpara>A type scheme binds list of type variables in a type. The only\r | |
37451 | interesting operation on type schemes is the application of a type\r | |
37452 | scheme to a list of types, which performs a simultaneous substitution\r | |
37453 | of the type arguments for the bound type variables of the scheme. For\r | |
37454 | the purposes of type checking, it is necessary to know the type scheme\r | |
37455 | of variables, constructors, and primitives. This is done by\r | |
37456 | associating the scheme with the identifier using its property list.\r | |
37457 | This approach is used instead of the more traditional environment\r | |
37458 | approach 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 | |
37463 | define an auxiliary signature <literal>XML_TREE</literal>, that contains the datatype\r | |
37464 | declarations for the expression trees of <link linkend="XML">XML</link>. This is done solely\r | |
37465 | for the purpose of modularity — it allows the simplifier and type\r | |
37466 | checker to be defined by separate functors (which take a structure\r | |
37467 | matching <literal>XML_TREE</literal>). Then, <literal>Xml</literal> is defined as the signature for a\r | |
37468 | module containing the expression trees, the simplifier, and the type\r | |
37469 | checker.</simpara>\r | |
37470 | <simpara>Both constructors and variables can have type schemes, hence both\r | |
37471 | constructor and variable references specify the instance of the scheme\r | |
37472 | at the point of references. An instance is specified with a vector of\r | |
37473 | types, 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 | |
37475 | constructor with an optional argument variable. Patterns only occur\r | |
37476 | in <literal>case</literal> expressions. To evaluate a case expression, compare the\r | |
37477 | test value sequentially against each pattern. For the first pattern\r | |
37478 | that matches, destruct the value if necessary to bind the pattern\r | |
37479 | variables and evaluate the corresponding expression. If no pattern\r | |
37480 | matches, evaluate the default. All patterns of a case statement are\r | |
37481 | of the same variant of <literal>Pat.t</literal>, although this is not enforced by ML’s\r | |
37482 | type system. The type checker, however, does enforce this. Because\r | |
37483 | tuple patterns are irrefutable, there will only ever be one tuple\r | |
37484 | pattern 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 | |
37486 | declarations. There are no free type variables in <link linkend="XML">XML</link>. All type\r | |
37487 | variables are explicitly bound at either a value or function\r | |
37488 | declaration. At some point in the future, exception declarations may\r | |
37489 | go away, and exceptions may be represented with a single datatype\r | |
37490 | containing 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 | |
37492 | exceptions. There are no records expressions. After type inference,\r | |
37493 | all records (some of which may have originally been tuples in the\r | |
37494 | source) are converted to tuples, because once flexible record patterns\r | |
37495 | have been resolved, tuple labels are superfluous. Tuple components\r | |
37496 | are ordered based on the field ordering relation. <link linkend="XML">XML</link> eta expands\r | |
37497 | primitives and constructors so that there are always fully applied.\r | |
37498 | Hence, the only kind of value of arrow type is a lambda. This\r | |
37499 | property 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 | |
37501 | body expression. Because datatype declarations are not generative,\r | |
37502 | the 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 | |
37534 | not even called at all. Match compilation introduces many such\r | |
37535 | functions. In order to reduce the program size, speed up later\r | |
37536 | phases, and improve the flow analysis, a source to source simplifier\r | |
37537 | is 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 | |
37539 | eliminate unnecessary declarations (see the side constraint in the\r | |
37540 | figure), applications where the function is immediate, and case\r | |
37541 | statements where the test is immediate. Declarations can be\r | |
37542 | eliminated only when the expression is nonexpansive (see Section 4.7\r | |
37543 | of the <link linkend="DefinitionOfStandardML">Definition</link>), which is a syntactic\r | |
37544 | condition that ensures that the expression has no effects\r | |
37545 | (assignments, raises, or nontermination). The reductions on case\r | |
37546 | statements do not show the other irrelevant cases that may exist. The\r | |
37547 | reductions were chosen so that they were strongly normalizing and so\r | |
37548 | that 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 -> 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 => 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 => e1 ...</programlisting>\r | |
37577 | <simpara>reduces to</simpara>\r | |
37578 | <programlisting language="sml" linenumbering="unnumbered">let d in case e of p1 => 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 => 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 | |
37594 | collected 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 <pass></literal> — keep diagnostic info for pass\r | |
37615 | </simpara>\r | |
37616 | </listitem>\r | |
37617 | <listitem>\r | |
37618 | <simpara>\r | |
37619 | <literal>-disable-pass <pass></literal> — skip optimization pass (if normally performed)\r | |
37620 | </simpara>\r | |
37621 | </listitem>\r | |
37622 | <listitem>\r | |
37623 | <simpara>\r | |
37624 | <literal>-enable-pass <pass></literal> — perform optimization pass (if normally skipped)\r | |
37625 | </simpara>\r | |
37626 | </listitem>\r | |
37627 | <listitem>\r | |
37628 | <simpara>\r | |
37629 | <literal>-keep-pass <pass></literal> — keep the results of pass\r | |
37630 | </simpara>\r | |
37631 | </listitem>\r | |
37632 | <listitem>\r | |
37633 | <simpara>\r | |
37634 | <literal>-xml-passes <passes></literal> — 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 | |
37647 | unused 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 | |
37667 | to determine which <literal>datatype</literal> <literal>tycon</literal> args are actually used. Then it\r | |
37668 | does a single pass over the program to determine which polymorphic\r | |
37669 | declaration type variables are used, and rewrites types to eliminate\r | |
37670 | unused 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 | |
37683 | connected subgraphs of the dominator tree. For each zone, at the node\r | |
37684 | that dominates the zone (the "zone root"), it places a tuple\r | |
37685 | collecting all of the live variables at that node. It replaces any\r | |
37686 | variables used in that zone with offsets from the tuple. The goal is\r | |
37687 | to 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 | |
37702 | in 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 <n></literal>\r | |
37708 | </simpara>\r | |
37709 | </listitem>\r | |
37710 | <listitem>\r | |
37711 | <simpara>\r | |
37712 | <literal>-zone-cut-depth <n></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 | |
37717 | function is greater than <literal>n</literal>. The <literal>n</literal> used to cut the dominator tree\r | |
37718 | is 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 | |
37720 | tuples 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 | |
37722 | which has 161,783 blocks and 257,519 variables — the product of those\r | |
37723 | two numbers being about 41 billion. Now, we’re not likely going to\r | |
37724 | need that much space since we use a sparse representation. But even\r | |
37725 | 1/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 |