# Evaluation

## The Standard Evaluation Sequence

The following is the sequence of steps that

*Mathematica* follows in evaluating an expression like

h[e_{1}, e_{2}...]. Every time the expression changes,

*Mathematica* effectively starts the evaluation sequence over again.

- If the expression is a raw object (e.g., Integer, String, etc.), leave it unchanged.

- Evaluate the head h of the expression.

- If h has attribute Flat, then flatten out all nested expressions with head h.

- If h has attribute Listable, then thread through any e
_{i} that are lists.

- If h has attribute Orderless, then sort the e
_{i} into order.

- Unless h has attribute HoldAllComplete, use any applicable transformation rules associated with f that you have defined for objects of the form h[f[e
_{1}, ...], ...].

- Use any built-in transformation rules associated with f for objects of the form h[f[e
_{1}, ...], ...].

- Use any applicable transformation rules that you have defined for h[f[e
_{1}, e_{2}, ...], ...] or for h[...][...].

- Use any built-in transformation rules for h[e
_{1}, e_{2}, ...] or for h[...][...].

## Nonstandard Argument Evaluation

There are a number of built-in

*Mathematica* functions that evaluate their arguments in special ways. The control structure

While is an example. The symbol

While has the attribute

HoldAll. As a result, the arguments of

While are not evaluated as part of the standard evaluation process. Instead, the internal code for

While evaluates the arguments in a special way. In the case of

While, the code evaluates the arguments repeatedly, so as to implement a loop.

Control structures | arguments evaluated in a sequence determined by control flow (e.g., CompoundExpression) |

Conditionals | arguments evaluated only when they correspond to branches that are taken (e.g., If, Which) |

Logical operations | arguments evaluated only when they are needed in determining the logical result (e.g., And, Or) |

Iteration functions | first argument evaluated for each step in the iteration (e.g., Do, Sum, Plot) |

Tracing functions | form never evaluated (e.g., Trace) |

Assignments | first argument only partially evaluated (e.g., Set, AddTo) |

Pure functions | function body not evaluated (e.g., Function) |

Scoping constructs | variable specifications not evaluated (e.g., Module, Block) |

Holding functions | argument maintained in unevaluated form (e.g., Hold, HoldPattern) |

Built-in functions that evaluate their arguments in special ways.

### Logical Operations

In an expression of the form

*e*_{1}&&*e*_{2}&&*e*_{3} the

*e*_{i} are evaluated in order. As soon as any

*e*_{i} is found to be

False, evaluation is stopped, and the result

False is returned. This means that you can use the

*e*_{i} to represent different "branches" in a program, with a particular branch being evaluated only if certain conditions are met.

The

Or function works much like

And; it returns

True as soon as it finds any argument that is

True.

Xor, on the other hand, always evaluates

*all* its arguments.

### Iteration Functions

An iteration function such as

Do[f, {i, i_{min}, i_{max}}] is evaluated as follows:

- The limits i
_{min}, i_{max} are evaluated.

- The value of the iteration variable
*i* is made local, effectively using Block.

- i
_{min} and i_{max} are used to determine the sequence of values to be assigned to the iteration variable i.

- The iteration variable is successively set to each value, and f is evaluated in each case.

- The local values assigned to i are cleared.

If there are several iteration variables, the same procedure is followed for each variable in turn, for every value of all the preceding variables.

Unless otherwise specified,

f is not evaluated until a specific value has been assigned to

i, and is then evaluated for each value of

i chosen. You can use

Evaluate[f] to make

f be evaluated immediately, rather than only after a specific value has been assigned to

i.

### Assignments

The left-hand sides of assignments are only partially evaluated.

- If the left-hand side is a symbol, no evaluation is performed.

- If the left-hand side is a function without hold attributes, the arguments of the function are evaluated, but the function itself is not evaluated.

The right-hand side is evaluated for immediate (

=), but not for delayed (

:=), assignments.

Any subexpression of the form

HoldPattern[expr] that appears on the left-hand side of an assignment is not evaluated. When the subexpression is used for pattern matching, it matches as though it were

expr without the

HoldPattern.

## Overriding Nonstandard Argument Evaluation

Overriding holding of arguments.

By using

Evaluate, you can get any argument of a function evaluated immediately, even if the argument would usually be evaluated later under the control of the function. An exception to this is when the function has the

HoldComplete attribute; in this case, the contents of the function are not modified by the evaluator.

## Preventing Evaluation

*Mathematica* provides various functions which act as "wrappers" to prevent the expressions they contain from being evaluated.

Wrappers that prevent expressions from being evaluated.

## Global Control of Evaluation

In the evaluation procedure described so far, two basic kinds of steps are involved:

- Iteration: evaluate a particular expression until it no longer changes.

- Recursion: evaluate subsidiary expressions needed to find the value of a particular expression.

Iteration leads to evaluation chains in which successive expressions are obtained by the application of various transformation rules.

Trace shows evaluation chains as lists, and shows subsidiary evaluations corresponding to recursion in sublists.

The expressions associated with the sequence of subsidiary evaluations which lead to an expression currently being evaluated are given in the list returned by

Stack[].

Global variables controlling the evaluation of expressions.

## Aborts

You can ask

*Mathematica* to abort at any point in a computation, either by calling the function

Abort[], or by typing appropriate interrupt keys.

When asked to abort,

*Mathematica* will terminate the computation as quickly as possible. If the answer obtained would be incorrect or incomplete, then

*Mathematica* returns

$Aborted instead of giving that answer.

Aborts can be caught using

CheckAbort, and can be postponed using

AbortProtect.