SML vs Ocaml for ECMA script spec.

Stephen Weeks sweeks at sweeks.com
Tue Oct 24 11:56:38 PDT 2006


I am happy to hear about the decision to use SML to specify ES4 and
think it is a good one.  I have a few comments.


I don't understand why meta-language continuations are necessary for
the spec.  If performance really isn't an issue, why not express
stacks/continuations as ordinary data structures and do whatever
manipulations you want on them directly?  It would probably make the
spec more clear to not rely on meta-language features like call/cc.
Illuminating reading for this kind of thing is Reynold's "Definitional
Interpreters for Higher-Order Programming Languages":

  http://mlton.org/References#Reynolds98_2

If you do decide to use meta-language continuations, I suspect that
exceptions and threads really are enough.  You should consider using
(a very small subset of) MLton's thread interface:

  http://mlton.org/MLtonThread

  MLton.Thread provides access to MLton's user-level thread
  implementation (i.e. not OS-level threads).  Threads are lightweight
  data structures that represent a paused computation. Runnable
  threads are threads that will begin or continue computing when
  switched to.  MLton.Thread does not include a default scheduling
  mechanism, but it can be used to implement both preemptive and
  non-preemptive threads.

In order to specify ES4's yield, all you probably need is Thread.new
and Thread.switch.  Importantly, MLton.Thread.switch is constant time,
unlike MLton.Cont.throw, which takes time proportional to the size of
the stack:

  http://mlton.org/MLtonCont

Plus, it is trivial to implement Thread.{new,switch} on top of a
constant-time implementation of callcc/throw like SML/NJ has (and not
vice versa).


Now, for a few comments on the choice of SML implementation.

SML does have the benefit of a number of active implementations (eight
or so):

  http://mlton.org/StandardMLImplementations

However, SML/NJ is the least conforming to the Definition.

  http://mlton.org/DefinitionOfStandardML
  http://mlton.org/SMLNJDeviations

If you want to develop code that matches the Definition and is
portable among SML implementations, you should use at least one of the
other implementations from the start of the project (Hamlet and MLton
being the most pedantic about following the Definition).  I can not
understate the number of times I have heard people who started a
project with SML/NJ encounter porting problems because they
unknowingly used some aspect of SML/NJ that is not SML and is not
supported by other SML implementations.


One feature missing from SML/NJ that may be relevant in providing an
executable spec is exact binary<->decimal conversions.  For example,
if you try

  Real.fmt StringCvt.EXACT Real.Math.pi

in SML/NJ you will get

  uncaught exception Fail [Fail: RealFormat: fmtReal: EXACT not supported]

On the other hand, if you try this in MLton, you will get

  0.3141592653589793E1

MLton uses gdtoa for binary<->decimal conversions.  I don't know of
any other SML implementation that does.


Another feature missing from SML/NJ, but is present in MLton, the ML
Kit, and Poly/ML, is the generation of standalone executables.  This
could be useful for shipping a binary package containing the
executable spec.



More information about the Es4-discuss mailing list