///|
fn Vm::sort_values(
  self : Vm,
  input : Value,
  key : Value?,
  loc : Location,
) -> Value raise {
  let items = array_value(input, loc)
  if key is Some(f) && value_type(f) != "function" {
    raise problem(
      Type,
      loc,
      "Unexpected type " + value_type(f) + ", expected function",
    )
  }
  // Cache keys once; retain original thunks so unused payloads remain lazy.
  let mut source = items.map(t => {
    self.tick(loc)
    let value = match key {
      None => self.force(t, loc)
      Some(f) => self.call(f, [(None, t)], loc)
    }
    (t, value)
  })
  let n = source.length()
  let mut target = source.copy()
  let mut width = 1
  while width < n {
    let mut start = 0
    while start < n {
      let middle = start + Int::min(width, n - start)
      let end = middle + Int::min(width, n - middle)
      let mut left = start
      let mut right = middle
      for out in start..= n - width {
      break
    }
    width *= 2
  }
  ArrayValue(source.map(item => item.0))
}