Programming Languages

Similar documents
Recap: ML s Holy Trinity. Story So Far... CSE 130 Programming Languages. Datatypes. A function is a value! Next: functions, but remember.

CSE 130 Programming Languages. Datatypes. Ranjit Jhala UC San Diego

Recap: ML s Holy Trinity

CSE 130 Programming Languages. Lecture 3: Datatypes. Ranjit Jhala UC San Diego

Programming Languages

Programming Languages. Datatypes

Programming Languages. Next: Building datatypes. Suppose I wanted. Next: Building datatypes 10/4/2017. Review so far. Datatypes.

Recap from last time. Programming Languages. CSE 130 : Fall Lecture 3: Data Types. Put it together: a filter function

CSE 130 [Winter 2014] Programming Languages

News. Programming Languages. Recap. Recap: Environments. Functions. of functions: Closures. CSE 130 : Fall Lecture 5: Functions and Datatypes

Programming Languages

Programming Languages

Recap. Recap. If-then-else expressions. If-then-else expressions. If-then-else expressions. If-then-else expressions

News. Programming Languages. Complex types: Lists. Recap: ML s Holy Trinity. CSE 130: Spring 2012

Programming Languages

Programming Languages

Programming Languages

OCaml. ML Flow. Complex types: Lists. Complex types: Lists. The PL for the discerning hacker. All elements must have same type.

Programming Languages

Programming Languages

Plan (next 4 weeks) 1. Fast forward. 2. Rewind. 3. Slow motion. Rapid introduction to what s in OCaml. Go over the pieces individually

OCaml. History, Variants. ML s holy trinity. Interacting with ML. Base type: Integers. Base type: Strings. *Notes from Sorin Lerner at UCSD*

Any questions. Say hello to OCaml. Say hello to OCaml. Why readability matters. History, Variants. Plan (next 4 weeks)

So what does studying PL buy me?

sum: tree -> int sum_leaf: tree -> int sum_leaf: tree -> int Representing Trees Next: Lets get cosy with Recursion Sum up the leaf values. E.g.

Programming Languages. Tail Recursion. CSE 130: Winter Lecture 8: NOT TR. last thing function does is a recursive call

Today s Plan. Programming Languages. Example : Factorial. Recursion. CSE 130 : Spring Lecture 6: Higher-Order Functions

Programming Languages

CMSC 330: Organization of Programming Languages. Functional Programming with Lists

CMSC 330: Organization of Programming Languages. Functional Programming with Lists

Begin at the beginning

Mini-ML. CS 502 Lecture 2 8/28/08

CSC324- TUTORIAL 5. Shems Saleh* *Some slides inspired by/based on Afsaneh Fazly s slides

Programming Languages Lecture 14: Sum, Product, Recursive Types

Exercises on ML. Programming Languages. Chanseok Oh

CSE 130: Programming Languages. Polymorphism. Ranjit Jhala UC San Diego

CS 11 Haskell track: lecture 1

CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists. Zach Tatlock Winter 2018

Function definitions. CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists. Example, extended. Some gotchas. Zach Tatlock Winter 2018

Logic - CM0845 Introduction to Haskell

Haske k ll An introduction to Functional functional programming using Haskell Purely Lazy Example: QuickSort in Java Example: QuickSort in Haskell

Programming Languages Lecture 15: Recursive Types & Subtyping

Side note: Tail Recursion. Begin at the beginning. Side note: Tail Recursion. Base Types. Base Type: int. Base Type: int

Tail Recursion: Factorial. Begin at the beginning. How does it execute? Tail recursion. Tail recursive factorial. Tail recursive factorial

An introduction introduction to functional functional programming programming using usin Haskell

Inductive Data Types

Informatics 1 Functional Programming Lecture 9. Algebraic Data Types. Don Sannella University of Edinburgh

Handout 2 August 25, 2008

Tuples. CMSC 330: Organization of Programming Languages. Examples With Tuples. Another Example

CS Lecture 5: Pattern Matching. Prof. Clarkson Fall Today s music: Puff, the Magic Dragon by Peter, Paul & Mary

Functions & First Class Function Values

Redefinition of an identifier is OK, but this is redefinition not assignment; Thus

Recursion. Q: What does this evaluate to? Q: What does this evaluate to? CSE 130 : Programming Languages. Higher-Order Functions

CSE341 Autumn 2017, Midterm Examination October 30, 2017

A Third Look At ML. Chapter Nine Modern Programming Languages, 2nd ed. 1

Introduction to Functional Programming in Haskell 1 / 56

Functional Programming

Lists. Michael P. Fourman. February 2, 2010

CSC324 Functional Programming Typing, Exceptions in ML

Cornell University 12 Oct Solutions. (a) [9 pts] For each of the 3 functions below, pick an appropriate type for it from the list below.

SCHEME 8. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. March 23, 2017

News. CSE 130: Programming Languages. Environments & Closures. Functions are first-class values. Recap: Functions as first-class values

CMSC 330: Organization of Programming Languages. Operational Semantics

Lecture #23: Conversion and Type Inference

CSE 130 [Winter 2014] Programming Languages

CSCI-GA Scripting Languages

SCHEME The Scheme Interpreter. 2 Primitives COMPUTER SCIENCE 61A. October 29th, 2012

GADTs. Wouter Swierstra. Advanced functional programming - Lecture 7. Faculty of Science Information and Computing Sciences

Conversion vs. Subtyping. Lecture #23: Conversion and Type Inference. Integer Conversions. Conversions: Implicit vs. Explicit. Object x = "Hello";

Lecture #13: Type Inference and Unification. Typing In the Language ML. Type Inference. Doing Type Inference

Type Checking and Type Inference

Programming Languages. Programming with λ-calculus. Lecture 11: Type Systems. Special Hour to discuss HW? if-then-else int

A Second Look At ML. Chapter Seven Modern Programming Languages, 2nd ed. 1

CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists. Dan Grossman Fall 2011

Background. CMSC 330: Organization of Programming Languages. Useful Information on OCaml language. Dialects of ML. ML (Meta Language) Standard ML

Programming Languages. Example 5. Example 4. CSE 130 : Fall type, can reuse code for all types! let rec cat l = match l with

A Programming Language. A different language g is a different vision of life. CSE 130 : Fall Two variables. L1: x++; y--; (y=0)?

Summer 2017 Discussion 10: July 25, Introduction. 2 Primitives and Define

Programming with Math and Logic

GADTs. Wouter Swierstra and Alejandro Serrano. Advanced functional programming - Lecture 7. [Faculty of Science Information and Computing Sciences]

Recap: Functions as first-class values

CSE 341, Autumn 2005, Assignment 3 ML - MiniML Interpreter

CS558 Programming Languages

CSE 341: Programming Languages

GADTs. Alejandro Serrano. AFP Summer School. [Faculty of Science Information and Computing Sciences]

CS558 Programming Languages

Introduction to OCaml

CSE341, Fall 2011, Midterm Examination October 31, 2011

CSE341 Spring 2016, Midterm Examination April 29, 2016

Problem Set CVO 103, Spring 2018

CSci 4223 Lecture 12 March 4, 2013 Topics: Lexical scope, dynamic scope, closures

Dialects of ML. CMSC 330: Organization of Programming Languages. Dialects of ML (cont.) Features of ML. Functional Languages. Features of ML (cont.

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

CMSC 330: Organization of Programming Languages

Announcements. CSCI 334: Principles of Programming Languages. Lecture 5: Fundamentals III & ML

Lists. Prof. Clarkson Fall Today s music: "Blank Space" by Taylor Swift

Standard ML. Data types. ML Datatypes.1

CSE341, Fall 2011, Midterm Examination October 31, 2011

CSE 307: Principles of Programming Languages

CS558 Programming Languages

Transcription:

CSE 130 : Winter 2013 Programming Languages Lecture 3: Crash Course, Datatypes Ranjit Jhala UC San Diego 1

Story So Far... Simple Expressions Branches Let-Bindings... Today: Finish Crash Course Datatypes 2 2

Next class: functions, but remember Expression Value Type Everything is an expression Everything has a value Everything has a type A function is a value! 3

Complex types: Functions! Parameter (formal) Body Expr fun x -> x+1;; fn int -> int # let inc = fun x -> x+1 ; val inc : int -> int = fn # inc 0; val it : int = 1 # inc 10; val it : int = 11 4

A Problem Parameter (formal) Body Expr fun x -> x+1;; fn int -> int Functions only have ONE parameter?! How a call ( application ) is evaluated: 1. Evaluate argument 2. Bind formal to arg value 3. Evaluate Body expr 5

A Solution: Simultaneous Binding Parameter (formal) Body Expr fun (x,y) -> x<y; fn (int * int) -> bool Functions only have ONE parameter? How a call ( application ) is evaluated: 1. Evaluate argument 2. Bind formal to arg value 3. Evaluate Body expr 6

Another Solution ( Currying ) Parameter (formal) Body Expr fun x -> fun y-> x<y; fn int -> (int -> bool) Whoa! A function can return a function # let lt = fun x -> fun y -> x < y ; val lt : int -> int -> bool = fn # let is5lt = lt 5; val is5lt : int -> bool = fn; # is5lt 10; val it : bool = true; # is5lt 2; val it : bool = false; 7

Question: What is result of? (fun x -> not x) (a) Syntax Error (b) <fun> : int -> int (c) <fun> : int -> bool (d) <fun> : bool -> int (e) <fun> : bool -> bool 8

And how about Parameter (formal) Body Expr fun f -> fun x -> not(f x); fn ( a ->bool) -> ( a -> bool) A function can also take a function argument # let neg = fun f -> fun x -> not (f x); val lt : int -> int -> bool = fn # let is5gte = neg is5lt; val is5gte : int -> bool = fn # is5gte 10; val it : bool = false; # is5gte 2; val it : bool = true; (* odd, even *) 9

Question: What is result of? (fun f -> (fun x -> (f x)+x)) (a) Syntax Error (b) Type Error (c) <fun> : int -> int -> int (d) <fun> : int -> int (e) <fun> : (int->int)-> int -> int 10

A shorthand for function binding # let neg = fun f -> fun x -> not (f x); # let neg f x = not (f x); val neg : int -> int -> bool = fn # let is5gte = neg is5lt; val is5gte : int -> bool = fn; # is5gte 10; val it : bool = false; # is5gte 2; val it : bool = true; 11

Put it together: a filter function If arg matches this pattern then use this Body Expr - let rec filter f xs = match xs with [] -> [] (x::xs )-> if f x then x::(filter f xs ) else (filter f xs );; val filter : ( a->bool)-> a list-> a lisi) = fn # let list1 = [1;31;12;4;7;2;10];; # filter is5lt list1 ;; val it : int list = [31;12;7;10] # filter is5gte list1;; val it : int list = [1;4;2] # filter even list1;; val it : int list = [12;4;2;10] 12

Put it together: a partition function # let partition f l = (filter f l, filter (neg f) l); val partition :( a->bool)-> a list-> a lisi * a list = fn # let list1 = [1,31,12,4,7,2,10]; - # partition is5lt list1 ; val it : (int list * int list) = ([31,12,7,10],[1,2,10] # partition even list1; val it : (int list * int list) = ([12,4,2,10],[1,31,7]) 13

A little trick # 2 <= 3;; val it : bool = true # ba <= ab ;; val it : bool = false # let lt = (<) ;; val it : a -> a -> bool = fn # lt 2 3;; val it : bool = true; # lt ba ab ;; val it : bool = false; # let is5lt = lt 5; val is5lt : int -> bool = fn; # is5lt 10; val it : bool = true; # is5lt 2; val it : bool = false; 14

Put it together: a quicksort function let rec sort xs = match xs with [] -> [] (h::t) -> let (l,r) = partition ((<) h) t in (sort l)@(h::(sort r)) Now, lets begin at the beginning 15

What about more complex data? Expressions Values Types Many kinds of expressions: 1. Simple 2. Variables 3. Functions 16

What about more complex data? We ve seen some base types and values: Integers, Floats, Bool, String etc. Some ways to build up types: Products (tuples), records, lists Functions Design Principle: Orthogonality Don t clutter core language with stuff Few, powerful orthogonal building techniques Put derived types, values, functions in libraries 17

Next: Building datatypes Three key ways to build complex types/values 1. Each-of types Value of T contains value of T1 and a value of T2 2. One-of types Value of T contains value of T1 or a value of T2 3. Recursive Value of T contains (sub)-value of same type T 18

Next: Building datatypes Three key ways to build complex types/values 1. Each-of types (T1 * T2) Value of T contains value of T1 and a value of T2 2. One-of types Value of T contains value of T1 or a value of T2 3. Recursive Value of T contains (sub)-value of same type T 19

Suppose I wanted a program that processed lists of attributes Name (string) Age (integer) DOB (int-int-int) Address (string) Height (float) Alive (boolean) Phone (int-int) email (string) Many kinds of attributes (too many to put in a record) can have multiple names, addresses, phones, emails etc. Want to store them in a list. Can I? 20

Suppose I wanted Attributes: Name (string) Age (integer) DOB (int-int-int) Address (string) Height (real) Alive (boolean) Phone (int-int) email (string) type attrib = Name of string Age of int DOB of int*int*int Address of string Height of float Alive of bool Phone of int*int Email of string;; 21

Question: Here is a typedef... type attrib = Name of string Age of int Height of float What is the type of: (a) Syntax Error (b) Type Error (c) string (d) attrib (e) a Name Tony Stark 22

Constructing Datatypes type t = C1 of t1 C2 of t2 Cn of tn t is a new datatype. A value of type t is either: a value of type t1 placed in a box labeled C1 Or a value of type t2 placed in a box labeled C2 Or Or a value of type tn placed in a box labeled Cn 23

Constructing Datatypes type t = C1 of t1 C2 of t2 Cn of tn Label=C1 Value:t1 OR t Label=C2 Value:t2 OR Label=Cn Value:tn All have the type t 24

How to PUT values into box? 25

Question: Here is a typedef... type attrib = Name of string Age of int Height of float What is the type of: (a) Syntax Error (b) Type Error (c) string (d) attrib (e) a Age Tony Stark 26

How to PUT values into box? How to create values of type attrib? # let a1 = Name Ranjit ;; val x : attrib = Name Ranjit # let a2 = Height 5.83;; val a2 : attrib = Height 5.83 # let year = 1977 ;; val year : int = 1977 # let a3 = DOB (9,8,year) ;; val a3 : attrib = DOB (9,8,1977) # let a_l = [a1;a2;a3];; val a3 : attrib list = type attrib = Name of string Age of int DOB of int*int*int Address of string Height of float Alive of bool Phone of int*int Email of string;; 27

Constructing Datatypes type attrib = Name of string Age of int DOB of int*int*int Address of string Height of float Alive of bool Phone of int*int Email of string;; Name Ranjit OR Age 34 OR DOB (9,8,77) Name Ranjit Age 34 DOB (9,8,77) All have type attrib 28

One-of types We ve defined a one-of type named attrib Elements are one of: string, int, int*int*int, float, bool Can create uniform attrib lists datatype attrib = Name of string Age of int DOB of int*int*int Address of string Height of real Alive of bool Phone of int*int Email of string; Say I want a function to print attribs 29

Question: Here is a typedef... type attrib = Name of string Age of int Height of float What is the type of: [Name Ranjit ; Age 35; Dob(9,8,77)] (a) Syntax Error (b) Type Error (c) string * int * (int*int*int) list (d) a list (e) attrib list 30

How to TEST & TAKE whats in box? Is it a... string? or an int? or an int*int*int? or... 31

How to TEST & TAKE whats in box? Tag Look at TAG! 32

Question: Here is a typedef... type attrib = Name of string Age of int... What does this evaluate to? let welcome a = match a with Name s - > s in welcome (Name Ranjit ) (a) Name Ranjit : a (b) Type Error (c) Name Ranjit : attrib (d) Ranjit : string (e) Runtime Error 33

How to tell whats in the box? type attrib = Name of string Age of int DOB of int*int*int Address of string Height of float Alive of bool Phone of int*int match e with Name s ->...(*s: string *) Age i ->...(*i: int *) DOB(d,m,y)->...(*d: int,m: int,y: int*) Address a ->...(*a: string*) Height h ->...(*h: int *) Alive b ->...(*b: bool*) Phone(y,r)->...(*a: int, r: int*) Pattern-match expression: check if e is of the form On match: value in box bound to pattern variable matching result expression is evaluated Simultaneously test and extract contents of box 34

How to tell whats in the box? match e with Name s -> printf "%s" s Age i -> printf "%d" i DOB(d,m,y) -> printf "%d/%d/%d" d m y Address s -> printf "%s" s Height h -> printf "%f" h Alive b -> printf "%b" b s Phone(a,r) -> printf "(%d)-%d" a r Pattern-match expression: check if e is of the form On match: value in box bound to pattern variable matching result expression is evaluated Simultaneously test and extract contents of box 35

Question: Here is a typedef... type attrib = Name of string Age of int... What does this evaluate to? let welcome a = match a with in welcome (Age 34) Name s - > s (a) Name Ranjit : a (b) Type Error (c) Name Ranjit : attrib (d) Ranjit : string (e) Runtime Error 36

How to tell whats in the box # match (Name Ranjit ) with Name s - > printf "Hello %s\n" s Age i - > printf "%d years old" i ;; Hello Ranjit - : unit = () First case matches the tag (Name) Evals branch with s bound to string contents 37

How to TEST & TAKE whats in box? Tag BEWARE!! Be sure to handle all TAGS! 38

Beware! Handle All TAGS! # match (Name Ranjit ) with Age i - > Printf.printf "%d" i Email s - > Printf.printf "%s" s ;; Exception: Match Failure!! None of the cases matched the tag (Name) Causes nasty Run-Time Error 39

Compiler To The Rescue!! # let printattrib a = match a with Name s - > Printf.printf "%s" s Age i - > Printf.printf "%d" i DOB (d,m,y) - > Printf.printf "%d / %d / %d" d m y Address addr - > Printf.printf "%s" addr Height h - > Printf.printf "%f" h Alive b - > Printf.printf "%b" b Email e - > Printf.printf "%s" e ;; Warning P: this pattern- matching is not exhaustive. Here is an example of a value that is not matched: Phone (_, _) Compile-time checks for: missed cases: ML warns if you miss a case! 40

Q: What does this evaluate to? type attrib = Name of string... let welcome a = match a with Name s - > Hello! ^ s Name s - > Welcome! ^ s in welcome (Name Mickey ) (a) Type Error (b) Welcome!Mickey : string (c) Runtime Error (d) Hello!Mickey : string (e) Hello!MickeyWelcome!Mickey Ranjit : string 41

Compiler To The Rescue!! # let printattrib a = match a with Name s - > Printf.printf "%s" s Age i - > Printf.printf "%d" i DOB (d,m,y) - > Printf.printf "%d / %d / %d" d m y... Age i - > Printf.printf "%d" i ;; Warning U: this match case is unused. Compile-time checks for: redundant cases: ML warns if a case never matches 42

Benefits of match-with match e with C1 x1 -> e1 C2 x2 -> e2 Cn xn -> en type t = C1 of t1 C2 of t2 Cn of tn 1. Simultaneous test-extract-bind 2. Compile-time checks for: missed cases: ML warns if you miss a t value redundant cases: ML warns if a case never matches 43

match-with is an Expression match e with C1 x1 -> e1 C2 x2 -> e2 Cn xn -> en 44

Q: What does this evaluate to? type attrib = Name of string Age of int... let welcome a = match a with Name s - > s Age i - > i in welcome (Name Ranjit ) (a) Ranjit : string (b) Type Error (c) Name Ranjit : attrib (d) Runtime Error 45

T{ T match-with is an Expression match e with Name s -> e1 Age i -> e2 DOB (m,d,y) -> e3 Address a -> e4 Height h -> e5 Alive b -> e6 Phone (a,n) -> e7 Email e -> e8 Type Rule e1, e2,,en must have same type T Type of whole expression is T 46

Next: Building datatypes Three key ways to build complex types/values 1. Each-of types t1 * t2 Value of T contains value of T1 and a value of T2 2. One-of types type t = C1 of t1 C2 of t2 Value of T contains value of T1 or a value of T2 3. Recursive type Value of T contains (sub)-value of same type T 47

Recursive types type nat = Zero Succ of nat 48

Recursive types type nat = Zero Succ of nat Wait a minute! Zero of what?! 49

Recursive types type nat = Zero Succ of nat Wait a minute! Zero of what?! Relax. Means empty box with label Zero 50

Recursive types type nat = Zero Succ of nat What are values of nat? 51

Recursive types type nat = Zero Succ of nat What are values of nat? Zero 52

Recursive types type nat = Zero Succ of nat What are values of nat? One nat contains another! Succ Zero 53

Recursive types type nat = Zero Succ of nat What are values of nat? One nat contains another! Succ Succ Zero 54

Recursive types type nat = Zero Succ of nat What are values of nat? One nat contains another! Succ Succ Succ Zero 55

Recursive types type nat = Zero Succ of nat What are values of nat? One nat contains another! nat = recursive type Succ Succ Succ... Zero 56

Next: Building datatypes Three key ways to build complex types/values 1. Each-of types t1 * t2 Value of T contains value of T1 and a value of T2 2. One-of types type t = C1 of t1 C2 of t2 Value of T contains value of T1 or a value of T2 3. Recursive type type t =... C of (...*t) Value of T contains (sub)-value of same type T 57

Next: Lets get cosy with Recursion Recursive Code Mirrors Recursive Data 58

Next: Lets get cosy with Recursion Code Structure = Type Structure!!! 59

Q: What does this evaluate to? let rec foo n = if n<=0 then Zero else Succ(foo(n- 1)) in foo 2 (a) Zero : nat (b) Type Error (c) 2 : nat (c) Succ(Zero): nat (c) Succ(Succ(Zero)) : nat 60

of_int : int -> nat type nat = Zero Succ of nat let rec of_int n = 61

of_int : int -> nat Base pattern Inductive pattern type nat = Zero Succ of nat let rec of_int n = 62

of_int : int -> nat Base pattern Inductive pattern type nat = Zero Succ of nat Base pattern Inductive pattern let rec of_int n = if n <= 0 then else 63

of_int : int -> nat Base pattern Inductive pattern type nat = Zero Succ of nat Base pattern Inductive pattern let rec of_int n = if n <= 0 then Zero Base Expression else Succ (of_int (n-1)) Inductive Expression 64

to_int : nat -> int type nat = Zero Succ of nat let rec to_int n = 65

to_int : nat -> int Base pattern Inductive pattern type nat = Zero Succ of nat let rec to_int n = 66

to_int : nat -> int Base pattern Inductive pattern type nat = Zero Succ of nat Base pattern Inductive pattern let rec to_int n = match n with Zero -> Succ m -> 67

to_int : nat -> int Base pattern Inductive pattern type nat = Zero Succ of nat Base pattern Inductive pattern let rec to_int n = match n with Zero -> 0 Base Expression Succ m -> 1 + to_int m Inductive Expression 68

plus : nat*nat -> nat type nat = Zero Succ of nat let rec plus (n,m) = 69

plus : nat*nat -> nat Base pattern Inductive pattern type nat = Zero Succ of nat let rec plus (n,m) = 70

plus : nat*nat -> nat Base pattern Inductive pattern type nat = Zero Succ of nat Base pattern Inductive pattern let rec plus (n,m) = match m with Zero -> Succ m -> 71

plus : nat*nat -> nat Base pattern Inductive pattern type nat = Zero Succ of nat Base pattern Inductive pattern let rec plus (n,m) = match m with Base Expression Zero -> n Succ m -> Succ (plus (n,m )) Inductive Expression 72

times: nat*nat -> nat type nat = Zero Succ of nat let rec times (n,m) = 73

times: nat*nat -> nat Base pattern Inductive pattern type nat = Zero Succ of nat let rec times (n,m) = 74

times: nat*nat -> nat Base pattern Inductive pattern type nat = Zero Succ of nat Base pattern Inductive pattern let rec times (n,m) = match m with Zero -> Succ m -> 75

times: nat*nat -> nat Base pattern Inductive pattern type nat = Zero Succ of nat Base pattern Inductive pattern let rec times (n,m) = match m with Base Expression Zero -> Zero Succ m -> plus n (times (n,m )) Inductive Expression 76

type nat = Zero Succ of nat Q: How would you write: minus: nat*nat -> nat 77

times: nat*nat -> nat Base pattern Inductive pattern type nat = Zero Succ of nat let rec minus (n,m) = 78

times: nat*nat -> nat Base pattern Inductive pattern type nat = Zero Succ of nat Base pattern Inductive pattern let rec minus (n,m) = match (n, m) with (_, Zero) -> n (Succ n, Succ m ) -> minus(n,m ) 79

times: nat*nat -> nat Base pattern Inductive pattern type nat = Zero Succ of nat Base pattern Inductive pattern let rec minus (n,m) = match (n, m) with (_, Zero) -> n (Succ n, Succ m ) -> minus(n,m ) Base Expression Inductive Expression 80

Next: Lets get cosy with Recursion Recursive Code Mirrors Recursive Data 81

Lists are recursive types! type int_list = Nil Cons of int * int_list Think about this! What are values of int_list? Cons(1,Cons(2,Cons(3,Nil))) Cons(2,Cons(3,Nil)) Cons(3,Nil) Nil Cons 1, Cons 2, Cons 3, Nil 82

Lists aren t built-in! datatype int_list = Nil Cons of int * int_list Lists are a derived type: built using elegant core! 1. Each-of 2. One-of 3. Recursive :: is just a pretty way to say Cons [] is just a pretty way to say Nil 83

Some functions on Lists : Length Base pattern Ind pattern let rec len l = match l with Nil -> 0 Cons(h,t) -> 1 + (len t) Base Expression Inductive Expression let rec len l = match l with Nil -> 0 Cons(_,t) -> 1 + (len t) let rec len l = match l with Cons(_,t) -> 1 + (len t) _ -> 0 Matches everything, no binding Pattern-matching in order - Must match with Nil 84

Some functions on Lists : Max Base pattern let rec max xs = Base Expression Ind pattern Inductive Expression Find the right induction strategy Base case: pattern + expression Induction case: pattern + expression Well designed datatype gives strategy 85

Some functions on Lists : Append Base pattern let rec append (l1,l2) = Base Expression Ind pattern Inductive Expression Find the right induction strategy Base case: pattern + expression Induction case: pattern + expression Well designed datatype gives strategy 86

null, hd, tl are all functions Bad ML style: More than aesthetics! Pattern-matching better than test-extract: ML checks all cases covered ML checks no redundant cases at compile-time: fewer errors (crashes) during execution get the bugs out ASAP! 87

Next: Lets get cosy with Recursion Recursive Code Mirrors Recursive Data 88

Q: How is this tree represented? type tree = Leaf of int Node of tree*tree 1 2 3 (a) (1, 2), 3 (b) (Leaf 1, Leaf 2), Leaf 3 (c) Node (Node (Leaf 1, Leaf 2), Leaf 3) (d) Node ((Leaf 1, Leaf 2), Leaf 3) (e) None of the above 89

Representing Trees 1 2 3 Leaf 1 type tree = Leaf of int Node of tree*tree Node(Node(Leaf 1, Leaf 2), Leaf 3) 90

Representing Trees 1 2 3 Leaf 2 type tree = Leaf of int Node of tree*tree Node(Node(Leaf 1, Leaf 2), Leaf 3) 91

Representing Trees Node 1 2 3 Leaf 1 Leaf 2 type tree = Leaf of int Node of tree*tree Node(Node(Leaf 1, Leaf 2), Leaf 3) 92

Representing Trees 1 2 3 Leaf 3 type tree = Leaf of int Node of tree*tree Node(Node(Leaf 1, Leaf 2), Leaf 3) 93

Representing Trees Node Node Leaf Leaf Leaf 1 2 3 1 2 3 type tree = Leaf of int Node of tree*tree Node(Node(Leaf 1, Leaf 2), Leaf 3) 94

Representing Trees Node Node Leaf Leaf Leaf 1 2 3 1 2 3 type tree = Leaf of int Node of tree*tree Node(Node(Leaf 1, Leaf 2), Leaf 3) 95

Next: Lets get cosy with Recursion Recursive Code Mirrors Recursive Data 96

Q: What does this evaluate to? let rec foo t = match t with Leaf n - > 1 Node (t1, t2) - > foo t1 + foo t2 in foo (Node(Node(Leaf 1, Leaf 2), Leaf 3)) (a) Type Error (b) 1 : int (c) 3 : int (d) 6 : int 97

sum_leaf: tree -> int Sum up the leaf values. E.g. # let t0 = Node(Node(Leaf 1, Leaf 2), Leaf 3);; # sum_leaf t0 ;; - : int = 6 98

sum_leaf: tree -> int type tree = Leaf of int Node of tree*tree let rec sum_leaf t = 99

sum_leaf: tree -> int Base pattern Inductive pattern type tree = Leaf of int Node of tree*tree let rec sum_leaf t = 100

sum_leaf: tree -> int Base pattern Inductive pattern type tree = Leaf of int Node of tree*tree Base pattern Inductive pattern let rec sum_leaf t = match t with Leaf n -> Node(t1,t2)-> 101

sum_leaf: tree -> int Base pattern Inductive pattern type tree = Leaf of int Node of tree*tree Base pattern Inductive pattern let rec sum_leaf t = match t with Leaf n -> n Base Expression Node(t1,t2)-> sum_leaf t1 + sum_leaf t2 Inductive Expression 102

Recursive Code Mirrors Recursive Data Code almost writes itself! 103

Another Example: Calculator Want an arithmetic calculator to evaluate expressions like: 4.0 + 2.9 3.78 5.92 (4.0 + 2.9) * (3.78-5.92) 104

Another Example: Calculator Want an arithmetic calculator to evaluate expressions like: 4.0 + 2.9 ====> 6.9 3.78 5.92 ====> -2.14 (4.0 + 2.9) * (3.78-5.92) ====> -14.766 Whats a ML TYPE for REPRESENTING expressions? 105

Another Example: Calculator Want an arithmetic calculator to evaluate expressions like: 4.0 + 2.9 ====> 6.9 3.78 5.92 ====> -2.14 (4.0 + 2.9) * (3.78-5.92) ====> -14.766 Whats a ML TYPE for REPRESENTING expressions? type expr = Num of float Add of expr*expr Sub of expr*expr Mul of expr*expr 106

Another Example: Calculator Want an arithmetic calculator to evaluate expressions like: 4.0 + 2.9 ====> 6.9 3.78 5.92 ====> -2.14 (4.0 + 2.9) * (3.78-5.92) ====> -14.766 Whats a ML FUNCTION for EVALUATING expressions? type expr = Num of float Add of expr*expr Sub of expr*expr Mul of expr*expr 107

Another Example: Calculator Want an arithmetic calculator to evaluate expressions like: 4.0 + 2.9 ====> 6.9 3.78 5.92 ====> -2.14 (4.0 + 2.9) * (3.78-5.92) ====> -14.766 Whats a ML FUNCTION for EVALUATING expressions? type expr = Num of float Add of expr*expr Sub of expr*expr Mul of expr*expr 108

Another Example: Calculator Want an arithmetic calculator to evaluate expressions like: 4.0 + 2.9 ====> 6.9 3.78 5.92 ====> -2.14 (4.0 + 2.9) * (3.78-5.92) ====> -14.766 Whats a ML FUNCTION for EVALUATING expressions? type expr = Num of float Add of expr*expr Sub of expr*expr Mul of expr*expr let rec eval e = match e with Num f -> Add(e1,e2)-> Sub(e1,e2)-> Mul(e1,e2)-> 109

Another Example: Calculator Want an arithmetic calculator to evaluate expressions like: 4.0 + 2.9 ====> 6.9 3.78 5.92 ====> -2.14 (4.0 + 2.9) * (3.78-5.92) ====> -14.766 Whats a ML FUNCTION for EVALUATING expressions? type expr = Num of float Add of expr*expr Sub of expr*expr Mul of expr*expr let rec eval e = match e with Num f -> f Add(e1,e2)-> eval e1 +. eval e2 Sub(e1,e2)-> eval e1 -. eval e2 Mul(e1,e2)-> eval e1 *. eval e2 110

Random Art from Expressions PA #2 Build more funky expressions, evaluate them, to produce: 111