CS153, Class 7: Recursion
Overview:
* Short discussion of recursion in Scheme
* Lab
* Reflections
Adminstrivia and other Introductory Notes:
* Visitors from other classes? (151, 195, ...)
* if expressions with no false-part, such as
(if (< x 0) x)
* New reading: Recursion with numbers
* New homework: Deep recursion
* Comments on Eboards?
----------------------------------------
Recursion: Procedures can call themselves
By calling yourself, you can repeatedly do things
To mathematicians, recursion is natural
0! = 1
n! = n * (n-1)!
0 is a non-negative integer
If n is a non-negative integer, so is n+1
(define proc
(lambda (something)
(if (test-for-base-case something)
base-case
(combine (helper something)
(proc (simplify something))))))
For example, sum
(define sum
(lambda (lst)
(if (null? lst)
0
(+ (car lst) (sum (cdr lst))))))
Design idea:
* "Suppose I can solve a simpler problem, How do I use
that solution to solve the current problem?"
To write recursive procedures you need to think about
* How to identify the base case
* What value to use in the base case
+ Make sure you get the right type!
* How to simplify
* What to do with result of recursive call
----------------------------------------
POP QUIZ!
Why do professors (or at least Sam-like professors) give
quizzes?
* "Check": Are students learning what I want them to learn?
* Motivate students
Bad answers
* To panic students
* To exert authority
* To use up class time when they haven't prepared enough
Good answers
* To remind students of the importance of reading and thinking
ahead.
* To give students the opportunity to show what they've learned.
* To get quick feedback on how students are doing.
A solution
Parameters: source destination
a: When do we hit the base case?
When source is null.
b. What should we do in the base case?
Use destination
c. How do we simplify source?
By taking its cdr
d. Suppose we've appended the simplified source to
destination. What next?
Add the car of the unsimplified source
e. What does the Scheme look like?
(define append
(lambda (source destination)
(if (null? source)
destination
(cons (car source)
(append (cdr source) destination)))))
(define square
(lambda (val)
(* val val)))
(define expt
(lambda (base power)
(cond
((zero? power) 1)
((even? power) (square (expt val (/ power 2))))
(else (* base (expt base (- power 1)))))))
To compute 3^128
=> (square 3^64)
=> (square (square 3^32))
=> (square (square (square (3^16))))
8
4
2
1
0
----------------------------------------
Reflection
* A dot (period, ".") in your list is a polite way
for Scheme to say
"Bozo, your list didn't end in a null. Lists must
end in null. Try again."
* Yes, it's okay that you work at different speeds.
* Be careful about using quote to create lists
(length (car '('(1 2 3))))
* (* x x) is probably faster than (expt x 2)
* Think about what type to return. (That's why Sam writes
the six P's before writing his procedures.)
* Shoot for simpler base cases
(null? lst) rather than (null? (cdr? lst))
* Cassie is here 8-10 tonight for help
* Sam is running a lab from 2:15-3:05 here today