Programming Languages by nikeborome

VIEWS: 15 PAGES: 28

• pg 1
```									Programming Languages

COMP 321
Spring 2008
Practicum 5
Practicum 5
• lists as trees
• tail recursion
• let and letrec
reference
• reference:
– Dybvig chapter 2, sections 5-7
recursion
review
• finding the length of a list
(define length
(lambda (ls)                       (define list-copy
(lambda (ls)
(if (null? ls)                       (if (null? ls)
0                                    ‘( )
(+ (length (cdr ls)) 1)              (cons (car ls)
)                                            (list-copy (cdr ls)))
)                                     )
)
)                                    )
Deep Recursion
review
finding the number of items in a list (that contains lists)
example: (1 2 (3 4) 5 (6 (7 8) 9) 10) contains 10 items.
Note that pair? Returns false if a list is empty.
(define numItems
(lambda (ls)
(if (null? ls)
0
(if (or (null? (car ls)) (pair? (car ls))
(+ (numItems (car ls)) (numItems (cdr ls)))
(+ (numItems (cdr ls)) 1)
)
)
)
)
Lists as trees
• Can represent a list as a tree:
(a (b c d) ((e f) g))

a         (b c d)           ((e f) g)

b      c      d   (e f)       g

e       f
recursion
• tree-copy treats the structure of pairs as a tree rather
than as a list
– left subtree is car, right subtree is the cdr
– builds a new tree, leaves the leaves alone
(define tree-copy
(lambda (tr)
(if (not (pair? tr))                (tree-copy ‘((a . b) . c))
tr
(cons (tree-copy (car tr))
(tree-copy (cdr tr)))
)
)
)
Lists as trees
• procedure depth takes a list item as arg and returns
depth of the tree

(define depth
(lambda (item)
(if (not (pair? item))
0
(max (add1 (depth (car item))) (depth (cdr item))))))

• max is a built-in procedure
Lists as trees
• procedure flatten takes a list ls as arg and returns a list of all the
leaves

(define flatten
(lambda (ls)
(cond
((null? ls) ‘())
((pair? (car ls))
(append (flatten (car ls))(flatten (cdr ls))))
(else (cons (car ls)(flatten (cdr ls)))))))

•   append is a built-in procedure; takes two lists and combines into one list
Lists as trees
• flat recursion is over the top-level items of a list
– equivalent to recursion over the nodes of the corresponding
tree, where the nodes are one level below the root.
• deep recursion is over all items of a list
– equivalent to recursion over the leaves of the tree
Tail recursion
• Consider the factorial procedure below
(define fact
(lambda (n)
(if (zero? n)
1
(* n (fact (sub1 n))))))
Tail recursion
• when fact is applied to a number, like 3, a return table is built
– must wait for the return value from the recursive call to finish this
call
– when reach base case, work backwards, filling in the table. Called
backward substitution

Tail recursion
• another way of looking at the table (the recursive calls and the
returns):

(fact 3)
(* 3 (fact 2))
(* 3 (* 2 (fact 1)))
(* 3 (* 2 (* 1 (fact 0))))
(* 3 (* 2 (* 1 1)))
(* 3 (* 2 1))
(* 3 2)
6
Tail recursion
• to find the factorial of n, must perform n + 1 invocations and
will have n + 1 rows in the return table.
• for every call to fact must
– create the return table
– perform backward substitution
• This is space and time expensive!
• Better type of recursion:
– change the solution so that you do not have to do any
computation when the recursive call returns
– then do not need either a return table or backward
substitution
– this is called an iterative process or tail-recursion
Tail recursion
•   changing fact to a tail recursive procedure
– need a helper function.
– need another variable to accumulate the value of the result

(define fact-it
(lambda (n acc)
(if (zero? n)
acc
(fact-it (sub1 n) (* acc n)))))

(define fact
(lambda (n)
(fact-it n 1)))
let expressions
review
• variables and let expressions
(let ((x 1))
(let ((x (+ x 1)))
(+ x x)
)
)
(let ((x 1))
(let ((new-x (+ x 1)))
(+ new-x new-x)) )
procedures in let
• lambda expression in let

(let ((double (lambda (x) (+ x x))))
(list (double (* 3 4))
(double (/ 99 11))
(double (- 2 7))) )
closure
• Consider the procedure:
(let ((b 100))
(lambda (x)
(+ x b))))
• There are 3 parts to the lambda
expression:
– The list of prameters
– The body of the lambda expression (+ x b)
– The nonlocal environment in which the lambda
was defined (the let expression in this case)
bindings
• Local bindings always take precedence over global
or other nonlocal bindings:

(define a 5)
6
(let ((a 3))
4
6
(let ((a 5))
(let ((a 3))
6
4
6
bindings
•   In general, the let expression

(let ((var1 val1) (var2 val2) … (varn valn)) body)

•   is equivalent to

((lambda (var1 var2 … varn) body) val1 val2 … valn)
bindings
• Local bindings always take precedence
over global or other nonlocal bindings:

(define a 10)
(define b 2)
(let ((a (+ a 5)))
(* a b))
30
??

(let ((a 10)(b 2))
(let ((a (+ a 5)))
(* a b)))
30
??
closure
• Local bindings always take precedence
over global or other nonlocal bindings:

(let ((b 100))
(lambda (x)
(+ x b))))

(let ((b 10))

125
???
closure
• A closure includes the environment in
which the procedure was defined:

(let ((b 2))                                b       2
(let ((add2 (lambda (x) (+ x b)))
(b 0.5))                         environment 1

(/ 0.5 2.5) or 0.2
???
procedure (x) (+ x b) Env 1

b       0.5

environment 2
closure
• the procedure is still defined within
the second definition of b:
b       2
(let ((b 2))
(let ((b 0.5)                             environment 1
(add2 (lambda (x) (+ x b))))
procedure (x) (+ x b) Env 1
(/ 0.5
???     2.5) or 0.2
b       0.5

environment 2
local functions
• can define a local function

(define getEven
(lambda (ls)
(let ( (evenNum
(lambda (x)
(zero? (remainder x 2)))) )
(if (null? ls)
‘()
(if (evenNum (car ls))
(cons (car ls) (getEven (cdr ls)))
(getEven(cdr ls))))
)))
local functions
• Problem: local function cannot be recursive, since
it does not know its own name

(define fact
(lambda (n)
(let ( (fact-it
(lambda (k acc)
(if (zero? k)
acc
(fact-it (sub1 k) (* k acc))))) )
(fact-it n 1)
)))
local functions
• Solution: a special type of let called letrec

(define fact
(lambda (n)
(letrec ( (fact-it
(lambda (k acc)
(if (zero? k)
acc
(fact-it (sub1 k) (* k acc))))) )
(fact-it n 1)
)))
(test1 20)
functions
local(test2 20)
30

• Letrec functions 25 their local environment
get
(test3 20)
from the letrec that’s being defined.
25
(define test1           (define test2           (define test3
(let ((x 10))           (let ((x 10))           (let ((x 10))
(lambda (y)             (lambda (y)             (lambda (y)
(let ((x 5)             (letrec ( (x 5)         (letrec ((test4
(test2                  (test3                   (lambda (n)
(lambda (n)             (lambda (n)               (+ n x)))
(+ n x))))              (+ n x))))           (x 5) )
(test2 y)))))           (test3 y)))))           (test4 y)))))

```
To top