5.21.3 Traps

The low level C code of Guile's evaluator can be configured to call
out at key points to arbitrary user-specified procedures. These
procedures, and the circumstances under which the evaluator calls
them, are configured by the “evaluator trap options” interface
(see Evaluator trap options), and by the trace and
breakpoints fields of the “debug options” interface
(see Debugger options). In principle this allows Scheme code to
implement any model it chooses for examining the evaluation stack as
program execution proceeds, and for suspending execution to be resumed
later. Possible applications of this feature include breakpoints,
runtime tracing, code coverage, and profiling.

Based on these low level trap calls, Guile provides a higher level,
object-oriented interface for the manipulation of traps. Different
kinds of trap are represented as GOOPS classes; for example, the
<procedure-trap> class describes traps that are triggered by
invocation of a specified procedure. A particular instance of a trap
class — or trap object — describes the condition under which
a single trap will be triggered, and what will happen then; for
example, an instance of <procedure-trap> whose procedure
and behaviour slots contain my-factorial and
debug-trap would be a trap that enters the command line
debugger when the my-factorial procedure is invoked.

The following subsections describe all this in detail, for both the
user wanting to use traps, and the developer interested in
understanding how the interface hangs together.

5.21.3.1 A Quick Note on Terminology

It feels natural to use the word “trap” in some form for all levels
of the structure just described, so we need to be clear on the
terminology we use to describe each particular level. The terminology
used in this subsection is as follows.

“Low level trap calls”, or “low level traps”, are the calls made
directly from the C code of the Guile evaluator.

“Trap classes” are self-explanatory.

“Trap objects”, “trap instances”, or just “traps”, are instances
of a trap class, and each describe a single logical trap condition
plus behaviour as specified by the user of this interface.

A good example of when it is important to be clear, is when we talk
below of behaviours that should only happen once per low level trap.
A single low level trap call will typically map onto the processing of
several trap objects, so “once per low level trap” is significantly
different from “once per trap”.