The Standard Evaluation Procedure
Here the standard procedure used by the Wolfram System to evaluate expressions is described. This procedure is the one followed for most kinds of expression. There are, however, some kinds of expressions, such as those used to represent the Wolfram System programs and control structures, that are evaluated in a nonstandard way.
In the standard evaluation procedure, the Wolfram System first evaluates the head of an expression and then evaluates each element of the expression. These elements are in general themselves expressions, to which the same evaluation procedure is recursively applied.
As soon as the Wolfram System has evaluated the head of an expression, it sees whether the head is a symbol that has attributes. If the symbol has the attributes Orderless, Flat, or Listable, then immediately after evaluating the elements of the expression the Wolfram System performs the transformations associated with these attributes.
The next step in the standard evaluation procedure is to use definitions that the Wolfram System knows for the expression it is evaluating. The Wolfram System first tries to use definitions that you have made, and if there are none that apply, it tries built‐in definitions.
If the Wolfram System finds a definition that applies, it performs the corresponding transformation on the expression. The result is another expression, which must then in turn be evaluated according to the standard evaluation procedure.
|■ Evaluate the head of the expression.|
|■ Evaluate each element in turn.|
|■ Apply transformations associated with the attributes Orderless, Listable, and Flat.|
|■ Apply any definitions that you have given.|
|■ Apply any built‐in definitions.|
|■ Evaluate the result.|
As discussed in "Principles of Evaluation", the Wolfram System follows the principle that each expression is evaluated until no further definitions apply. This means that the Wolfram System must continue reevaluating results until it gets an expression that remains unchanged through the evaluation procedure.
|2ax+a^2+1||here is the original expression|
|Plus[Times[2,a,x],Power[a,2],1]||this is the internal form|
|Times[2,a,x]||this is evaluated first|
|Times[2,7,x]||a is evaluated to give 7|
|Times[14,x]||built‐in definitions for Times give this result|
|Power[a,2]||this is evaluated next|
|Power[7,2]||here is the result after evaluating a|
|49||built‐in definitions for Power give this result|
|Plus[Times[14,x],49,1]||here is the result after the arguments of Plus have been evaluated|
|Plus[50,Times[14,x]]||built‐in definitions for Plus give this result|
|50+14x||the result is printed like this|
The Wolfram System provides various ways to "trace" the evaluation process, as discussed in "Tracing Evaluation". The function Trace[expr] gives a nested list showing each subexpression generated during evaluation. (Note that the standard evaluation traverses the expression tree in a depth‐first way, so that the smallest subparts of the expression appear first in the results of Trace.)
The order in which the Wolfram System applies different kinds of definitions is important. The fact that the Wolfram System applies definitions you have given before it applies built‐in definitions means that you can give definitions that override the built‐in ones, as discussed in "Modifying Built-in Functions".
As discussed in "Associating Definitions with Different Symbols", you can associate definitions with symbols either as upvalues or downvalues. The Wolfram System always tries upvalue definitions before downvalue ones.
If you have an expression like f[g[x]], there are, in general, two sets of definitions that could apply: downvalues associated with f and upvalues associated with g. The Wolfram System tries the definitions associated with g before those associated with f.
This ordering follows the general strategy of trying specific definitions before more general ones. By applying upvalues associated with arguments before applying downvalues associated with a function, the Wolfram System allows you to make definitions for special arguments that override the general definitions for the function with any arguments.
|■ Definitions associated with g are applied before definitions associated with f in the expression f[g[x]].|
Most functions such as Plus that are built into the Wolfram System have downvalues. There are, however, some objects in the Wolfram System that have built‐in upvalues. For example, SeriesData objects, which represent power series, have built‐in upvalues with respect to various mathematical operations.
- Definitions you have given associated with g;
- Built‐in definitions associated with g;
- Definitions you have given associated with f;
- Built‐in definitions associated with f.
The fact that upvalues are used before downvalues is important in many situations. In a typical case, you might want to define an operation such as composition. If you give upvalues for various objects with respect to composition, these upvalues will be used whenever such objects appear. However, you can also give a general procedure for composition, to be used if no special objects are present. You can give this procedure as a downvalue for composition. Since downvalues are tried after upvalues, the general procedure will be used only if no objects with upvalues are present.
In general, there can be several objects that have upvalues in a particular expression. The Wolfram System first looks at the head of the expression and tries any upvalues associated with it. Then it successively looks at each element of the expression, trying any upvalues that exist. The Wolfram System performs this procedure first for upvalues that you have explicitly defined, and then for upvalues that are built-in. The procedure means that in a sequence of elements, upvalues associated with earlier elements take precedence over those associated with later elements.