Sophie

Sophie

distrib > Fedora > 18 > x86_64 > media > updates > by-pkgid > 171636fb720078ab07822dd4a76f1938 > files > 2567

mlton-20130715-4.fc18.x86_64.rpm

<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="generator" content="AsciiDoc 8.6.8">
<title>StandardMLGotchas</title>
<link rel="stylesheet" href="./asciidoc.css" type="text/css">
<link rel="stylesheet" href="./pygments.css" type="text/css">


<script type="text/javascript" src="./asciidoc.js"></script>
<script type="text/javascript">
/*<![CDATA[*/
asciidoc.install(2);
/*]]>*/
</script>
<link rel="stylesheet" href="./mlton.css" type="text/css"/>
</head>
<body class="article">
<div id="banner">
<div id="banner-home">
<a href="./Home">MLton 20130715</a>
</div>
</div>
<div id="header">
<h1>StandardMLGotchas</h1>
<div id="toc">
  <div id="toctitle">Table of Contents</div>
  <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
</div>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph"><p>This page contains brief explanations of some recurring sources of
confusion and problems that SML newbies encounter.</p></div>
<div class="paragraph"><p>Many confusions about the syntax of SML seem to arise from the use of
an interactive REPL (Read-Eval Print Loop) while trying to learn the
basics of the language.  While writing your first SML programs, you
should keep the source code of your programs in a form that is
accepted by an SML compiler as a whole.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_the_span_class_monospaced_and_span_keyword">The <span class="monospaced">and</span> keyword</h2>
<div class="sectionbody">
<div class="paragraph"><p>It is a common mistake to misuse the <span class="monospaced">and</span> keyword or to not know how
to introduce mutually recursive definitions.  The purpose of the <span class="monospaced">and</span>
keyword is to introduce mutually recursive definitions of functions
and datatypes.  For example,</p></div>
<div class="listingblock">
<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>
<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>
<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>
<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>
<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>
<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>
</pre></div></div></div>
<div class="paragraph"><p>and</p></div>
<div class="listingblock">
<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>
<span class="w">           </span><span class="cm">(* | ... *)</span><span class="w"></span>
<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>
<span class="w">           </span><span class="cm">(* | ... *)</span><span class="w"></span>
</pre></div></div></div>
<div class="paragraph"><p>You can also use <span class="monospaced">and</span> as a shorthand in a couple of other places, but
it is not necessary.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_constructed_patterns">Constructed patterns</h2>
<div class="sectionbody">
<div class="paragraph"><p>It is a common mistake to forget to parenthesize constructed patterns
in <span class="monospaced">fun</span> bindings.  Consider the following invalid definition:</p></div>
<div class="listingblock">
<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>
<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>
</pre></div></div></div>
<div class="dlist"><dl>
<dt class="hdlist1">
The pattern `h 
</dt>
<dd>
<p>
t` needs to be parenthesized:
</p>
</dd>
</dl></div>
<div class="listingblock">
<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>
<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>
</pre></div></div></div>
<div class="paragraph"><p>The parentheses are needed, because a <span class="monospaced">fun</span> definition may have
multiple consecutive constructed patterns through currying.</p></div>
<div class="paragraph"><p>The same applies to nonfix constructors.  For example, the parentheses
in</p></div>
<div class="listingblock">
<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>
<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>
</pre></div></div></div>
<div class="paragraph"><p>are required.  However, the outermost constructed pattern in a <span class="monospaced">fn</span> or
<span class="monospaced">case</span> expression need not be parenthesized, because in those cases
there is always just one constructed pattern.  So, both</p></div>
<div class="listingblock">
<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>
<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>
</pre></div></div></div>
<div class="paragraph"><p>and</p></div>
<div class="listingblock">
<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>
<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>
<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>
</pre></div></div></div>
<div class="paragraph"><p>are fine.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_declarations_and_expressions">Declarations and expressions</h2>
<div class="sectionbody">
<div class="paragraph"><p>It is a common mistake to confuse expressions and declarations.
Normally an SML source file should only contain declarations.  The
following are declarations:</p></div>
<div class="listingblock">
<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>
<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>
<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>
<span class="k">infix</span><span class="w"> </span><span class="p">...</span><span class="w"></span>
<span class="k">infixr</span><span class="w"> </span><span class="p">...</span><span class="w"></span>
<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>
<span class="k">nonfix</span><span class="w"> </span><span class="p">...</span><span class="w"></span>
<span class="k">open</span><span class="w"> </span><span class="p">...</span><span class="w"></span>
<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>
<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>
<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>
<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>
</pre></div></div></div>
<div class="paragraph"><p>Note that</p></div>
<div class="listingblock">
<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>
</pre></div></div></div>
<div class="paragraph"><p>isn&#8217;t a declaration.</p></div>
<div class="paragraph"><p>To specify a side-effecting computation in a source file, you can write:</p></div>
<div class="listingblock">
<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>
</pre></div></div></div>
</div>
</div>
<div class="sect1">
<h2 id="_equality_types">Equality types</h2>
<div class="sectionbody">
<div class="paragraph"><p>SML has a fairly intricate built-in notion of equality.  See
<a href="EqualityType">EqualityType</a> and <a href="EqualityTypeVariable">EqualityTypeVariable</a> for a thorough
discussion.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_nested_cases">Nested cases</h2>
<div class="sectionbody">
<div class="paragraph"><p>It is a common mistake to write nested case expressions without the
necessary parentheses.  See <a href="UnresolvedBugs">UnresolvedBugs</a> for a discussion.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_op">(op *)</h2>
<div class="sectionbody">
<div class="paragraph"><p>It used to be a common mistake to parenthesize <span class="monospaced">op *</span> as <span class="monospaced">(op *)</span>.
Before SML&#8217;97, <span class="monospaced">*)</span> was considered a comment terminator in SML and
caused a syntax error.  At the time of writing, <a href="SMLNJ">SML/NJ</a> still
rejects the code.  An extra space may be used for portability:
<span class="monospaced">(op * )</span>. However, parenthesizing <span class="monospaced">op</span> is redundant, even though it
is a widely used convention.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_overloading">Overloading</h2>
<div class="sectionbody">
<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
numeric constants are overloaded for some of the numeric types (<span class="monospaced">int</span>,
<span class="monospaced">real</span>, <span class="monospaced">word</span>).  It is a common surprise that definitions using
overloaded operators such as</p></div>
<div class="listingblock">
<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>
</pre></div></div></div>
<div class="paragraph"><p>are not overloaded themselves.  SML doesn&#8217;t really support
(user-defined) overloading or other forms of ad hoc polymorphism.  In
cases such as the above where the context doesn&#8217;t resolve the
overloading, expressions using overloaded operators or constants get
assigned a default type.  The above definition gets the type</p></div>
<div class="listingblock">
<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>
</pre></div></div></div>
<div class="paragraph"><p>See <a href="Overloading">Overloading</a> and <a href="TypeIndexedValues">TypeIndexedValues</a> for further discussion.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_semicolons">Semicolons</h2>
<div class="sectionbody">
<div class="paragraph"><p>It is a common mistake to use redundant semicolons in SML code.  This
is probably caused by the fact that in an SML REPL, a semicolon (and
enter) is used to signal the REPL that it should evaluate the
preceding chunk of code as a unit.  In SML source files, semicolons
are really needed in only two places.  Namely, in expressions of the
form</p></div>
<div class="listingblock">
<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>
</pre></div></div></div>
<div class="paragraph"><p>and</p></div>
<div class="listingblock">
<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>
</pre></div></div></div>
<div class="paragraph"><p>Note that semicolons act as expression (or declaration) separators
rather than as terminators.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_stale_bindings">Stale bindings</h2>
<div class="sectionbody">
<div class="paragraph"><p></p></div>
</div>
</div>
<div class="sect1">
<h2 id="_unresolved_records">Unresolved records</h2>
<div class="sectionbody">
<div class="paragraph"><p></p></div>
</div>
</div>
<div class="sect1">
<h2 id="_value_restriction">Value restriction</h2>
<div class="sectionbody">
<div class="paragraph"><p>See <a href="ValueRestriction">ValueRestriction</a>.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_type_variable_scope">Type Variable Scope</h2>
<div class="sectionbody">
<div class="paragraph"><p>See <a href="TypeVariableScope">TypeVariableScope</a>.</p></div>
</div>
</div>
</div>
<div id="footnotes"><hr></div>
<div id="footer">
<div id="footer-text">
</div>
<div id="footer-badges">
</div>
</div>
</body>
</html>