CSE321 Programming Languages Introduction to Functional Programming Part

  • Slides: 52
Download presentation
CSE-321 Programming Languages Introduction to Functional Programming (Part II) 박성우 POSTECH March 13, 2006

CSE-321 Programming Languages Introduction to Functional Programming (Part II) 박성우 POSTECH March 13, 2006

Outline • • • Expressions and values V Variables V Functions V Types –

Outline • • • Expressions and values V Variables V Functions V Types – Polymorphism Recursion Datatypes Pattern matching Higher-order functions Exceptions Modules 2

What is the Type of f ? All we know about f is that

What is the Type of f ? All we know about f is that it takes booleans as arguments. fn f => (f true, f false) ( f true, f false) 3

f : bool -> ? fn f => (f true, f false) : (bool

f : bool -> ? fn f => (f true, f false) : (bool -> ? ) -> ? * ? 4

f : bool -> 'a fn f => (f true, f false) : (bool

f : bool -> 'a fn f => (f true, f false) : (bool -> 'a) -> 'a * 'a • 'a – type variable – usually read as alpha – means 'for any type alpha' 5

Polymorphic Types • Types involving type variables 'a, 'b, 'c, . . . •

Polymorphic Types • Types involving type variables 'a, 'b, 'c, . . . • E. g. – fn x => x : 'a -> 'a – fn x => fn y => (x, y) : 'a -> 'b -> ('a * 'b) – fn (x : 'a) => fn (y : 'a) => x = y : 'a -> bool (* actually does not typecheck! *) 6

Equality Types • Motivation – Equality (=) is not defined on every type. –

Equality Types • Motivation – Equality (=) is not defined on every type. – E. g. • comparing two functions for equality? • Type variables with equality – ''a, ''b, ''c, . . . – ''a means 'for any type alpha for which equality is defined' – fn (x : ''a) => fn (y : ''a) => x = y : ''a -> bool 7

Outline • • • Expressions and values V Variables V Functions V Types V

Outline • • • Expressions and values V Variables V Functions V Types V Recursion Datatypes Pattern matching Higher-order functions Exceptions Modules 8

Recursion vs. Iteration • Recursion in SML fun sum n = if n =

Recursion vs. Iteration • Recursion in SML fun sum n = if n = 0 then 0 else sum (n - 1) + n • Iteration in C int i, sum; for (i = 0, sum = 0; i <= n; i++) sum += n; • Recursion is not an awkward tool if you are used to functional programming. • Recursion seems elegant but inefficient! 9

Recursion in Action fun sum n = if n = 0 then 0 else

Recursion in Action fun sum n = if n = 0 then 0 else sum (n - 1) + n call stack 0 f 1 f 9 f 10 further computation 1 + 2. . . f 8 0 + 1 36 + 9 45 + 10 55 evaluation 10

Funny Recursion fun zero n = if n = 0 then 0 else zero

Funny Recursion fun zero n = if n = 0 then 0 else zero (n - 1) call stack 0 f 1 f 9 f 10 no further computation 0. . . f 8 0 0 evaluation 11

Funny Recursion Optimized fun zero n = if n = 0 then 0 else

Funny Recursion Optimized fun zero n = if n = 0 then 0 else zero (n - 1) call stack 0 f 1 f 9 f 10 0. . . f 8 0 0 evaluation 12

Funny Recursion Further Optimized fun zero n = if n = 0 then 0

Funny Recursion Further Optimized fun zero n = if n = 0 then 0 else zero (n - 1) call stack f 10 f 9 f 8 . . . f 1 f 0 0 evaluation 13

Tail Recursive Function • A tail recursive function f: – A recursive call to

Tail Recursive Function • A tail recursive function f: – A recursive call to f is the last step in evaluating the function body. – That is, no more computation remains after calling f itself. • A tail recursive call needs no stack! • A tail recursive call is as efficient as iteration! 14

Example • Non-tail recursive sum fun sum n = if n = 0 then

Example • Non-tail recursive sum fun sum n = if n = 0 then 0 else sum (n - 1) + n • Tail recursive sum fun sum' accum k = if k = 0 then accum else sum' (accum + k) (k - 1) fun sum n = sum' 0 n • Think about the invariant of sum: – given: sum' accum k – invariant: accum = (k + 1) +. . . + n 15

Mathematics vs. Computer Science • CS ½ Math? Math CS • CS Math? Math

Mathematics vs. Computer Science • CS ½ Math? Math CS • CS Math? Math CS 16

Factorial Function fac 1 = 1 fac n = n * fac (n -

Factorial Function fac 1 = 1 fac n = n * fac (n - 1) • Makes sense in – Math – CS fac 1 = 1 fac n = fac (n + 1) / n • Makes sense in math. • But not in CS: – it always diverges. • "Then what kind of recursive functions are computationally meaningful? " ) domain theory in computer science • Other examples – real numbers vs. computable real numbers – logic in math vs. logic in computer science 17

Outline • • • Expressions and values V Variables V Functions V Types V

Outline • • • Expressions and values V Variables V Functions V Types V Recursion V Datatypes Pattern matching Higher-order functions Exceptions Modules 18

Enumeration Types in C enum shape { Circle, Rectangle, Triangle}; • Great flexibility –

Enumeration Types in C enum shape { Circle, Rectangle, Triangle}; • Great flexibility – e. g. Circle + 1 == Rectangle Triangle - 1 == Rectangle (Circle + Triangle) / 2 == Rectangle • But is this good or bad? 19

Datatypes in SML datatype shape = Circle | Rectangle | Triangle • No flexibility

Datatypes in SML datatype shape = Circle | Rectangle | Triangle • No flexibility – e. g. Circle + 1 Triangle - 1 Circle + Triangle (x) (x) • But high safety. 20

Primitive Set datatype set = Empty | Singleton | Pair | Many - Empty;

Primitive Set datatype set = Empty | Singleton | Pair | Many - Empty; val it = Empty : set - Many; val it = Many : set 21

Primitive Set with Arguments datatype set = Empty | Singleton | Pair | Many

Primitive Set with Arguments datatype set = Empty | Singleton | Pair | Many of int - Many 5; val it = Many 5 : set 22

Primitive Set with Type Parameters datatype 'a set = Empty | Singleton of 'a

Primitive Set with Type Parameters datatype 'a set = Empty | Singleton of 'a | Pair of 'a * 'a | Many of int - Singleton 0; val it = Singleton 0 : int set - Pair (0, 1); val it = Pair (0, 1) : int set 23

Primitive Set with Type Parameters datatype 'a set = Empty | Singleton of 'a

Primitive Set with Type Parameters datatype 'a set = Empty | Singleton of 'a | Pair of 'a * 'a | Many of int - Pair (Singleton 0, Pair (0, 1)) val it = Pair (Singleton 0, Pair (0, 1)) : int set 24

Primitive Set with Type Parameters datatype 'a set = Empty | Singleton of 'a

Primitive Set with Type Parameters datatype 'a set = Empty | Singleton of 'a | Pair of 'a * 'a | Many of int - Empty; val it = Empty : 'a set - Many 5; val it = Many 5 : 'a set 25

Primitive Set with Type Parameters datatype 'a set = Empty | Singleton of 'a

Primitive Set with Type Parameters datatype 'a set = Empty | Singleton of 'a | Pair of 'a * 'a | Many of int - Pair (0, true); std. In: 27. 1 -27. 15 Error: operator and operand don't agree [literal] operator domain: int * int operand: int * bool in expression: Pair (0, true) 26

Recursive Set with Type Parameters datatype 'a set = Empty | Non. Empty of

Recursive Set with Type Parameters datatype 'a set = Empty | Non. Empty of 'a * 'a set • This is essentially the definition of datatype list. 27

Datatype list datatype 'a list = nil | : : of 'a * 'a

Datatype list datatype 'a list = nil | : : of 'a * 'a list - nil; val it = [] : 'a list - 2 : : nil; val it = [2] : int list - 1 : : (2 : : nil); val it = [1, 2] : int list - 1 : : 2 : : nil; val it = [1, 2] : int list 28

Datatype list datatype 'a list = nil | : : of 'a * 'a

Datatype list datatype 'a list = nil | : : of 'a * 'a list (X) - 1 : : [2] : : nil; (X) - [1] : : 2 : : nil; - [1] : : [2] : : nil; val it = [[1], [2]] : int list - [1] : : [[2]]; val it = [[1], [2]] : int list 29

Using Datatypes • We know how to create values of various datatypes: – shape

Using Datatypes • We know how to create values of various datatypes: – shape – set – int list –. . . • But how do we use them in programming? • What is the point of creating datatype values that are never used? 30

Outline • • • Expressions and values V Variables V Functions V Types V

Outline • • • Expressions and values V Variables V Functions V Types V Recursion V Datatypes V Pattern matching Higher-order functions Exceptions Modules 31

Simple Pattern datatype shape = Circle | Rectangle | Triangle (* convert. To. Enum

Simple Pattern datatype shape = Circle | Rectangle | Triangle (* convert. To. Enum : shape -> int *) fun convert. To. Enum (x : shape) : int = case x of Circle => 0 | Rectangle => 1 | Triangle => 2 32

Pattern with Arguments datatype 'a set = Empty | Singleton of 'a | Pair

Pattern with Arguments datatype 'a set = Empty | Singleton of 'a | Pair of 'a * 'a | Many of int fun size (x : 'a set) : int = case x of Empty => 0 | Singleton e => 1 | Pair (e 1, e 2) => 2 | Many n => n 33

Wildcard Pattern _ : "don't care" datatype 'a set = Empty | Singleton of

Wildcard Pattern _ : "don't care" datatype 'a set = Empty | Singleton of 'a | Pair of 'a * 'a | Many of int fun is. Empty (x : 'a set) : bool = case x of Empty => true | _ => false 34

Pattern with Type Annotation datatype 'a list = nil | : : of 'a

Pattern with Type Annotation datatype 'a list = nil | : : of 'a * 'a list fun length (x : 'a list) : int = case x of (nil : 'a list) => 0 | (_ : 'a) : : (tail : 'a list) => 1 + length tail 35

Outline • • • Expressions and values V Variables V Functions V Types V

Outline • • • Expressions and values V Variables V Functions V Types V Recursion V Datatypes V Pattern matching V Higher-order functions Exceptions Modules 36

Higher-order Functions • Take functions as arguments. • Return functions as the result. 37

Higher-order Functions • Take functions as arguments. • Return functions as the result. 37

Why "Higher-order"? • • • T 0 T 1 T 2 T 3. .

Why "Higher-order"? • • • T 0 T 1 T 2 T 3. . . : : = int | T 0 -> T 1 -> T 2 -> bool T 0 | T 1 | T 2 | | real T 0 T 1 T 2 | (* (* (* unit |. . . 1 st order *) 2 nd order *) higher order *) 38

Higher-order Functions in List • • • val val val exists : ('a ->

Higher-order Functions in List • • • val val val exists : ('a -> bool) -> 'a list -> bool all : ('a -> bool) -> 'a list -> bool map : ('a -> 'b) -> 'a list -> 'b list filter : ('a -> bool) -> 'a list app : ('a -> unit) -> 'a list -> unit (* print. Int : int -> unit *) fun print. Int i = Text. IO. print ((Int. to. String i) ^ "n" ); List. app print. Int [1, 2, 3]; 39

List Fold Function • foldl : ('a * 'b -> 'b) -> 'b ->

List Fold Function • foldl : ('a * 'b -> 'b) -> 'b -> 'a list -> 'b foldr : ('a * 'b -> 'b) -> 'b -> 'a list -> 'b • foldl f b 0 [a 0, a 1, a 2, . . . , an-1] a 0 a 1 b 0 f b 1 f a 2 . . . an-2 b 2 f b 3. . . bn-2 f an-1 bn-1 f bn 40

Examples List. exists f l = List. foldl (fn (a, b) => b orelse

Examples List. exists f l = List. foldl (fn (a, b) => b orelse f a) false l List. all f l = List. foldl (fn (a, b) => b andalso f a) true l List. app f l = List. foldl (fn (a, _) => f a) () l List. map f l = List. foldr (fn (a, b) => f a : : b) nil l List. filter f l = List. foldr (fn (a, b) => if f a then a : : b else b) nil l 41

More Examples fun sum (l : int list) = List. foldl (fn (a, accum)

More Examples fun sum (l : int list) = List. foldl (fn (a, accum) => a + accum) 0 l fun reverse (l : 'a list) = List. foldl (fn (a, rev) => a : : rev) nil l • Whenever you need iterations over lists, first consider foldl and foldr. 42

Outline • • • Expressions and values V Variables V Functions V Types V

Outline • • • Expressions and values V Variables V Functions V Types V Recursion V Datatypes V Pattern matching V Higher-order functions V Exceptions – exception: please see the course notes. • Modules 43

Outline • • • Expressions and values V Variables V Functions V Types V

Outline • • • Expressions and values V Variables V Functions V Types V Recursion V Datatypes V Pattern matching V Higher-order functions V Exceptions V Modules 44

Structures and Signatures • Structure – collection of type declarations, exceptions, values, and so

Structures and Signatures • Structure – collection of type declarations, exceptions, values, and so on. • Signature – conceptually type of structures. structure Set = struct type 'a set = 'a list val empty. Set = nil fun singleton x = [x] fun union s 1 s 2 = s 1 @ s 2 end signature SET = sig type 'a set val empty. Set : 'a set val singleton : 'a -> 'a set val union : 'a set -> 'a set end 45

Structures + Signatures • Transparent constraint – Type definition is exported to the outside.

Structures + Signatures • Transparent constraint – Type definition is exported to the outside. • Opaque constraint – No type definition is exported. structure Set : SET = struct type 'a set = 'a list val empty. Set = nil fun singleton x = [x] fun union s 1 s 2 = s 1 @ s 2 end structure Set : > SET = struct type 'a set = 'a list val empty. Set = nil fun singleton x = [x] fun union s 1 s 2 = s 1 @ s 2 end - Set. singleton 1 = [1]; val it = true : bool - Set. singleton 1 = [1]; (* Error! *) 46

I need to test your 57 structures! structure. . . structure Bet. One :

I need to test your 57 structures! structure. . . structure Bet. One : > HW_ONE =. . . Bigh 2000 One : > HW_ONE =. . . Boong. One : > HW_ONE = Brandon. One : > HW_ONE =. . . Ziedrich. One : > HW_ONE =. . . • How can I test 57 structures? – They all conform to the same signature. 47

Simple (but Ugly) Solution fun sum. Test f = f nil = 0 andalso

Simple (but Ugly) Solution fun sum. Test f = f nil = 0 andalso f [1, 2, 3] = 6 fun fac. Test f = f 1 = 1 andalso f 3 = 6 andalso f 7 = 5040. . . fun all. Test (sum, fac, . . . ) = let val sum. Score = if sum. Test sum then 10 else 0 val fac. Score = if fac. Test fac then 4 else 0. . . in sum. Score + fac. Score +. . . end all. Test. . . all. Test (Bet. One. sum, Bet. One. fac, . . . ); (Bigh 2000 One. sum, Bigh 2000 One. fac, . . . ); (Boong. One. sum, Boong. One. fac, . . . ); (Brandon. One. sum, Brandon. One. fac, . . . ); (Ziedrich. One. sum, Ziedrich. One. fac, . . . ); 48

Functors • Functions on structures – takes a structure as an argument – returns

Functors • Functions on structures – takes a structure as an argument – returns a structure as the result structure 49

HW 1 Test Functor signature HW_TEST = sig val score : int end functor

HW 1 Test Functor signature HW_TEST = sig val score : int end functor Hw 1 Test. Fn (P : HW_ONE) : HW_TEST = structure S = Hw 1 Solution val sum. Score = if P. sum nil = S. sum nil andalso P. sum [1, 2, 3] = S. sum [1, 2, 3] then 10 else 0 val fac. Score = if P. fac 1 = S. fac 1 andalso P. fac 3 = S. fac 3 andalso P. fac 7 = S. fac 7 then 4 else 0. . . val score = sum. Score + fac. Score +. . . end 50

HW 1 Test Functor in Action structure. . . structure Bet. One. Test =

HW 1 Test Functor in Action structure. . . structure Bet. One. Test = Hw 1 Test. Fn (Bet. One) Bigh 2000 One. Test = Hw 1 Test. Fn (Bigh 2000 One) Boong. One. Test = Hw 1 Test. Fn (Boong. One) Brandon. One. Test = Hw 1 Test. Fn (Brandon. One) Ziedrich. One. Test = Hw 1 Test. Fn (Ziedrich. One) Bet. One. Test. score; Bigh 2000 One. Test. score; Boong. One. Test. score; Brandon. One. Test. score; . . . Ziedrich. One. Test. score; 51

So it is YOU who will grade your homework! 52

So it is YOU who will grade your homework! 52