

it
To start SML, you just type sml
For this course, though, you should generally use the command sml-cs131 defined in /cs/cs131/bin
As I described the nature of the read-eval-print loop is such that you can just type an expression and SML will respond with its value:
3;
3 + 2;
SML will always echo a TYPE along with a VALUE.

There are two numeric base types, real and int.
The usual operators, +, -, and *
are defined for the integers and for the reals (but not with a mixed
pair). Integer division is
done with the infix operator div, while / is
used for real division.
Note that - is used only for binary subtraction. The unary negation operator
is written '~'. So, minus three is written ~3.
The full complement of relational operators, =, <, >,
<=, >=, and <> are supported
as well.
bool, the booleans, is a built in type with two values: false, and true.
May be checked for equality (and inequality), but no other comparisons or operations are allowed.

Many built-in functions. Function application pretty much like other languages, except you don't in general use parentheses:
Math.sqrt 4.0;
You only use parentheses for grouping and precedence purposes:
Math.sqrt (4.0 + 12.0);
Notice that functions are themselves just named values:
Math.sqrt;
op +;
Real.~;

The arrow means that sqrt is a function which takes a real and returns a real. Any violation causes an error:
Math.sqrt 3;
There is no automatic casting, period!
A few functions like plus are overloaded so they work on different types
3 + 4;
3.0 + 4.0;
But there are limits:
3 + 4.0;
Instead of general overloading, ML supports much richer notion of Polymorphism TBD later.

Assigning a name to a value:
val x = 3+4;
3 + 4;
it + 5;

Last base types are string and char.
String constants are written with double-quotes as in C.
All the relational operators described above are defined for strings.
Concatenate two strings using the ^:
val s = "Hello " ^ "World!";
Character literals are written in a slightly odd notation, as singleton strings preceeded by a '#' character:
val c = #"h";
As above, the usual relational operators are supported
SML-NJ supports the usual
C-like mechanism of using the backslash to write the standard control codes,
such as \n for newline and \"
for the double-quote character.
The function explode takes a string and returns a list of
characters (more on lists later). implode
does the opposite.

There is actually one more base type
called unit, even simpler than the booleans.
It has only one value, (), which is also called unit.
Why does it exist?

Three built-in structured types, tuples, records, and lists.
Tuples are unlabeled ordered pairs, triples, etc.
A pair of integers
(2,3)
A triple of reals
(2.3,3.4,5.6)
A quadruple of strings
("this","is","a","test")
Tuples are heterogeneous:
val bigtup = (1,true,(),"test",(2,"hello","world"),3.14159)
Can be tested for equality and inequality. They are equal if each field is equal.
You can select out the fields of a tuple using numeric selectors:
#2 bigtup;
#5 bigtup;
#2 (#5 bigtup);
These selectors are rarely used because of the availability of pattern matching.

Records are similar to tuples but use field names rather than position to distinguish the different fields.
val emprec1 = {name="Josh",ext=8650};
Fields are selected similarly to tuples:
#ext emprec1
Records can also be compared for equality and inequality. This is done fieldwise, by the name of the field, not position:
val emprec2 = {name="Ran",ext=8976};
val emprec3 = {ext=8650,name="Josh"};
emprec1 = emprec2;
emprec1 = emprec3;

Lists are homogeneous variable length structures. A list has a head
and a tail. The head is a single item of some type. The tail is a list
of that type. There is a special element named nil that is used
to terminate a list. Nil is a list of arbitrary type.
The basic notation for lists uses the infix constructor ::
which is pronounced `cons' for `construct'.
You would write a list of integers like:
val ilist1 = (1::2::3::nil);
No internal parentheses are needed here because cons associates to the right. So the last expression is equivalent to
(1::(2::(3::nil)));
Notice that cons takes an element on the left and a list on the right. So we can build up a list out of existing ones like:
val ilist2 = (4::ilist1);
Remember, though, that lists must be homogeneous, so:
val badlist = (1::2::3.0::4::nil);
will generate an error.

There is a more comact notation for lists that can be used when you
can enumerate all the elements of the list. Just use a pair of square
braces with the elements separated by commas, with nil[].
Recall, list items can be of any first class type in the system.
val wierd1 = [(1,"hello"),(2,"goodbye")];
val wierd2 = [[1,2],[3,4,5],[6]];
val wierd3 = [op *,op div]
val wierd3a = [op *,op /]
You will need to get pretty good at reading ML types and understanding them. For instance, notice the difference between the types of:
wierd1;
and
val wierd5 = ([1,2],["hello","goodbye"]);

As with tuples and records, lists come with a set of little-used
selectors, hd which gives you the head of a list, and tl
which gives you the tail of a list:
wierd2;
hd wierd2;
tl wierd2;
hd (tl wierd2);
hd (tl (hd (tl wierd2)));
(hd wierd3) (2,3);

Code written in a file, as opposed to entered directly at the input prompt, is
generally commented. The comment style in SML is the same as that for pascal:
Comments have both opening and closing delimeters, which are the character pairs
(* and *), respctively. So, for example:
(* This is a brief comment. *)
Since there are delimeters at both ends, comments may, obviously, stretch across
multiple lines.
One of the advantages of the extremely high level of structure and abstraction provided by SML is that code is typically more self-commenting than in languages like C, so you will find the natural level of explicit commenting lighter.
As usual, take a cue from the graders and the sample solutions as to an adequate level of commenting for your code.

This page copyright ©2000 by Joshua S. Hodas. It was built on a Macintosh. Last rebuilt on Saturday, January 22, 2000 | |
http://www.cs.hmc.edu/~hodas/courses/cs131/lectures/lecture02s.html | |