Lecture 10
Iterative Recursion - A Slightly Different Flavour
Basic template for recursion
(define function
(lambda (args)� (if easy-case?� solve-easy-case� (fix-solution� (function simplified))))
Special kinds of recursion
(define function
(lambda (args)� (if easy-case?� solve-easy-case� (fix-solution� (function simplified))))
Iterative recursion
Summing a list using recursion
We can add up the elements of a list by
;; sum-list:
;; (listof number) -> number
;; Total of elements of a list
(define sum-list
(lambda (sum-list)
(if (empty? list)
0
(+ (first list)
(sum-list (rest list))))))
Is that the only way to do it?
;; sum-list:
;; (listof number) -> number
;; Total of elements of a list
(define sum-list
(lambda (sum-list)
(if (empty? list)
0
(+ (first list)
(sum-list (rest list))))))
Keeping a partial sum (an accumulator)
;; sum-list:
;; (listof number) -> number
;; Sum of all numbers in list
(define sum-list
(lambda (a-list)
(if (empty? a-list)
0
(+ (first a-list)
(sum-list (rest a-list))))))
;; sum-list:
;; (listof number) number -> number
;; Sum of all numbers in list plus partial-sum
(define sum-list
(lambda (a-list partial-sum)
(if (empty? a-list)
partial-sum
(sum-list (rest a-list)
(+ (first a-list)
partial-sum)))))
Why it matters
Adding last:
'())))))
Adding first:
Holding + until last requires more stack space to keep track pending operations.
Iteration and recursion
How do we write foldl?
;; sum-list:
;; (listof number) number -> number
;; Sum of all numbers in list plus partial-sum
(define sum-list
(lambda (a-list partial-sum)
(if (empty? a-list)
partial-sum
(sum-list (rest a-list)
(+ (first a-list)
partial-sum)))))
How do we write foldl?
;; foldl:
;; (X X -> X) X (listof X) -> X
;; Uses func to collapse all elements of list
;; plus partial-sum
(define foldl
(lambda (func partial-result a-list)
(if (empty? a-list)
partial-result
(foldl func
(func (first a-list)
partial-result)
(rest a-list))))
Helper procedures
Example
;; length: (listof X) -> number
;; Number of elements in list
Example
;; length: (listof X) -> number
;; Number of elements in list
(define length
(lambda (a-list)
(length-loop a-list 0)))
;; length-loop: (listof X) number -> number
;; Number of elements in list plus length-so-far
(define length-loop
(lambda (list-remaining length-so-far)
(if (empty? list-remaining)
length-so-far
(length-loop (rest list-remaining)
(+ length-so-far 1)))))
Execution under the substitution model
0
(length-loop (rest '(1 2 3))
(+ 0 1)))
0
(length-loop (rest '(1 2 3))
(+ 0 1)))
(+ 0 1)))
1
(length-loop (rest '(2 3))
(+ 1 1)))
1
(length-loop (rest '(2 3))
(+ 1 1)))
(+ 1 1)))
2
(length-loop (rest '(3)) (+ 2 1)))
2
(length-loop (rest '(3)) (+ 2 1)))
Execution under the substitution model
3
(length-loop (rest '())
(+ 3 1)))
3
(length-loop (rest '())
(+ 3 1)))
Making it prettier
;; length: (listof X) -> number
;; Number of elements in list
(define my-length
(lambda (a-list)
;; loop: (listof X) number -> number
;; Number of elements in list plus length-so-far
(local [(define loop
(lambda (a-list length-so-far)
(if (empty? a-list)
length-so-far
(loop (rest a-list)
(+ length-so-far 1)))))]
(loop a-list 0))))
Iterative Recursion
(define (help args … accum)
(if easy-case?� accum� (help args …
(updater accum …))))
(define (func args …) � (help args … start-accum))
Tree recursion
Basic template for recursion
(define function
(lambda (args)� (if easy-case?� solve-easy-case� (fix-solution� (function simplified))))
Splitting the Problem into Chunks
(define (func args …) � (if easy-case?� solve-easy-case� (combine (func one-part)� (func other-part)))))
How google sums a list
(define sum-list
(lambda (a-list)
(if (list-fits-on-one-processor? a-list)
(add-it-up a-list)
(+ (sum-list (first-half a-list))
(sum-list (second-half a-list)))))
Parallel summation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Sum this list:
Parallel summation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Sum this list:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Sum this list: + Sum this list:
Parallel summation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Sum this list:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Sum this list: + Sum this list:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Sum this list: + Sum this list: Sum this list: + Sum this list:
Parallel summation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Sum this list:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Sum this list: + Sum this list:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
10 + 26 42 + 58
Parallel summation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Sum this list:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
36 + 100
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
10 + 26 42 + 58
Parallel summation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
136
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
36 + 100
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
10 + 26 42 + 58
Optional reading
Chapter 1 of Abelson and Sussman
Basic template for ordinary recursion
(define function
(lambda (args)� (if easy-case?� solve-easy-case� (fix-solution� (function simplified))))
Iterative Recursion
(define (func args …) � (if easy-case?� solve-easy-case� (combine (func one-part)� (func other-part)))))
Tree Recursion
(define (help args … accum)
(if easy-case?� accum� (help args …
(updater accum …))))
(define (func args …) � (help args … start-accum))