ML-Yacc & SML/NJ Libraries in Poly/ML

The SML/NJ Library includes many features that the Standard ML Basis library does not, including: maps, sets, random numbers, atoms, parser combinators, pretty printing, regular expressions, and HTML generation. The manual pages do not do the library justice; a careful study of the source can be rewarding.

ML-Yacc is required to build the SML/NJ library.

Step-by-step instructions

The SML/NJ Library can be used in Poly/ML, on i386 and PPC, with little effort, using either the MLton or SML/NJ distributions. In the latter case, patches must be applied, and both mlyacc and mllex are required.

Building from an MLton installation

  1. Download and install MLton.
  2. Download the poly_mlyacc.sml and poly_smlnj-lib.sml scripts.
  3. Edit the root path in both scripts to point at the sml subdirectory of the MLton installation.
  4. Inside Poly/ML type:
    use "poly_mlyacc.sml";
    use "poly_smlnj-lib.sml";
    

Building from an SML/NJ installation

  1. Make copies of the ml-yacc and smlnj-lib subdirectories of the SML/NJ installation.
  2. Apply some minor patches, taken from MLton, by typing
    patch -p0 < poly_smlnj-lib.patch
    
  3. Download the poly_mlyacc.sml and poly_smlnj-lib.sml scripts.
  4. Edit the root path in both scripts to point at the directory containing the copied subdirectories.
  5. Inside Poly/ML type:
    use "poly_mlyacc.sml";
    use "poly_smlnj-lib.sml";
    

Building from the SML/NJ distribution with mllex and mlyacc

  1. Download and extract the ml-yacc source and the smlnj-lib source,
  2. Build the lexer and grammar files
    mllex smlnj-lib/HTML/html-lex
    mlyacc smlnj-lib/HTML/html-grm
    
  3. Apply some minor patches, taken from MLton, by typing
    patch -p0 < poly_smlnj-lib.patch
    
  4. Download the poly_mlyacc.sml and poly_smlnj-lib.sml scripts.
  5. Edit the root path in both scripts to point at the directory containing the patched subdirectories.
  6. Inside Poly/ML type:
    use "poly_mlyacc.sml";
    use "poly_smlnj-lib.sml";
    

The patches

Four files (Util/hash-string.sml, Util/array-qsort.sml, Util/real-order-stats.sml, and Util/univariate-stats.sml) use SML/NJ's Unsafe structure, which does not exist in Poly/ML.

Three files (Util/redblack-set-fn.sml, Util/redblack-map-fn, and Util/graph-scc-fn.sml) use a non-standard where qualification over structures.

Two files (HTML/html-elements-fn.sml and HTML/html-attrs-fn.sml) use non-standard Or-patterns.

All issues are easily patched, after extracting the distribution:

patch -p0 < poly_smlnj-lib.patch

The where type and Or-pattern patches were taken from the MLton distribution of the SML/NJ Library, but the Unsafe patches are also needed under Poly/ML unless the additional declaration is made:

structure Unsafe = struct
  structure CharVector = CharVector
  structure Array = Array
end;

Importing files

The basis is enriched by declaring library components in order of their dependencies, that is, the file containing a signature, structure, or functor must be loaded (with use) before any other file that relies upon the declaration. Unfortunately, each SML implementation handles this issue differently.

The *.mlb files used by MLton list the library *.sml files in the required order. They are easily transformed into a list of strings, using grep and sed, for example

cat sml/smlnj-lib/Util/smlnj-lib.mlb | sed 's/ *(\*.*\*) *//'  \
                                     | egrep '\.(sml|sig)$'    \
                                     | sed 's/^ *\(.*\)/"\1",/'

The poly_mlyacc.sml and poly_smlnj-lib.sml files described above are built from MLton's *.mlb files by running the shell scripts makemlyacc and makesmlnj-lib respectively.

Six files are intentionally missing from the smlnj-lib/Util/smlnj-lib.mlb file:

array2-sig.sml, array2.sml The SML Basis Library already includes an Array2 structure.
bit-vector.sml Requires BitArray.Vector, which is not exported.
iterate-sig.sml, iterate.sml TODO suggests that this module will be revised.
time-limit.sml Relies on SMLofNJ.cont.callcc.

The SML/NJ Library requires a Word31 structure that is not provided by Poly/ML. Since Poly/ML's default Word structure has 31 bits (Word.wordSize = 31), at least on i386 and PPC, a simple declaration can help:

structure Word31 = Word;

On other platforms, five files should be excluded from the list: random-sig.sml, random.sml, real-order-stats.sml, univariate-stats.sml, rand-sig.sml and rand.sml.

The library also requires an Int32 structure, but Poly/ML does not support fixed precision integers. Again, a simple declaration can help:

structure Int32 = Int;

Otherwise, the rand.sml file should be excluded.

The modifications and list described above, as well as details from the next section are incorporated available in the poly_smlnj-lib.sml file.