

                     STANDARD ML SYNTAX REFERENCE SHEET


RESERVED WORDS

    abstype  and  andalso  as  case  do  datatype  else
    end  exception  fn  fun  handle  if  in  infix
    infixr  let  local  nonfix  of  op  open  orelse
    raise  rec  then  type  val  with  withtype  while
    (  )  [  ]  {  }  ,  :  ;  ...  _  |  =  =>  ->  #


SPECIAL CONSTANTS

Integer constants:
    Examples            0      ~0      4         ~04     999999
    Non-examples        0.0    ~0.0    4.0       1E0

Real constants:
    Examples            0.7    ~0.7    3.32E5    3E~7    ~3E~7
    Non-examples        23     .3      4.E5      1E2.0   1E+7

String constants:

A string constant is a sequence, between quotes ("), of zero or more
printable characters (i.e., numbered 33-126), spaces, or escape
sequences.  An escape sequence starts with the escape character \ and
stands for a character sequence:

    \n          A single character interpreted by the system as end-of-line.
    \t          Tab.
    \^c         The control character c, where c may be any character
                with number 64-96.  The number of \^c is 64 less than
                the number of c.
    \ddd        The character with number ddd (3 decimal digits
                denoting an integer in the interval [0,255]).
    \"          "
    \\          \
    \f..f\      This sequence is ignored, where f..f stands for a
                sequence of one or more formatting characters 
                (such as space, tab, newline, form-feed).


COMMENTS

A comment is any character sequence within comment brackets (* *) in
which comment brackets are properly nested.


IDENTIFIERS

An identifier is either 

    alphanumeric: any sequence of letters, digits, primes (') and 
                  underbars (_) starting with a letter or prime,
or
    symbolic:     any non-empty sequence of the following symbols
                  ! % & $ # + - / : < = > ? @ \ ~ ` ^ | *

In either case, however, reserved words are excluded.  This means that
for example # and | are not identifiers, but ## and |=| are identifiers.

There are six classes of identifiers:

    var         (value variables)               long
    con         (value constructors)            long
    excon       (exception constructors)        long
    tyvar       (type variables)
    tycon       (type constructors)             long
    lab         (record labels)
    strid       (structure identifiers)         long

* A type variable 'a is an alphanumeric identifier starting with a prime.
* An equality type variable ''a starts with two or more primes.
* An imperative type variable '_a starts with one or two primes
  followed by an underbar.
* An applicative type variable is one which is not imperative.

* A label lab is an identifier, or a numeral 1 2 3 .. not starting with 0.

* For each identifier class X marked "long" above there is a class
  longX of long identifiers, which are sequences of structure
  identifiers separated by "." and followed by "." and an identifier:

    longx  ::=  x                       identifier
                strid1. .. .stridn.x    qualified identifier


INFIXED OPERATORS

An identifier may be given infix status by the infix or infixr
directive, which may occur as a declaration.  If identifier id has
infix status, then "exp1 id exp2" may occur --- in parentheses if
necessary --- wherever the application "id(exp1, exp2)" or
"id{1=exp1,2=exp2}" would otherwise occur.  The same holds when id
occurs in patterns.  
    On the other hand, an occurrence of a long identifier prefixed by
op is treated as non-infixed.
    The form of the fixity directives is as follows (n >= 1):
        
        infix  <d> id1 .. idn           left associative
        infixr <d> id1 .. idn           right associative
        nonfix     id1 .. idn

where <d> is an optional decimal digit d indicating binding precedence.  
A higher value of d indicates tighter binding; the default is 0.


NOTATIONAL CONVENTIONS USED IN THE GRAMMAR BELOW

* Each syntax class is defined by a list of alternatives, one alternative 
  on each line.  An empty phrase is represented by an empty line.

* The brackets < > enclose optional phrases.

* For any syntax class X (over which x ranges) we define the syntax
  class Xseq (over which xseq ranges) as follows:

    xseq   ::=  x                       (singleton sequence)
                                        (empty sequence)
                (x1, .. , xn)           (sequence, n>=1)

* Alternative phrases are listed in order of decreasing precedence.

* L and R stand for left and right association.

* The syntax of types binds more tightly than that of expressions.


GRAMMAR FOR THE CORE LANGUAGE

Expressions and Matches:

atexp      ::=  scon                            special constant
                <op> longvar                    value variable
                <op> longcon                    value constructor
                <op> longexcon                  exception constructor
                { <exprow> }                    record
                #lab                            record selector
                ()                              0-tuple
                (exp1, .. , expn)               n-tuple,  n>=2
                [exp1, .. , expn]               list,     n>=0
                (exp1; .. ; expn)               sequence, n>=2
                let dec in exp1; .. ; expn end  local declaration, n>=1
                ( exp ) 

exprow     ::=  lab = exp < , exprow >          expression row

appexp     ::=  atexp
                appexp atexp                    application expression

infexp     ::=  appexp
                infexp1 id infexp2              infix expression

exp        ::=  infexp
                exp : ty                        type constraint (L)
                exp1 andalso exp2               sequential conjunction
                exp1 orelse exp2                sequential disjunction
                exp handle match                handle exception
                raise exp                       raise exception
                if exp1 then exp2 else exp3     conditional
                while exp1 do exp2              iteration
                case exp of match               case analysis
                fn match

match      ::=  mrule < | match >

mrule      ::=  pat => exp


Declarations and Bindings:

dec        ::=  val valbind                     value declaration
                fun fvalbind                    function declaration
                type typbind                    type declaration
                datatype datbind                datatype declaration
                        < withtype typbind >
                abstype datbind                 abstype declaration
                        < withtype typbind >
                        with dec end
                exception exbind                exception declaration
                local dec1 in dec2 end          local declaration
                open longstrid1 .. longstridn   open declaration, n>=1
                                                empty declaration
                dec1 < ; > dec2                 sequential declaration
                infix  < d > id1 ... idn        infix (L) directive, n>=1
                infixr < d > id1 ... idn        infix (R) directive, n>=1
                nonfix       id1 ... idn        nonfix directive,    n>=1

valbind    ::=  pat = exp < and valbind >       
                rec valbind                     recursive binding

fvalbind   ::=    <op> var atpat11 .. atpat1n <:ty> = exp1      m,n>=1 
                | <op> var atpat21 .. atpat2n <:ty> = exp2
                | ..
                | <op> var atpatm1 .. atpatmn <:ty> = expm

typbind    ::=  tyvarseq tycon = ty < and typbind >

datbind    ::=  tyvarseq tycon = conbind < and datbind >

conbind    ::=  <op> con <of ty> < | conbind >

exbind     ::=  <op> excon <of ty> < and exbind >
                <op> excon = <op> longexcon < and exbind >

Note: In the fvalbind form above, if var has infix status then either
op must be present, or var must be infixed.  Thus, at the start of any
clause, "op var (atpat, atpat')" may be written "(atpat var atpat)".
The parentheses may be dropped if ":ty" or "=" follows immediately.


Patterns:

atpat      ::=  _                               wildcard
                scon                            special constant
                <op> var                        variable
                <op> longcon                    constant 
                <op> longexcon                  exception constant
                { < patrow > }                  record
                ()                              0-tuple
                (pat1, .. , patn)               n-tuple, n>=2
                [pat1, .. , patn]               list,    n>=0
                ( pat )

patrow     ::=  ...                             wildcard
                lab = pat < , patrow >          pattern row
                id <:ty> <as pat> < , patrow >  label as variable

pat        ::=  atpat                           atomic
                <op> longcon atpat              value construction
                <op> longexcon atpat            exception construction
                pat1 con pat2                   infixed value construction
                pat1 excon pat2                 infixed exception construction
                pat : ty                        typed
                <op> var <:ty> as pat           layered

Type expressions:

ty         ::=  tyvar                           type variable
                { < tyrow > }                   record type expression
                tyseq longtycon                 type construction
                ty1 * .. * tyn                  tuple type, n>=2
                ty1 -> ty2                      function type expression
                ( ty )

tyrow      ::=  lab : ty < , tyrow >            type-expression row


SYNTACTIC RESTRICTIONS

* No pattern may bind the same var twice.  No expression row, pattern
  row or type row may bind the same lab twice.

* No binding valbind, typbind, datbind or exbind may bind the same identifier
  twice; this applies also to value constructors within a datbind.
        
* In the left side tyvarseq tycon of any typbind or datbind, tyvarseq
  must not contain the same tyvar twice.  Any tyvar occurring within the
  right side must occur in tyvarseq.

* For each val binding pat = exp within rec, exp must be of the form 
  "fn match", possibly constrained by one or more type expressions.


GRAMMAR FOR THE MODULE LANGUAGE          


Structure and Signature Expressions:

strexp     ::=  struct strdec end               generative
                longstrid                       structure identifier
                funid ( strexp )                functor application
                funid ( strdec )                (variant of same)
                let strdec in strexp end        local declaration

strdec     ::=  dec                             declaration
                structure strbind               structure
                local strdec1 in strdec2 end    local
                                                empty
                strdec1 < ; > strdec2           sequential

strbind    ::=  strid <:sigexp> = strexp <and strbind>

sigexp     ::=  sig spec end                    generative
                sigid                           signature identifier

sigdec     ::=  signature sigbind               single
                                                empty
                sigdec1 < ; > sigdec2           sequential

sigbind    ::=  sigid = sigexp < and sigbind >


Specifications:

spec       ::=  val valdesc                     value
                type typdesc                    type
                eqtype typdesc                  eqtype
                datatype datdesc                datatype
                exception exdesc                exception
                structure strdesc               structure
                sharing shareq                  sharing
                local spec1 in spec2 end        local
                open longstrid1 .. longstridn   open,    n>=1
                include sigid1 .. sigidn        include, n>=1
                                                empty
                spec1 < ; > spec2               sequential

valdesc    ::=  var : ty < and valdesc >

typdesc    ::=  tyvarseq tycon < and typdesc >
        
datdesc    ::=  tyvarseq tycon = condesc < and datdesc >

condesc    ::=  con <of ty> < | condesc >

exdesc     ::=  excon <of ty> < and exdesc >

strdesc    ::=  strid : sigexp < and strdesc >

shareq     ::=  longstrid1 = .. = longstridn         structure sharing, n>=2
                type longtycon1 = .. = longtyconn    type sharing,      n>=2
                shareq1 and shareq2                  multiple


Functors and Top-Level Declarations:

fundec     ::=  functor funbind                 single
                                                empty
                fundec1 < ; > fundec2           sequence

funbind    ::=  funid(strid:sigexp1) <:sigexp2> = strexp < and funbind >
                funid(spec)          <:sigexp>  = strexp < and funbind >

funsigexp  ::=  (strid:sigexp1):sigexp2         functor signature expression
                (spec):sigexp                   (variant of same)

funspec    ::=  functor fundesc                 functor specification
                                                empty
                funspec1 < ; > funspec2         sequential

fundesc    ::=  funid funsigexp < and fundesc >

topdec     ::=  strdec                          structure-level declaration
                sigdec                          signature declaration
                fundec                          functor declaration
                exp                             top-level expression

* An expression "exp" which occurs as a topdec is taken to be an
  abbreviation for the declaration "let it = exp".


SYNTACTIC RESTRICTIONS

* No binding strbind, sigbind, or funbind may bind the same identifier twice.

* No description valdesc, typdesc, datdesc, exdesc, strdesc or fundesc
  may describe the same identifier twice; this applies also to value
  constructors within a datdesc.

* In the left side tyvarseq tycon in any typdesc or datdesc, tyvarseq 
  must not contain the same tyvar twice.  Any tyvar occurring within 
  the right side of the datdesc must occur in tyvarseq.


GRAMMAR FOR PROGRAMS

program    ::=  topdec ; < program >            


BUILT-IN TYPES, CONSTRUCTORS AND EXCEPTIONS

Types

                                         Admits
    Type        Values                   equality       Constructors
    ----------------------------------------------------------------
    unit        the 0-tuple ()           yes
    bool        Booleans                 yes            false, true
    int         Integers                 yes
    real        Floating-point numbers   yes
    string      Strings                  yes
    'a list     Lists                    if 'a does     nil, ::
    'a ref      References               yes            ref
    exn         Exceptions               no
    instream    Input streams            no
    outstream   Output streams           no

Built-in exceptions:

    Neg  Abs  Floor Sqrt  Exp  Ln  Quot  Div  Mod  Prod  Sum  Diff  
    Ord  Chr  Match  Bind  Interrupt  Io


BUILT-IN VARIABLES AND FUNCTIONS

For each variable we list its type, effect, and any exception it may raise.

An identifier with type involving num stands for two functions: one in
which num (in the type) is replaced by int, and another in which num
is replaced by real.  An explicit type constraint will be needed if the
surrounding text does not determine the type of a particular occurrence.

Nonfix:

    id          type                            effect                  Excepn
    ---------------------------------------------------------------------------
    map         ('a->'b) -> 'a list -> 'b list  map over list
    rev         'a list -> 'a list              reverse list
    not         bool -> bool                    logical negation
    ~           num -> num                      arithmetic negation     Neg
    abs         num -> num                      absolute value          Abs
    floor       real -> int                     round towards ~infinity Floor
    real        int -> real                     int to real     
    sqrt        real -> real                    square root             Sqrt
    sin         real -> real                    sine (from rad)
    cos         real -> real                    cosine (from rad)
    arctan      real -> real                    arc-tangent (to rad)
    exp         real -> real                    exponential function    Exp
    ln          real -> real                    natural logarithm       Ln
    size        string -> int                   length of string
    chr         int -> string                   character with number   Chr
    ord         string -> int                   number of character     Ord
    explode     string -> string list           split to 1-char strings
    implode     string list -> string           concatenate strings
    !           'a ref -> 'a                    dereference
    ref         '_a -> '_a ref                  create reference
    true        bool    
    false       bool                            
    nil         'a list                         empty list

Infix precedence 7:

    id          type                            effect                  Excepn
    ---------------------------------------------------------------------------
    /           real * real -> real             real quotient           Quot
    div         int * int -> int                integer quotient        Div
    mod         int * int -> int                remainder               Mod
    *           num * num -> num                product                 Prod

Infix precedence 6:

    +           num * num -> num                sum                     Sum
    -           num * num -> num                difference              Diff
    ^           string * string -> string       concatenate

Infix precedence 5:

    ::          'a * 'a list -> 'a list         cons onto list
    @           'a list * 'a list -> 'a list    append lists

Infix precedence 4:

    =           ''a * ''a -> bool               equal to
    <>          ''a * ''a -> bool               not equal to
    <           num * num -> bool               less than
    >           num * num -> bool               greater than
    <=          num * num -> bool               less or equal
    >=          num * num -> bool               greater or equal

Infix precedence 3:

    :=          'a ref * 'a -> unit             assignment
    o           ('b->'c) * ('a->'b) -> ('a->'c) function composition

Built-in values and functions for input/output:

    std_in         instream                     standard input stream
    open_in        string -> instream           open file for input
    input          instream * int -> string     input at most n chars
    lookahead      instream -> string           get next char non-destructively
    close_in       instream -> unit             close input stream
    end_of_stream  instream -> bool             true if stream at end
    std_out        outstream                    standard output stream
    open_out       string -> outstream          open file for output
    output         outstream * string -> unit   write to output stream
    close_out      outstream -> unit            close output stream

* On error, these will raise exception Io with an explanatory string argument.

* input(is, n) returns a string containing the n first characters of
  is, also removing them from is.  If only k<n characters are available
  on is, and it is terminated, then those k characters are returned;
  otherwise no result is returned until n characters are available or it
  gets closed.

* lookahead(is) returns a 1-character string s containing the first
  character from is, without removing it.  If no character is
  available, and it is closed, the empty string is returned; otherwise
  no result is returned until a character is available or it gets closed.

* open_out(s) deletes any existing contents of file s and returns a
  new outstream associated with s.

The definitive reference on Standard ML, with the full semantics, is
Milner, Tofte & Harper: The Definition of Standard ML, MIT Press 1990.
This reference sheet describes only syntax and built-in functions, and
is based on Sections 2.1, 2.2, 2.3, 2.4, 2.6, 2.9, 3.4, 3.5, A, B, C,
and D of the Definition.      Version 0.2 of 1994-09-27 Peter Sestoft.
