- Most functional languages are interactive. If you enter an expression, the
computer
immediately evaluates and displays the results.
- To start ML: sml
- Type in an expresion of integers: 2 + 2;
End the expression with a semicolon
- 2 + 2;
val it = 4 : int
- 1 + 2 * 3;
val it = 7 : int
ML responds with the value and type of the variable "it" - a special
variable that receives the value of any expression in the interactive
mode.
- Integers
- 0;
val it = 0 : int
- 1234;
val it = 1234 : int
- 11111111;
val it = 11111111 : int
- ~1234; Negative numbers begin with a tilde!
val it = ~1234 : int
- 0x1234; Hexadecimal numbers begin with 0x
val it = 4660 : int
- Reals
- ~123.0;
val it = ~123.0 : real
- 3e~3;
val it = 0.003 : real
- 3.14e12;
val it = 3.14E12 : real
- 3.14159;
val it = 3.14159 : real
- Booleans
- true;
val it = true : bool
- false;
val it = false : bool
- 1=2;
val it = false : bool
- Strings
- "hello";
val it = "hello" : string
- "hello world";
val it = "hello world" : string
- print("h\tI\n");
h I
val it = () : unit
- Characters: # followed by a string of length 1
- #"A";
val it = #"A" : char
- #"\n";
val it = #"\n" : char
- Arithmetic operators
- 3.0 - 4.5 + 6.7 * 12.8;
val it = 84.26 : real
- 43 div (8 mod 3) * 5;
val it = 105 : int
CAREFUL WITH MIXED MODE EXPRESSIONS!
- 3.0 - 4.5 + 6.7 * 12;
Error: operator and operand don't agree [literal]
operator domain: real * real
operand: real * int
in expression: 6.7 * 12
- String operators
- "house" ^ "cat";
val it = "housecat" : string
- Comparison Operators
- 2=2;
val it = true : bool
- 2.0=2.0; CAN'T COMPARE REALS WITH EQUALITY!
Error: operator and operand don't agree
operator domain: ''Z * ''Z <- NOT SURE WHAT THIS MEANS
operand: real * real
in expression:
2.0 = 2.0
- #"Z" < #"a";
val it = true : bool
- 2 < 1 + 3;
val it = true : bool
- 2 < 1;
val it = false : bool
- "abc" < "ab";
val it = false : bool
- "Apple" < "apple";
val it = true : bool
- "apple" < "Apple";
val it = false : bool
- "abc" <= "ab";
val it = false : bool
- "abc" <= "ac";
val it = true : bool
- Combining logical values
- 1<2 orelse 3>4;
val it = true : bool
- 1<2 andalso 3>4;
val it = false : bool
- not(1<2);
val it = false : bool
- If-Then-Else expressions (THERE ARE NO IF-THEN EXPRESSIONS!)
- if 1<2 then 3+4 else 5+6;
val it = 7 : int
- Coercion between types
- real(4);
val it = 4.0 : real
- real(1) + 2.0;
val it = 3.0 : real
- ord(#"A");
val it = 65 : int
- ord(#"a");
val it = 97 : int
- ord(#"a")- ord(#"A");
val it = 32 : int
- chr(65);
val it = #"A" : char
- str(#"a");
val it = "a" : string
- Assignment-like statement
- val pi = 3.14159;
val pi = 3.14159 : real
- pi;
val it = 3.14159 : real
- val radius=4.0;
val radius = 4.0 : real
- pi*radius*radius;
val it = 50.26544 : real
- val area = pi*radius*radius;
val area = 50.26544 : real
- area;
val it = 50.26544 : real
- val +-+-+ = 1234; Symbolic names can consist of ! % & $ + - * /
val +-+-+ = 1234 : int : < = > ? @ \ ~ ` ^ |
- +-+-+;
val it = 1234 : int
- val ++ = 2;
val ++ = 2 : int
- val -- = 3;
val -- = 3 : int
- ++ + --;
val it = 5 : int
- +-+-+ * +-+-+;
val it = 1522756 : int
- Special libraries
- Math.sin 0.5;
val it = 0.479425538604 : real
- Int.min(7, Int.sign 12);
val it = 1 : int
Also: round(), floor(), ceil(), trunc()
- Tuples: a tuple is formed by taking a list of two or more expressions of any types,
separating them by commas, and surrounding them by parenthesis.
- (1,2);
val it = (1,2) : int * int
- (4, 5.0, "six");
val it = (4,5.0,"six") : int * real * string
- val t = (4, 5.0, "six");
val t = (4,5.0,"six") : int * real * string
- (1,2,3,4);
val it = (1,2,3,4) : int * int * int * int
- (1,(2,3.0));
val it = (1,(2,3.0)) : int * (int * real)
- Accessing components of tuples
- #1(t);
val it = 4 : int
- #3(t);
val it = "six" : string
- Lists: a list of elements OF THE SAME TYPE, separated by commas, enclosed in square brackets.
- [1,2,3];
val it = [1,2,3] : int list
- ["a","b","c"];
val it = ["a","b","c"] : string list
- [(1,2),(3,4),(5,6)];
val it = [(1,2),(3,4),(5,6)] : (int * int) list
- [[1,2],[3,4],[5,6]];
val it = [[1,2],[3,4],[5,6]] : int list list
- List operators and operations
- val L = [2,3,4];
val L = [2,3,4] : int list
- val M = [5];
val M = [5] : int list
- hd(L);
val it = 2 : int
- tl(L);
val it = [3,4] : int list
- tl(M);
val it = [] : int list
- [1,2] @ [3,4];
val it = [1,2,3,4] : int list
- 2::[3,4];
val it = [2,3,4] : int list
- 2.0::nil;
val it = [2.0] : real list
NOTE that :: separates a list into it's first and rest components,
it's car and cdr. This is the same as hd() and tl().
- Defining functions
fun upper(c) = chr(ord(c)-32);
val upper = fn : char -> char
- upper(#"a");
val it = #"A" : char
TO LOAD A FUNCTION FROM A FILE: use "filename.ml"
This function would be typed into a file as
fun upper(c) = chr(ord(c)-32);
or
fun upper(c) =
chr(ord(c)-32);
- Type concerns when defining functions
- fun square(x:real) = x*x;
val square = fn : real -> real
- square(45.67);
val it = 2085.7489 : real
- square(45);
Error: operator and operand don't agree [literal]
operator domain: real
operand: int
in expression: square 45
- fun square(x) = x*x; DEFAULTS TO INT
val square = fn : int -> int
- square(4567);
val it = 20857489 : int
fun max3(a:real, b, c) = (* maximum of 3 reals *)
if a>b then
if a>c then a
else c
else
if b>c then b
else c;
val max3 = fn : real * real * real -> real (ML respond with this line)
TWO VERSIONS OF REVERSE A LIST:
fun reverse(L) =
if L = nil then nil
else reverse(tl(L)) @ [hd(L)];
fun reverse2(nil) = nil
| reverse2(first::rest) = reverse2(rest) @ [first]
- Local declarations in functions
Reducing a fraction, version 1:
fun gcd(m,n) =
if m=0 then n
else gcd(n mod m, m);
fun fractionOne (n,d) = (n div gcd(n,d), d div gcd(n,d));
"fractionOne" uses two calls to the recursive gcd function
- fractionOne(1238,20004);
val it = (619,10002) : int * int
Version 2: using a local variable to store gcd(n,d)
fun fraction(n,d) =
let val com = gcd(n,d)
in (n div com, d div com) end;
FORMAT OF "LET": let D in E end;
- fraction(1248,20004);
val it = (104,1667) : int * int