### 5.3 Debugging Aids

This section describes additional commands that are useful for debugging.

procedure: bkpt datum argument …

  Sets a breakpoint. When the breakpoint is encountered, datum and the arguments are typed (just as for `error`) and a read-eval-print loop is entered. The environment of the read-eval-print loop is derived by examining the continuation of the call to `bkpt`; if the call appears in a non-tail-recursive position, the environment will be that of the call site. To exit from the breakpoint and proceed with the interrupted process, call the procedure `continue`. Sample usage:

      1 ]=> (begin (write-line 'foo)
                   (bkpt 'test-2 'test-3)
                   (write-line 'bar)
                   'done)

      foo
       test-2 test-3
      ;To continue, call RESTART with an option number:
      ; (RESTART 2) => Return from BKPT.
      ; (RESTART 1) => Return to read-eval-print level 1.

      2 bkpt> (+ 3 3)

      ;Value: 6

      2 bkpt> (continue)

      bar
      ;Value: done

procedure: pp object [output-port [as-code?]]

  The `pp` procedure is described in Output Procedures in MIT/GNU Scheme Reference Manual. However, since this is a very useful debugging tool, we also mention it here. `pp` provides two very useful functions:

  1. `pp` will print the source code of a given procedure. Often, when debugging, you will have a procedure object but will not know exactly what procedure it is. Printing the procedure using `pp` will show you the source code, which greatly aids identification.
  2. `pp` will print the fields of a record structure. If you have a compound object pointer, print it using `pp` to see the component fields, like this:

         (pp (->pathname "~"))
         -| #[pathname 14 "/usr/home/cph"]
         -| (host #[host 15])
         -| (device unspecific)
         -| (directory (absolute "usr" "home"))
         -| (name "cph")
         -| (type ())
         -| (version unspecific)

     When combined with use of the `#@` syntax, `pp` provides the functionality of a simple object inspector. For example, let’s look at the fields of the host object from the above example:

         (pp #@15)
         -| #[host 15]
         -| (type-index 0)
         -| (name ())

procedure: pa procedure

  `pa` prints the arguments of procedure. This can be used to remind yourself, for example, of the correct order of the arguments to a procedure.

      for-all?
       ⇒ #[compiled-procedure 40 ("boole" #x6) #xC #x20ECB0]

      (pa for-all?)
      -| (items predicate)

      (pp for-all?)
      -|(named-lambda (for-all? items predicate)
      -|  (let loop ((items items))
      -|    (or (null? items)
      -|        (and (predicate (car items))
      -|             (loop (cdr items))))))

procedure: where [obj]

  The procedure `where` enters the environment examination system. This allows environments and variable bindings to be examined and modified. `where` accepts one-letter commands. The commands can be found by typing `?` to the ‘`where>`’ prompt. The optional argument, obj, is an object with an associated environment: an environment, a procedure, or a promise. If obj is omitted, the environment examined is the read-eval-print environment from which `where` was called (or an error or breakpoint environment if called from the debugger). If a procedure is supplied, `where` lets the user examine the closing environment of the procedure. This is useful for debugging procedure arguments and values.

procedure: apropos string [environment [search-parents?]]

  Search an environment for bound names containing string and print out the matching bound names. If environment is specified, it must be an environment or package name, and it defaults to the current REPL environment. The flag search-parents? specifies whether the environment’s parents should be included in the search. The default is `#f` if environment is specified, and `#t` if environment is not specified.

      (apropos "search")
      -| #[package 47 (user)]
      -| #[package 48 ()]
      -| list-search-negative
      -| list-search-positive
      -| nt-fs-flag/case-sensitive-search
      -| re-string-search-backward
      -| re-string-search-forward
      -| re-substring-search-backward
      -| re-substring-search-forward
      -| search-ordered-subvector
      -| search-ordered-vector
      -| search-protection-list
      -| string-search-all
      -| string-search-backward
      -| string-search-forward
      -| substring-search-all
      -| substring-search-backward
      -| substring-search-forward
      -| vector-binary-search