Previous section: Conditionals

Dylan reference manual -- Iteration Constructs

## Iteration Constructs

```while   ( test  ) 	[Macro]
body
end [while]
=>  #f
```
while evaluates the expressions in the body over and over until the test returns false.

Each pass through the loop begins by evaluating test. If test evaluates to a true value, the expressions in the body are evaluated and the looping continues. If test evaluates to #f, the loop terminates and while returns #f.

```until   ( test  ) 	[Macro]
body
end [until]
=>  #f
```
until evaluates the expressions in the body over and over until the test returns true.

Each pass through the loop begins by evaluating test. If test evaluates to #f, the expressions in the body are evaluated and the looping continues. If test evaluates to a true value, the loop terminates and until returns #f.

```for ( clauses 	[Special Form]
[{until | while} end-test] )
body
[finally result-body]
end [for]
=> values
```
for allows one or more clauses. Each clause controls one iteration variable throughout the iteration. The optional end-test controls whether the iteration continues or terminates. It does not control any iteration variables.

The kinds of clauses include explicit step clauses, collection clauses, and numeric clauses:

Explicit step clauses

{variable | variable :: type} = init-value then next-value

Collection clauses

{variable | variable :: type} in collection

Numeric clauses

{variable | variable :: type} from start

[{to | above | below} bound]

[by increment]

Iteration with for proceeds through the following steps:

1) Evaluate the expressions that are evaluated just once, in left to right order as they appear in the for statement.

* For explicit step clauses, these expressions are type and init-value.

* For collection clauses, these are type and collection. If the value of collection is not a collection, signal an error.

* For numeric clauses, these are type, start, bound if it is supplied, and increment if it is supplied. If increment is not supplied, it defaults to 1.

2) Bind the iteration variables of explicit step and numeric clauses.

* For each explicit step clause, bind variable to the value of init-value. If type is supplied and the value of init-value is not of the specified type, signal an error.

* For each numeric clause, bind variable to the value of start. If type is supplied and the value of start is not of the specified type, signal an error.

3) Check numeric and collection clauses for exhaustion. If a clause is exhausted, go to step 9.

* A collection clause is exhausted if its collection has no next element.

* Numeric clauses cannot be exhausted if bound is not supplied. If bound is supplied, the following table gives the conditions for exhaustion:

```                    increment >= 0        increment < 0
to      variable > bound       variable < bound

abovebelow         variable <=         variable <=
boundvariable >= bound    boundvariable >= bound

```

4) Bind the iteration variables of collection clauses. Fresh bindings are created each time through the iteration.

* For each collection clause, bind variable to the next element of the collection for that clause. If type is supplied and this next element of the collection is not of the specified type, signal an error.

5) If end-test is supplied, evaluate it. The termination conditions depend on the symbol used to introduce the end-test in the for statement.

* If the value of end-test is false and the symbol is while, go to step 9.

* If the value of end-test is true and the symbol is until, go to step 9.

6) Execute the expressions in the body in sequence. The expressions in the body are used to produce side-effects.

7) Obtain the next values for explicit step and numeric clauses. Values are obtained in left to right order, in the environment produced by step 6.

* For each explicit step clause, evaluate next-value.

* For each numeric clause, add the values of variable and increment.

8) Bind the iteration variables of explicit step and numeric clauses to the values obtained in step 7. For each clause, if type is supplied and the next value for that clause is not of the specified type, signal an error. Fresh bindings are created each time through the iteration. After variables are bound, go to step 3.

9) Evaluate the expressions in the result-body in sequence. Bindings created in step 2 and 8 are visible during the execution of result-body. Bindings created in step 4 (i.e. the iteration variables of collection clauses) are not visible during the execution of result-body. The values of the last expression in the result-body are returned by the for statement. If there are no expressions in the result-body, for returns #f.

Examples of for:

```for ( thing = first-thing then next(thing),
until done?(thing) )
do-some(thing)
end;
```
```for (j :: <integer> from 0 to height)
for (i :: <integer> from 0 to width)
erase(i,j);
plot (i,j);
end for;
end for;
```
```for (city in olympic-cities,
year from start-year by 4)
schedule-olympic-game(city, year)
finally notify(press);
sell(tickets);
end;
```
```for (i from 0 below 100,
zombies from 0 below 100,
normals from 100 above 0 by -1)
population[i] := zombies + normals
end;
```

Next section: Non-local Exits