///|
fn Vm::extreme_value(
  self : Vm,
  input : Value,
  key : Value?,
  on_empty : Value?,
  maximum : Bool,
  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",
    )
  }
  if items.is_empty() {
    return match on_empty {
      Some(v) => v
      None =>
        raise problem(
          Runtime,
          loc,
          "Expected at least one element in array. Got none",
        )
    }
  }
  // Go forces each element and computes its key once, even when keyF ignores it.
  let mut selected = self.force(items[0], loc)
  let mut selected_key = match key {
    None => selected
    Some(f) => self.call(f, [(None, items[0])], loc)
  }
  for i in 1.. current
      Some(f) => self.call(f, [(None, items[i])], loc)
    }
    if boolean(
        self.binary(
          if maximum {
            "<"
          } else {
            ">"
          },
          selected_key,
          current_key,
          loc,
        ),
        loc,
      ) {
      selected = current
      selected_key = current_key
    }
  }
  selected
}