The Evaluation Stack

Throughout any computation, the Wolfram System maintains an evaluation stack containing the expressions it is currently evaluating. You can use the function (RefLink[Stack, paclet:ref/Stack]) to look at the stack. This means, for example, that if you interrupt the Wolfram System in the middle of a computation, you can use (RefLink[Stack, paclet:ref/Stack]) to find out what the Wolfram System is doing.

The expression that the Wolfram System most recently started to evaluate always appears as the last element of the evaluation stack. The previous elements of the stack are the other expressions whose evaluation is currently in progress.

Thus at the point when x is being evaluated, the stack associated with the evaluation of an expression like f[g[x]] will have the form {f[g[x]],g[x],x}.

(RefLink[Stack, paclet:ref/Stack])[_] gives the expressions that are being evaluated at the time when it is called, in this case including the (RefLink[Print, paclet:ref/Print]) function:

f[g[Print[Stack[_]]]];

(RefLink[Stack, paclet:ref/Stack])[] gives the tags associated with the evaluations that are being done when it is called:

f[g[Print[Stack[]]]];

In general, you can think of the evaluation stack as showing what functions called what other functions to get to the point the Wolfram System is at in your computation. The sequence of expressions corresponds to the first elements in the successively nested lists returned by (RefLink[Trace, paclet:ref/Trace]) with the option (RefLink[TraceAbove, paclet:ref/TraceAbove]) set to (RefLink[True, paclet:ref/True]).

Looking at the evaluation stack.

It is rather rare to call (RefLink[Stack, paclet:ref/Stack]) directly in your main Wolfram System session. More often, you will want to call (RefLink[Stack, paclet:ref/Stack]) in the middle of a computation. Typically, you can do this from within a dialog, or subsidiary session, as discussed in "Dialogs".

Here is the standard recursive definition of the factorial function:

fac[1]=1;fac[n_]:=n fac[n-1]

This evaluates fac[10], starting a dialog when it encounters fac[4]:

TraceDialog[fac[10],fac[4]]

This shows what objects were being evaluated when the dialog was started:

Stack[]

This ends the dialog:

Return[]

In the simplest cases, the Wolfram System evaluation stack is set up to record all expressions currently being evaluated. Under some circumstances, however, this may be inconvenient. For example, executing (RefLink[Print, paclet:ref/Print])[(RefLink[Stack, paclet:ref/Stack])[]] will always show a stack with (RefLink[Print, paclet:ref/Print]) as the last function.

The function (RefLink[StackInhibit, paclet:ref/StackInhibit]) allows you to avoid this kind of problem. (RefLink[StackInhibit, paclet:ref/StackInhibit])[expr] evaluates expr without modifying the stack.

(RefLink[StackInhibit, paclet:ref/StackInhibit]) prevents (RefLink[Print, paclet:ref/Print]) from being included on the stack:

f[g[StackInhibit[Print[Stack[]]]]];

Functions like (RefLink[TraceDialog, paclet:ref/TraceDialog]) automatically call (RefLink[StackInhibit, paclet:ref/StackInhibit]) each time they start a dialog. This means that (RefLink[Stack, paclet:ref/Stack]) does not show functions that are called within the dialog, only those outside.

Controlling the evaluation stack.

By using (RefLink[StackInhibit, paclet:ref/StackInhibit]) and (RefLink[StackBegin, paclet:ref/StackBegin]), you can control which parts of the evaluation process are recorded on the stack. (RefLink[StackBegin, paclet:ref/StackBegin])[expr] evaluates expr, starting a fresh stack. This means that during the evaluation of expr, the stack does not include anything outside the (RefLink[StackBegin, paclet:ref/StackBegin]). Functions like (RefLink[TraceDialog, paclet:ref/TraceDialog])[expr,…] call (RefLink[StackBegin, paclet:ref/StackBegin]) before they begin evaluating expr, so that the stack shows how expr is evaluated, but not how (RefLink[TraceDialog, paclet:ref/TraceDialog]) was called.

(RefLink[StackBegin, paclet:ref/StackBegin])[expr] uses a fresh stack in the evaluation of expr:

f[StackBegin[g[h[StackInhibit[Print[Stack[]]]]]]]

(RefLink[Stack, paclet:ref/Stack]) normally shows you only those expressions that are currently being evaluated. As a result, it includes only the latest form of each expression. Sometimes, however, you may find it useful also to see earlier forms of the expressions. You can do this using (RefLink[StackComplete, paclet:ref/StackComplete]).

What (RefLink[StackComplete, paclet:ref/StackComplete])[expr] effectively does is to keep on the stack the complete evaluation chain for each expression that is currently being evaluated. In this case, the stack corresponds to the sequence of expressions obtained from (RefLink[Trace, paclet:ref/Trace]) with the option (RefLink[TraceBackward, paclet:ref/TraceBackward])->(RefLink[All, paclet:ref/All]) as well as (RefLink[TraceAbove, paclet:ref/TraceAbove])->(RefLink[True, paclet:ref/True]).