diff --git a/base/operators.jl b/base/operators.jl index 7269a15718a58..bf4a8a98bddf6 100644 --- a/base/operators.jl +++ b/base/operators.jl @@ -93,6 +93,10 @@ and of missing values. `isequal` treats all floating-point `NaN` values as equal to each other, treats `-0.0` as unequal to `0.0`, and [`missing`](@ref) as equal to `missing`. Always returns a `Bool` value. +`isequal` is an equivalence relation - it is reflexive (`===` implies `isequal`), symmetric +(`isequal(a, b)` implies `isequal(b, a)`) and transitive (`isequal(a, b)` and +`isequal(b, c)` implies `isequal(a, c)`). + # Implementation The default implementation of `isequal` calls `==`, so a type that does not involve floating-point values generally only needs to define `==`. @@ -101,8 +105,12 @@ floating-point values generally only needs to define `==`. that `hash(x) == hash(y)`. This typically means that types for which a custom `==` or `isequal` method exists must -implement a corresponding `hash` method (and vice versa). Collections typically implement -`isequal` by calling `isequal` recursively on all contents. +implement a corresponding [`hash`](@ref) method (and vice versa). Collections typically +implement `isequal` by calling `isequal` recursively on all contents. + +Furthermore, `isequal` is linked with [`isless`](@ref), and they work together to +define a fixed total ordering, where exactly one of `isequal(x, y)`, `isless(x, y)`, or +`isless(y, x)` must be `true` (and the other two `false`). Scalar types generally do not need to implement `isequal` separate from `==`, unless they represent floating-point numbers amenable to a more efficient implementation than that @@ -121,6 +129,12 @@ true julia> isequal(0.0, -0.0) false + +julia> missing == missing +missing + +julia> isequal(missing, missing) +true ``` """ isequal(x, y) = x == y @@ -135,8 +149,8 @@ isequal(x::AbstractFloat, y::Real ) = (isnan(x) & isnan(y)) | signequal( """ isless(x, y) -Test whether `x` is less than `y`, according to a fixed total order. -`isless` is not defined on all pairs of values `(x, y)`. However, if it +Test whether `x` is less than `y`, according to a fixed total order (defined together with +[`isequal`](@ref)). `isless` is not defined on all pairs of values `(x, y)`. However, if it is defined, it is expected to satisfy the following: - If `isless(x, y)` is defined, then so is `isless(y, x)` and `isequal(x, y)`, and exactly one of those three yields `true`.