Iteration in Dylan

Simple iteration with while and until

while (condition?)
  // do something while the test condition? is true
end;
until (condition?)
  // do something until the test condition? is true
end;

Read more in the DRM: while and until.

The for loop

The for loop can be used in many different ways, but we’ll demonstrate a couple possibilities here:

Iterating over a collection

for (element in collection)
  // do something with element
end;

Iterating over a range

for (count from 0 below num)
  // do work
  // count ranges from 0 to the integer below num
end;

for (column from 1 to 3)
  // do work
  // count ranges from 1 to 3, inclusive.
end;

// Changing the stepping and going in reverse
for (index from stop - 1 to start by -1)
  // index will start at 'stop - 1' and end at the
  // value of 'start', decrementing by 1 with each
  // iteration of the loop.
end;

Iterating over a table

The easiest way to iterate over a table is to use an extension to the standard for loop that Open Dylan supports:

for (value keyed-by key in table)
  // do work
end;

If you want to directly access the keys of the table, you can use key-sequence:

for (key in table.key-sequence)
  // do work
end;

Read more in the DRM: for.

Breaking out of a loop

Breaking out of a loop is just like any other non-local exit in Dylan. Combine any loop with a block expression:

block (break)
  while (condition?)
    if (want-out?)
      break();
    end;
  end;
end;

A value can be passed to the exit function (break in this case) and that will be the value of the block expression. This shouldn’t be confused with break.

Collection Functions

When working with a collection, some additional operations are available that remove the need for explicit iteration over the collection.

In all of these, the function passed in can be any of:

  • An existing function.
  • An escaped operator name (\+ for example).
  • A locally defined method.
  • The result of a method that returns a function such as curry rcurry or other functional operations.

do

do iterates over one or more collections, performing side effects:

do(method (x) format-out("%s\n", x) end, #[1, 2, 3])

map, map-as, map-into

map iterates over one or more collections, applying a function and returns the results in a new collection. map-as and map-into allow control over the way that the results are returned.

let type-bindings = map(generate-type-binding, all-var-specs);
let strings = map(curry(as, <string>), names);
let c-direct-superclasses = map-as(<list>, convert, direct-superclasses(c));

Read more in the DRM: map, map-as, map-into.

reduce, reduce1

reduce combines the elements of a collection and a seed value into a single value by repeatedly applying a binary function.

reduce1 is similar to reduce, except that the first value of the collection is used as the seed value.

reduce(\*, 1, dimensions(x))
reduce1(\+, #(1, 2, 3, 4, 5))

reduce is often combined with map operations:

reduce(\+, 0, map(size, qqs))