Skip to content

Commit 1131876

Browse files
authored
Document the guarantees that should be provided by isequal (#34798)
1 parent 592db58 commit 1131876

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

base/operators.jl

+18-4
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ and of missing values. `isequal` treats all floating-point `NaN` values as equal
9393
to each other, treats `-0.0` as unequal to `0.0`, and [`missing`](@ref) as equal
9494
to `missing`. Always returns a `Bool` value.
9595
96+
`isequal` is an equivalence relation - it is reflexive (`===` implies `isequal`), symmetric
97+
(`isequal(a, b)` implies `isequal(b, a)`) and transitive (`isequal(a, b)` and
98+
`isequal(b, c)` implies `isequal(a, c)`).
99+
96100
# Implementation
97101
The default implementation of `isequal` calls `==`, so a type that does not involve
98102
floating-point values generally only needs to define `==`.
@@ -101,8 +105,12 @@ floating-point values generally only needs to define `==`.
101105
that `hash(x) == hash(y)`.
102106
103107
This typically means that types for which a custom `==` or `isequal` method exists must
104-
implement a corresponding `hash` method (and vice versa). Collections typically implement
105-
`isequal` by calling `isequal` recursively on all contents.
108+
implement a corresponding [`hash`](@ref) method (and vice versa). Collections typically
109+
implement `isequal` by calling `isequal` recursively on all contents.
110+
111+
Furthermore, `isequal` is linked with [`isless`](@ref), and they work together to
112+
define a fixed total ordering, where exactly one of `isequal(x, y)`, `isless(x, y)`, or
113+
`isless(y, x)` must be `true` (and the other two `false`).
106114
107115
Scalar types generally do not need to implement `isequal` separate from `==`, unless they
108116
represent floating-point numbers amenable to a more efficient implementation than that
@@ -121,6 +129,12 @@ true
121129
122130
julia> isequal(0.0, -0.0)
123131
false
132+
133+
julia> missing == missing
134+
missing
135+
136+
julia> isequal(missing, missing)
137+
true
124138
```
125139
"""
126140
isequal(x, y) = x == y
@@ -135,8 +149,8 @@ isequal(x::AbstractFloat, y::Real ) = (isnan(x) & isnan(y)) | signequal(
135149
"""
136150
isless(x, y)
137151
138-
Test whether `x` is less than `y`, according to a fixed total order.
139-
`isless` is not defined on all pairs of values `(x, y)`. However, if it
152+
Test whether `x` is less than `y`, according to a fixed total order (defined together with
153+
[`isequal`](@ref)). `isless` is not defined on all pairs of values `(x, y)`. However, if it
140154
is defined, it is expected to satisfy the following:
141155
- If `isless(x, y)` is defined, then so is `isless(y, x)` and `isequal(x, y)`,
142156
and exactly one of those three yields `true`.

0 commit comments

Comments
 (0)