This Design Note unifies Dylan's existing iteration constructs, for, for-each, and dotimes, into one general for statement. It also changes the keywords in <range> to be compatible with the numeric clauses in the new for statement.Dylan Design Notes
Dylan Design Notes: #29: For Loops (Change) #29: For Loops (Change)
Version 1, January 1994 Copyright (c) 1993-1994, Apple Computer
for (clauses [{until | while} end-test]) [Special Form]
body-forms
[finally result-forms]
end
=> values
for allows any number of 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 allowed in a for statement include the following:
Explicit step clauses provide the functionality of the old for statement. The syntax for an explicit step clause is as follows:
{variable | variable :: type} = init-value then next-value
Collection clauses provide the functionality of the old for-each
statement. The syntax for a collection clause is as follows:
{variable | variable :: type} in collection
Numeric clauses provide a convenient shorthand for iterating over
integers. The syntax for a numeric clause is as follows:
{variable | variable :: type} from start
[{to | above | below} bound]
[by increment]
Iteration with for proceeds through the following steps:
For explicit step clauses, these expressions are type and init-value.
For collection clauses, these expressions are type and collection. If the value of collection is not a collection, signal an error.
For numeric clauses, these expressions are type, start, bound if it is supplied, and increment if it is supplied. If increment is not supplied, it defaults to 1, or -1 if it is an above clause.
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.
A collection clause is exhausted if its collection has no next element. (The first time through, the "next element" is the first, if any.)
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
keyword = to variable > bound variable < bound
keyword = above variable <= bound variable <= bound
keyword = below variable >= bound variable >= bound
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.
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.
For each explicit step clause, evaluate next-value.
For each numeric clause, add the values of variable and increment.
Various kinds of iteration clauses (general iteration clauses, numeric iteration clauses, and clauses for iterating over collections) are allowed to appear in the same construct.
Since clauses themselves can cause the iteration to terminate (for example, when a collection is exhausted), the end test is moved into the clauses and becomes an optional "termination clause."
Optional result expressions are separated from the end test. They now appear at the end of the construct rather than in the middle.
Types may be declared for iteration variables.