Skip to content

Commit 86b031b

Browse files
committed
docs: Correct terminology in std::cmp
Some clarifications regarding used (mathematical) terminology: * Avoid using the terms "total equality" and "partial equality" in favor of "equivalence relation" and "partial equivalence relation", which are well-defined and unambiguous. * Clarify that `Ordering` is an ordering between two values (and not an order in the mathematical sense). * Avoid saying that `PartialEq` and `Eq` are "equality comparisons" because the terminology "equality comparison" could be misleading: it's possible to implement `PartialEq` and `Eq` for other (partial) equivalence relations, in particular for relations where `a == b` for some `a` and `b` even when `a` and `b` are not the same value. * Added a section "Strict and non-strict partial orders" to document that the `<=` and `>=` operators do not correspond to non-strict partial orders. * Corrected section "Corollaries" in documenation of Ord in regard to `<` only describing a strict total order in cases where `==` conforms to mathematical equality. Made documentation easier to understand: * Explicitly state at the beginning of `PartialEq`'s documentation comment that implementing the trait will provide the `==` and `!=` operators. * Added an easier to understand rule when to implement `Eq` in addition to `PartialEq`: "if it’s guaranteed that `PartialEq::eq(a, a)` always returns `true`." * Explicitly mention in documentation of `Eq` that the properties "symmetric" and "transitive" are already required by `PartialEq`.
1 parent eea2614 commit 86b031b

File tree

1 file changed

+50
-17
lines changed

1 file changed

+50
-17
lines changed

library/core/src/cmp.rs

+50-17
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,17 @@
33
//! This module contains various tools for comparing and ordering values. In
44
//! summary:
55
//!
6-
//! * [`Eq`] and [`PartialEq`] are traits that allow you to define total and
7-
//! partial equality between values, respectively. Implementing them overloads
8-
//! the `==` and `!=` operators.
6+
//! * [`PartialEq<Rhs>`] overloads the `==` and `!=` operators. In cases where
7+
//! `Rhs` (the right hand side's type) is `Self`, this trait corresponds to a
8+
//! partial equivalence relation.
9+
//! * [`Eq`] indicates that the overloaded `==` operator corresponds to an
10+
//! equivalence relation.
911
//! * [`Ord`] and [`PartialOrd`] are traits that allow you to define total and
1012
//! partial orderings between values, respectively. Implementing them overloads
1113
//! the `<`, `<=`, `>`, and `>=` operators.
1214
//! * [`Ordering`] is an enum returned by the main functions of [`Ord`] and
13-
//! [`PartialOrd`], and describes an ordering.
15+
//! [`PartialOrd`], and describes an ordering of two values (less, equal, or
16+
//! greater).
1417
//! * [`Reverse`] is a struct that allows you to easily reverse an ordering.
1518
//! * [`max`] and [`min`] are functions that build off of [`Ord`] and allow you
1619
//! to find the maximum or minimum of two values.
@@ -27,16 +30,21 @@ pub(crate) use bytewise::BytewiseEq;
2730

2831
use self::Ordering::*;
2932

30-
/// Trait for equality comparisons.
33+
/// Trait for comparisons using the equality operator.
34+
///
35+
/// Implementing this trait for types provides the `==` and `!=` operators for
36+
/// those types.
3137
///
3238
/// `x.eq(y)` can also be written `x == y`, and `x.ne(y)` can be written `x != y`.
3339
/// We use the easier-to-read infix notation in the remainder of this documentation.
3440
///
35-
/// This trait allows for partial equality, for types that do not have a full
36-
/// equivalence relation. For example, in floating point numbers `NaN != NaN`,
37-
/// so floating point types implement `PartialEq` but not [`trait@Eq`].
38-
/// Formally speaking, when `Rhs == Self`, this trait corresponds to a [partial equivalence
39-
/// relation](https://en.wikipedia.org/wiki/Partial_equivalence_relation).
41+
/// This trait allows for comparisons using the equality operator, for types
42+
/// that do not have a full equivalence relation. For example, in floating point
43+
/// numbers `NaN != NaN`, so floating point types implement `PartialEq` but not
44+
/// [`trait@Eq`]. Formally speaking, when `Rhs == Self`, this trait corresponds
45+
/// to a [partial equivalence relation].
46+
///
47+
/// [partial equivalence relation]: https://en.wikipedia.org/wiki/Partial_equivalence_relation
4048
///
4149
/// Implementations must ensure that `eq` and `ne` are consistent with each other:
4250
///
@@ -242,15 +250,15 @@ pub macro PartialEq($item:item) {
242250
/* compiler built-in */
243251
}
244252

245-
/// Trait for equality comparisons which are [equivalence relations](
253+
/// Trait for comparisons corresponding to [equivalence relations](
246254
/// https://en.wikipedia.org/wiki/Equivalence_relation).
247255
///
248-
/// This means, that in addition to `a == b` and `a != b` being strict inverses, the equality must
249-
/// be (for all `a`, `b` and `c`):
256+
/// This means, that in addition to `a == b` and `a != b` being strict inverses,
257+
/// the relation must be (for all `a`, `b` and `c`):
250258
///
251259
/// - reflexive: `a == a`;
252-
/// - symmetric: `a == b` implies `b == a`; and
253-
/// - transitive: `a == b` and `b == c` implies `a == c`.
260+
/// - symmetric: `a == b` implies `b == a` (required by `PartialEq` as well); and
261+
/// - transitive: `a == b` and `b == c` implies `a == c` (required by `PartialEq` as well).
254262
///
255263
/// This property cannot be checked by the compiler, and therefore `Eq` implies
256264
/// [`PartialEq`], and has no extra methods.
@@ -260,6 +268,10 @@ pub macro PartialEq($item:item) {
260268
/// undefined behavior. This means that `unsafe` code **must not** rely on the correctness of these
261269
/// methods.
262270
///
271+
/// Implement `Eq` in addition to `PartialEq` if it's guaranteed that
272+
/// `PartialEq::eq(a, a)` always returns `true` (reflexivity), in addition to
273+
/// the symmetric and transitive properties already required by `PartialEq`.
274+
///
263275
/// ## Derivable
264276
///
265277
/// This trait can be used with `#[derive]`. When `derive`d, because `Eq` has
@@ -676,12 +688,19 @@ impl<T: Clone> Clone for Reverse<T> {
676688
///
677689
/// ## Corollaries
678690
///
679-
/// From the above and the requirements of `PartialOrd`, it follows that `<` defines a strict total order.
680-
/// This means that for all `a`, `b` and `c`:
691+
/// From the above and the requirements of `PartialOrd`, it follows that for
692+
/// all `a`, `b` and `c`:
681693
///
682694
/// - exactly one of `a < b`, `a == b` or `a > b` is true; and
683695
/// - `<` is transitive: `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
684696
///
697+
/// Mathematically speaking, the `<` operator defines a strict [weak order]. In
698+
/// cases where `==` conforms to mathematical equality, it also defines a
699+
/// strict [total order].
700+
///
701+
/// [weak order]: https://en.wikipedia.org/wiki/Weak_ordering
702+
/// [total order]: https://en.wikipedia.org/wiki/Total_order
703+
///
685704
/// ## Derivable
686705
///
687706
/// This trait can be used with `#[derive]`.
@@ -920,6 +939,20 @@ pub macro Ord($item:item) {
920939
/// - transitivity of `>`: if `a > b` and `b > c` then `a > c`
921940
/// - duality of `partial_cmp`: `partial_cmp(a, b) == partial_cmp(b, a).map(Ordering::reverse)`
922941
///
942+
/// ## Strict and non-strict partial orders
943+
///
944+
/// The `<` and `>` operators behave according to a *strict* partial order.
945+
/// However, `<=` and `>=` do **not** behave according to a *non-strict*
946+
/// partial order.
947+
/// That is because mathematically, a non-strict partial order would require
948+
/// reflexivity, i.e. `a <= a` would need to be true for every `a`. This isn't
949+
/// always the case for types that implement `PartialOrd`, for example:
950+
///
951+
/// ```
952+
/// let a = f64::sqrt(-1.0);
953+
/// assert_eq!(a <= a, false);
954+
/// ```
955+
///
923956
/// ## Derivable
924957
///
925958
/// This trait can be used with `#[derive]`.

0 commit comments

Comments
 (0)