Types, values and functions

A pre-defined type in Standard ML is the type of truth values, called bool. This has exactly two values, true and false. Another simple type is string. Strings are enclosed in double quotes (as in "Hello") and are joined by ``^'' (the caret or up arrow symbol). As expected, the expression "Hello" ^ " world!" evaluates to "Hello world!". There also is a type char for single characters. A character constant is a string constant of length one preceded by a hash symbol. Thus #"a" is the letter a, #"\n" is the newline character, #"\t" is tab and the backslash character can be used in the expected way to quote itself or the double quote character. Eight-bit characters can be accessed by their ASCII code, with #"\163" yielding #"£", #"\246" yielding #"ö" and so forth. The function explode turns a string into a list of single characters and implode goes the other way. The function ord turns a character into its ASCII code and chr goes the other way. The function size returns the number of characters in a string. Because strings and characters are values of different types we need a function to convert a character into a string of length one. The function str is used for this.

The numeric types in Standard ML are the integers of type int, the real numbers of type real, and unsigned integers (or words) of type word. In addition to these, an implementation of the language may provide other numeric types in a library, for example perhaps arbitrary precision integers or double precision reals or even bytes (8-bit unsigned integers). The integers may be represented in decimal or hexadecimal notation thus 255 and 0xff (zero x ff) both represent the integer 255. The numbers have one striking oddity ``~'' (tilde) is used for unary minus (with the exception of words of course, which cannot be negative). Reals must have either a fraction part--as in 4000.0--or an exponent part--as in 4E3--or both. A word or byte constant is written as a decimal numeral if following the characters 0w (zero w) or as a hexadecimal numeral if following the characters 0wx (zero w x). Thus 0w255 and 0wxff are two different ways of writing the word constant 255. Integers, reals and words are thus lexically distinct and when we see a numeric constant we can infer its type, if we are not explicitly told what it is. Operators such as +, -, *, div and mod are provided for integers and words: +, -, * and / are provided for the reals. Functions such as absolute value, abs, and unary negation are provided for the signed numeric types only. Relational operators =, <>, <, <=, > and >= are provided for the numeric types.

The numeric types which we have mentioned are separate types and we must use functions to convert an integer to a real or a word or a byte. There is no implicit coercion between types as found in other programming languages. Standard ML provides two library functions to convert between integers and reals. Arbitrary precision integer arithmetic is provided by some implementations of the language. In order to determine which do and which do not, consult the reference manual for the implementation or calculate a large integer value, say by multiplying a million by itself.

The integer successor function may be denoted by fn x => x+1. Function application is indicated by juxtaposition of the function--or function expression--and the argument value--or argument expression. Parentheses are introduced where necessary. If the argument to the function is to be obtained by evaluating an expression then parentheses will be obligatory. They can be used at other times just to clarify the structure of the function application. As might be expected, the function application (fn x => x+1) 4 evaluates to 5. Function application associates to the left in Standard ML so an expression which uses the successor function twice must use parentheses, as in (fn x => x+1) ((fn x => x+1) 4). Since unary minus is a function the parentheses are necessary in the expression ~ (~ x).

Of course, a mechanism is provided for binding names to values; even titchy programs would be unreadable without it. The declaration val succ = fn x => x+1 binds the name succ to the successor function and we may now write succ (succ 4) as an abbreviation for (fn x => x+1) ((fn x => x+1) 4).

Standard ML is a case-sensitive language . All of the reserved words of the language, such as val and fn, must be in lower case and occurrences of a program identifier must use capitalization consistently.