This column should be of great interest to programming language aficionados. Everyone else should probably go on to the next article. As a functional programming language, ML differs greatly from imperative languages such as C. Here are two descriptions from "Principles of Functional Programming" (Glaser, et al.; Prentice Hall, 1984):
A program in an Imperative Language is used to convey a list of commands, to be executed in some particular order, such that on completion of the commands the required behavior has been produced.
A program in a Functional Language is used to define an expression which is the solution to a set of problems; this definition can then be used by a machine to produce an answer to a particular problem from the set of problems.
So, where an imperative program might say "Do this; Do that.", a functional program would say "Construct one of these from one or more of those.". Now, let's look at ML itself. The "ML Primer" (Stansifer, Prentice Hall, 1992) says:
The programming language ML was originally designed for use as the metalanguage in the Logic for Computable Functions (LCF) verification system. Hence the source of the name for the language, ML for MetaLanguage. Despite its origins in the 1980s as a language for a specific purpose, it is a versatile language. A language standard has emerged. ML is a strongly typed, functional programming language with a natural syntax and just a few primitive concepts.
ML has become very popular among functional programmers. Standard ML appears to be the most popular version, but several alternative definitions and implementations are available.
Start with Standard ML of New Jersey (SML/NJ). It is a complete language system (about 23 MB, compressed), including source code, documentation, and contributed software. SML/NJ can be found in ftp://research.att.com/dist/ml/. The directory also includes Concurrent ML (CML), described in the announcement as follows:
Concurrent ML is a concurrent extension of SML/NJ, supporting dynamic thread creation, synchronous message passing on synchronous channels, and first-class synchronous operations. First-class synchronous operations allow users to tailor their synchronization abstractions for their application. CML also supports both stream I/O and low-level I/O in an integrated fashion.
You might also look at the Standard ML to C compiler, available in ftp://dravido.soar.cs.cmu.edu/usr/nemo/sml2c/. The distribution takes up about 7.5 MB (compressed), and includes source code, documentation, associated tools, and a test suite.
Be sure to pick up the Edinburgh Standard ML Library, stored in ftp://ftp.lfcs.ed.ac.uk/export/ml/library/. The library is small (less than 1 MB, compressed) but contains over 200 functions on several basic types, including sets, hash tables and the built-in types.
Finally, check out the ML Kit, stored in ftp://ftp.diku.dk/diku/users/birkedal/. As described in the announcement:
The ML Kit is a straight translation of the Definition of Standard ML into a collection of Standard ML modules. For example, every inference rule in the Definition is translated into a small piece of Standard ML code which implements it. The translation has been done with as little originality as possible -- even variable conventions from the Definition are carried straight over to the Kit.
If you are primarily interested in executing Standard ML programs efficiently, the ML Kit is not the system for you! (It uses a lot of space and is very slow.) The Kit is intended as a tool box for those people in the programming language community who may want a self-contained parser or type checker for full Standard ML but do not want to understand the clever bits of a high-performance compiler. We have tried to write simple code and module interfaces; we have not paid any attention to efficiency.
Developed at the INRIA research facility in France, CAML (Categorical Abstract Machine Language) is a functional language in the ML family. Like ML itself, it has spawned a series of descendents.
The CAML distribution is archived in ftp://gatekeeper.dec.com/pub/plan/caml/. CAML Light, a variant for smaller machines (PCs, etc.), is archived in ftp://ftp.inria.fr/lang/caml-light/. As the CAML Light README says:
Caml Light is a small, portable implementation of the ML language. It runs on most Unix machines; on Macintoshes under the Macintosh Programmer's Workshop environment; on all PCs (even those with only 640K and a 8088, though there is a version for 386 processors that is faster and can take advantage of more memory); and on the Amiga.
Caml Light implements a large subset of the Caml language, a functional language from the ML family. Caml Light is quite close to Standard ML, though not strictly conformant. There are some slight differences in syntax and semantics, and major differences in the module system (these changes were required to support separate compilation).
For adventurous (strong?) types, Inria offers Alcool-90 (190 proof alcohol). Stored in ftp://ftp.inria.fr/lang/alcool/, Alcool-90 "is an experimental extension of ML with run-time overloading and a type-based notion of modules, functors and inheritance".
Lazy ML (LML) is a lazy, completely functional variant of ML. That is, LML puts off evaluation of all expressions until the last possible moment, allowing programmers a great deal of flexibility. LML is archived in ftp://ftp.cs.chalmers.se/pub/haskell/chalmers/. The LML distribution also contains a compiler for Haskell, a further variation.
I find "Principles of Functional Programming" (see above) to be a clear exposition of the rationale and methods of functional programming. I would strongly recommend it or some similar treatment as a prelude to any of the following works.
The "ML Primer" (see above) has a wealth of clear explanations, but it is a bit short on motivation. If reader already understands ML's philosophy, s/he will do just fine. Otherwise, s/he may wonder what's going on.
Making matters worse, the Primer contains a large number of forward references. Although this can be resolved by reading the book in several passes, a more organized approach would have been more useful.
For a full mathematical description of ML, go to "Definition of Standard ML" (Milner, et al., MIT, 1990). The companion volume, "Commentary on Standard ML" (Milner, et al., MIT, 1991) gives a detailed explanation of ML's semantic theory.
I haven't seen "ML for the Working Programmer" (Paulson, Cambridge, 1991), so I can't say much about it. On the other hand, I am quite impressed by the fact that the author has provided a wealth of on-line code for his readers. The answers to the exercises in the first five chapters are stored as answers1-5.txt.Z in ftp://ftp.cl.cam.ac.uk/ml/. The source code for all programs in the book are stored as working.tar.Z in the same archive.