Julia Language Using ==, ===, and isequal


Example

There are three equality operators: ==, ===, and isequal. (The last is not really an operator, but it is a function and all operators are functions.)

When to use ==

== is value equality. It returns true when two objects represent, in their present state, the same value.

For instance, it is obvious that

julia> 1 == 1
true

but furthermore

julia> 1 == 1.0
true

julia> 1 == 1.0 + 0.0im
true

julia> 1 == 1//1
true

The right hand sides of each equality above are of a different type, but they still represent the same value.

For mutable objects, like arrays, == compares their present value.

julia> A = [1, 2, 3]
3-element Array{Int64,1}:
 1
 2
 3

julia> B = [1, 2, 3]
3-element Array{Int64,1}:
 1
 2
 3

julia> C = [1, 3, 2]
3-element Array{Int64,1}:
 1
 3
 2

julia> A == B
true

julia> A == C
false

julia> A[2], A[3] = A[3], A[2]  # swap 2nd and 3rd elements of A
(3,2)

julia> A
3-element Array{Int64,1}:
 1
 3
 2

julia> A == B
false

julia> A == C
true

Most of the time, == is the right choice.

When to use ===

=== is a far stricter operation than ==. Instead of value equality, it measures egality. Two objects are egal if they cannot be distinguished from each other by the program itself. Thus we have

julia> 1 === 1
true

as there is no way to tell a 1 apart from another 1. But

julia> 1 === 1.0
false

because although 1 and 1.0 are the same value, they are of different types, and so the program can tell them apart.

Furthermore,

julia> A = [1, 2, 3]
3-element Array{Int64,1}:
 1
 2
 3

julia> B = [1, 2, 3]
3-element Array{Int64,1}:
 1
 2
 3

julia> A === B
false

julia> A === A
true

which may at first seem surprising! How could the program distinguish between the two vectors A and B? Because vectors are mutable, it could modify A, and then it would behave differently from B. But no matter how it modifies A, A will always behave the same as A itself. So A is egal to A, but not egal to B.

Continuing along this vein, observe

julia> C = A
3-element Array{Int64,1}:
 1
 2
 3

julia> A === C
true

By assigning A to C, we say that C has aliased A. That is, it has become just another name for A. Any modifications done to A will be observed by C also. Therefore, there is no way to tell the difference between A and C, so they are egal.

When to use isequal

The difference between == and isequal is very subtle. The biggest difference is in how floating point numbers are handled:

julia> NaN == NaN
false

This possibly surprising result is defined by the IEEE standard for floating point types (IEEE-754). But this is not useful in some cases, such as sorting. isequal is provided for those cases:

julia> isequal(NaN, NaN)
true

On the flip side of the spectrum, == treats IEEE negative zero and positive zero as the same value (also as specified by IEEE-754). These values have distinct representations in memory, however.

julia> 0.0
0.0

julia> -0.0
-0.0

julia> 0.0 == -0.0
true

Again for sorting purposes, isequal distinguishes between them.

julia> isequal(0.0, -0.0)
false