4 Here are some deviations of <:SMLNJ:SML/NJ> from
5 <:DefinitionOfStandardML:The Definition of Standard ML (Revised)>.
6 Some of these are documented in the
7 http://www.smlnj.org/doc/Conversion/index.html[SML '97 Conversion Guide].
8 Since MLton does not deviate from the Definition, you should look here
9 if you are having trouble porting a program from MLton to SML/NJ or
10 vice versa. If you discover other deviations of SML/NJ that aren't
11 listed here, please send mail to
12 mailto:MLton-devel@mlton.org[`MLton-devel@mlton.org`].
14 * SML/NJ allows spaces in long identifiers, as in `S . x`. Section
15 2.5 of the Definition implies that `S . x` should be treated as three
16 separate lexical items.
18 * SML/NJ allows `op` to appear in `val` specifications:
23 val op + : int * int -> int
27 The grammar on page 14 of the Definition does not allow it. Recent
28 versions of SML/NJ do give a warning.
37 as an unmatched close comment.
39 * SML/NJ allows `=` to be rebound by the declaration:
46 This is explicitly forbidden on page 5 of the Definition. Recent
47 versions of SML/NJ do give a warning.
49 * SML/NJ allows rebinding `true`, `false`, `nil`, `::`, and `ref` by
61 This is explicitly forbidden on page 9 of the Definition.
63 * SML/NJ extends the syntax of the language to allow vector
64 expressions and patterns like the following:
72 MLton supports vector expressions and patterns with the <:SuccessorML#VectorExpsAndPats:`allowVectorExpsAndPats`> <:MLBasisAnnotations:ML Basis annotation>.
74 * SML/NJ extends the syntax of the language to allow _or patterns_
79 datatype foo = Foo of int | Bar of int
80 val (Foo x | Bar x) = Foo 13
83 MLton supports or patterns with the <:SuccessorML#OrPats:`allowOrPats`> <:MLBasisAnnotations:ML Basis annotation>.
85 * SML/NJ allows higher-order functors, that is, functors can be
86 components of structures and can be passed as functor arguments and
87 returned as functor results. As a consequence, SML/NJ allows
88 abbreviated functor definitions, as in the following:
97 functor F (structure A: S): S =
105 * SML/NJ extends the syntax of the language to allow `functor` and
106 `signature` declarations to occur within the scope of `local` and
107 `structure` declarations.
109 * SML/NJ allows duplicate type specifications in signatures when the
110 duplicates are introduced by `include`, as in the following:
131 This is disallowed by rule 77 of the Definition.
133 * SML/NJ allows sharing constraints between type abbreviations in
134 signatures, as in the following:
146 These are disallowed by rule 78 of the Definition. Recent versions of
147 SML/NJ correctly disallow sharing constraints between type
148 abbreviations in signatures.
150 * SML/NJ disallows multiple `where type` specifications of the same
151 type name, as in the following
163 This is allowed by rule 64 of the Definition.
165 * SML/NJ allows `and` in `sharing` specs in signatures, as in
179 * SML/NJ does not expand the `withtype` derived form as described by
180 the Definition. According to page 55 of the Definition, the type
181 bindings of a `withtype` declaration are substituted simultaneously in
182 the connected datatype. Consider the following program.
194 According to the Definition, it should be expanded to the following.
206 However, SML/NJ expands `withtype` bindings sequentially, meaning that
207 earlier bindings are expanded within later ones. Hence, the above
208 program is expanded to the following.
220 * SML/NJ allows `withtype` specifications in signatures.
222 MLton supports `withtype` specifications in signatures with the <:SuccessorML#SigWithtype:`allowSigWithtype`> <:MLBasisAnnotations:ML Basis annotation>.
224 * SML/NJ allows a `where` structure specification that is similar to a
225 `where type` specification. For example:
229 structure S = struct type t = int end
232 structure T : sig type t end
236 This is equivalent to:
240 structure S = struct type t = int end
243 structure T : sig type t end
244 end where type T.t = S.t
247 SML/NJ also allows a definitional structure specification that is
248 similar to a definitional type specification. For example:
252 structure S = struct type t = int end
255 structure T : sig type t end = S
259 This is equivalent to the previous examples and to:
263 structure S = struct type t = int end
266 structure T : sig type t end where type t = S.t
270 * SML/NJ disallows binding non-datatypes with datatype replication.
271 For example, it rejects the following program that should be allowed
272 according to the Definition.
276 type ('a, 'b) t = 'a * 'b
277 datatype u = datatype t
280 This idiom can be useful when one wants to rename a type without
281 rewriting all the type arguments. For example, the above would have
282 to be written in SML/NJ as follows.
286 type ('a, 'b) t = 'a * 'b
287 type ('a, 'b) u = ('a, 'b) t
290 * SML/NJ disallows sharing a structure with one of its substructures.
291 For example, SML/NJ disallows the following.
300 structure T: sig type t end
306 This signature is allowed by the Definition.
308 * SML/NJ disallows polymorphic generalization of refutable
309 patterns. For example, SML/NJ disallows the following.
314 val _ = (1 :: x, "one" :: x)
317 Recent versions of SML/NJ correctly allow polymorphic generalization
318 of refutable patterns.
320 * SML/NJ uses an overly restrictive context for type inference. For
321 example, SML/NJ rejects both of the following.
327 val z = (fn x => x) []
328 val y = z :: [true] :: nil
334 structure S : sig val z : bool list end =
336 val z = (fn x => x) []
340 These structures are allowed by the Definition.
342 == Deviations from the Basis Library Specification ==
344 Here are some deviations of SML/NJ from the <:BasisLibrary:Basis Library>
345 http://www.standardml.org/Basis[specification].
347 * SML/NJ exposes the equality of the `vector` type in structures such
348 as `Word8Vector` that abstractly match `MONO_VECTOR`, which says
349 `type vector`, not `eqtype vector`. So, for example, SML/NJ accepts
350 the following program:
354 fun f (v: Word8Vector.vector) = v = v
357 * SML/NJ exposes the equality property of the type `status` in
358 `OS.Process`. This means that programs which directly compare two
359 values of type `status` will work with SML/NJ but not MLton.
361 * Under SML/NJ on Windows, `OS.Path.validVolume` incorrectly considers
362 absolute empty volumes to be valid. In other words, when the
367 OS.Path.validVolume { isAbs = true, vol = "" }
370 is evaluated by SML/NJ on Windows, the result is `true`. MLton, on
371 the other hand, correctly follows the Basis Library Specification,
372 which states that on Windows, `OS.Path.validVolume` should return
373 `false` whenever `isAbs = true` and `vol = ""`.
375 This incorrect behavior causes other `OS.Path` functions to behave
376 differently. For example, when the expression
380 OS.Path.toString (OS.Path.fromString "\\usr\\local")
383 is evaluated by SML/NJ on Windows, the result is `"\\usr\\local"`,
384 whereas under MLton on Windows, evaluating this expression (correctly)
385 causes an `OS.Path.Path` exception to be raised.