CS 227 lecture -*- Outline -*-
Focus on: the "recursive moment": how to see the "dragon's 3 steps".
* recursion
** problem
we can now write procedures that do different things
with their output, but we can't
yet repeat something any number of times,
** stories
tell the story about being distracted and not wanting to slice
a loaf of freshly baked bread, but slicing one slice off
several loaves of bread, until it was all sliced
then going grocery shopping: I'll get the first thing
on the list, you be responisble for the rest
then in the checkout line: I can't add all these numbers,
I have to think about recursion..., but 1 can
add one price to the price of a cart's worth
(write down things to remember for the other carts)
** the idea
--------------
PHILOSOPHY OF RECURSION
On ending:
* All good things must come to an end
On starting:
* A thousand mile journey begins
with a single step.
How to live life:
* One day at a time
* Sieze the Day
On worrying:
* Today's trouble is enough for today.
* Don't be anxious about tomorrow.
* Tomorrow will take care of itself
--------------
Translate this into code
days as a list
(born day2 ... dying)
() <-- Lincoln
define today, future, and living (one day at a time)
define value of life (arbitrarily) summing up value of each day
** initial example
-------------
A PROBLEM
(add1-to-each '()) ==> ()
(add1-to-each '(2 3 4)) ==> (3 4 5)
(add1-to-each '(2 6 8 -1 9 1 2 4 5 7 9))
==> (3 7 9 0 10 2 3 5 6 8 10)
PLAN
TYPE: (-> ((list number)) (list number))
(define add1-to-each
(lambda (ls)
; if ls is empty, return ()
; else add 1 to car of ls
; cons that onto
; the result of add1-to-each of
; cdr of ls))
TRANSLATION
(define add1-to-each
(lambda (ls)
(cond
((null? ls) '())
(else (cons (add1 (car ls))
(add1-to-each (cdr ls)))
))))
------------
perhaps best to put the above on the board...
** why we need recursion, and what it is.
----------
SNOC
add an item to the end of a list
(snoc '() 'a) ==> (a)
(snoc '(a) 'b) ==> (a b)
(snoc '(1 2) 3) ==> (1 2 3)
snoc: (-> ((list T) T) (list T))
ALGORITHM?
if list is empty,
cons new item onto '()
if list has 1 item,
cons new item onto '()
and cons car onto that
if list has 2 items,
cons new item onto '()
and cons cadr onto that
and cons car onto that
...
-----------
can translate the plan to code
but shows the problem
this plan is unworkable! (Scheme doesn't do ...)
what are the problems?
can't write it all down
lots of redundancy
how did we eliminate writing the same thing twice before?
used helping procedures
but what other procedures have we got that can help?
none
so this procedure will have to help itself
such procedures are called recursive
they have the advantage of being able to do an
indefinite amount of work.
-------------
RECURSIVE PROCEDURES
def: a procedure is recursive if
it uses itself as a helping procedure.
RECURSIVE DEFINITION OF snoc
(snoc '() item) = (cons item '())
(snoc (cons x l) item)
= (cons x (snoc l item))
IS IT CORRECT?
(snoc '() 'a)
=
(cons 'a '())
==>
(a)
(snoc '(a) 'b)
=
(snoc (cons 'a '()) 'b)
=
(cons 'a (snoc '() 'b))
=
(cons 'a (cons 'b '()))
==>
(a b)
--------------
why does the recursive definition work?
by induction on (length or) structure of lists
(do this both forwards and backwards)
The recursive definition corresponds to the a new plan
--------------
NEW PLAN
base case: if list is empty,
cons new item onto '()
recursive case: (if list is not empty)
cons the car of list onto
snoc of (cdr list)
and the item
--------------
develop the code for this on the board
(DEFINE snoc
(LAMBDA (lst item)
(IF (null? lst)
(cons item '())
(cons (car lst)
(snoc (cdr lst) item)))))
why does it stop?
stops on empty list by inspection of code
length of non-empty list is always greater than 0
each recursive call decreases the length
can't both decrease and remain greater than 0 forever
** more examples
*** copy
this is THE standard paradigm, the simplest recursion
-------------
WRITE THIS YOURSELF
(copy '()) ==> ()
(copy '(1 2 3 4 5)) ==> (1 2 3 4 5)
(copy '(a b c)) ==> (a b c)
copy: (-> ((list T)) (list T))
-------------
note can't just handle these cases
*** rac
following is last-item in the book
-------------
RAC
(rac '(1)) ==> 1
(rac '(1 2)) ==> 2
(rac '(1 2 3)) ==> 3
(rac '(a b c surprise)) ==> surprise
rac: (-> ((list T)) T)
------------
add an item to the tail of a list
rac of empty list is an error
how do we know when to stop?
put an answer on the board with REQUIRES: ls is not empty
*** more examples to work in class
--------------
MORE EXAMPLES
(member? 'x '()) ==> ()
(member? 'a '(a)) ==> #t
(member? 'a '(b c)) ==> #f
(member? '(hi) '((a) (hi) (there))) ==> #t
member?: (-> (T (list T)) boolean)
(remove-1st 'fox '()) ==> ()
(remove-1st 'fox '(fox hen fox pig))
==> (hen fox pig)
(remove-1st '(duck) '((look out) (duck)))
==> ((look out))
remove-1st: (-> (T (list T)) (list T))
(append '() '(1 2 3)) ==> (1 2 3)
(append '(7 9) '(1 2 3)) ==> (7 9 1 2 3)
(append '(a b) '(c)) ==> (a b c)
----------------
can also try
double (a b) ==> (a a b b)
rdc
assoc
reverse