Presentation is loading. Please wait.

Presentation is loading. Please wait.

Map and Fold Building Powerful Abstractions. Hello. I’m Zach, one of Sorin’s students.

Similar presentations


Presentation on theme: "Map and Fold Building Powerful Abstractions. Hello. I’m Zach, one of Sorin’s students."— Presentation transcript:

1 Map and Fold Building Powerful Abstractions

2 Hello. I’m Zach, one of Sorin’s students. ztatlock@cs.ucsd.edu

3 A language that doesn't affect the way you think about programming is not worth knowing. Alan Jay Perlis If you manage to survive a shipwreck by clinging to a piano top, well, that doesn’t mean the best way to design a life preserver is as a piano top. I think we are clinging to a great many piano tops. Buckminster Fuller

4 Evolution of Iteration

5 i = 0 label L0 if(i >= n) goto L1 print a[i] * 2 i++ goto L0 label L1 i = 0; while(i < n) { print a[i] * 2 i++ } for(x in a) { print x * 2 } for(i=0; i<n; i++) { print a[i] * 2 } UglyElegant Abstract

6 Building Iteration Abstractions Roll our own abstractions w/ higher order funcs Step 1: Identify common patterns Step 2: Retain the fundamental and Parameterize away the incidental

7 Building Iteration Abstractions 1.Map 2.Fold 3.Tail Recursion A good loop is fast, safe, and elegant.

8 Map : Apply Func Over List Common Task: do something to every item in a list map f [x1; x2;...; xN] = [f x1; f x2;...; f xN] But how do we implement it? Derive by abstracting from particular instances

9 Instance: Double an int list Assume function double_int = (*) 2 Write function to double a list of ints

10 Instance: Double an int list Assume function double_int = (*) 2 Write function to double a list of ints let rec double_ints xs = match xs with | [] –> [] | x::ys –> double_int x :: double_ints ys

11 Instance: Lengths from a string list Assume function str_len Write function for lengths of strings in a list

12 Instance: Lengths from a string list Assume function str_len Write function for lengths of strings in a list let rec str_lens xs = match xs with | [] –> [] | x::ys –> str_len x :: str_lens ys

13 Map : Find the Pattern let rec double_ints xs = match xs with | [] –> [] | x::ys –> double_int x :: double_ints ys let rec str_lens xs = match xs with | [] –> [] | x::ys –> str_len x :: str_lens ys

14 Map : Find the Pattern let rec double_ints xs = match xs with | [] –> [] | x::ys –> double_int x :: double_ints ys let rec str_lens xs = match xs with | [] –> [] | x::ys –> str_len x :: str_lens ys 1.Base function

15 Map : Find the Pattern let rec double_ints xs = match xs with | [] –> [] | x::ys –> double_int x :: double_ints ys let rec str_lens xs = match xs with | [] –> [] | x::ys –> str_len x :: str_lens ys 1.Base function 2.Apply to head

16 Map : Find the Pattern let rec double_ints xs = match xs with | [] –> [] | x::ys –> double_int x :: double_ints ys let rec str_lens xs = match xs with | [] –> [] | x::ys –> str_len x :: str_lens ys 1.Base function 2.Apply to head 3.Recurse

17 Map : Derive from the Pattern 1.Base function 2.Apply to head 3.Recurse

18 Map : Derive from the Pattern 1.Base function 2.Apply to head 3.Recurse let rec map f xs = match xs with | [] –> [] | x::ys -> f x :: map f ys

19 Map : Derive from the Pattern 1.Base function 2.Apply to head 3.Recurse let rec map f xs = match xs with | [] –> [] | x::ys -> f x :: map f ys

20 Map : Derive from the Pattern 1.Base function 2.Apply to head 3.Recurse let rec map f xs = match xs with | [] –> [] | x::ys -> f x :: map f ys Key Idea : Take a function as a parameter!

21 Map : Derive from the Pattern 1.Base function 2.Apply to head 3.Recurse let rec map f xs = match xs with | [] –> [] | x::ys -> f x :: map f ys

22 Map : Derive from the Pattern 1.Base function 2.Apply to head 3.Recurse let rec map f xs = match xs with | [] –> [] | x::ys -> f x :: map f ys

23 Application: Print an int list Assume function print_int Use map to print a list of ints

24 Application: Print an int list Assume function print_int Use map to print a list of ints let print_ints = map print_int

25 Compare: Using Map vs. Not let print_ints = map print_int vs. let rec print_ints xs = match xs with | [] -> [] | x::ys -> print_int x :: print_ints ys

26 Map Summary Map takes: a -> b and provides: a list -> b list Which corresponds to the common task: do something to every item in a list map f [x1; x2;...; xN] = [f x1; f x2;...; f xN]

27 Evolution of Iteration i = 0 label L0 if(i >= n) goto L1 print a[i] * 2 i++ goto L0 label L1 i = 0; while(i < n) { print a[i] * 2 i++ } for(i=0; i<n; i++) { print a[i] * 2 } UglyElegant Abstract map print (map double a) for(x in a) { print x * 2 }

28 Building Iteration Abstractions 1.Map 2.Fold 3.Tail Recursion A good loop is fast, safe, and elegant.

29 Fold : Crunch Down a List Common Task: crunch a list of values down to a single value fold f [x1; x2;...; xN] base = (f x1 (f x2... (f xN base)... ) But how do we implement it? Derive by abstracting from particular instances

30 Instance: Add up an int list Assume function add = (+) Write function to add up a list of ints

31 Instance: Add up an int list Assume function add = (+) Write function to add up a list of ints let rec add_ints xs = match xs with | [] -> 0 | x::ys -> add x (add_ints ys)

32 Instance: Concat together string list Assume function cat = (^) Write function to concat a list of strings

33 Instance: Concat together string list Assume function cat = (^) Write function to concat a list of strings let rec cat_strs xs = match xs with | [] -> “” | x::ys -> cat x (cat_strs ys)

34 Fold : Find the Pattern let rec add_ints xs = match xs with | [] –> 0 | x::ys –> add x (add_ints ys) let rec cat_strs xs = match xs with | [] –> “” | x::ys –> cat x (cat_strs ys)

35 Fold : Find the Pattern let rec add_ints xs = match xs with | [] –> 0 | x::ys –> add x (add_ints ys) let rec cat_strs xs = match xs with | [] –> “” | x::ys –> cat x (cat_strs ys) 1. Base Val b

36 Fold : Find the Pattern let rec add_ints xs = match xs with | [] –> 0 | x::ys –> add x (add_ints ys) let rec cat_strs xs = match xs with | [] –> “” | x::ys –> cat x (cat_strs ys) 1. Base Val b 2. Base Fun f

37 Fold : Find the Pattern let rec add_ints xs = match xs with | [] –> 0 | x::ys –> add x (add_ints ys) let rec cat_strs xs = match xs with | [] –> “” | x::ys –> cat x (cat_strs ys) 1. Base Val b 2. Base Fun f 3. End on b

38 Fold : Find the Pattern let rec add_ints xs = match xs with | [] –> 0 | x::ys –> add x (add_ints ys) let rec cat_strs xs = match xs with | [] –> “” | x::ys –> cat x (cat_strs ys) 1. Base Val b 2. Base Fun f 3. End on b 4. Apply f to head and val from rest

39 Fold : Derive from the Pattern 1. Base Val b 2. Base Fun f 3. End on b 4. Apply f to head and val from rest

40 Fold : Derive from the Pattern 1. Base Val b 2. Base Fun f 3. End on b 4. Apply f to head and val from rest let rec fold f xs b = match xs with | [] –> b | x::ys –> f x (fold f ys b)

41 Fold : Derive from the Pattern 1. Base Val b 2. Base Fun f 3. End on b 4. Apply f to head and val from rest let rec fold f xs b = match xs with | [] –> b | x::ys –> f x (fold f ys b)

42 Fold : Derive from the Pattern 1. Base Val b 2. Base Fun f 3. End on b 4. Apply f to head and val from rest let rec fold f xs b = match xs with | [] –> b | x::ys –> f x (fold f ys b)

43 Fold : Derive from the Pattern 1. Base Val b 2. Base Fun f 3. End on b 4. Apply f to head and val from rest let rec fold f xs b = match xs with | [] –> b | x::ys –> f x (fold f ys b) Key Idea : Take a function as a parameter!

44 Fold : Derive from the Pattern 1. Base Val b 2. Base Fun f 3. End on b 4. Apply f to head and val from rest let rec fold f xs b = match xs with | [] –> b | x::ys –> f x (fold f ys b)

45 Fold : Derive from the Pattern 1. Base Val b 2. Base Fun f 3. End on b 4. Apply f to head and val from rest let rec fold f xs b = match xs with | [] –> b | x::ys –> f x (fold f ys b)

46 Fold : Derive from the Pattern 1. Base Val b 2. Base Fun f 3. End on b 4. Apply f to head and val from rest let rec fold f xs b = match xs with | [] –> b | x::ys –> f x (fold f ys b)

47 Application: Multiply int list Assume function mul = (*) Use fold to take product of a list of ints

48 Application: Multiply int list Assume function mul = (*) Use fold to take product of a list of ints let product xs = fold (*) xs 1

49 Compare: Using Fold vs. Not let product xs = fold (*) xs 1 vs. let rec product xs = match xs with | [] -> 1 | x::ys -> x * (product ys)

50 Fold Summary Fold turns: x1 :: x2 ::... :: [] into: x1 op x2 op... op base where op and base are the params to fold. Which corresponds to the common task: crunch a list of values down to a single value fold f [x1; x2;...; xN] base = (f x1 (f x2... (f xN base)... )

51 Building Iteration Abstractions 1.Map 2.Fold 3.Tail Recursion A good loop is fast, safe, and elegant.

52 Tail Recursion Special type of function compiler can easily optimize into a loop More efficient than naïve recursion uses less time and stack space Require all returns to be either A: a value B: call to the same function

53 Tail Recursion Is this function tail recursive? let rec is_even x = match x with | 0 -> true | 1 -> false | _ -> is_even (x – 2) Yes.

54 Tail Recursion Is this function tail recursive? let rec factorial x = match x with | 0 -> 1 | _ -> x * (factorial (x – 1)) No. not a call to factorial

55 Tail Recursion Can we make factorial tail recursive?

56 Tail Recursion Can we make factorial tail recursive? let factorial x = let rec loop acc x = match x with | 0 -> acc | _ -> loop (x * acc) (x – 1) in loop 1 x Yes.

57 Tail Recursion Is this function tail recursive? let rec range a b = if a > b then [] else a :: range (a + 1) b No. not a call to range

58 Tail Recursion Can we make range tail recursive?

59 Tail Recursion Can we make range tail recursive? let range a b = let rec loop acc a b = if a > b then acc else loop (b::acc) a (b – 1) in loop [] a b Yes.

60 Tail Recursion : What’s the Pattern? Not a generic recipe like Map and Fold! Roughly : 1. write a “ loop ” helper function 2. loop takes an accumulator argument 3. base case returns the accumulator 4. recursive case calls loop w/ updated acc

61 Putting the Pieces Together Use functions from today to write factorial. let factorial n =

62 Putting the Pieces Together Use functions from today to write factorial. let factorial n = fold (*) (range 1 n) 1

63 A Final Thought... It’s abstractions all the way down!

64 abstraction


Download ppt "Map and Fold Building Powerful Abstractions. Hello. I’m Zach, one of Sorin’s students."

Similar presentations


Ads by Google