# 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:

### `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))
```