Next: , Up: Debugging

5.21.1 Evaluation and the Scheme Stack

The idea of the Scheme stack is central to a lot of debugging. It always exists implicitly, as a result of the way that the Guile evaluator works, and can be summoned into concrete existence as a first-class Scheme value by the make-stack call, so that an introspective Scheme program – such as a debugger – can present it in some way and allow the user to query its details. The first thing to understand, therefore, is how the workings of the evaluator build up the stack.

Broadly speaking, the evaluator performs evaluations and applications. An evaluation means that it is looking at a source code expression like (+ x 5) or (if msg (loop)), deciding whether the top level of the expression is a procedure call, macro, builtin syntax, or whatever, and doing some appropriate processing in each case. (In the examples here, (+ x 5) would normally be a procedure call, and (if msg (loop)) builtin syntax.) For a procedure call, “appropriate processing” includes evaluating the procedure's arguments, as that must happen before the procedure itself can be called. An application means calling a procedure once its arguments have been calculated.

Typically evaluations and applications alternate with each other, and together they form a stack of operations pending completion. This is because, on the one hand, evaluation of an expression like (+ x 5) requires — once its arguments have been calculated — an application (in this case, of the procedure +) before it can complete and return a result, and, on the other hand, the application of a procedure written in Scheme involves evaluating the sequence of expressions that constitute that procedure's code. Each level on this stack is called a frame.

Therefore, when an error occurs in a running program, or the program hits a breakpoint, or in fact at any point that the programmer chooses, its state at that point can be represented by a stack of all the evaluations and procedure applications that are logically in progress at that time, each of which is known as a frame. The programmer can learn more about the program's state at that point by inspecting the stack and its frames.