SML Short Reference

Overview of the Syntax

syntactic categorypurpose
expressiondenotes a value
declarationintroduces an identifier
typecollection of values

Here are examples of the major syntactic categories in the SML programming language.

Expressions

expressionSML example
int literal 47
string literal "abcdefhijk"
tuple (3.4, "A", 7+3)
function application fact 3
conditional expression if p x then x else 0
anonymous function fn n => n+1
let expression let val pi = 3.14 in 2.0*pi end

Declarations

declarationSML example
value binding val x = 2
function binding fun f n = 2*n
type binding datatype color = red | green | blue
local declaration local val pi=3.14 in fun cir r = 2.0*pi*r end

Types

typeSML example
primitive int
structured (real*bool) list
polymorphic 'a->('b*int*'a)

Example Dialog

SML is an interactive system. After you invoke the system (usually with the command name sml), a banner is displayed. Then you can enter SML expressions and declarations at the prompt. The system responds with the value and the type.
Standard ML of New Jersey, Version 110.0.6, October 31, 1999 [CM&CMB] 

- 3+5;
val it = 8 : int 

- ~4 + floor (2.3 * ~4.5E~2);
val it = ~5 : int 

- fun fact n = if n<1 then 1 else n*(fact (n-1));
val fact = fn : int -> int 

- fact 7;
val it = 5040 : int 

- [1, 1+1, 2+1, 2*2, 2+3];
val it = [1,2,3,4,5] : int list 

- 1 :: [2, 3, 4];
val it = [1,2,3,4] : int list 

- [1.0] @ [2.0, 3.0, Math.sin 4.0];
val it = [1.0,2.0,3.0,~0.756802495308] : real list 

- let val p = 9973 * 9967 in (p, p+2, p+4) end;
val it = (99400891,99400893,99400895) : int * int * int

- [control-D]
The interactive dialog is terminated by typing control-D at the SML prompt. An easy way to develop an SML program is to edit a file, say file.sml, and simultaneously maintain a dialog with the SML system. After you make changes, load the whole file by entering the phrase:
use "file.sml";
This has the same effect as typing in the entire contents of the file interactively. After testing, the file can be edited again, and then loaded again.

It

Typing an expression to the interactive system is short for binding the variable it to the value of the expression. This has the useful consequence that, even if you forget to name a value, you can refer to the last expression entered at the top level as it.

Controlling the SML-NJ system

Printing values

Large structures or strings printed by the SML system will contain the character `#' or the string `...'. To those that are caught unaware it appears that the "wrong" value has been obtained. Actually the SML system uses these symbols to indicate that some portion of the value's representation has been omitted. This behavior can be easily controled.

The structure Compiler.Control.Print contains the following declarations:

val printLength = ref 12 : int ref  (* how much of long lists to print      *)
val printDepth  = ref  5 : int ref  (* how much of deeply nested structures *)
val stringDepth = ref 70 : int ref  (* how much of a long string to print   *)

Change the value of printLength, if it desired to see more of the elements of a long list. Change the value of printDepth to print more of deeply nested data structures. For example,

- val l = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
val l = [1,2,3,4,5,6,7,8,9,10,11,12,...] : int list 

- l;
val it = [1,2,3,4,5,6,7,8,9,10,11,12,...] : int list 

- Compiler.Control.Print.printLength := 20;
val it = () : unit 

- l;
val it = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15] : int list 

- datatype tree = leaf | node of int * tree * tree;
datatype tree = leaf | node of int * tree * tree 

- val t = node (1, node (2, node (3, leaf, leaf), leaf), leaf);
val t = node (1,node (2,node #,leaf),leaf) : tree 

- Compiler.Control.Print.printDepth := 6;
val it = () : unit 

- t;
val it = node (1,node (2,node (#,#,#),leaf),leaf) : tree 

- Compiler.Control.Print.printDepth := 7;
val it = () : unit 

- t;
val it = node (1,node (2,node (3,leaf,leaf),leaf),leaf) : tree 

- Compiler.Control.Print.stringDepth := 9;
val it = () : unit 

- "elide, omit, abridge, curtail";
val it = "elide, om#" : string

Also in the structure Compiler.Control.Print, the variable out is declared:

(* where compiler messages are sent     *)
val out : {say : string -> unit, flush : unit -> unit} ref 
To surpress the SML-NJ prompt and response, use the following assignment.

Compiler.Control.Print.out := {say=fn _=>(), flush=fn()=>()};

Prompts

The structure Complier.Control contains the following variables:

val primaryPrompt   = ref "- " : string ref
val secondaryPrompt = ref "= " : string ref
To change the primary prompt, for example, type:
Compiler.Control.primaryPrompt := "ML> ";

Garbage collection

The structure SMLofNJ.Internals.GC contains the following function:

SMLofNJ.Internals.GC.messages : bool -> unit
To turn off the printing of garbage collection messages, call the function messages:
SMLofNJ.Internals.GC.messages (false);

Profiling and Performance Evaluation

- Compiler.Profile.setProfMode true;
Creating profiled version of standard library
val it = () : unit 

- fun fact n = if n<2 then 1 else n * fact(n-1);
val fact = fn : int -> int 

- Compiler.Profile.setProfMode false;
val it = () : unit 

- Compiler.Profile.setTimingMode true;
val it = () : unit 

- fact 12;
val it = 479001600 : int 

- Compiler.Profile.setTimingMode false;
val it = () : unit 

- Compiler.Profile.report (TextIO.stdOut);
 %time cumsec #call  name
100.00    .01     0  Major GC
   .00    .01    12  fact.fact
val it = () : unit

Miscellaneous

- SMLofNJ.exportML;
val it = fn : string -> bool 

- SMLofNJ.exportFn;
val it = fn : string * (string * string list -> OS.Process.status) -> unit 

- SMLofNJ.getArgs;
val it = fn : unit -> string list

More Information


Ryan Stansifer <ryan@cs.fit.edu>
Last modified: Tue Aug 11 17:46:14 EDT 1998