Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add min and max methods to Ord and PartialOrd #16067

Closed
wants to merge 1 commit into from
Closed

Add min and max methods to Ord and PartialOrd #16067

wants to merge 1 commit into from

Conversation

HeroesGrave
Copy link
Contributor

I would've also changed the min and max functions in core::cmp, but they were marked as stable and operated by-value rather than by-reference, so I want to check if it was okay.

The new methods return the greater/lesser of two values, and if an ordering cannot be found or the two values are equal, return the value that the method was called on (self).

As for the min/max functions, would it be a good idea to a) change them to use the min/max methods provided from PartialOrd, and b) only require PartialOrd rather than Ord. Or should they just be left alone as they are "stable".

@huonw
Copy link
Member

huonw commented Jul 29, 2014

The nature of PartialOrd means it is possible for a.max(&b) to be different to b.max(&a) (e.g. a = std::f64::NAN, b = 0.0); this applies to the freestanding functions.

This seems like a strong negative.

@HeroesGrave
Copy link
Contributor Author

I was aware of that issue, which is why I added the doc comments, but perhaps it should return an Option<&Self> instead?

My reasoning was that when you compare identical numbers of some kind, you still want a return value, and returning the first value (self) seemed like a sane default.

If it was to return an option instead, what would be the desired behaviour when the values are equal?


/// This method returns the greater of two values.
/// If the values are equal or cannot be compared, the value which this
/// method was called on (self) is returned.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docstring formatting is wrong.

/// Returns the greater of two values.
///
/// If the values are equal or cannot be compared, the receiver is returned.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is, rustdoc parses the first paragraph of the doc string as the main functionality-summary, so the extra info should be it's own paragraph.

@lilyball
Copy link
Contributor

I'm with @huonw, partial ordering seems like a reason not to have this.

If we did have this, I think it would have to return Option<T>. But that's not really appropriate for a method named max().

Perhaps the right approach is to add functions partial_max() and partial_min() to std::cmp that operate on PartialOrd values and return Option<T>. Make it behave the same way as max()/min() (in that the second value is returned if they're equal).

#[inline]
pub fn partial_min<T: PartialOrd>(v1: T, v2: T) -> Option<T> {
    match v1.partial_cmp(&v2) {
        None => None,
        Some(Less) => Some(v1),
        _ => Some(v2),
    }
}

#[inline]
pub fn partial_max<T: PartialOrd>(v1: T, v2: T) -> Option<T> {
    match v1.partial_cmp(&v2) {
        None => None,
        Some(Greater) => Some(v1),
        _ => Some(v2)
    }
}

@HeroesGrave HeroesGrave changed the title Add min and max methods to PartialOrd Add min and max methods to Ord PartialOrd Jul 30, 2014
@HeroesGrave HeroesGrave changed the title Add min and max methods to Ord PartialOrd Add min and max methods to Ord and PartialOrd Jul 30, 2014
@HeroesGrave
Copy link
Contributor Author

Okay, I added the methods to Ord instead, and added partial methods which return an option to PartialOrd.

One thing I'm not sure about is the following:

(in that the second value is returned if they're equal).

If I called a.max(&b) and they were equal, it would make more sense to return the self object as that is what the method was called on in the first place, and so would appear to be more important.

@lilyball
Copy link
Contributor

If I called a.max(&b) and they were equal, it would make more sense to return the self object as that is what the method was called on in the first place, and so would appear to be more important.

But that's not how the already-marked-#[stable] existing min()/max() work.

Also, I am not convinced it's appropriate to be adding min()/max() methods to every single orderable type. That's very frequently not correct. For example, I would expect min() on e.g.TreeSet to return the minimum contained element.

@Gankra
Copy link
Contributor

Gankra commented Jul 30, 2014

+1 to what @kballard said. min/max should be free standing functions, not methods. That way they can be pulled in unambiguously when desired. Losing clean chaining is minor in comparison, imo.

@HeroesGrave
Copy link
Contributor Author

Hmm. My original idea for this was because integer types were lacking min/max methods (whereas floats do), but then I thought that there would probably be a use case for most other Ord/PartialOrd types.

Would it be worth having min/max methods for just integers instead?

(Edit: It appears some trailing whitespace slipped in at the last minute.)

lnicola pushed a commit to lnicola/rust that referenced this pull request Jan 3, 2024
…l-inside-types, r=Veykril

fix: no code action 'introduce_named_generic' for impl inside types

Fix rust-lang#15734.

### Changes Made
- Find params in `ancestors` instead of just `parent`
- Added tests (`replace_impl_with_mut` and `replace_impl_inside`)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants