# Loops

`for item in items` goes through a list, and the loop variable takes its
type from the list.

```jadpo
function stock_total(lines: List<OrderLine>) -> Stock {
    var mut total: Stock = 0
    for line in lines {
        total = Stock(total + line.needed)
    }
    return total
}
```

`for` is the only loop. There is no `while`, `break` or `continue`, and
`return` is allowed inside the body.

`for` also goes through a set, in its canonical order, one fixed order that is
the same on every target ([Collections](collections.md)). It
goes through a map's keys with `for loaf in map.keys(stock)`
([Maps](maps.md)). A map itself can't be looped over,
since each step would need a key and a value together. The error's edit
writes `map.keys`:

```jadpo
type Loaf = Text {
    min_length: 1
}

type Stock = Int {
    min: 0
}

function loaves(stock: Map<Loaf, Stock>) -> List<Loaf> {
    var mut out: List<Loaf> = []
    for loaf in stock {
        out = list.append(out, loaf)
    }
    return out
}
```

```text
error: `Map<Loaf, Stock>` can't be looped over
 --> main.jadpo:11:17
   |
11 |     for loaf in stock {
   |                 ^^^^^ this is `Map<Loaf, Stock>`
  reason: `for` loops over a `List` or a `Set`; a map is walked through its keys, a `Set<Loaf>`, and each key's value read with `map.get`.
  next: Loop over `map.keys(stock)` (agent)
  rule: type.mismatch
  help: https://jadpo.dev/docs/errors/type.mismatch

check failed: 1 error, 1 file
```

## No outside calls inside a loop

An outside call is one that leaves your app: a provider operation (an
outside service, reached through its package;
[Integrations](external-services.md)), a package action, a file store's
`put` or `read`, or a `documents` render. Inside a loop's body, any of
these is a compile error, in any action. A query inside a loop already is
([Reading in a loop](reading-in-a-loop.md)).

To make a call for each item, use `batches.each`, the one way
([Batches: work over many items](batches-work-over-many-items.md)).
A provider that takes a list is called once, with the list.

Keeping calls out of loops means the steps of an action that makes several
changing calls lie along a path whose length the compiler knows
([Several changing calls in one action](several-changing-calls-in-one-action.md)).

The error is [`effect.call_in_loop`](../errors/effect.call_in_loop.md), at
the call. It covers any outside call, one that only reads included, made
in a loop's body or by an action called there, in an action or a fixture.
