Import Upstream version 20180207
[hcoop/debian/mlton.git] / doc / guide / localhost / StandardMLGotchas
CommitLineData
7f918cf1
CE
1<!DOCTYPE html>\r
2<html lang="en">\r
3<head>\r
4<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">\r
5<meta name="generator" content="AsciiDoc 8.6.9">\r
6<title>StandardMLGotchas</title>\r
7<link rel="stylesheet" href="./asciidoc.css" type="text/css">\r
8<link rel="stylesheet" href="./pygments.css" type="text/css">\r
9\r
10\r
11<script type="text/javascript" src="./asciidoc.js"></script>\r
12<script type="text/javascript">\r
13/*<![CDATA[*/\r
14asciidoc.install(2);\r
15/*]]>*/\r
16</script>\r
17<link rel="stylesheet" href="./mlton.css" type="text/css">\r
18</head>\r
19<body class="article">\r
20<div id="banner">\r
21<div id="banner-home">\r
22<a href="./Home">MLton 20180207</a>\r
23</div>\r
24</div>\r
25<div id="header">\r
26<h1>StandardMLGotchas</h1>\r
27<div id="toc">
28 <div id="toctitle">Table of Contents</div>
29 <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
30</div>\r
31</div>\r
32<div id="content">\r
33<div id="preamble">\r
34<div class="sectionbody">\r
35<div class="paragraph"><p>This page contains brief explanations of some recurring sources of\r
36confusion and problems that SML newbies encounter.</p></div>\r
37<div class="paragraph"><p>Many confusions about the syntax of SML seem to arise from the use of\r
38an interactive REPL (Read-Eval Print Loop) while trying to learn the\r
39basics of the language. While writing your first SML programs, you\r
40should keep the source code of your programs in a form that is\r
41accepted by an SML compiler as a whole.</p></div>\r
42</div>\r
43</div>\r
44<div class="sect1">\r
45<h2 id="_the_span_class_monospaced_and_span_keyword">The <span class="monospaced">and</span> keyword</h2>\r
46<div class="sectionbody">\r
47<div class="paragraph"><p>It is a common mistake to misuse the <span class="monospaced">and</span> keyword or to not know how\r
48to introduce mutually recursive definitions. The purpose of the <span class="monospaced">and</span>\r
49keyword is to introduce mutually recursive definitions of functions\r
50and datatypes. For example,</p></div>\r
51<div class="listingblock">\r
52<div class="content"><div class="highlight"><pre><span class="k">fun</span><span class="w"> </span><span class="n">isEven</span><span class="w"> </span><span class="mi">0w0</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">true</span><span class="w"></span>\r
53<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="n">isEven</span><span class="w"> </span><span class="mi">0w1</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">false</span><span class="w"></span>\r
54<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="n">isEven</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">isOdd</span><span class="w"> </span><span class="p">(</span><span class="n">n-</span><span class="mi">0w1</span><span class="p">)</span><span class="w"></span>\r
55<span class="k">and</span><span class="w"> </span><span class="n">isOdd</span><span class="w"> </span><span class="mi">0w0</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">false</span><span class="w"></span>\r
56<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="n">isOdd</span><span class="w"> </span><span class="mi">0w1</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">true</span><span class="w"></span>\r
57<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="n">isOdd</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">isEven</span><span class="w"> </span><span class="p">(</span><span class="n">n-</span><span class="mi">0w1</span><span class="p">)</span><span class="w"></span>\r
58</pre></div></div></div>\r
59<div class="paragraph"><p>and</p></div>\r
60<div class="listingblock">\r
61<div class="content"><div class="highlight"><pre><span class="k">datatype</span><span class="w"> </span><span class="n">decl</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">VAL</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="n">*</span><span class="w"> </span><span class="n">pat</span><span class="w"> </span><span class="n">*</span><span class="w"> </span><span class="n">expr</span><span class="w"></span>\r
62<span class="w"> </span><span class="cm">(* | ... *)</span><span class="w"></span>\r
63<span class="w"> </span><span class="k">and</span><span class="w"> </span><span class="n">expr</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">LET</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="n">decl</span><span class="w"> </span><span class="n">*</span><span class="w"> </span><span class="n">expr</span><span class="w"></span>\r
64<span class="w"> </span><span class="cm">(* | ... *)</span><span class="w"></span>\r
65</pre></div></div></div>\r
66<div class="paragraph"><p>You can also use <span class="monospaced">and</span> as a shorthand in a couple of other places, but\r
67it is not necessary.</p></div>\r
68</div>\r
69</div>\r
70<div class="sect1">\r
71<h2 id="_constructed_patterns">Constructed patterns</h2>\r
72<div class="sectionbody">\r
73<div class="paragraph"><p>It is a common mistake to forget to parenthesize constructed patterns\r
74in <span class="monospaced">fun</span> bindings. Consider the following invalid definition:</p></div>\r
75<div class="listingblock">\r
76<div class="content"><div class="highlight"><pre><span class="k">fun</span><span class="w"> </span><span class="n">length</span><span class="w"> </span><span class="n">nil</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">0</span><span class="w"></span>\r
77<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="n">length</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="n">::</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">+</span><span class="w"> </span><span class="n">length</span><span class="w"> </span><span class="n">t</span><span class="w"></span>\r
78</pre></div></div></div>\r
79<div class="dlist"><dl>\r
80<dt class="hdlist1">\r
81The pattern `h \r
82</dt>\r
83<dd>\r
84<p>\r
85t` needs to be parenthesized:\r
86</p>\r
87</dd>\r
88</dl></div>\r
89<div class="listingblock">\r
90<div class="content"><div class="highlight"><pre><span class="k">fun</span><span class="w"> </span><span class="n">length</span><span class="w"> </span><span class="n">nil</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">0</span><span class="w"></span>\r
91<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="n">length</span><span class="w"> </span><span class="p">(</span><span class="n">h</span><span class="w"> </span><span class="n">::</span><span class="w"> </span><span class="n">t</span><span class="p">)</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">+</span><span class="w"> </span><span class="n">length</span><span class="w"> </span><span class="n">t</span><span class="w"></span>\r
92</pre></div></div></div>\r
93<div class="paragraph"><p>The parentheses are needed, because a <span class="monospaced">fun</span> definition may have\r
94multiple consecutive constructed patterns through currying.</p></div>\r
95<div class="paragraph"><p>The same applies to nonfix constructors. For example, the parentheses\r
96in</p></div>\r
97<div class="listingblock">\r
98<div class="content"><div class="highlight"><pre><span class="k">fun</span><span class="w"> </span><span class="n">valOf</span><span class="w"> </span><span class="n">NONE</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="k">raise</span><span class="w"> </span><span class="n">Option</span><span class="w"></span>\r
99<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="n">valOf</span><span class="w"> </span><span class="p">(</span><span class="n">SOME</span><span class="w"> </span><span class="n">x</span><span class="p">)</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">x</span><span class="w"></span>\r
100</pre></div></div></div>\r
101<div class="paragraph"><p>are required. However, the outermost constructed pattern in a <span class="monospaced">fn</span> or\r
102<span class="monospaced">case</span> expression need not be parenthesized, because in those cases\r
103there is always just one constructed pattern. So, both</p></div>\r
104<div class="listingblock">\r
105<div class="content"><div class="highlight"><pre><span class="k">val</span><span class="w"> </span><span class="n">valOf</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">NONE</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="k">raise</span><span class="w"> </span><span class="n">Option</span><span class="w"></span>\r
106<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="n">SOME</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="n">x</span><span class="w"></span>\r
107</pre></div></div></div>\r
108<div class="paragraph"><p>and</p></div>\r
109<div class="listingblock">\r
110<div class="content"><div class="highlight"><pre><span class="k">fun</span><span class="w"> </span><span class="n">valOf</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">of</span><span class="w"></span>\r
111<span class="w"> </span><span class="n">NONE</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="k">raise</span><span class="w"> </span><span class="n">Option</span><span class="w"></span>\r
112<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="n">SOME</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="n">x</span><span class="w"></span>\r
113</pre></div></div></div>\r
114<div class="paragraph"><p>are fine.</p></div>\r
115</div>\r
116</div>\r
117<div class="sect1">\r
118<h2 id="_declarations_and_expressions">Declarations and expressions</h2>\r
119<div class="sectionbody">\r
120<div class="paragraph"><p>It is a common mistake to confuse expressions and declarations.\r
121Normally an SML source file should only contain declarations. The\r
122following are declarations:</p></div>\r
123<div class="listingblock">\r
124<div class="content"><div class="highlight"><pre><span class="k">datatype</span><span class="w"> </span><span class="n">dt</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">...</span><span class="w"></span>\r
125<span class="k">fun</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="p">...</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">...</span><span class="w"></span>\r
126<span class="k">functor</span><span class="w"> </span><span class="n">Fn</span><span class="w"> </span><span class="p">(...)</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">...</span><span class="w"></span>\r
127<span class="k">infix</span><span class="w"> </span><span class="p">...</span><span class="w"></span>\r
128<span class="k">infixr</span><span class="w"> </span><span class="p">...</span><span class="w"></span>\r
129<span class="k">local</span><span class="w"> </span><span class="p">...</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="p">...</span><span class="w"> </span><span class="k">end</span><span class="w"></span>\r
130<span class="k">nonfix</span><span class="w"> </span><span class="p">...</span><span class="w"></span>\r
131<span class="k">open</span><span class="w"> </span><span class="p">...</span><span class="w"></span>\r
132<span class="k">signature</span><span class="w"> </span><span class="n">SIG</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">...</span><span class="w"></span>\r
133<span class="k">structure</span><span class="w"> </span><span class="n">Struct</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">...</span><span class="w"></span>\r
134<span class="k">type</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">...</span><span class="w"></span>\r
135<span class="k">val</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">...</span><span class="w"></span>\r
136</pre></div></div></div>\r
137<div class="paragraph"><p>Note that</p></div>\r
138<div class="listingblock">\r
139<div class="content"><div class="highlight"><pre><span class="k">let</span><span class="w"> </span><span class="p">...</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="p">...</span><span class="w"> </span><span class="k">end</span><span class="w"></span>\r
140</pre></div></div></div>\r
141<div class="paragraph"><p>isn&#8217;t a declaration.</p></div>\r
142<div class="paragraph"><p>To specify a side-effecting computation in a source file, you can write:</p></div>\r
143<div class="listingblock">\r
144<div class="content"><div class="highlight"><pre><span class="k">val</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">...</span><span class="w"></span>\r
145</pre></div></div></div>\r
146</div>\r
147</div>\r
148<div class="sect1">\r
149<h2 id="_equality_types">Equality types</h2>\r
150<div class="sectionbody">\r
151<div class="paragraph"><p>SML has a fairly intricate built-in notion of equality. See\r
152<a href="EqualityType">EqualityType</a> and <a href="EqualityTypeVariable">EqualityTypeVariable</a> for a thorough\r
153discussion.</p></div>\r
154</div>\r
155</div>\r
156<div class="sect1">\r
157<h2 id="_nested_cases">Nested cases</h2>\r
158<div class="sectionbody">\r
159<div class="paragraph"><p>It is a common mistake to write nested case expressions without the\r
160necessary parentheses. See <a href="UnresolvedBugs">UnresolvedBugs</a> for a discussion.</p></div>\r
161</div>\r
162</div>\r
163<div class="sect1">\r
164<h2 id="_op">(op *)</h2>\r
165<div class="sectionbody">\r
166<div class="paragraph"><p>It used to be a common mistake to parenthesize <span class="monospaced">op *</span> as <span class="monospaced">(op *)</span>.\r
167Before SML&#8217;97, <span class="monospaced">*)</span> was considered a comment terminator in SML and\r
168caused a syntax error. At the time of writing, <a href="SMLNJ">SML/NJ</a> still\r
169rejects the code. An extra space may be used for portability:\r
170<span class="monospaced">(op * )</span>. However, parenthesizing <span class="monospaced">op</span> is redundant, even though it\r
171is a widely used convention.</p></div>\r
172</div>\r
173</div>\r
174<div class="sect1">\r
175<h2 id="_overloading">Overloading</h2>\r
176<div class="sectionbody">\r
177<div class="paragraph"><p>A number of standard operators (<span class="monospaced">+</span>, <span class="monospaced">-</span>, <span class="monospaced">~</span>, <span class="monospaced">*</span>, <span class="monospaced">&lt;</span>, <span class="monospaced">&gt;</span>, &#8230;) and\r
178numeric constants are overloaded for some of the numeric types (<span class="monospaced">int</span>,\r
179<span class="monospaced">real</span>, <span class="monospaced">word</span>). It is a common surprise that definitions using\r
180overloaded operators such as</p></div>\r
181<div class="listingblock">\r
182<div class="content"><div class="highlight"><pre><span class="k">fun</span><span class="w"> </span><span class="n">min</span><span class="w"> </span><span class="p">(</span><span class="n">x</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="p">)</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">&lt;</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">then</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="n">x</span><span class="w"></span>\r
183</pre></div></div></div>\r
184<div class="paragraph"><p>are not overloaded themselves. SML doesn&#8217;t really support\r
185(user-defined) overloading or other forms of ad hoc polymorphism. In\r
186cases such as the above where the context doesn&#8217;t resolve the\r
187overloading, expressions using overloaded operators or constants get\r
188assigned a default type. The above definition gets the type</p></div>\r
189<div class="listingblock">\r
190<div class="content"><div class="highlight"><pre><span class="k">val</span><span class="w"> </span><span class="n">min</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="n">int</span><span class="w"> </span><span class="n">*</span><span class="w"> </span><span class="n">int</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">int</span><span class="w"></span>\r
191</pre></div></div></div>\r
192<div class="paragraph"><p>See <a href="Overloading">Overloading</a> and <a href="TypeIndexedValues">TypeIndexedValues</a> for further discussion.</p></div>\r
193</div>\r
194</div>\r
195<div class="sect1">\r
196<h2 id="_semicolons">Semicolons</h2>\r
197<div class="sectionbody">\r
198<div class="paragraph"><p>It is a common mistake to use redundant semicolons in SML code. This\r
199is probably caused by the fact that in an SML REPL, a semicolon (and\r
200enter) is used to signal the REPL that it should evaluate the\r
201preceding chunk of code as a unit. In SML source files, semicolons\r
202are really needed in only two places. Namely, in expressions of the\r
203form</p></div>\r
204<div class="listingblock">\r
205<div class="content"><div class="highlight"><pre><span class="p">(</span><span class="n">exp</span><span class="w"> </span><span class="p">;</span><span class="w"> </span><span class="p">...</span><span class="w"> </span><span class="p">;</span><span class="w"> </span><span class="n">exp</span><span class="p">)</span><span class="w"></span>\r
206</pre></div></div></div>\r
207<div class="paragraph"><p>and</p></div>\r
208<div class="listingblock">\r
209<div class="content"><div class="highlight"><pre><span class="k">let</span><span class="w"> </span><span class="p">...</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">exp</span><span class="w"> </span><span class="p">;</span><span class="w"> </span><span class="p">...</span><span class="w"> </span><span class="p">;</span><span class="w"> </span><span class="n">exp</span><span class="w"> </span><span class="k">end</span><span class="w"></span>\r
210</pre></div></div></div>\r
211<div class="paragraph"><p>Note that semicolons act as expression (or declaration) separators\r
212rather than as terminators.</p></div>\r
213</div>\r
214</div>\r
215<div class="sect1">\r
216<h2 id="_stale_bindings">Stale bindings</h2>\r
217<div class="sectionbody">\r
218<div class="paragraph"><p></p></div>\r
219</div>\r
220</div>\r
221<div class="sect1">\r
222<h2 id="_unresolved_records">Unresolved records</h2>\r
223<div class="sectionbody">\r
224<div class="paragraph"><p></p></div>\r
225</div>\r
226</div>\r
227<div class="sect1">\r
228<h2 id="_value_restriction">Value restriction</h2>\r
229<div class="sectionbody">\r
230<div class="paragraph"><p>See <a href="ValueRestriction">ValueRestriction</a>.</p></div>\r
231</div>\r
232</div>\r
233<div class="sect1">\r
234<h2 id="_type_variable_scope">Type Variable Scope</h2>\r
235<div class="sectionbody">\r
236<div class="paragraph"><p>See <a href="TypeVariableScope">TypeVariableScope</a>.</p></div>\r
237</div>\r
238</div>\r
239</div>\r
240<div id="footnotes"><hr></div>\r
241<div id="footer">\r
242<div id="footer-text">\r
243</div>\r
244<div id="footer-badges">\r
245</div>\r
246</div>\r
247</body>\r
248</html>\r