# Loops and Control Structures

The execution of a *Mathematica* program involves the evaluation of a sequence of *Mathematica* expressions. In simple programs, the expressions to be evaluated may be separated by semicolons, and evaluated one after another. Often, however, you need to evaluate expressions several times, in some kind of "loop".

Do[expr,{i,i_{max}}] | evaluate expr repetitively, with i varying from to in steps of |

Do[expr,{i,i_{min},i_{max},di}] | evaluate expr with i varying from to in steps of di |

Do[expr,{i,list}] | evaluate expr with i taking on values from list |

Do[expr,{n}] | evaluate expr n times |

In[2]:= |

Out[2]= |

The way iteration is specified in Do is exactly the same as in functions like Table and Sum. Just as in those functions, you can set up several nested loops by giving a sequence of iteration specifications to Do.

Sometimes you may want to repeat a particular operation a certain number of times, without changing the value of an iteration variable. You can specify this kind of repetition in Do just as you can in Table and other iteration functions.

In[4]:= |

Out[4]= |

Nest[f,expr,n] | apply f to expr n times |

FixedPoint[f,expr] | start with expr, and apply f repeatedly until the result no longer changes |

NestWhile[f,expr,test] | start with expr, and apply f repeatedly until applying test to the result no longer yields True |

Applying functions repetitively.

Do allows you to repeat operations by evaluating a particular expression many times with different values for iteration variables. Often, however, you can make more elegant and efficient programs using the functional programming constructs discussed in "Applying Functions Repeatedly". Nest[f, x, n], for example, allows you to apply a function repeatedly to an expression.

In[6]:= |

Out[6]= |

In[7]:= |

Out[7]= |

Nest allows you to apply a function a specified number of times. Sometimes, however, you may simply want to go on applying a function until the results you get no longer change. You can do this using FixedPoint[f, x].

You can use FixedPoint to imitate the evaluation process in *Mathematica*, or the operation of functions such as . FixedPoint goes on until two successive results it gets are the same. NestWhile allows you to go on until an arbitrary function no longer yields True.

Catch[expr] | evaluate expr until Throw[value] is encountered, then return value |

Catch[expr,form] | evaluate expr until Throw[value, tag] is encountered, where form matches tag |

Catch[expr,form,f] | return instead of value |

Nonlocal control of evaluation.

Throw and Catch provide a flexible way to control the process of evaluation in *Mathematica*. The basic idea is that whenever a Throw is encountered, the evaluation that is then being done is stopped, and *Mathematica* immediately returns to the nearest appropriate enclosing Catch.

You can use Throw and Catch to divert the operation of functional programming constructs, allowing for example the evaluation of such constructs to continue only until some condition has been met. Note that if you stop evaluation using Throw, then the structure of the result you get may be quite different from what you would have got if you had allowed the evaluation to complete.

In[13]:= |

Out[13]= |

In[14]:= |

Out[14]= |

In[15]:= |

Out[15]= |

Throw and Catch operate in a completely global way: it does not matter how or where a Throw is generated—it will always stop evaluation and return to the enclosing Catch.

In[16]:= |

Out[16]= |

In[17]:= |

In[18]:= |

Out[18]= |

In[19]:= |

Out[19]= |

In small programs, it is often adequate to use Throw[value] and Catch[expr] in their simplest forms. But particularly if you write larger programs that contain many separate pieces, it is usually much better to use Throw[value, tag] and Catch[expr, form]. By keeping the expressions tag and form local to a particular piece of your program, you can then ensure that your Throw and Catch will also operate only within that piece.

In[20]:= |

Out[20]= |

In[21]:= |

Out[21]= |

In[22]:= |

Out[22]= |

In[23]:= |

Out[23]= |

You should realize that there is no need for the tag that appears in Throw to be a constant; in general it can be any expression.

In[24]:= |

Out[24]= |

When you use Catch[expr, form] with Throw[value, tag], the value returned by Catch is simply the expression value given in the Throw. If you use Catch[expr, form, f], however, then the value returned by Catch is instead .

In[25]:= |

Out[25]= |

In[26]:= |

Out[26]= |

While[test,body] | evaluate body repetitively, so long as test is True |

For[start,test,incr,body] | evaluate start, then repetitively evaluate body and incr, until test fails |

Functions like Do, Nest, and FixedPoint provide structured ways to make loops in *Mathematica* programs, while Throw and Catch provide opportunities for modifying this structure. Sometimes, however, you may want to create loops that even from the outset have less structure. And in such cases, you may find it convenient to use the functions While and For, which perform operations repeatedly, stopping when a specified condition fails to be true.

The functions While and For in *Mathematica* are similar to the control structures and in languages such as C. Notice, however, that there are a number of important differences. For example, the roles of comma and semicolon are reversed in *Mathematica* For loops relative to C language ones.

In *Mathematica*, both While and For always evaluate the loop test before evaluating the body of the loop. As soon as the loop test fails to be True, While and For terminate. The body of the loop is thus only evaluated in situations where the loop test is True.

In[30]:= |

In a While or For loop, or in general in any *Mathematica* procedure, the *Mathematica* expressions you give are evaluated in a definite sequence. You can think of this sequence as defining the "flow of control" in the execution of a *Mathematica* program.

In most cases, you should try to keep the flow of control in your *Mathematica* programs as simple as possible. The more the flow of control depends for example on specific values generated during the execution of the program, the more difficult you will typically find it to understand the structure and operation of the program.

Functional programming constructs typically involve very simple flow of control. While and For loops are always more complicated, since they are set up to make the flow of control depend on the values of the expressions given as tests. Nevertheless, even in such loops, the flow of control does not usually depend on the values of expressions given in the body of the loop.

In some cases, however, you may need to construct *Mathematica* programs in which the flow of control is affected by values generated during the execution of a procedure or of the body of a loop. One way to do this, which fits in with functional programming ideas, is to use Throw and Catch. But *Mathematica* also provides various functions for modifying the flow of control which work like in languages such as C.

Break[] | exit the nearest enclosing loop |

Continue[] | go to the next step in the current loop |

Return[expr] | return the value expr from a function |

Goto[name] | go to the element Label[name] in the current procedure |

Throw[value] | return value as the value of the nearest enclosing Catch (nonlocal return) |

Return[expr] allows you to exit a particular function, returning a value. You can think of Throw as a kind of nonlocal return which allows you to exit a whole sequence of nested functions. Such behavior can be convenient for handling certain error conditions.

In[33]:= |

In[34]:= |

Out[34]= |

In[35]:= |

In[36]:= |

Out[36]= |

In[37]:= |

Out[37]= |

Functions like Continue[] and Break[] allow you to "transfer control" to the beginning or end of a loop in a *Mathematica* program. Sometimes you may instead need to transfer control to a particular element in a *Mathematica* procedure. If you give a Label as an element in a procedure, you can use Goto to transfer control to this element.

Note that you can use Goto in a particular *Mathematica* procedure only when the Label it specifies occurs as an element of the same *Mathematica* procedure. In general, use of Goto reduces the degree of structure that can readily be perceived in a program, and therefore makes the operation of the program more difficult to understand.