-
SML/NJ allows spaces in long identifiers, as in S . x.
Section 2.5 of the Definition implies that S . x should be
treated as three separate lexical items.
- SML/NJ allows = to be rebound by the declaration:
val op = = 13
This is explicitly forbidden on page 5 of the Definition.
- SML/NJ extends the syntax of the language to allow
vector expressions and patterns like the following:
val v = #[1,2,3]
val #[x,y,z] = v
- SML/NJ extends the syntax of the language to allow or patterns
like the following:
datatype foo = Foo of int | Bar of int
val (Foo x | Bar x) = Foo 13
- 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:
signature S =
sig
type t
val x : t
end
functor F(structure A : S) : S =
struct
type t = A.t * A.t
val x = (A.x, A.x)
end
functor G = F
- SML/NJ extends the syntax of the language to allow functor and
signature definitions to occur within the scope of local and structure declarations.
- SML/NJ allows sharing constraints between type abbreviations in
signatures, as in the following:
signature SIG =
sig
type t = int * int
type u = int * int
sharing type t = u
end
These are disallowed by rule 78 of the Definition.
- SML/NJ allows and in sharing specs in signatures, as in
signature S =
sig
type t
type u
type v
sharing type t = u
and type u = v
end
- SML/NJ does not expand the withtype derived form as described by
the Definition. According to page 55 of the Definition, the type
bindings of a withtype declaration are substituted simultaneously
in the connected datatype. Consider the following program.
type u = real
datatype a =
A of t
| B of u
withtype u = int
and t = u
According to the Definition, it should be expanded to the following.
type u = real
datatype a =
A of u
| B of int
However, SML/NJ expands withtype bindings sequentially, meaning
that earlier bindings are expanded within later ones. Hence, the
above program is expanded to the following.
type u = real
datatype a =
A of int
| B of int
- SML/NJ allows withtype specifications in signatures.
- SML/NJ allows a where structure specification that is similar
to a where type specification. For example:
structure S = struct type t = int end
signature SIG =
sig
structure T : sig type t end
end where T = S
This is equivalent to:
structure S = struct type t = int end
signature SIG =
sig
structure T : sig type t end
end where type T.t = S.t
SML/NJ also allows a definitional structure specification that is
similar to a definitional type specification. For example:
structure S = struct type t = int end
signature SIG =
sig
structure T : sig type t end = S
end
This is equivlalent to the previous examples and to:
structure S = struct type t = int end
signature SIG =
sig
structure T : sig type t end where type t = S.t
end
- SML/NJ disallows binding non-datatypes with datatype replication.
For example, it rejects the following program that should be allowed
according to the Definition.
type ('a, 'b) t = 'a * 'b
datatype u = datatype t
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.
type ('a, 'b) t = 'a * 'b
type ('a, 'b) u = ('a, 'b) t
- SML/NJ disallows sharing a structure with one of its substructures.
For example, SML/NJ disallows the following.
signature SIG =
sig
structure S:
sig
type t
structure T: sig type t end
end
sharing S = S.T
end
This signature is allowed by the Definition.
- SML/NJ disallows polymorphic generalization of refutable patterns.
For example, SML/NJ disallows the following.
val [x] = [[]]
val _ = (1 :: x, "one" :: x)