Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "CSE-321 Programming Languages Introduction to Functional Programming (Part II) POSTECH March 13, 2006 박성우."— Presentation transcript:

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

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

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

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

5 5 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'

6 6 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 -> 'a -> bool (* actually does not typecheck! *)

7 7 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 -> ''a -> bool

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

9 9 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!

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

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

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

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

14 14 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!

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

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

17 17 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

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

19 19 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?

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

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

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

23 23 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

24 24 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 set

25 25 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

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

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

28 28 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

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

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

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

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

33 33 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 (e1, e2) => 2 | Many n => n

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

35 35 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

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

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

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

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

40 40 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,..., a n-1 ] b0b0 a0a0 f b1b1 a1a1 f b2b2 a n-1 f bnbn a2a2 f b3b3 b n-2 a n-2 f b n-1...

41 41 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

42 42 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.

43 43 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

44 44 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

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

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

47 47 I need to test your 57 structures! structure BetOne :> HW_ONE =... structure Bigh2000One :> HW_ONE =... structure BoongOne :> HW_ONE = structure BrandonOne :> HW_ONE =...... structure ZiedrichOne :> HW_ONE =... How can I test 57 structures? –They all conform to the same signature.

48 48 Simple (but Ugly) Solution fun sumTest f = f nil = 0 andalso f [1, 2, 3] = 6 fun facTest f = f 1 = 1 andalso f 3 = 6 andalso f 7 = 5040... fun allTest (sum, fac,...) = let val sumScore = if sumTest sum then 10 else 0 val facScore = if facTest fac then 4 else 0... in sumScore + facScore +... end allTest (BetOne.sum, BetOne.fac,...); allTest (Bigh2000One.sum, Bigh2000One.fac,...); allTest (BoongOne.sum, BoongOne.fac,...); allTest (BrandonOne.sum, BrandonOne.fac,...);... allTest (ZiedrichOne.sum, ZiedrichOne.fac,...);

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

50 50 HW1 Test Functor signature HW_TEST = sig val score : int end functor Hw1TestFn (P : HW_ONE) : HW_TEST = struct structure S = Hw1Solution val sumScore = if P.sum nil = S.sum nil andalso P.sum [1, 2, 3] = S.sum [1, 2, 3] then 10else 0 val facScore = 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 = sumScore + facScore +... end

51 51 HW1 Test Functor in Action structure BetOneTest = Hw1TestFn (BetOne) structure Bigh2000OneTest = Hw1TestFn (Bigh2000One) structure BoongOneTest = Hw1TestFn (BoongOne) structure BrandonOneTest = Hw1TestFn (BrandonOne)... structure ZiedrichOneTest = Hw1TestFn (ZiedrichOne) BetOneTest.score; Bigh2000OneTest.score; BoongOneTest.score; BrandonOneTest.score;... ZiedrichOneTest.score;

52 52 So it is YOU who will grade your homework!


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

Similar presentations


Ads by Google