A stack group (usually abbreviated "SG") is a type of Lisp object useful for implementation of certain advanced control structures such as coroutines and generators. A stack group represents a computation and its internal state, including the Lisp stack. At any time, the computation being performed by the Lisp Machine is associated with one stack group, called the current or running stack group. The operation of making some stack group be the current stack group is called a resumption or a stack group switch; the running stack group is said to have resumed the new stack group. The resume operation has two parts: first, the state of the running computation is saved away inside the current stack group, and secondly the state saved in the new stack group is restored, and the new stack group is made current. Then the computation of the new stack group resumes its course. The stack group remembers all functions which were active at the time of the resumption (that is, the running function, its caller, its caller's caller, etc.), and where in each function the computation was up to. In other words, the entire control stack (or regular pdl) is saved. In addition, the bindings that were present are saved also; that is, the environment stack (or special pdl) is saved. When the state of the current stack group is saved away, all of its bindings are undone, and when the state is restored, the bindings are put back. Note that although bindings are temporarily undone, unwind-protect handlers are not run (see let-globally). There are several ways that a resumption can happen. First of all, there are several Lisp functions, described below, which resume some other stack group. When some stack group (call it c) calls such a function, it is suspended in the state of being in the middle of a call to that function. When someone eventually resumes c, the function will return. The arguments to these functions and the returned values can therefore be used to pass information back and forth between stack groups. Secondly, if an error is signalled, the current stack group resumes an error handler stack group, which handles the error in some way. Thirdly, a sequence break can happen, which transfers control to a special stack group called the scheduler (see (scheduler)). Note: the following discussion of resumers is incomplete, and the way they work is being changed anyway.
Each stack group has a resumer. c's resumer is some other stack group, which essentially is the last stack group to resume c. This is not completely right, however, because some resume-forms set the resumed stack group's resumer, and some don't. So c's resumer is actually the last stack group to resume c by means of one of the types of resume-form which does set the resumer. .defvar si:%current-stack-group-previous-stack-group The binding of this variable is the resumer of the current stack group. .end_defvar There are currently four kinds of resume-forms: .table 1 .item 1) If c calls s as a function with an argument x, then s is resumed, and the object transmitted is x. s's resumer is now c. .item 2) If c evaluates (stack-group-return x), then its resumer is resumed, and the object transmitted is x. The resumer's resumer is not affected. .item 3) If c evaluates (stack-group-resume s x), then c is resumed, and the object transmitted is x. c's resumer is not affected. (This is not currently implemented.) .item 4) If the initial function of c attempts to return a value x, the regular kind of Lisp function return cannot take place, since the function did not have any caller (it got there when the stack group was initialized). So instead of returning, its resumer is resumed, and the value transmitted is x. The resumer's resumer is not affected. c is left in a state from which it cannot be resumed again; any attempt to resume it would signal an error. .end_table There is one other way a stack group can be resumed. If the running stack group c gets a microcode trap, then the error handler stack group is resumed. The object transmitted is nil, and the error handler's resumer is set to c. This kind of resuming will only happen to the error handler, so regular programs should not see it.