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  , 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 () – 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