(define member?
(lambda (item ls)
(if (null? ls)
#f
(or (eq? (car ls) item)
(member? item (cdr ls))))))
(define fact
(lambda (x)
(if (= x 0)
1
(* x (fact (- x 1))))))
;; You may use the functions and macros defined below this line,
;; but it is not necessary for you to understand them (yet!).
;; You may need to do: (require (lib "defmacro.ss")).
(define-macro trace
(lambda (name)
`(set! ,name (make-traceable ,name (quote ,name)))))
(define make-traceable
(lambda (proc name)
(letrec
((tab
(lambda (n)
(if (eq? n 1)
""
(string-append "| " (tab (- n 1)))))))
(let ((c 1))
(lambda args
(display (tab c))
(display (cons name args))
(newline)
(set! c (+ c 1))
(let ((value (apply proc args)))
(set! c (- c 1))
(display (tab c))
(display value)
(newline)
value))))))
The following examples show how trace is used:
>(trace fact)
>(fact 5)
(fact 5)
| (fact 4)
| | (fact 3)
| | | (fact 2)
| | | | (fact 1)
| | | | | (fact 0)
| | | | | 1
| | | | 1
| | | 2
| | 6
| 24
120
120
>
>(trace member?)
>(member? 'foo '(1 2 3 foo 4))
(member? foo (1 2 3 foo 4))
| (member? foo (2 3 foo 4))
| | (member? foo (3 foo 4))
| | | (member? foo (foo 4))
| | | #t
| | #t
| #t
#t
#t
>
>(member? 'foo '(1 2 3 4))
(member? foo (1 2 3 4))
| (member? foo (2 3 4))
| | (member? foo (3 4))
| | | (member? foo (4))
| | | | (member? foo ())
| | | | #f
| | | #f
| | #f
| #f
#f
#f
>