Imperative control flow

to do:

  • discuss return

  • discuss labels and labeled gotos

  • discuss use of for loops

  • discuss iterators; discuss examples of iterating an array and iterating a text value (.keys, .vals, .chars, .size, etc.)

  • discuss use of while loops

  • discuss use of do loops

Using range with a for loop

The range function produces an iterator (of type Iter) with the given lower and upper bound, inclusive.

The following loop example prints the numbers 0 through 10 over its eleven iterations:

var i = 0;
for (j in range(0, 10)) {
 assert(j == i);
 i += 1;
assert(i == 11);

More generally, the function range is a class that constructs iterators over sequences of natural numbers. Each such iterator has type Iter<Nat>.

As a constructor function, range has a function type:

(lower:Nat, upper:Nat) -> Iter<Nat>

Where Iter<Nat> is an iterator object type with a next method that produces optional elements, each of type ?Nat:

type Iter<Nat> = {next : () -> ?Nat};

For each invocation, next returns an optional element (of type ?Nat).

The value null indicates that the iteration sequence has terminated.

Until reaching null, each non-null value, of the form ?n for some number n, contains the next successive element in the iteration sequence.

Using revrange

Like range, the function revrange is a class that constructs iterators (each of type Iter). As a constructor function, it has a function type:

(upper:Nat, lower:Nat) -> Iter

Unlike range, the revrange function descends in its iteration sequence, from an initial upper bound to a final lower bound.