Why is collect(1:3) === [1, 2, 3] false?

Both sides of the comparison have the same values and the same type. I must not understand === correctly.

=== compares object identity, while == compares object equality. The former checks whether two objects are the exact same object (more formally, whether they are indistinguishable by any computer program representable in julia), whereas the latter “only” checks whether they reasonably behave the same (but are still distinguishable).

In this case, the two arrays have the same contents, but are two distinct objects.

5 Likes

I’m thinking the reason they are separate objects is because they are mutable; is that right? If I assign the left- and right-hand-sides to different variables, I can mutate them separately.

[1,2,3] === [1,2,3]
false  # ???

More or less, yes.

These again construct two distinct objects that happen to contain the same elements.

4 Likes

I understand. The two things have different memory locations, so you could write a program to distinguish them. Whereas with simple values, like a = 1.0 and b = 1.0, a and b are identical; they are immutable and have no fixed address.

1 Like

Precisely - this also extends to immutable custom structs:

julia> struct ImmutableExample                    
           a::Int                                 
       end                                        
                                                  
julia> ImmutableExample(4) === ImmutableExample(4)
true                                              
                                                  
julia> mutable struct MutableExample              
           a::Int                                 
       end                                        
                                                  
julia> MutableExample(4) === MutableExample(4)    
false                                             
3 Likes

just to demonstrate what you said with a related example, one way to think about === is to think about:

julia> a = [1,2,3]; a2 = a; b = [1,2,3];

julia> a===a2
true

julia> a == a2 == b
true

julia> push!(a2, 0);

julia> a === a2, a2==b
(true, false)

Let’s consider an array as a wallet. :stuck_out_tongue_closed_eyes:

Executing [1, 5, 10] will create a wallet with $1, $5, and $10 bills inside. :money_mouth_face:

Executing [1, 5, 10] again will create another wallet of the same type with the same contents. :money_mouth_face:

Comparing them with == will compare if the contents are equal and the result will be true. :dollar:

If they are compared with ===, they are wallets of the same type with same contents but different, so the result will be false. :partying_face:

7 Likes

Tuples are different kind of wallets:

(1,2,3) === (1,2,3)  # true

NB: less money is printed with them :dollar:

1 Like

playing along: are they wallets if you can’t add or take money out of them?

2 Likes
?===

gives

help?> ===
search: === == !==

  ===(x,y) -> Bool
  ≡(x,y) -> Bool

  Determine whether x and y are identical, in the sense that no program could distinguish them. First the types of x and y are
  compared. If those are identical, mutable objects are compared by address in memory and immutable objects (such as numbers) are
  compared by contents at the bit level. 

So, given that the comparison is of two vectors, which are mutable, the comparison involves checking the address in memory, which will be different.

1 Like