Designed by Robin Milnor, Mike Gordon and Chris Wadsworth.
Success led to adoption and strengthening as programming language.
Important attributes:
Type:
sml
System responds with message saying in ML, and then "-" prompt.
Can load definitions from UNIX file by typing:
use ["myfile.sml"];
where myfile.sml is the name of your file. It should be in the same directory you were in when you typed sml.
Terminate session by typing control-D.
Evaluate an expression by typing in and following with ";", e.g.
- 3 + 5;
val it = 8 : int
"it" refers to last value computed. Can also bind value to an identifier:
- val six = 6;
val six = 6 : int;
Thus typing an expression, exp, is equivalent to typing: val it = exp;
Identifier often called a variable, but really a constant declaration ("val" for value).
Can also define functions.
- fun succ x = x + 1;
val succ = fn : int -> int
- succ 12;
val it = 13 : int
- 17 * (succ 3);
val it = 68 : int;
Can also write:
- val succ = fn x => x + 1;
val succ = fn : int -> int
Note semi-colon at top-level terminates parsing and causes evaluation.
No loops in the language, all functions written via recursion and if.. then.. else:
- fun fact n = if n = 0 then 1 else n * fact (n-1);
unit has only one value: ()
bool includes true, false and operators: not, andalso, orelse
int includes positive and negative: ...,~2, ~1,0,1,2...
supports +,-,*,div,mod,<,<=,>,>=
real of form 3.17, 2.4E17 with +,-,*,/,<,<=,>,>=, log, exp, sin,arctan
string of form "my string" - \t = tab, \n = newline.
supports ^ (concatenation), length, substring where substring("hello",1,3) -> "ell"
- fun double x = x + x;
Type checking error in: (syntactic context unknown)
Unresolvable overloaded identifier: +
Definition cannot be found for the type: ('a * 'a) -> 'a
- fun succ (x:int) = x + 1;
or
-fun succ x : int = x + 1;
or even
-fun succ (x:int) : int = x + 1;
Tuples are abbreviations of records where labels are 1,2,3,...
Thus (17,"abc", true) = {1 = 17, 2 = "abc", 3 = true}
Selectors: #lab : {lab : 'a,...} -> 'a
Thus #rank({name = "bob",salary = 50000.99, rank=1}) = 1
#2((17,"abc", true)) -> "abc"
Ex. of function on tuples:
- fun power (m,n):int = if n = 0 then 1
else m * power (m,n-1);
val power = fn : (int * int) -> int
On the other hand
- fun cpower m n :int = if n = 0 then 1
else m * cpower m (n-1);
val cpower = fn : int -> (int -> int)
Note these are different functions!
Latter said to be in "Curried" form (after Haskell Curry).
Can define
- val twopower = cpower 2
val twopower = fn : int -> int
- twopower 3;
val it = 8 : int
Operations: length
@ append - e.g. [1,2,3]@[4,5,6] = [1,2,3,4,5,6]
:: prefix (e.g. 1::x = [1,2,3,4,5,6])
map apply function to all elements of a list,
e.g. map round [1.1,2.2,4.4] = [1,2,4]
rev reverses list
[],nil empty list
Many kinds of lists:
int list: [1,2,3]
string list: ["ab","cd","ef"]
nil is part of any list type,
- nil;
val it = [] : 'a list
where 'a stands for a type variable. Similarly write:
- map;
val it = fn: ('a -> 'b) -> (('a list) -> ('b list))
Map is first example of a polymorphic function.
Lists are built up using ::, can also be decomposed the same way,
i.e., [1,2,3] = 1::[2,3] = 1::2::[3] = 1::2::3::nil
Can define functions by cases.
- fun product [] : int = 1
= | product (fst::rest) = fst * (product rest);
Note that "=" is automatically printed on continuation line. Don't include it in your program files!