Xo is experimental. The source is now public on GitHub, or try Xo in your browser.
Menu · XO0907

Docs

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

note · reported by the vet --cost

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

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

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.