<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 2.0.23">
<title>SMLNJDeviations</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
<link rel="stylesheet" href="./asciidoctor.css">
<link rel="stylesheet" href="./rouge-github.css">
<link rel="stylesheet" href="./mlton.css">

</head>
<body class="article">
<div id="mlton-header">
<div id="mlton-header-text">
<h2>
<a href="./Home">
MLton
20241230
</a>
</h2>
</div>
</div>
<div id="header">
<h1>SMLNJDeviations</h1>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Here are some deviations of <a href="SMLNJ">SML/NJ</a> from
<a href="DefinitionOfStandardML">The Definition of Standard ML (Revised)</a>.
Some of these are documented in the
<a href="http://www.smlnj.org/doc/Conversion/index.html">SML '97 Conversion Guide</a>.
Since MLton does not deviate from the Definition, you should look here
if you are having trouble porting a program from MLton to SML/NJ or
vice versa.  If you discover other deviations of SML/NJ that aren&#8217;t
listed here, please send mail to
<a href="mailto:MLton-devel@mlton.org"><code>MLton-devel@mlton.org</code></a>.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>SML/NJ allows spaces in long identifiers, as in <code>S . x</code>.  Section
2.5 of the Definition implies that <code>S . x</code> should be treated as three
separate lexical items.</p>
</li>
<li>
<p>SML/NJ allows <code>op</code> to appear in <code>val</code> specifications:</p>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml"><span class="kr">signature</span> <span class="nn">FOO</span> <span class="p">=</span> <span class="kr">sig</span>
   <span class="kr">val</span> <span class="nv">op</span> <span class="n">+</span> <span class="p">:</span> <span class="n">int</span> <span class="n">*</span> <span class="n">int</span> <span class="p">-&gt;</span> <span class="n">int</span>
<span class="kr">end</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>The grammar on page 14 of the Definition does not allow it. Recent
versions of SML/NJ do give a warning.</p>
</div>
</li>
<li>
<p>SML/NJ rejects</p>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml"><span class="p">(</span><span class="kr">op</span> <span class="n">*</span><span class="p">)</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>as an unmatched close comment.</p>
</div>
</li>
<li>
<p>SML/NJ allows <code>=</code> to be rebound by the declaration:</p>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml"><span class="kr">val</span> <span class="nv">op</span> <span class="p">=</span> <span class="p">=</span> <span class="mi">13</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>This is explicitly forbidden on page 5 of the Definition. Recent
versions of SML/NJ do give a warning.</p>
</div>
</li>
<li>
<p>SML/NJ allows rebinding <code>true</code>, <code>false</code>, <code>nil</code>, <code>::</code>, and <code>ref</code> by
the declarations:</p>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml"><span class="kr">fun</span> <span class="nf">true</span> <span class="p">()</span> <span class="p">=</span> <span class="p">()</span>
<span class="kr">fun</span> <span class="nf">false</span> <span class="p">()</span> <span class="p">=</span> <span class="p">()</span>
<span class="kr">fun</span> <span class="nf">nil</span> <span class="p">()</span> <span class="p">=</span> <span class="p">()</span>
<span class="kr">fun</span> <span class="nf">op</span> <span class="n">::</span> <span class="p">()</span> <span class="p">=</span> <span class="p">()</span>
<span class="kr">fun</span> <span class="nf">ref</span> <span class="p">()</span> <span class="p">=</span> <span class="p">()</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>This is explicitly forbidden on page 9 of the Definition.</p>
</div>
</li>
<li>
<p>SML/NJ extends the syntax of the language to allow vector
expressions and patterns like the following:</p>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml"><span class="kr">val</span> <span class="nv">v</span> <span class="p">=</span> <span class="p">#[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">]</span>
<span class="kr">val</span> <span class="nv">#</span><span class="p">[</span><span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">,</span><span class="n">z</span><span class="p">]</span> <span class="p">=</span> <span class="n">v</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>MLton supports vector expressions and patterns with the <a href="SuccessorML#VectorExpsAndPats"><code>allowVectorExpsAndPats</code></a> <a href="MLBasisAnnotations">ML Basis annotation</a>.</p>
</div>
</li>
<li>
<p>SML/NJ extends the syntax of the language to allow <em>or patterns</em>
like the following:</p>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml"><span class="kr">datatype</span> <span class="kt">foo</span> <span class="p">=</span> <span class="nc">Foo</span> <span class="kr">of</span> <span class="n">int</span> <span class="p">|</span> <span class="nc">Bar</span> <span class="kr">of</span> <span class="n">int</span>
<span class="kr">val</span> <span class="p">(</span><span class="n">Foo</span> <span class="n">x</span> <span class="n">|</span> <span class="n">Bar</span> <span class="n">x</span><span class="p">)</span> <span class="nv">=</span> <span class="n">Foo</span> <span class="mi">13</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>MLton supports or patterns with the <a href="SuccessorML#OrPats"><code>allowOrPats</code></a> <a href="MLBasisAnnotations">ML Basis annotation</a>.</p>
</div>
</li>
<li>
<p>SML/NJ allows higher-order functors, that is, functors can be
components of structures and can be passed as functor arguments and
returned as functor results.  As a consequence, SML/NJ allows
abbreviated functor definitions, as in the following:</p>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml"><span class="kr">signature</span> <span class="nn">S</span> <span class="p">=</span>
  <span class="kr">sig</span>
    <span class="kr">type</span> <span class="kt">t</span>
    <span class="kr">val</span> <span class="nv">x</span><span class="p">:</span> <span class="n">t</span>
  <span class="kr">end</span>
<span class="kr">functor</span> <span class="nn">F</span> <span class="p">(</span><span class="kr">structure</span> <span class="nn">A</span><span class="p">:</span> <span class="n">S</span><span class="p">):</span> <span class="n">S</span> <span class="p">=</span>
  <span class="kr">struct</span>
    <span class="kr">type</span> <span class="kt">t</span> <span class="p">=</span> <span class="nn">A</span><span class="p">.</span><span class="n">t</span> <span class="n">*</span> <span class="nn">A</span><span class="p">.</span><span class="n">t</span>
    <span class="kr">val</span> <span class="nv">x</span> <span class="p">=</span> <span class="p">(</span><span class="nn">A</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="nn">A</span><span class="p">.</span><span class="n">x</span><span class="p">)</span>
  <span class="kr">end</span>
<span class="kr">functor</span> <span class="nn">G</span> <span class="p">=</span> <span class="n">F</span></code></pre>
</div>
</div>
</li>
<li>
<p>SML/NJ extends the syntax of the language to allow <code>functor</code> and
<code>signature</code> declarations to occur within the scope of <code>local</code> and
<code>structure</code> declarations.</p>
</li>
<li>
<p>SML/NJ allows duplicate type specifications in signatures when the
duplicates are introduced by <code>include</code>, as in the following:</p>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml"><span class="kr">signature</span> <span class="nn">SIG1</span> <span class="p">=</span>
   <span class="kr">sig</span>
      <span class="kr">type</span> <span class="kt">t</span>
      <span class="kr">type</span> <span class="kt">u</span>
   <span class="kr">end</span>
<span class="kr">signature</span> <span class="nn">SIG2</span> <span class="p">=</span>
   <span class="kr">sig</span>
      <span class="kr">type</span> <span class="kt">t</span>
      <span class="kr">type</span> <span class="kt">v</span>
   <span class="kr">end</span>
<span class="kr">signature</span> <span class="nn">SIG</span> <span class="p">=</span>
   <span class="kr">sig</span>
      <span class="kr">include</span> <span class="nn">SIG1</span>
      <span class="kr">include</span> <span class="nn">SIG2</span>
   <span class="kr">end</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>This is disallowed by rule 77 of the Definition.</p>
</div>
</li>
<li>
<p>SML/NJ allows sharing constraints between type abbreviations in
signatures, as in the following:</p>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml"><span class="kr">signature</span> <span class="nn">SIG</span> <span class="p">=</span>
   <span class="kr">sig</span>
      <span class="kr">type</span> <span class="kt">t</span> <span class="p">=</span> <span class="n">int</span> <span class="n">*</span> <span class="n">int</span>
      <span class="kr">type</span> <span class="kt">u</span> <span class="p">=</span> <span class="n">int</span> <span class="n">*</span> <span class="n">int</span>
      <span class="kr">sharing</span> <span class="kr">type</span> <span class="kt">t</span> <span class="p">=</span> <span class="n">u</span>
   <span class="kr">end</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>These are disallowed by rule 78 of the Definition.  Recent versions of
SML/NJ correctly disallow sharing constraints between type
abbreviations in signatures.</p>
</div>
</li>
<li>
<p>SML/NJ disallows multiple <code>where type</code> specifications of the same
type name, as in the following</p>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml"><span class="kr">signature</span> <span class="nn">S</span> <span class="p">=</span>
  <span class="kr">sig</span>
     <span class="kr">type</span> <span class="kt">t</span>
     <span class="kr">type</span> <span class="kt">u</span> <span class="p">=</span> <span class="n">t</span>
  <span class="kr">end</span>
  <span class="kr">where</span> <span class="kr">type</span> <span class="kt">u</span> <span class="p">=</span> <span class="n">int</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>This is allowed by rule 64 of the Definition.</p>
</div>
</li>
<li>
<p>SML/NJ allows <code>and</code> in <code>sharing</code> specs in signatures, as in</p>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml"><span class="kr">signature</span> <span class="nn">S</span> <span class="p">=</span>
   <span class="kr">sig</span>
      <span class="kr">type</span> <span class="kt">t</span>
      <span class="kr">type</span> <span class="kt">u</span>
      <span class="kr">type</span> <span class="kt">v</span>
      <span class="kr">sharing</span> <span class="kr">type</span> <span class="kt">t</span> <span class="p">=</span> <span class="n">u</span>
      <span class="kr">and</span> <span class="kr">type</span> <span class="kt">u</span> <span class="p">=</span> <span class="n">v</span>
   <span class="kr">end</span></code></pre>
</div>
</div>
</li>
<li>
<p>SML/NJ does not expand the <code>withtype</code> derived form as described by
the Definition.  According to page 55 of the Definition, the type
bindings of a <code>withtype</code> declaration are substituted simultaneously in
the connected datatype.  Consider the following program.</p>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml"><span class="kr">type</span> <span class="kt">u</span> <span class="p">=</span> <span class="n">real</span> <span class="p">;</span>
<span class="kr">datatype</span> <span class="kt">a</span> <span class="p">=</span>
    <span class="nc">A</span> <span class="kr">of</span> <span class="n">t</span>
  <span class="p">|</span> <span class="nc">B</span> <span class="kr">of</span> <span class="n">u</span>
<span class="kr">withtype</span> <span class="kt">u</span> <span class="p">=</span> <span class="n">int</span>
<span class="kr">and</span> <span class="kt">t</span> <span class="p">=</span> <span class="n">u</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>According to the Definition, it should be expanded to the following.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml"><span class="kr">type</span> <span class="kt">u</span> <span class="p">=</span> <span class="n">real</span> <span class="p">;</span>
<span class="kr">datatype</span> <span class="kt">a</span> <span class="p">=</span>
    <span class="nc">A</span> <span class="kr">of</span> <span class="n">u</span>
  <span class="p">|</span> <span class="nc">B</span> <span class="kr">of</span> <span class="n">int</span> <span class="p">;</span>
<span class="kr">type</span> <span class="kt">u</span> <span class="p">=</span> <span class="n">int</span>
<span class="kr">and</span> <span class="kt">t</span> <span class="p">=</span> <span class="n">u</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>However, SML/NJ expands <code>withtype</code> bindings sequentially, meaning that
earlier bindings are expanded within later ones. Hence, the above
program is expanded to the following.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml"><span class="kr">type</span> <span class="kt">u</span> <span class="p">=</span> <span class="n">real</span> <span class="p">;</span>
<span class="kr">datatype</span> <span class="kt">a</span> <span class="p">=</span>
    <span class="nc">A</span> <span class="kr">of</span> <span class="n">int</span>
  <span class="p">|</span> <span class="nc">B</span> <span class="kr">of</span> <span class="n">int</span> <span class="p">;</span>
<span class="kr">type</span> <span class="kt">u</span> <span class="p">=</span> <span class="n">int</span>
<span class="kr">type</span> <span class="kt">t</span> <span class="p">=</span> <span class="n">int</span></code></pre>
</div>
</div>
</li>
<li>
<p>SML/NJ allows <code>withtype</code> specifications in signatures.</p>
<div class="paragraph">
<p>MLton supports <code>withtype</code> specifications in signatures with the <a href="SuccessorML#SigWithtype"><code>allowSigWithtype</code></a> <a href="MLBasisAnnotations">ML Basis annotation</a>.</p>
</div>
</li>
<li>
<p>SML/NJ allows a <code>where</code> structure specification that is similar to a
<code>where type</code> specification.  For example:</p>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml"><span class="kr">structure</span> <span class="nn">S</span> <span class="p">=</span> <span class="kr">struct</span> <span class="kr">type</span> <span class="kt">t</span> <span class="p">=</span> <span class="n">int</span> <span class="kr">end</span>
<span class="kr">signature</span> <span class="nn">SIG</span> <span class="p">=</span>
  <span class="kr">sig</span>
     <span class="kr">structure</span> <span class="nn">T</span> <span class="p">:</span> <span class="kr">sig</span> <span class="kr">type</span> <span class="kt">t</span> <span class="kr">end</span>
  <span class="kr">end</span> <span class="kr">where</span> <span class="n">T</span> <span class="p">=</span> <span class="n">S</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>This is equivalent to:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml"><span class="kr">structure</span> <span class="nn">S</span> <span class="p">=</span> <span class="kr">struct</span> <span class="kr">type</span> <span class="kt">t</span> <span class="p">=</span> <span class="n">int</span> <span class="kr">end</span>
<span class="kr">signature</span> <span class="nn">SIG</span> <span class="p">=</span>
  <span class="kr">sig</span>
     <span class="kr">structure</span> <span class="nn">T</span> <span class="p">:</span> <span class="kr">sig</span> <span class="kr">type</span> <span class="kt">t</span> <span class="kr">end</span>
  <span class="kr">end</span> <span class="kr">where</span> <span class="kr">type</span> <span class="kt">T</span><span class="err">.</span><span class="kt">t</span> <span class="p">=</span> <span class="nn">S</span><span class="p">.</span><span class="n">t</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>SML/NJ also allows a definitional structure specification that is
similar to a definitional type specification.  For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml"><span class="kr">structure</span> <span class="nn">S</span> <span class="p">=</span> <span class="kr">struct</span> <span class="kr">type</span> <span class="kt">t</span> <span class="p">=</span> <span class="n">int</span> <span class="kr">end</span>
<span class="kr">signature</span> <span class="nn">SIG</span> <span class="p">=</span>
  <span class="kr">sig</span>
     <span class="kr">structure</span> <span class="nn">T</span> <span class="p">:</span> <span class="kr">sig</span> <span class="kr">type</span> <span class="kt">t</span> <span class="kr">end</span> <span class="p">=</span> <span class="n">S</span>
  <span class="kr">end</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>This is equivalent to the previous examples and to:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml"><span class="kr">structure</span> <span class="nn">S</span> <span class="p">=</span> <span class="kr">struct</span> <span class="kr">type</span> <span class="kt">t</span> <span class="p">=</span> <span class="n">int</span> <span class="kr">end</span>
<span class="kr">signature</span> <span class="nn">SIG</span> <span class="p">=</span>
  <span class="kr">sig</span>
     <span class="kr">structure</span> <span class="nn">T</span> <span class="p">:</span> <span class="kr">sig</span> <span class="kr">type</span> <span class="kt">t</span> <span class="kr">end</span> <span class="kr">where</span> <span class="kr">type</span> <span class="kt">t</span> <span class="p">=</span> <span class="nn">S</span><span class="p">.</span><span class="n">t</span>
  <span class="kr">end</span></code></pre>
</div>
</div>
</li>
<li>
<p>SML/NJ disallows binding non-datatypes with datatype replication.
For example, it rejects the following program that should be allowed
according to the Definition.</p>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml"><span class="kr">type</span> <span class="p">(</span><span class="nd">'a</span><span class="p">,</span> <span class="nd">'b</span><span class="p">)</span> <span class="kt">t</span> <span class="p">=</span> <span class="nd">'a</span> <span class="n">*</span> <span class="nd">'b</span>
<span class="kr">datatype</span> <span class="kt">u</span> <span class="p">=</span> <span class="kr">datatype</span> <span class="n">t</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>This idiom can be useful when one wants to rename a type without
rewriting all the type arguments.  For example, the above would have
to be written in SML/NJ as follows.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml"><span class="kr">type</span> <span class="p">(</span><span class="nd">'a</span><span class="p">,</span> <span class="nd">'b</span><span class="p">)</span> <span class="kt">t</span> <span class="p">=</span> <span class="nd">'a</span> <span class="n">*</span> <span class="nd">'b</span>
<span class="kr">type</span> <span class="p">(</span><span class="nd">'a</span><span class="p">,</span> <span class="nd">'b</span><span class="p">)</span> <span class="kt">u</span> <span class="p">=</span> <span class="p">(</span><span class="nd">'a</span><span class="p">,</span> <span class="nd">'b</span><span class="p">)</span> <span class="n">t</span></code></pre>
</div>
</div>
</li>
<li>
<p>SML/NJ disallows sharing a structure with one of its substructures.
For example, SML/NJ disallows the following.</p>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml"><span class="kr">signature</span> <span class="nn">SIG</span> <span class="p">=</span>
   <span class="kr">sig</span>
      <span class="kr">structure</span> <span class="nn">S</span><span class="p">:</span>
         <span class="kr">sig</span>
            <span class="kr">type</span> <span class="kt">t</span>
            <span class="kr">structure</span> <span class="nn">T</span><span class="p">:</span> <span class="kr">sig</span> <span class="kr">type</span> <span class="kt">t</span> <span class="kr">end</span>
         <span class="kr">end</span>
      <span class="kr">sharing</span> <span class="n">S</span> <span class="p">=</span> <span class="nn">S</span><span class="p">.</span><span class="n">T</span>
   <span class="kr">end</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>This signature is allowed by the Definition.</p>
</div>
</li>
<li>
<p>SML/NJ disallows polymorphic generalization of refutable
patterns. For example, SML/NJ disallows the following.</p>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml"><span class="kr">val</span> <span class="p">[</span><span class="n">x</span><span class="p">]</span> <span class="p">=</span> <span class="p">[[]]</span>
<span class="kr">val</span> <span class="nv">_</span> <span class="p">=</span> <span class="p">(</span><span class="mi">1</span> <span class="n">::</span> <span class="n">x</span><span class="p">,</span> <span class="s2">"one"</span> <span class="n">::</span> <span class="n">x</span><span class="p">)</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Recent versions of SML/NJ correctly allow polymorphic generalization
of refutable patterns.</p>
</div>
</li>
<li>
<p>SML/NJ uses an overly restrictive context for type inference.  For
example, SML/NJ rejects both of the following.</p>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml"><span class="kr">structure</span> <span class="nn">S</span> <span class="p">=</span>
<span class="kr">struct</span>
  <span class="kr">val</span> <span class="nv">z</span> <span class="p">=</span> <span class="p">(</span><span class="kr">fn</span> <span class="n">x</span> <span class="p">=&gt;</span> <span class="n">x</span><span class="p">)</span> <span class="p">[]</span>
  <span class="kr">val</span> <span class="nv">y</span> <span class="p">=</span> <span class="n">z</span> <span class="n">::</span> <span class="p">[</span><span class="n">true</span><span class="p">]</span> <span class="n">::</span> <span class="n">nil</span>
<span class="kr">end</span></code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml"><span class="kr">structure</span> <span class="nn">S</span> <span class="p">:</span> <span class="kr">sig</span> <span class="kr">val</span> <span class="nv">z</span> <span class="p">:</span> <span class="n">bool</span> <span class="n">list</span> <span class="kr">end</span> <span class="p">=</span>
<span class="kr">struct</span>
  <span class="kr">val</span> <span class="nv">z</span> <span class="p">=</span> <span class="p">(</span><span class="kr">fn</span> <span class="n">x</span> <span class="p">=&gt;</span> <span class="n">x</span><span class="p">)</span> <span class="p">[]</span>
<span class="kr">end</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>These structures are allowed by the Definition.</p>
</div>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_deviations_from_the_basis_library_specification">Deviations from the Basis Library Specification</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Here are some deviations of SML/NJ from the <a href="BasisLibrary">Basis Library</a>
<a href="https://smlfamily.github.io/Basis">specification</a>.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>SML/NJ exposes the equality of the <code>vector</code> type in structures such
as <code>Word8Vector</code> that abstractly match <code>MONO_VECTOR</code>, which says
<code>type vector</code>, not <code>eqtype vector</code>.  So, for example, SML/NJ accepts
the following program:</p>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml"><span class="kr">fun</span> <span class="nf">f</span> <span class="p">(</span><span class="n">v</span><span class="p">:</span> <span class="nn">Word8Vector</span><span class="p">.</span><span class="n">vector</span><span class="p">)</span> <span class="p">=</span> <span class="n">v</span> <span class="p">=</span> <span class="n">v</span></code></pre>
</div>
</div>
</li>
<li>
<p>SML/NJ exposes the equality property of the type <code>status</code> in
<code>OS.Process</code>. This means that programs which directly compare two
values of type <code>status</code> will work with SML/NJ but not MLton.</p>
</li>
<li>
<p>Under SML/NJ on Windows, <code>OS.Path.validVolume</code> incorrectly considers
absolute empty volumes to be valid. In other words, when the
expression</p>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml"><span class="nn">OS</span><span class="p">.</span><span class="nn">Path</span><span class="p">.</span><span class="n">validVolume</span> <span class="p">{</span> <span class="n">isAbs</span> <span class="p">=</span> <span class="n">true</span><span class="p">,</span> <span class="n">vol</span> <span class="p">=</span> <span class="s2">""</span> <span class="p">}</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>is evaluated by SML/NJ on Windows, the result is <code>true</code>.  MLton, on
the other hand, correctly follows the Basis Library Specification,
which states that on Windows, <code>OS.Path.validVolume</code> should return
<code>false</code> whenever <code>isAbs = true</code> and <code>vol = ""</code>.</p>
</div>
<div class="paragraph">
<p>This incorrect behavior causes other <code>OS.Path</code> functions to behave
differently. For example, when the expression</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="sml"><span class="nn">OS</span><span class="p">.</span><span class="nn">Path</span><span class="p">.</span><span class="n">toString</span> <span class="p">(</span><span class="nn">OS</span><span class="p">.</span><span class="nn">Path</span><span class="p">.</span><span class="n">fromString</span> <span class="s2">"</span><span class="se">\\</span><span class="s2">usr</span><span class="se">\\</span><span class="s2">local"</span><span class="p">)</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>is evaluated by SML/NJ on Windows, the result is <code>"\\usr\\local"</code>,
whereas under MLton on Windows, evaluating this expression (correctly)
causes an <code>OS.Path.Path</code> exception to be raised.</p>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
<div id="mlton-footer">
<div id="mlton-footer-text">
<div>
Last updated Thu Oct 21 15:53:06 2021 -0400 by Matthew Fluet.
<a href="https://github.com/MLton/mlton/commits/master/doc/guide/src/SMLNJDeviations.adoc">Log</a>
<a href="https://github.com/MLton/mlton/edit/master/doc/guide/src/SMLNJDeviations.adoc">Edit</a>
</div>
</div>
</body>
</html>