Homework 3 (Spring 2004)

• lambda calculus

• Using the lambda calculus interpreter found here, and using the given definitions of true, false, succ, pred, nil?, etc., use the Y-combinator to write a lambda expression, equals, with natural number argument, x, which returns a lambda expression with natural number argument, y, which returns true, if x=y, and returns false otherwise. For example, > true (lambda (x) (lambda (y) x)) > false (lambda (x) (lambda (y) y)) > (define one (reduce `(,succ ,nil))) > (define two (reduce `(,succ ,one))) > (reduce '((,equals ,one) ,one)) (lambda (x) (lambda (y) x)) > (reduce '((,equals ,one) ,two)) (lambda (x) (lambda (y) y)) >
• Using the definitions of kar, kdr, and nil? found here, give a definition of sexpr->lambda, which takes a Scheme s-expression (comprised of symbols, pairs, and ()), and returns the corresponding lambda calculus representation.
• Use the Y-combinator to write a lambda expression, fact, which takes a natural number, x, and returns x!. For example, > (define answer (reduce '(,fact ,three))) > (reduce '((,equals ,answer) ,six)) (lambda (x) (lambda (y) x)) >
• Unlike the lambda calculus, Scheme reduces expressions in applicative order, not normal order. Consequently, the normal order Y-combinator, which you used above, will not work in Scheme. An applicative order Y-combinator, which can be used to define anonymous recursive functions in Scheme, is given below: (define Y (lambda (f) ((lambda (g) (g g)) (lambda (g) (f (lambda (x) ((g g) x))))))) Use the applicative-order Y-combinator to write a Scheme expression which evaluates to a function that appends two lists.
• call/cc

• Use call/cc to write a function list-length which takes an s-expression, sexpr, as an argument. If sexpr is a list it returns its length, otherwise it returns #f. Write the function so that it does zero additions in the latter case.

• Use call/cc to write a function tree? which takes an s-expression as an argument and returns #t if the s-expression is a tree and #f otherwise. Your function should exit immediately upon detecting a cycle by calling the continuation captured with call/cc.

• Some implementations of Scheme have a syntactic form called letcc which has the following abstract syntax:

(letcc <name>
<expr1>
.
.
.
<exprM>)

=>
(call/cc
(lambda (<name>)
expr1>
.
.
.
<exprM>)

Define letcc using define-macro.

• Rewrite list-length using letcc.