4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5 <meta name="generator" content="AsciiDoc 8.6.9">
6 <title>StandardMLGotchas</title>
7 <link rel="stylesheet" href="./asciidoc.css" type="text/css">
8 <link rel="stylesheet" href="./pygments.css" type="text/css">
11 <script type="text/javascript" src="./asciidoc.js"></script>
12 <script type="text/javascript">
17 <link rel="stylesheet" href="./mlton.css" type="text/css">
19 <body class="article">
21 <div id="banner-home">
22 <a href="./Home">MLton 20180207</a>
26 <h1>StandardMLGotchas</h1>
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>
34 <div class="sectionbody">
35 <div class="paragraph"><p>This page contains brief explanations of some recurring sources of
36 confusion and problems that SML newbies encounter.</p></div>
37 <div class="paragraph"><p>Many confusions about the syntax of SML seem to arise from the use of
38 an interactive REPL (Read-Eval Print Loop) while trying to learn the
39 basics of the language. While writing your first SML programs, you
40 should keep the source code of your programs in a form that is
41 accepted by an SML compiler as a whole.</p></div>
45 <h2 id="_the_span_class_monospaced_and_span_keyword">The <span class="monospaced">and</span> keyword</h2>
46 <div class="sectionbody">
47 <div class="paragraph"><p>It is a common mistake to misuse the <span class="monospaced">and</span> keyword or to not know how
48 to introduce mutually recursive definitions. The purpose of the <span class="monospaced">and</span>
49 keyword is to introduce mutually recursive definitions of functions
50 and datatypes. For example,</p></div>
51 <div class="listingblock">
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>
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>
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>
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>
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>
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>
58 </pre></div></div></div>
59 <div class="paragraph"><p>and</p></div>
60 <div class="listingblock">
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>
62 <span class="w"> </span><span class="cm">(* | ... *)</span><span class="w"></span>
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>
64 <span class="w"> </span><span class="cm">(* | ... *)</span><span class="w"></span>
65 </pre></div></div></div>
66 <div class="paragraph"><p>You can also use <span class="monospaced">and</span> as a shorthand in a couple of other places, but
67 it is not necessary.</p></div>
71 <h2 id="_constructed_patterns">Constructed patterns</h2>
72 <div class="sectionbody">
73 <div class="paragraph"><p>It is a common mistake to forget to parenthesize constructed patterns
74 in <span class="monospaced">fun</span> bindings. Consider the following invalid definition:</p></div>
75 <div class="listingblock">
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>
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>
78 </pre></div></div></div>
79 <div class="dlist"><dl>
85 t` needs to be parenthesized:
89 <div class="listingblock">
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>
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>
92 </pre></div></div></div>
93 <div class="paragraph"><p>The parentheses are needed, because a <span class="monospaced">fun</span> definition may have
94 multiple consecutive constructed patterns through currying.</p></div>
95 <div class="paragraph"><p>The same applies to nonfix constructors. For example, the parentheses
97 <div class="listingblock">
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>
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>
100 </pre></div></div></div>
101 <div class="paragraph"><p>are required. However, the outermost constructed pattern in a <span class="monospaced">fn</span> or
102 <span class="monospaced">case</span> expression need not be parenthesized, because in those cases
103 there is always just one constructed pattern. So, both</p></div>
104 <div class="listingblock">
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">=></span><span class="w"> </span><span class="k">raise</span><span class="w"> </span><span class="n">Option</span><span class="w"></span>
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">=></span><span class="w"> </span><span class="n">x</span><span class="w"></span>
107 </pre></div></div></div>
108 <div class="paragraph"><p>and</p></div>
109 <div class="listingblock">
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>
111 <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>
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">=></span><span class="w"> </span><span class="n">x</span><span class="w"></span>
113 </pre></div></div></div>
114 <div class="paragraph"><p>are fine.</p></div>
118 <h2 id="_declarations_and_expressions">Declarations and expressions</h2>
119 <div class="sectionbody">
120 <div class="paragraph"><p>It is a common mistake to confuse expressions and declarations.
121 Normally an SML source file should only contain declarations. The
122 following are declarations:</p></div>
123 <div class="listingblock">
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>
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>
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>
127 <span class="k">infix</span><span class="w"> </span><span class="p">...</span><span class="w"></span>
128 <span class="k">infixr</span><span class="w"> </span><span class="p">...</span><span class="w"></span>
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>
130 <span class="k">nonfix</span><span class="w"> </span><span class="p">...</span><span class="w"></span>
131 <span class="k">open</span><span class="w"> </span><span class="p">...</span><span class="w"></span>
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>
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>
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>
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>
136 </pre></div></div></div>
137 <div class="paragraph"><p>Note that</p></div>
138 <div class="listingblock">
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>
140 </pre></div></div></div>
141 <div class="paragraph"><p>isn’t a declaration.</p></div>
142 <div class="paragraph"><p>To specify a side-effecting computation in a source file, you can write:</p></div>
143 <div class="listingblock">
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>
145 </pre></div></div></div>
149 <h2 id="_equality_types">Equality types</h2>
150 <div class="sectionbody">
151 <div class="paragraph"><p>SML has a fairly intricate built-in notion of equality. See
152 <a href="EqualityType">EqualityType</a> and <a href="EqualityTypeVariable">EqualityTypeVariable</a> for a thorough
153 discussion.</p></div>
157 <h2 id="_nested_cases">Nested cases</h2>
158 <div class="sectionbody">
159 <div class="paragraph"><p>It is a common mistake to write nested case expressions without the
160 necessary parentheses. See <a href="UnresolvedBugs">UnresolvedBugs</a> for a discussion.</p></div>
164 <h2 id="_op">(op *)</h2>
165 <div class="sectionbody">
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>.
167 Before SML’97, <span class="monospaced">*)</span> was considered a comment terminator in SML and
168 caused a syntax error. At the time of writing, <a href="SMLNJ">SML/NJ</a> still
169 rejects the code. An extra space may be used for portability:
170 <span class="monospaced">(op * )</span>. However, parenthesizing <span class="monospaced">op</span> is redundant, even though it
171 is a widely used convention.</p></div>
175 <h2 id="_overloading">Overloading</h2>
176 <div class="sectionbody">
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"><</span>, <span class="monospaced">></span>, …) and
178 numeric constants are overloaded for some of the numeric types (<span class="monospaced">int</span>,
179 <span class="monospaced">real</span>, <span class="monospaced">word</span>). It is a common surprise that definitions using
180 overloaded operators such as</p></div>
181 <div class="listingblock">
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"><</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>
183 </pre></div></div></div>
184 <div class="paragraph"><p>are not overloaded themselves. SML doesn’t really support
185 (user-defined) overloading or other forms of ad hoc polymorphism. In
186 cases such as the above where the context doesn’t resolve the
187 overloading, expressions using overloaded operators or constants get
188 assigned a default type. The above definition gets the type</p></div>
189 <div class="listingblock">
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">-></span><span class="w"> </span><span class="n">int</span><span class="w"></span>
191 </pre></div></div></div>
192 <div class="paragraph"><p>See <a href="Overloading">Overloading</a> and <a href="TypeIndexedValues">TypeIndexedValues</a> for further discussion.</p></div>
196 <h2 id="_semicolons">Semicolons</h2>
197 <div class="sectionbody">
198 <div class="paragraph"><p>It is a common mistake to use redundant semicolons in SML code. This
199 is probably caused by the fact that in an SML REPL, a semicolon (and
200 enter) is used to signal the REPL that it should evaluate the
201 preceding chunk of code as a unit. In SML source files, semicolons
202 are really needed in only two places. Namely, in expressions of the
204 <div class="listingblock">
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>
206 </pre></div></div></div>
207 <div class="paragraph"><p>and</p></div>
208 <div class="listingblock">
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>
210 </pre></div></div></div>
211 <div class="paragraph"><p>Note that semicolons act as expression (or declaration) separators
212 rather than as terminators.</p></div>
216 <h2 id="_stale_bindings">Stale bindings</h2>
217 <div class="sectionbody">
218 <div class="paragraph"><p></p></div>
222 <h2 id="_unresolved_records">Unresolved records</h2>
223 <div class="sectionbody">
224 <div class="paragraph"><p></p></div>
228 <h2 id="_value_restriction">Value restriction</h2>
229 <div class="sectionbody">
230 <div class="paragraph"><p>See <a href="ValueRestriction">ValueRestriction</a>.</p></div>
234 <h2 id="_type_variable_scope">Type Variable Scope</h2>
235 <div class="sectionbody">
236 <div class="paragraph"><p>See <a href="TypeVariableScope">TypeVariableScope</a>.</p></div>
240 <div id="footnotes"><hr></div>
242 <div id="footer-text">
244 <div id="footer-badges">