# XO0907: a loop that copies a map's entries first

Reported by `xo vet --cost`, which builds the program and reads what the compiler did. A Map written while other values hold it (a store under a Mutex) is in log mode (decision 0291); a `for` over it walks its table in place when the table has no parent views and the body is small (at most 64 nodes) with no closure or defer. Otherwise the loop first copies every entry into fresh lists, counting each key and value up and down once per loop, atomically when the map is shared across threads. Keep the body small (call a function for the work), or read the entries once outside an outer loop.

## Example

```xo
fn names(m: Mutex[Map[Int, Str]]) -> List[Str] {
  m.with_read(fn(st) {
    var out: List[Str] = []
    for (_, n) in st {
      out.push(n)
      let f = fn() { n }
      out.push(f())
    }
    out
  })
}
```

## Fix

```xo
fn names(m: Mutex[Map[Int, Str]]) -> List[Str] {
  m.with_read(fn(st) {
    var out: List[Str] = []
    for (_, n) in st {
      out.push(n)
      out.push(n)
    }
    out
  })
}
```

Run `xo explain XO0907` for this text in a terminal, or see
[section 10.6 of the specification](../../spec/core/#106-diagnostic-codes).

