Title: Essentials of Programming Languages
1Essentials of Programming Languages
2Recursively Specified Programs
- In section 1.1, recursion was used to define sets
of data - In this section we use recursion to define
procedures to manipulate those sets
3Recursively Specified Programs
- We define e(n,x) xn
- E(0,x) x0
- E(1,x) x1
- E(2,x) x2 or x . X1
- E(3,x) x3 or x . x2
- E(n,x) xn or x . xn-1 or x . E(n-1,x)
4Using Recursion to Compute xn
- (define e
- (lambda (n x)
- (if (zero? N)
- 1
- ( x (e (- n 1) x)))))
Base step in the recursion
Recursive step
Calling the procedure to solve a smaller version
of the problem
5Counting Bintree Nodes
- ltbintreegt ltnumbergt
- (ltsymbolgt ltbintreegtltbintreegt)
- (define count-nodes
- (lambda (s)
- (if (number? S)
- 1
- ( (count-nodes (cadr s)
- (count-nodes (caddr s))
- 1 ))))
6Counting Bintree Nodes
- (define t1 '(a (b 2 3) (c 4 6)))
- (count-nodes t1)
- (define t2 3)
- (count-nodes t2)
- (define t3 '(a 1 (b 2 3)))
- (count-nodes t3)
a
b
c
2
3
4
6
7Follow the Grammar!
- A BNF definition for the type of data being
manipulated serves as a guide to where recursive
calls should be used and to which base cases need
to be handled - When defining a program based on structural
induction, the structure of the program should be
patterned after the structure of the data
8List-of-numbers
- ltlist-of-numbersgt ( ) (ltnumbergt .
ltlist-of-numbersgt) - (define list-of-numbers?
- (lambda (lst)
- (if (null? lst)
- t
- (and
- (number? (car lst))
- (list-of-numbers? (cdr
lst)))))) - (list-of-numbers? '(1 . ( 2 . (3 . () ))))
9Finding the nth Element
- (define nth-elt
- (lambda (lst n)
- (if (null? lst)
- (eoplerror 'nth-elt
- "List too short by s elements"
( n 1)) - (if (zero? n)
- (car lst)
- (nth-elt (cdr lst) (- n 1))))))
- (nth-elt '(a b c d e) 4)
10Finding the Length of a List
- (define list-length
- (lambda (lst)
- (if (null? lst)
- 0
- ( 1 (list-length (cdr lst))))))
- (list-length '(a b c d e))
11Removing the First Occurrence
- s - symbol
- los -list of symbols
- (define remove-first
- (lambda (s los)
- (if (null? los)
- '()
- (if (eqv? (car los) s)
- (cdr los)
- (cons (car los) (remove-first s (cdr
los))))))) - (remove-first 'a '(1 2 3 4 a 5 6 a))
12Removing All Occurrences
- (define remove
- (lambda (s los)
- (if (null? los)
- '()
- (if (eqv? (car los) s)
- (remove s (cdr los))
- (cons (car los) (remove s (cdr
los))))))) - (remove 'a '(1 2 3 4 5 a 6 a))
13SLists Reviewed
- lts-listgt (ltsymbol-expressiongt)
- ltsymbol-expressiongt ltsymbolgt lts-listgt
- Removing the Kleene star we have
- lts-listgt ( )
- (ltsymbol-expressiongt .
lts-listgt) - ltsymbol-expressiongt ltsymbolgt lts-listgt
- To recognize this grammar we must write two
procedures, one for each non-terminal symbol
14Substituting Symbols in Slists
- new - a new replacement symbol
- old - the old symbol to be replace
- slist - an slist
- (define subst
- (lambda (new old slist)
- (if (null? slist)
- '()
- (cons
- (subst-in-symbol-expression new old (car
slist)) - (subst new old (cdr slist))))))
- (define subst-in-symbol-expression
- (lambda (new old se)
- (if (symbol? se)
- (if (eqv? se old) new se)
- (subst new old se))))
- (subst 'a 'b '(a (a b a b (a b))))
15Notate Depth of an S-list
- We want to assign a number (depth) to each symbol
in an S-list - Each symbol is replaced by a list containing the
symbol and a number equal to the depth at which
the symbol appears - A symbol appearing at the top level is at depth 0
16Notate Depth of an S-list
- We distinquish the s-list that is input from an
s-list that appears as a sublist - lttop-levelgt lts-listgt
- lts-listgt ( )
- (ltsymbol-expressiongt .
lts-listgt) - ltsymbol-expressiongt ltsymbolgt lts-listgt
- We write three procedures
- notate-depth,
- notate-depth-in-s-list,
- notate-depth-in-symbol-expression
17Notate Depth of an S-list
- (define notate-depth
- (lambda (slist)
- (notate-depth-in-s-list slist 0)))
- (define notate-depth-in-s-list
- (lambda (slist d)
- (if (null? slist)
- '()
- (cons (notate-depth-in-symbol-expression
(car slist) d) - (notate-depth-in-s-list (cdr slist)
d))))) - (define notate-depth-in-symbol-expression
- (lambda (se d)
- (if (symbol? se)
- (list se d)
- (notate-depth-in-s-list se( d 1)))))
- (notate-depth '(a (b () c) ((d)) e))
18Other Patterns of Recursion
- (define list-sum
- (lambda (lon)
- (if (null? lon)
- 0
- ( (car lon)
- (list-sum (cdr lon))))))
- (list-sum '(1 2 3 4 5))
19Summing a Vector
- von - vector of numbers
- (define partial-vector-sum
- (lambda (von n)
- (if (zero? n)
- 0
- ( (vector-ref von (- n 1))
- (partial-vector-sum von (- n 1))))))
- (define vector-sum
- (lambda (von)
- (partial-vector-sum von (vector-length
von)))) - (vector-sum '(1 2 3 4 5))