## Homework 1 (Spring 2004)

1. The definition of a function, foo, is a <tail definition> if it has the following form:

(define foo (lambda (<symbol>*) <tail wrt foo>))

where <symbol>* is zero or more symbols and an expression is <tail wrt foo> if it is not an application of foo:

<contains no foo applications>

#### or

if it is an application of foo to zero or more expressions which contain no applications of foo:

(foo <contains no foo applications>*)

#### or

if all applications of foo are contained in expressions which are (themselves) tail recursive with respect to foo and which occur in any of the following contexts:

• (if <contains no foo applications> <tail wrt foo> <tail wrt foo>)
• (and <contains no foo applications>* <tail wrt foo>)
• (or <contains no foo applications>* <tail wrt foo>)

where <contains no foo applications> is an expression which contains no applications of foo,and <contains no foo applications>* is zero or more expressions which contain no applications of foo.

Write a function, tail-definition?, which takes an expression, expr, as an argument, and returns #t if the expression is a <tail definition> and #f otherwise. For example:

```> (tail-definition? '(define fact (lambda (x acc) (if (= x 0) acc (fact (- x 1) (* x acc))))))
#t
> (tail-definition? '(define fact (lambda (x) (if (= x 0) 1 (* x (fact (- x 1)))))))
#f
> (tail-definition? '(define member? (lambda (item ls) (and (not (null? ls)) (or (eq? item (car ls)) (member? item (cdr ls)))))))
#t
>
```
Hint: Divide and conquer. Write helper-functions, tail-wrt? and no-applications-of?. Both take a function name, fname, and an expression, expr, as arguments. tail-wrt? returns #t if expr is tail with respect to fname and #f otherwise. no-applications-of? returns #t if there are no applications of fname in expr, and #f otherwise.

2. Write a function, curry-skip, with the following behavior:
```> ((curry-skip 0) 'foo)
foo
> (((curry-skip 1) 'foo) 'bar)
bar
> ((((curry-skip 2) 'foo) 'bar) 'baz)
baz
>
```
3. Write iterate-to-fixedpoint which takes as arguments: 1) A function of one argument, f; 2) A function of two arguments, pred (used to test for convergence); and 3) An initial value, x0. iterate-to-fixedpoint applies f repeatedly to its own output, (f (f (f ... (f x0)))), until the value stops changing (as determined by pred). iterate-to-fixedpoint then returns that value, i.e., it returns a fixedpoint of f. For example,
```> (iterate-to-fixedpoint (lambda (x) (/ (+ x (/ 2 x)) 2)) (lambda (x y) (< (abs (- x y)) 0.00001)) 1.0)
1.41421
> (iterate-to-fixedpoint (lambda (x) (if (pair? x) (car x) x)) eq? '(((((a b) c) d) e f g) h))
a
>
```
4. Write make-lookup-function which takes as arguments: 1) A symbol, target; and 2) An s-expression, sexpr, to be searched. make-lookup-function returns a function composed of car's and cdr's that will fetch target out of sexpr. If target is not found in sexpr, make-lookup-function returns #f. If target appears more than once, the returned function should access the first occurence of target (as printed). > (define foo (make-lookup-function 'd '(a (b c (d e) f g) h))) > (foo '(a (b c (d e) f g) h)) d > (foo '(1 (2 3 (4 5) 6 7) 8)) 4 > (define bar (make-lookup-function 'j '(a (b c (d e) f g) h))) > (bar '(1 (2 3 (4 5) 6 7) 8)) #f > (define baz (make-lookup-function 'b 'b)) > (baz 'b) b > (baz 6) 6 >
5. Define a function clock-maker which creates instances of a class, clock, representing a 12 hour clock, using three restricted-counter objects (See Exercise 12.4 in Springer and Friedman) to represent hours, minutes, and seconds. Clock instances should recognize the following methods:
• type - Returns 'clock.
• tic! - Advances the time by one second.
• seconds! - Set the second hand to the value of the first optional argument. Displays an error message if the argument is less than 0 or greater than 59.
• minutes! - Set the minute hand to the value of the first optional argument. Displays an error message if the argument is less than 0 or greater than 59.
• hours! - Set the hour hand to the value of the first optional argument. Displays an error message if the argument is less than 0 or greater than 11.
• display - Displays the current time in a HH:MM:SS format.
You can test your clock class using the following test routine:
```(define clock-tester
(lambda ()
(let ((clock (clock-maker)))
(letrec
((loop
(lambda (seconds)
(if (< seconds 3601)
(begin
(send clock 'tic!)