Download presentation
Presentation is loading. Please wait.
Published byClement Lucas Modified over 9 years ago
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
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.