# Add \`chmax\` / \`chmin\` functions to standard library

**URL:** <https://internals.rust-lang.org/t/add-chmax-chmin-functions-to-standard-library/15085>\
**Category:** libs\
**Created:** [July 26, 2021, 3:28pm UTC](https://internals.rust-lang.org/t/add-chmax-chmin-functions-to-standard-library/15085 "2021-07-26T15:28:17Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![magurofly](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/magurofly/32/8399_2.png) [@magurofly](https://internals.rust-lang.org/u/magurofly)\
**Post date:** [July 26, 2021, 3:28pm UTC](https://internals.rust-lang.org/t/add-chmax-chmin-functions-to-standard-library/15085/1 "2021-07-26T15:28:17Z")

</div>

Hi

I suggest new methods for Ord working like below:

```rust
trait Ord {
  fn chmax(&mut self, other: Self) -> bool { ... }
  fn chmin(&mut self, other: Self) -> bool { ... }
}

```

```rust
x.chmax(y);
// x = x.max(y);

x.chmin(y);
// x = x.min(y);

```

The method `chmax` replaces `self` and returns `true` if `self < other`, else returns `false` The method `chmin` works in same way

Also I suggest adding these methods for `Option<T> where T: Ord`

```rust
impl<T> Option<T> {
  fn chmin(&mut self, other: T) where T: Ord { ... }
  fn chmin(&mut self, other: T) where T: Ord { ... }
}

```

---

<div class="post-metadata">

**Author:** ![steffahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/steffahn/32/13288_2.png) [@steffahn](https://internals.rust-lang.org/u/steffahn)\
**Post date:** [July 26, 2021, 3:58pm UTC](https://internals.rust-lang.org/t/add-chmax-chmin-functions-to-standard-library/15085/2 "2021-07-26T15:58:19Z")

</div>

What does `chmax`/`chmin` stand for?

`Option` implements `Ord`, so it seems suboptimal to add methods with the same name both as inherent and as trait methods.

* * *

It’s good to provide the default implementation with your suggestion (which also helps to demonstrate if the new method is a significant simplification). I suppose `x.chmax(y)` is something like

```rust
if *x < y { *x = y; true } else { false }

```

If you ignore the return value, it becomes

```rust
if *x < y { *x = y }

```

which isn’t particularly long. A use-case/example that _does_ use the return value would be nice to see as well.

There’s also the option of providing these kinds of methods in a third-party extension trait – the only downside is that you’ll need an extra dependency and implementations can’t override/special-case the implementation. Is there any performance benefits that a specialized implementation for any `Ord` type could have over the default implementation?

---

<div class="post-metadata">

**Author:** ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)\
**Post date:** [July 26, 2021, 6:07pm UTC](https://internals.rust-lang.org/t/add-chmax-chmin-functions-to-standard-library/15085/3 "2021-07-26T18:07:41Z")

</div>

If I'm understanding correctly, these are effectively the compound-assignment operators `max=` and `min=`?

I don't think these need to be part of Ord. For other kinds of compound assignment operators, such as `+=`, it makes sense to have a trait that allows implementing them, because sometimes `+=` can be implemented much more efficiently than `+` by consuming the destination.

For min and max, there's no need to modify-as-you-go and end up with an object that's a combination of two other objects. These operations will _always_ end up either keeping the current object or entirely replacing it with a different object. If there are ways we can optimize that operation that we're not already doing, those optimizations would apply equally well to any other kind of "replace" operation, and we shouldn't make them specific to one particular replacement operation.

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [July 26, 2021, 10:22pm UTC](https://internals.rust-lang.org/t/add-chmax-chmin-functions-to-standard-library/15085/4 "2021-07-26T22:22:25Z")

</div>

> [@magurofly](#):
>
> The method `chmax` replaces `self` and returns `true` if `self < other` , else returns `false`

Note that _just_ a bool return like that is suspicious in a language with move semantics. Since `String: Ord`, for example, one would have to make an owned string to call it, which might then get thrown away.

So consider, if this moves forward, what it could look like such that it returns the other owned value somehow -- either the passed-in one, or the one from replacing self. Or consider exploring versions that use `Borrow`&`ToOwned` to allow passing simpler things as `other`.

---

<div class="post-metadata">

**Author:** ![magurofly](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/magurofly/32/8399_2.png) [@magurofly](https://internals.rust-lang.org/u/magurofly)\
**Post date:** [July 26, 2021, 11:31pm UTC](https://internals.rust-lang.org/t/add-chmax-chmin-functions-to-standard-library/15085/5 "2021-07-26T23:31:04Z")

</div>

Here's a sample that computes shortest path by Floyd-Warshall algorithm

```rust
fn floyd_warshall(mat: &mut Vec<Vec<i64>>) {
  assert!(mat.len() == 0 || mat.len() == mat[0].len());
  for k in 0..mat.len() {
    for i in 0..mat.len() {
      for j in 0..mat.len() {
        let d = mat[i][k] + mat[k][j];
        mat[i][j].chmin(d);
      }
    }
  }
}

```

---

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [July 26, 2021, 11:39pm UTC](https://internals.rust-lang.org/t/add-chmax-chmin-functions-to-standard-library/15085/6 "2021-07-26T23:39:05Z")

</div>

You don't use the return value here; in what way is `mat[i][j].chmin(d);` notably better/clearer than just writing `mat[i][j] = min(mat[i][j], d);`? (Or is it `max`? I'm honestly not sure...)

Such a function _could_ be interestingly useful for types that aren't `Copy`, but that case might also be better served by a simple written out `if < { swap }`.

---

<div class="post-metadata">

**Author:** ![magurofly](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/magurofly/32/8399_2.png) [@magurofly](https://internals.rust-lang.org/u/magurofly)\
**Post date:** [July 27, 2021, 12:03am UTC](https://internals.rust-lang.org/t/add-chmax-chmin-functions-to-standard-library/15085/7 "2021-07-27T00:03:56Z")

</div>

OK, I'll show another sample that computes shortest path by Dijkstra algorithm

This sample uses `Option::chmin` and its return value

```rust
// graph: Adjacency List
fn dijkstra(graph: &Vec<Vec<(usize, i64)>>, start: usize) -> Vec<Option<i64>> {
  let mut dist = vec![None; graph.len()];
  dist[start] = Some(0);
  let mut heap = BinaryHeap::new();
  heap.push((Reverse(0), start));
  while let Some((Reverse(d), u)) = heap.pop() {
    if dist[u] != Some(d) {
      continue;
    }
    for &(cost, v) in &graph[u] {
      if dist[v].chmin(d + cost) {
        heap.push((Reverse(d + cost), v);
      }
    }
  }
  dist
}

```

---

<div class="post-metadata">

**Author:** ![matt1985](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matt1985/32/4772_2.png) [@matt1985](https://internals.rust-lang.org/u/matt1985)\
**Post date:** [July 27, 2021, 12:42am UTC](https://internals.rust-lang.org/t/add-chmax-chmin-functions-to-standard-library/15085/8 "2021-07-27T00:42:24Z")

</div>

Not a fan of non-`is_*` methods (other querying methods like `contains` are fine too) that return a `bool`, I always have to look up what the `bool` is supposed to indicate is `true` or `false`

---

<div class="post-metadata">

**Author:** ![magurofly](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/magurofly/32/8399_2.png) [@magurofly](https://internals.rust-lang.org/u/magurofly)\
**Post date:** [July 27, 2021, 6:10am UTC](https://internals.rust-lang.org/t/add-chmax-chmin-functions-to-standard-library/15085/9 "2021-07-27T06:10:51Z")

</div>

Thank you

That seems not bad

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [October 25, 2021, 6:11am UTC](https://internals.rust-lang.org/t/add-chmax-chmin-functions-to-standard-library/15085/10 "2021-10-25T06:11:49Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
