# XO0909: a list update that copies the whole list every iteration

Reported by `xo vet --cost`, which builds the program and reads what the compiler did. A list update (`push`, `set`, `pop`, `take`) copies the list unless its count is 1. When the loop keeps the list as well as updating it (`snaps.push(xs)`, or a name bound to it and used after the update), the count is 2 at every update, so each iteration copies the whole list: O(n squared). A holder made before the loop costs one copy, after which the loop's list is its own again; a loop that updates the list on every iteration has that one copy moved to its entry. Update a copy you own, or keep the other holder out of the loop.

## Example

```xo
fn history(n: Int) -> Int {
  var xs: List[Int] = []
  var snaps: List[List[Int]] = []
  for i in 0..n {
    snaps.push(xs)
    xs.push(i)
  }
  snaps.len() + xs.len()
}
```

## Fix

```xo
fn history(n: Int) -> Int {
  var xs: List[Int] = []
  var lens: List[Int] = []
  for i in 0..n {
    lens.push(xs.len())
    xs.push(i)
  }
  lens.len() + xs.len()
}
```

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

