Language Sequence
Lisp Algol 60
ML Algol 68
Pascal CSCI 334 Stephen Freund ML Modula
Many other languages: Algol 58, Algol W, Euclid, EL1, Mesa (PARC), …
1 Modula-2, Oberon, Modula-3 (DEC) 2
Algol 60 Sample ML real procedure average(A,n); Combination of Lisp and Algol-like features real array A; integer n; – Expression-oriented – Higher-order functions begin – Garbage collection real sum; sum := 0; – Static types – Abstract data types for i = 1 step 1 until n do – Module system sum := sum + A[i]; – Exceptions average := sum/n General purpose non-C-like, non-OO language end;
3 4
Goals in study of ML Robin Milner and ML's Origins
Types and type checking Dana Scott, 1969 – Static vs. dynamic typing – LCF – Type inference – logic for stating theorems – Polymorphism and Generic Programming about programs Memory management Robin Milner – Static scope and block structure – automated theorem proving – parameter passing for LCF – Function activation records, higher-order functions – theorem proving is a hard Control search problem – Statements, { blocks }, ... – ML: meta-language for – Exceptions writing programs (tactics) to – Tail recursion find proofs
5 6
1 Tactics Language Ideas to Support Tactics Tactics guide search in theorem prover Type system – guarantees correctness of generated proof Tactic is partial function from formula -> proof – finds proof Exception handling – never terminates – deals with tactics that fail (Turing Award) – reports an error higher-order functions – composition of tactics – fun compose(t1, t2) = λformula. if t1(formula) then ... 7 else if t2(formula) ... 8
A Recent Implementation... Running ML Type sml on Unix machines System will give you prompt Enter expression or declarations to evaluate: - 3 + 5; val it = 8 : int - it * 2; val it = 16 : int - val six = 3 + 3; val six = 6 : int Or "sml < file.ml"
9 10
No type info Defining Functions given- compiler Recursion infers it Example All functions written using recursion and - fun succ x = x + 1; if.. then.. else (and patterns): val succ = fn : int -> int - fun fact n = - succ 12; if n = 0 then 1 else n * fact (n-1); val it = 13 : int - 17 * (succ 3); if..then..else is an expression: val it = 68 : int; - if 3<4 then "moo" else "cow"; Or: val it = "moo" : string - val succ = fn x => x + 1; - types of branches must match val succ = fn : int -> int
11 12
2 Local Declarations Built-in Data Types - fun cylinderVolume diameter height = unit let val radius = diameter / 2.0; – only value is () fun square y = y * y in bool 3.14 * square(radius) * height – true, false end; – operators not, andalso, orelse int val cylinderVolume = fn : real -> real -> real – ..., ~2, ~1, 0, 1, 2, ... - cylinderVolume 6.0 6.0; – +,-,*,div,mod,abs val it = 169.56 : real – =,<,<=, etc.
13 14
Built-in Data Types Overloaded Operators real +,-,etc. defined on both int and real – 3.17, 2.2, ... Which one to use depends on operands: – +, -, *, / - fun succ x = x + 1 – <, <=, etc. val succ = fn : int -> int – no conversions from int to real: 2 + 3.3 is bad – no equality (test that -0.001 < x-y < 0.001, etc.) - fun double x = x * 2.0 strings val double = fn : real -> real – "moo" – "moo" ^ "cow" - fun double x = x + x val double = fn : int -> int 15 16
Type Declarations Compound Types Can add types when type inference does not work Tuples, Records, Lists Tuples - fun double (x:real) = x + x; (14, "moo", true): int * string * bool val double = fn : real -> real Functions can take tuple argument - fun double (x:real) : real = x + x; - fun power (exp,base) = val double = fn : real -> real if exp = 0 then 1 else base * power(exp-1,base); val power = fn : int * int -> int - power(3,2);
17 18
3 Curried Functions (named after Curry) Curried Functions (named after Curry) Previous power Previous power - fun power (exp,base) = - fun power (exp,base) = if exp = 0 then 1 if exp = 0 then 1 else base * power(exp-1,base); else base * power(exp-1,base); val power = fn : int * int -> int val power = fn : int * int -> int Curried power function Curried power function - fun cpower exp = - fun cpower exp base = fn base => if exp = 0 then 1 if exp = 0 then 1 else base * cpower (exp-1) base; else base * cpower (exp-1) base; val cpower = fn : int -> (int -> int) val cpower = fn : int -> (int -> int) 19 20
Curried Functions Records Why is this useful? Like tuple, but with labeled elements: - fun cpower exp base = { name="Gus", salary=3.33, id=11 }: if exp = 0 then 1 { name:string, salary:real, id:int }; else base * cpower (exp-1) base; Selector operator: val cpower = fn : int -> (int -> int) - val x = Can define { name="Gus", salary=3.33, id=11 }; - val square = cpower 2 - #salary(x); val square = fn : int -> int val it = 3.33 : real - square 3; - #name(x); val it = 9 : int val it = "Gus" : string
21 22
Lists Lists Examples Functions on Lists – [1, 2, 3, 4], ["wombat", "numbat"] – nil is empty list (sometimes written []) - fun product (nums) = – all elements must be same type if (nums = nil) Operations then 1 – length length [1,2,3] ⇒ 3 else (hd nums) * product(tl nums); – @ - append [1,2]@[3,4] ⇒ [1, 2, 3, 4] – :: - prefix 1::[2,3] ⇒ [1, 2, 3] val product = fn : int list -> int – map map succ [1,2,3] ⇒ [2,3,4] - product([5, 2, 3]); 23 val it = 30 : int; 24
4 Pattern Matching Patterns on Integers List is one of two things: Patterns on integers – nil fun listInts 0 = [0] – "first elem" :: "rest of elems" | listInts n = n::listInts(n-1); – [1, 2, 3] = 1::[2,3] = 1::2::[3] = 1::2::3::nil listInts 3 ⇒ [3, 2, 1, 0]; Can define function by cases More on patterns for other data types next time fun product (nil) = 1 | product (x::xs) = x * product (xs);
25 26
Many Types Of Lists The Length Function 1::2::nil : int list Another Example "wombat"::"numbat"::nil : string list What type of list is nil? fun length (nil) = 0 - nil; | length (x::xs) = 1 + length (xs); val it = [] : 'a list Polymorphic type What is the type of length? – 'a is a type variable that represents any type How about this one: – 1::nil : int list "a"::nil : string list fun id x = x;
27 28
Polymorphism
fun length (nil) = 0 | length (x::xs) = 1 + length (xs); - val it = fun 'a list -> int
fun id x = x; Type variable - val it = fun 'a -> 'a represents any type
29 30
5