# How to use iterators

_This page explains how to use q's iterators to apply a function to each item of a list, in parallel, pairwise across two lists, and cumulatively, and how to repeat a function a fixed number of times, while a condition holds, or until its result stops changing._

An iterator takes a function and returns a new function, called a **derived function**, that applies the original in a particular pattern. `count` returns the length of a list; `count each` returns the length of every item in it. Iterators are how q expresses most of what other languages write as `for` and `while` loops, usually in a single short expression.

The iterators on this page, from simplest to most general, are:

| Iterator | Glyph | Keyword | Applies the function |
|---|---|---|---|
| [Each](#each) | `'` | `each` | to each item of a list |
| [Each Parallel](#each-parallel) | `':` | `peach` | to each item, spread across secondary threads |
| [Each Both](#each-both) | `'` | | to corresponding pairs of items from two lists |
| [Each Left, Each Right](#each-left-and-each-right) | `\:` `/:` | | between each item of one argument and the whole of the other |
| [Each Prior](#each-prior) | `':` | `prior` | between each item and the one before it |
| [Scan, Over](#scan-and-over) | `\` `/` | `scan` `over` | cumulatively, carrying a result from one step to the next |
| [Do, While, Converge](#do-while-and-converge) | `\` `/` | | repeatedly to its own result |

## Before you iterate: atomic functions

Many q operators are **atomic**: they already apply to every item of a list, so they need no iterator at all.
```q
q)1 2 3+10
11 12 13
```

Use an iterator only when a function does not already do what you want across a list. `count`, for example, is not atomic: it treats its argument as one list and counts its items.
```q
q)count ("the";"quick";"brown";"fox")
4
q)count each ("the";"quick";"brown";"fox")
3 5 5 3
```

> **Tip — Do not iterate an atomic function**
>
>
> `(2*) each 1 2 3` returns the same result as `2*1 2 3`, but calls the function once per item instead of once for the whole list. See [do not iterate atomic functions](../performance/code-optimization.md#do-not-iterate-atomic-functions).
>
## Each

[`each`](../../ref/each.md) applies a unary function to each item of a list and returns a list of the results, one per item.


**q**
```q
q)words:("the";"quick";"brown";"fox")
q)count each words
3 5 5 3
q){x where x>0} each (1 -2 3; -4 5)
1 3
,5
```


**Python**
```python
>>> words = ["the", "quick", "brown", "fox"]
>>> list(map(len, words))
[3, 5, 5, 3]
>>> list(map(lambda xs: list(filter(lambda v: v > 0, xs)),
...          ([1, -2, 3], [-4, 5])))
[[1, 3], [5]]
```


The keyword is a readable name for the Each iterator, `'`. The following three forms are equivalent, and good q style prefers the keyword for a unary function:
```q
q)count each words
3 5 5 3
q)(count')words
3 5 5 3
q)count'[words]
3 5 5 3
```

`each` works on a dictionary too, applying the function to each value and keeping the keys:
```q
q)d:([a:1 2 3; b:4 5; c:6 7 8 9])
q)sum each d
a| 6
b| 9
c| 30
```

To reach one level deeper into a nested list, apply `each` to a function that already uses `each`:
```q
q)(count each) each (("ab";"cde");enlist "f")
2 3
,1
```

> **Warning — An empty list can change type**
>
>
> Each never calls the function on an empty list, so q cannot know what type the results would have had. It returns the generic empty list, of type `0h`, rather than an empty list of the expected type:
>
> ```q
> q)type {2*x} each 0#0
> 0h
> q)type 2*0#0
> 7h
> ```
>
> Allow for this when the length of the list is not known in advance.
>
## Each Parallel

[`peach`](../../ref/each.md) computes the same result as `each`, but divides the items between **secondary threads** so that several calls run at once. Start q with secondary threads using the [`-s`](../../ref/cmdline.md#-s-secondary-threads) command-line option, and check the number with [`\s`](../../ref/syscmds.md#s-number-of-secondary-threads):
```bash
q -s 4
```
```q
q)\s
4i
q){sum x*x} peach (til 5;til 10)
30 285
```

Without secondary threads, `peach` runs on the main thread and behaves exactly like `each`.

`peach` is faster when each call is independent and does enough work to outweigh the cost of handing it to another thread, for example reading separate files or processing separate partitions. A cheap function is usually slower with `peach` than with `each`. See [`peach`](../performance/code-optimization.md#peach) in the performance guide before you rely on it for speed.

Like `each`, `peach` takes a unary function. To parallelize a function that takes more than one argument, project [Apply](../../ref/apply.md) (`.`) on it, so that each item supplies the full argument list:
```q
q).[{x+y*z};] peach (1 2 3;4 5 6)
7 34
```

> **Warning — A secondary thread cannot update a global variable**
>
>
> Return results from the function and assign them on the main thread instead:
>
> ```q
> q){a::x} peach 1 2
> 'noupdate: `. `a
> ```
>
> This restriction applies only when q has secondary threads. Without them, the same code runs without error, so test `peach` code in a process started with `-s`. For the other operations that `peach` blocks, and for its memory use, see [`each`, `peach`](../../ref/each.md#blocked-within-peach).
>
## Each Both

Applied to a binary function, the Each iterator `'` pairs the items of its two arguments: the first item of the left list with the first item of the right list, and so on. This form is often called **Each Both**, and it works like a zip.


**q**
```q
q)3 2 4#'("apple";"kiwi";"plum")
"app"
"ki"
"plum"
q)1 2 3,'10 20 30
1 10
2 20
3 30
```


**Python**
```python
>>> list(map(lambda n, w: w[:n], [3, 2, 4],
...          ["apple", "kiwi", "plum"]))
['app', 'ki', 'plum']

>>> list(zip([1, 2, 3], [10, 20, 30]))
[(1, 10), (2, 20), (3, 30)]
```


Unlike Python's `map` and `zip`, which stop at the end of the shorter list, q requires both lists to have the same length:
```q
q)1 2,'10 20 30
'length
```

An atom on either side is paired with every item of the other:
```q
q)"-",'("ab";"cd")
"-ab"
"-cd"
```

Each also applies functions of rank three or more. Write the arguments in brackets:
```q
q){x+y*z}'[1 2;10 20;3 4]
31 82
```

## Each Left and Each Right

Each Both pairs items one to one. Often you want instead to apply a function between **each** item of one argument and the **whole** of the other:

- **Each Left** `\:` iterates over the left argument, and passes the whole right argument each time.
- **Each Right** `/:` iterates over the right argument, and passes the whole left argument each time.
```q
q)"abc",\:"XY"          / each of "abc", joined to "XY"
"aXY"
"bXY"
"cXY"
q)"abc",/:"XY"          / "abc", joined to each of "XY"
"abcX"
"abcY"
```

> **Tip — Which side does the slash iterate?**
>
>
> The top of the slash leans toward the argument that q iterates. `\` leans left, so `\:` iterates the left argument; `/` leans right, so `/:` iterates the right argument.
>
Each Right is the natural way to test one list against several values. Here each threshold is compared with all the prices, giving one row of booleans per threshold, and `sum each` counts the prices above each threshold:


**q**
```q
q)prices:101 98 105 110
q)prices >/: 100 105
1011b
0001b

q)sum each prices >/: 100 105
3 1i
```


**Python**
```python
>>> from itertools import repeat
>>> from operator import gt
>>> prices = [101, 98, 105, 110]
>>> [list(map(gt, prices, repeat(t))) for t in (100, 105)]
[[True, False, True, True], [False, False, False, True]]
>>> [sum(map(gt, prices, repeat(t))) for t in (100, 105)]
[3, 1]
```


Each Left suits a function that is not atomic in its left argument. [`ss`](../../ref/ss.md) finds the positions of a substring in one string, so Each Left applies it to each string in a list:
```q
q)("hello";"yellow";"sky") ss\: "l"
2 3
2 3
`long$()
```

Each Left and Each Right are shorthand for a [projection](work-with-functions.md#projections-and-partial-application) with `each`: `x f\:y` is `f[;y] each x`, and `x f/:y` is `f[x;] each y`.

### Combine Each Left and Each Right

Apply both to pair every item of one argument with every item of the other. With [join](../../ref/join.md) (`,`), the result shows each pair. The iterator written last, on the outside, determines how q groups the pairs:
```q
q)1 2 3,/:\:10 20       / one row for each item on the left
1 10 1 20
2 10 2 20
3 10 3 20
q)1 2 3,\:/:10 20       / one row for each item on the right
1 10 2 10 3 10
1 20 2 20 3 20
```

Flatten the first form with [`raze`](../../ref/raze.md) and you get the Cartesian product, which q provides directly as the keyword [`cross`](../../ref/cross.md):


**q**
```q
q)1 2 3 cross 10 20
1 10
1 20
2 10
2 20
3 10
3 20
q)(raze 1 2 3,/:\:10 20)~1 2 3 cross 10 20
1b
```


**Python**
```python
>>> from itertools import product
>>> list(product([1, 2, 3], [10, 20]))
[(1, 10), (1, 20), (2, 10), (2, 20), (3, 10), (3, 20)]
```


Use `cross` when you want the pairs themselves, for example every combination of symbol and date to query:
```q
q)`AAPL`MSFT cross 2026.11.02 2026.11.03
`AAPL 2026.11.02
`AAPL 2026.11.03
`MSFT 2026.11.02
`MSFT 2026.11.03
```

Use the iterators when you want to apply some other function to every combination, and keep the results grouped. `1 2 3*/:\:10 20`, for example, is a multiplication table with one row for each item on the left.

> **Note — Atomic functions do not need Each Left or Each Right with an atom**
>
>
> `1 2 3+10` already adds 10 to every item. The iterators matter when the other argument is a list that you want treated as a whole, as in `1 2 3+/:10 20`. Without the iterator, q pairs the items and signals a `length` error because the lists differ in length.
>
## Each Prior

Each Prior `':` applies a binary function between each item of a list and the item before it. The keyword [`prior`](../../ref/prior.md) is its readable form, and [`deltas`](../../ref/deltas.md) is the most common case, the difference between successive values:


**q**
```q
q)(-':)100 102 101 105
100 2 -1 4
q)(-) prior 100 102 101 105
100 2 -1 4
q)deltas 100 102 101 105
100 2 -1 4
```


**Python**
```python
>>> from itertools import chain
>>> from operator import sub
>>> p = [100, 102, 101, 105]
>>> list(map(sub, p, chain([0], p)))
[100, 2, -1, 4]
```


The function receives the current item as its left argument `x`, and the previous item as its right argument `y`. The first item has no previous item, so q supplies one: for `-` it uses 0, which leaves the first item unchanged. Drop the first result with `1_` when you only want the changes:
```q
q)1_deltas 100 102 101 105
2 -1 4
```

See [Each Prior](../../ref/maps.md#each-prior) for how q chooses the starting value for other functions.

## Scan and Over

The iterators so far apply a function to items independently. Scan `\` and Over `/` instead **carry a result forward**: they apply a binary function to the first two items, then to that result and the third item, and so on. Scan returns every intermediate result; Over returns only the last. Over is often called a _reduce_ or _fold_ in other languages.


**q**
```q
q)(+\)1 2 3 4 5        / running total
1 3 6 10 15
q)(+/)1 2 3 4 5        / final total
15
```


**Python**
```python
>>> from itertools import accumulate
>>> from functools import reduce
>>> from operator import add
>>> list(accumulate([1, 2, 3, 4, 5], add))
[1, 3, 6, 10, 15]
>>> reduce(add, [1, 2, 3, 4, 5])
15
```


The keywords [`scan` and `over`](../../ref/over.md) are readable alternatives. Put the function in parentheses when it is an operator:
```q
q)(+) scan 1 2 3 4 5
1 3 6 10 15
q)(+) over 1 2 3 4 5
15
```

Common combinations also have their own keywords, which good q style prefers: [`sums`](../../ref/sum.md#sums) is `+\`, [`sum`](../../ref/sum.md) is `+/`, and [`maxs`](../../ref/max.md#maxs) is `|\`, the running maximum.
```q
q)(|\)3 1 4 1 5 9 2
3 3 4 4 5 9 9
q)maxs 3 1 4 1 5 9 2
3 3 4 4 5 9 9
```

### Supply a starting value

Write a left argument to give Scan or Over a starting value. Here an account starts at 1000 and the right argument lists the deposits and withdrawals:


**q**
```q
q)1000+\50 -20 30      / balance after each transaction
1050 1030 1060
q)1000+/50 -20 30      / closing balance
1060
```


**Python**
```python
>>> list(accumulate([50, -20, 30], add, initial=1000))[1:]
[1050, 1030, 1060]
>>> reduce(add, [50, -20, 30], 1000)
1060
```


Note that Scan does not include the starting value in its result, whereas Python's `accumulate` does.

### Use your own function

Scan and Over accept any binary function, which makes them the tool for a calculation in which each step depends on the one before. In the function, `x` is the result carried forward and `y` is the next item. This balance is not allowed to fall below zero, which a running sum alone cannot express:
```q
q){0|x+y}\[0;5 -10 3 -1]
5 0 3 2
```

Over works on lists of any type, not only numbers. [`inter`](../../ref/inter.md) finds the items two lists have in common, so Over finds the items common to all of them:
```q
q)(inter/)(1 2 3 4;2 3 4;3 4 5)
3 4
```

A function of rank three takes one extra list for each extra argument. Each step receives the carried result and the next item of each list. Here a trading position changes by each quantity multiplied by its side: `1` for a buy and `-1` for a sell:
```q
q){x+y*z}\[0;100 50 30;1 -1 1]
100 50 80
```

> **Tip — Replace Over with Scan to debug**
>
>
> When an Over returns a result you did not expect, change `/` to `\`. Scan performs the same computation and shows each intermediate result.
>
> **Warning — Over on an empty list**
>
>
> q does not call the function on an empty list. For an operator with a known identity, such as `+`, Over returns that identity; for a lambda, it returns the generic empty list:
>
> ```q
> q)(+/)0#0
> 0
> q)()~{x+y}/[0#0]
> 1b
> ```
>
> See [empty lists](../../ref/accumulators.md#empty-lists) for the full rules.
>
## Do, While, and Converge

Scan and Over also accept a **unary** function. They then apply the function to its own result repeatedly, and the left argument determines when to stop:

| Form | Left argument | Stops |
|---|---|---|
| Do | an integer `n` | after `n` applications |
| While | a unary test function | when the test returns false on the latest result |
| Converge | none | when the result stops changing |

As with binary functions, Scan `\` returns every result, including the starting value, and Over `/` returns only the last. These forms replace most uses of the [`do` and `while`](control-execution.md#loops) keywords.

### Do

With an integer on the left, q applies the function that many times. Here 100 grows by 5% a year for 3 years:


**q**
```q
q)3 {x*1.05}\ 100f
100 105 110.25 115.7625
q)3 {x*1.05}/ 100f
115.7625
```


**Python**
```python
>>> list(accumulate(repeat(None, 3),
...                  lambda x, _: x * 1.05, initial=100.0))
[100.0, 105.0, 110.25, 115.7625]
>>> reduce(lambda x, _: x * 1.05, repeat(None, 3), 100.0)
115.7625
```


The function can build up a list. In the following example, each step appends the sum of the last two numbers, so five steps extend `0 1` into the Fibonacci sequence:
```q
q)5 {x,sum -2#x}/ 0 1
0 1 1 2 3 5 8
```

> **Warning — The rank of the function decides the meaning of the left argument**
>
>
> With a unary function, an integer on the left is a repeat count. With a binary function, the same integer is a starting value:
>
> ```q
> q)3 {x*2}/ 1            / unary: double 1, three times
> 8
> q)3 +/ 1 2              / binary: 3 + 1 + 2
> 6
> ```
>
### While

With a test function on the left, q keeps applying the function while the test is true of the latest result:


**q**
```q
q){x<1000} {x*2}\ 1
1 2 4 8 16 32 64 128 256 512 1024
```


**Python**
```python
>>> from itertools import takewhile
>>> list(takewhile(lambda x: x < 1000,
...     accumulate(repeat(None), lambda x, _: x * 2,
...                initial=1)))
[1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
```


The two results differ in their last item. 1024 fails the test, and Python's `takewhile` drops it, but q still returns it: q tests each result after computing it, and stops there. Write the test to look one step ahead if you do not want that result. Here a dictionary maps each person to their manager, and the test stops before the person with no manager:
```q
q)boss:`ann`bob`cat!``ann`bob
q){not null boss x} boss\ `cat
`cat`bob`ann
```

The function being applied here is the dictionary `boss` itself: indexing a dictionary works like applying a function, so iterators accept dictionaries and lists too.

### Converge

With no left argument, q applies the function until a result matches the previous one, or matches the starting value. This suits calculations that settle on an answer, such as Newton's method for the square root of 2:
```q
q){(x+2%x)%2}\[1f]
1 1.5 1.416667 1.414216 1.414214 1.414214
q){(x+2%x)%2}/[1f]
1.414214
```

You do not need to know in advance how many steps it takes. Matching uses [comparison tolerance](../../ref/precision.md#comparison-tolerance), so floating-point results converge when they are close enough.

Converge is also the idiomatic way to repeat an operation until there is nothing left to do. [`raze`](../../ref/raze.md) removes one level of nesting, so `raze/` flattens a list of any depth:
```q
q)(raze/)(1;(2;(3;4)))
1 2 3 4
```

Following the manager chain from [While](#while) with Converge runs until the lookup of the null name returns the null name again:
```q
q)(boss\)`cat
`cat`bob`ann`
```

> **Warning — Converge does not stop if the result never repeats**
>
>
> `(not/) 42` alternates between `0b` and `1b` forever, because no result matches the one before it or the starting value `42`. Press ++ctrl+c++ to interrupt it, and use Do or While when you cannot be sure a function converges.
>
Recursion is the other way to repeat a function on its own result, but q limits its depth. Iterators have no such limit; see [recursive functions](work-with-functions.md#recursive-functions).

## Combine iterators: FIFO allocation

Iterators combine, and a few of them together often replace a loop that would take a dozen lines in another language. This example, from [_Q for Mortals_ §1.14](../../learn/q4m/1_Q_Shock_and_Awe.md#114-example-fifo-allocation), fills a sell order from a time-ordered list of buys, first in, first out (FIFO): take from each buy in turn until the sell is filled, then stop.
```q
q)buys:2 1 4 3 5 4
q)sell:12
```

The insight is to work with running totals rather than individual buys. [`sums`](../../ref/sum.md#sums), the Scan `+\`, gives the total available after each buy:
```q
q)sums buys
2 3 7 10 15 19
```

The amount filled can never exceed the sell, so cap the running total at the sell amount with `&`, the [lesser](../../ref/lesser.md) of the two:
```q
q)sell&sums buys
2 3 7 10 12 12
```

That is the running total of the allocation. [`deltas`](../../ref/deltas.md), the Each Prior `-':`, turns a running total back into the individual amounts, and leaves the first item unchanged:


**q**
```q
q)deltas sell&sums buys
2 1 4 3 2 0
```


**Python**
```python
>>> from itertools import accumulate, chain
>>> from functools import partial
>>> from operator import sub
>>> buys = [2, 1, 4, 3, 5, 4]
>>> sell = 12
>>> filled = list(map(partial(min, sell), accumulate(buys)))
>>> list(map(sub, filled, chain([0], filled)))
[2, 1, 4, 3, 2, 0]
```


The first four buys are used in full, 2 is taken from the fifth, and the last is untouched. There is no loop, no counter, and no test for when to stop.

### Fill orders from an order book

The same calculation fills orders against a market. A _level 2_ order book records, at each moment, the price and size available at the best few price levels on each side: bids from buyers and asks from sellers, each list ordered best price first. An order fills against the opposite side of the book, taking each level in turn until the order is filled. The levels play the part of the buys in the previous example, and the order quantity plays the part of the sell.

Here is a small book with seven snapshots for two symbols, recorded in time order as a market data feed would deliver them, and three orders. Each item of the `bidpx`, `bidsz`, `askpx`, and `asksz` columns is a list with one item per price level:
```q
book:([]
  sym:`AAPL`MSFT`AAPL`MSFT`AAPL`MSFT`AAPL;
  time:09:30:00.000 09:30:00.000 09:30:00.600 09:30:00.700 09:30:01.000 09:30:01.100 09:30:01.500;
  bidpx:(189.98 189.97 189.96; 420.05 420.00 419.95; 189.99 189.98 189.97; 420.10 420.05 420.00;
         190.00 189.99 189.98; 420.15 420.10 420.05; 190.01 190.00 189.99);
  bidsz:(300 500 200; 100 200 300; 200 300 400; 200 300 400; 100 400 300; 300 200 100; 200 300 300);
  askpx:(190.01 190.02 190.03; 420.10 420.15 420.20; 190.02 190.03 190.04; 420.15 420.20 420.25;
         190.02 190.03 190.04; 420.25 420.30 420.35; 190.03 190.04 190.05);
  asksz:(200 400 600; 300 200 100; 100 300 500; 100 200 300; 300 300 500; 200 200 400; 400 200 300))

orders:([]
  sym:`AAPL`AAPL`MSFT;
  time:09:30:00.500 09:30:01.200 09:30:00.800;
  side:`buy`sell`buy;
  qty:500 600 800)
```

First, find the book each order met. An [as-of join](../../ref/aj.md), `aj`, matches each order to the most recent snapshot of the same symbol at or before the order's time. It expects `book` to be sorted by time within each symbol, which a book recorded in time order is:
```q
q)t:aj[`sym`time;orders;book]
q)delete bidpx,askpx from t
sym  time         side qty asksz       bidsz
--------------------------------------------------
AAPL 09:30:00.500 buy  500 200 400 600 300 500 200
AAPL 09:30:01.200 sell 600 300 300 500 100 400 300
MSFT 09:30:00.800 buy  800 100 200 300 200 300 400
```

Each order picked up the latest snapshot for its symbol, not the nearest one. The AAPL buy at 09:30:00.500 matched the AAPL snapshot from 09:30:00.000, ignoring the later one at 09:30:00.600. The MSFT buy at 09:30:00.800 matched the MSFT snapshot from 09:30:00.700, and the AAPL sell at 09:30:01.200 matched the one from 09:30:01.000.

Next, pick the side of the book that each order trades against: asks for a buy, bids for a sell. The [vector conditional](../../ref/vector-conditional.md) `?` chooses, row by row, which column supplies the whole list:
```q
q)t:update px:?[side=`buy;askpx;bidpx], sz:?[side=`buy;asksz;bidsz] from t
q)select sym,time,side,qty,px,sz from t
sym  time         side qty px                   sz
-----------------------------------------------------------
AAPL 09:30:00.500 buy  500 190.01 190.02 190.03 200 400 600
AAPL 09:30:01.200 sell 600 190    189.99 189.98 100 400 300
MSFT 09:30:00.800 buy  800 420.15 420.2  420.25 100 200 300
```

Now apply the single-sell calculation, `deltas sell&sums buys`, to every row at once. Each row has its own quantity and its own list of sizes, so each step needs an iterator:

- `sums each sz` gives the running total of the sizes in each row.
- `qty&'` caps each row's running total at that row's quantity. This is Each Both: it pairs the first quantity with the first list, and so on.
- `deltas each` turns each capped running total back into the amount taken from each level.
```q
q)exec qty&'sums each sz from t
200 500 500
100 500 600
100 300 600
q)t:update fill:deltas each qty&'sums each sz from t
```

Finally, summarize the fills. `sum each` adds up the amount filled, and [`wavg`](../../ref/avg.md#wavg) with Each Both weights each row's prices by that row's fills to give the average price:
```q
q)select sym,time,side,qty,fill,filled:sum each fill,avgpx:fill wavg'px from t
sym  time         side qty fill        filled avgpx
------------------------------------------------------
AAPL 09:30:00.500 buy  500 200 300 0   500    190.016
AAPL 09:30:01.200 sell 600 100 400 100 600    189.99
MSFT 09:30:00.800 buy  800 100 200 300 600    420.2167
```

The AAPL buy is filled from the first two ask levels and leaves the third untouched. The MSFT buy wants 800, but the book shows only 600, so it fills 600 across all three levels. There is no loop over the orders and none over the price levels, so the same query works for any number of orders, symbols, and levels.

## Choose an iterator

| You want to | Use | Example |
|---|---|---|
| Apply a function to each item | `each` | `count each words` |
| Do the same in parallel | `peach` | `f peach files` |
| Pair the items of two lists | `'` | `3 2 4#'words` |
| Apply between each left item and the whole right | `\:` | `words ss\: "l"` |
| Apply between the whole left and each right item | `/:` | `prices>/:100 105` |
| Compare each item with the one before | `prior`, `':` | `deltas prices` |
| Keep a running result | `scan`, `\` | `1000+\50 -20 30` |
| Reduce a list to one result | `over`, `/` | `(inter/) lists` |
| Repeat a function `n` times | `n f\x` | `3 {x*1.05}\ 100f` |
| Repeat while a condition holds | `t f\x` | `{x<1000} {x*2}\ 1` |
| Repeat until the result settles | `(f\)x` | `(raze/) nested` |

## Next steps

- Use iterators instead of loops in [control execution](control-execution.md#prefer-an-iterator-to-a-loop), and learn when explicit control flow is still the right choice.
- Build the functions you pass to iterators with [projections](work-with-functions.md#projections-and-partial-application) and [operator projections](work-with-functions.md#operator-projections).
- Parallelize work effectively with [`peach`](../performance/code-optimization.md#peach) and [secondary threads](../performance/code-optimization.md#parallelize).
- Read the [guide to iterators](../../ref/iterators/index.md) for more examples, including iterators on nested columns.
- Look up the full syntax in the reference: [iterators](../../ref/iterators.md), [maps](../../ref/maps.md), [accumulators](../../ref/accumulators.md), and [`each`, `peach`](../../ref/each.md).
