[MLton] MLton's adherence to the Definition of SML

Matthew Fluet fluet@cs.cornell.edu
Tue, 3 Aug 2004 09:58:34 -0400 (EDT)


> Here's a few thoughts on our philosophy regarding MLton's adherence to
> the Definition of SML.

I like Stephen's thoughts, but I'll point out that you occasionally mix
adherence to the Definition of SML with adherence to the Basis Library;
I agree that one needs to take the two together to have a stable bedrock
on which to build a program, and the Basis Library defines sufficiently
complicated constructs that one cannot build an SML compiler without
anticipating supporting the Basis Library, but the Basis Library is
necessarily incomplete.  I see a difference between providing more
structures than dictated by the Basis Library (i.e., an extension of the
BL), and providing more syntax than dictated by the Definition (i.e., an
extension of the D).

> We can consider three ways that one might deviate from the Definition.
>
> 1. restrictions,
> 2. differences,
> 3. extensions,

We can also consider these as ways that one might deviate from the Basis
Library.

In addition to the points you make, the Unresolved Bugs section of the
User's guide specifies a few additional differences.

> Other than bugs, the last time that MLton had a difference
> was when we didn't raise the Overflow exception on integer operations.
> And, we still have this difference available via the -detect-overflow
> flag.  Another example is the -safe flag.

Note that these are actually differences with the Basis Library (the
Definition doesn't specify the Overflow exception or any of the operations
govered by -safe).  Also, note that we currently deviate from the Basis
Library in the StreamIO functor.

> We do have one restriction in MLton that I can think of:
> -sequence-unit true, which disallows certain programs that are allowed
> by the definition.  I guess this means that we think that a
> restriction governed by a flag is OK, at least if it has a simple
> explanation.

Also, the explanation can be recast in the language of the Definition
(namely, by modifying the derived form in Fig. 15, p. 56;  also, note that
in specifying the behavior of -sequence-unit true in this manner, we
_must_ apply -sequence-unit true to the body of a while expression).

Our behavior with regards to pattern matching might also be considered a
restriction; at the very least, both our default behavior and our behavior
under -warn-match false deviate from what the Definition specifies a
compiler must do.  (Our default behavior is to warn even if the
nonexhaustive pattern is in a val binding at the top-level.  With
-warn-match false, we fail to warn on any nonehaustive or redundant
patterns.)

> Extensions are the least bad of the three.  Examples of extensions in
> MLton are _export, _import, and the MLton structure.

I agree that _export and _import are extensions of the language specified
in the Definition of SML --- they modify the grammer of expressions,
introduce new keywords, etc.  The MLton structure is an extension of the
the Basis Library.

> What I see in common is that all of them let us do
> something that is *impossible* to do in the language without the
> extension.

I think that is a fair characterization.  For me, at least, it clarifies
the situation between supporting SMLofNJ.Cont but not or-patterns.

> Another difference between library extensions and language
> extensions is that library extensions are mostly implemented outside
> the compiler, and are hence presumably more accessible to non MLton
> experts.

I don't agree with this as much.  If an extension is really impossible to
support in Definition/Basis Library, then it almost certainly requires
some compiler support.  It may be the case that a library extension can be
implemented using just FFI, but that is just an indirect dependence on
compiler support.

There is also the situation where some of the MLton. structures are really
providing a richer interface than that specified by the Basis Library.
There are some pragmatic concerns there as well.  For example,
MLton.Vector.unfoldi can be implemented against the Basis Library, but the
provided function is marginally more effcient.  Another scenario is
MLton.TextIO, which mostly remembers some implementation details that are
hidden away behind the Basis Library specification for TextIO.