Skip to content

Commit e5186ad

Browse files
committed
Document the guarantees that should be provided by isequal
1 parent b0d1c1a commit e5186ad

File tree

1 file changed

+18
-5
lines changed

1 file changed

+18
-5
lines changed

base/operators.jl

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,10 @@ should therefore also implement [`hash`](@ref).
8888
Similar to [`==`](@ref), except for the treatment of floating point numbers
8989
and of missing values. `isequal` treats all floating-point `NaN` values as equal
9090
to each other, treats `-0.0` as unequal to `0.0`, and [`missing`](@ref) as equal
91-
to `missing`. Always returns a `Bool` value.
91+
to `missing`. Always returns a `Bool` value. It can be assumed that two values which
92+
are `===` are also `isequal`. `isequal` is an equivalance relation - it is reflexive
93+
(`isequal(a, b)` implies `isequal(a, b)`) and transitive (`isequal(a, b)` and
94+
`isequal(b, c)` implies `isequal(a, c)`).
9295
9396
# Implementation
9497
The default implementation of `isequal` calls `==`, so a type that does not involve
@@ -98,8 +101,12 @@ floating-point values generally only needs to define `==`.
98101
that `hash(x) == hash(y)`.
99102
100103
This typically means that types for which a custom `==` or `isequal` method exists must
101-
implement a corresponding `hash` method (and vice versa). Collections typically implement
102-
`isequal` by calling `isequal` recursively on all contents.
104+
implement a corresponding [`hash`](@ref) method (and vice versa). Collections typically
105+
implement `isequal` by calling `isequal` recursively on all contents.
106+
107+
Furthermore, `isequal` is linked with [`isless`](@ref), and they work together to
108+
define a fixed total ordering, where exactly one of `isequal(x, y)`, `isless(x, y)`, or
109+
`isless(y, x)` must be `true` (and the other two `false`).
103110
104111
Scalar types generally do not need to implement `isequal` separate from `==`, unless they
105112
represent floating-point numbers amenable to a more efficient implementation than that
@@ -118,6 +125,12 @@ true
118125
119126
julia> isequal(0.0, -0.0)
120127
false
128+
129+
julia> missing == missing
130+
missing
131+
132+
julia> isequal(missing, missing)
133+
true
121134
```
122135
"""
123136
isequal(x, y) = x == y
@@ -132,8 +145,8 @@ isequal(x::AbstractFloat, y::Real ) = (isnan(x) & isnan(y)) | signequal(
132145
"""
133146
isless(x, y)
134147
135-
Test whether `x` is less than `y`, according to a fixed total order.
136-
`isless` is not defined on all pairs of values `(x, y)`. However, if it
148+
Test whether `x` is less than `y`, according to a fixed total order (defined together with
149+
[`isequal`](@ref)). `isless` is not defined on all pairs of values `(x, y)`. However, if it
137150
is defined, it is expected to satisfy the following:
138151
- If `isless(x, y)` is defined, then so is `isless(y, x)` and `isequal(x, y)`,
139152
and exactly one of those three yields `true`.

0 commit comments

Comments
 (0)