## Debugging programs using micro-Scheme

Our interpreters don't provide the full-fledged debugging
facilities of real Lisp and Scheme systems, nor do they provide the
breakpoint/print debuggers familiar from imperative programming.
Here are two strategies to help you cope.
The first strategy is simply to exploit the interactive nature of the
interpreters. Define small functions and test them interactively
before going on to more complicated functions.
Be sure you know how to cut and paste between your editor and terminal
windows.
Emacs users should find M-x shell helpful.
For larger groups of functions, you can
exploit the `use` primitive.

Many problems with Lisp and Scheme arise from dynamic typing and from
the requirement that every data structure be represented using lists.
We'll see how ML eliminates these problems through its static
polymorphic type inference, but meanwhile, you can use run-time type
tags.
Let's say, for example, that you want certain lists to represent edge
lists in a graph.
Instead of just using `car`, `cdr`, and similar functions,
you can add tags to the representation and define versions of
functions that only work with the tagged representations:

(define mk-edgelist (l) (cons l 'edgelist))
(define un-edgelist (p)
(if (= (cdr p) 'edgelist)
(car p)
(error (list2 'bogus:expected-edgelist,got p))))
(define edgelist-car (l) (car (un-edgelist l)))
(define edgelist-cdr (l) (mk-edgelist (cdr (un-edgelist l))))
(define edgelist-cons (e l) (mk-edgelist (cons e (un-edgelist l))))
(define edgelist-null? (l) (null? (un-edgelist l)))

If we define similar functions for node lists,
we can, for example, produce the successors of a node:
(define successors (node edges)
(if (edgelist-null? edges)
(mk-nodelist '())
(let ((p (edgelist-car edges))
(rest (successors node (edgelist-cdr edges))))
(if (= node (car p))
(nodelist-cons (car (cdr p)) rest)
rest))))

and we can use the function as follows:
-> (successors 'a (mk-edgelist '((a b) (b c) (c d) (a d))))
((b d) . nodelist)

If we screw up, for example, we try to apply `successors` to a
straight list, we get a suitable error message:
-> (successors 'a '((a b) (b c) (c d) (a d)))
error: error: (bogus:expected-edgelist,got ((a b) (b c) (c d) (a d)))