2

I think I am missing a point, as in my tests it seems the behavior of "===" doesn't comply to the documentation.

The documentation states "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".

I understand from this definition is that :

  • for mutable objects, two distincts objects (ie. different memory address) should not be "==="
  • for immutable objects, when the contents are identical, they should be "==="

However :

The Sets are immutable, but two identical objects by the content are not "==="

set1 = Set(["S"])
set2 = Set(["S"])
ismutable(set1) 

Returns false

set1 === set2 

Returns false, but according to the documentation should return true, as set1 and set2 are two immutable objects with identical contents. (or ismutable(set1) should return true?)

The Strings are mutable, but two distinct objects are "==="

string1 = String("test")
string2 = String("test")
ismutable(string1) 

Returns true

string1 === string2 

Returns true, but according to the documentation should return false as string1 and string2 are two distinct mutable objects, and hence their address in memory should be different. (or ismutable(string1) should return false?)


What is the point I am missing ?

GomsqB0T
  • 95
  • 9

1 Answers1

3

These cases are tricky and I agree that not intuitive. Set is a bit easier to explain.

Set is defined as:

struct Set{T} <: AbstractSet{T}
    dict::Dict{T,Nothing}

    Set{T}() where {T} = new(Dict{T,Nothing}())
    Set{T}(s::Set{T}) where {T} = new(Dict{T,Nothing}(s.dict))
end

so you can see that although it is an immutable struct its field is a mutable object dict. So the comparison of dict field uses memory address and all is consistent.

But I agree that it is confusing that Set is immutable, but Dict is mutable; however, all is consistent here.


With String the situation is more complex. They are defined to be immutable, see here:

As in Java, strings are immutable: the value of an AbstractString object cannot be changed. To construct a different string value, you construct a new string from parts of other strings.

but they are implemented in non standard way in Julia Base for performance.

Therefore most of the functions follow the rule of respecting immutability (in particular ===). I think ismutable for string should either change its docstring or return false (my personal opinion is that it should return false).

Bogumił Kamiński
  • 66,844
  • 3
  • 80
  • 107
  • So in practice Sets are immutable but mutable, and Strings are mutable but immutable ;-) – GomsqB0T Nov 20 '20 at 13:12
  • 1
    I have never needed to use `ismutable` in my code. I think it is best to treat it as a low-level function used when working with internals to get `mutable` field of the type of the variable you have. – Bogumił Kamiński Nov 20 '20 at 13:22
  • 1
    Actually, with your answers to this question and my [other question on structs](https://stackoverflow.com/questions/64909449/does-for-struct-check-recursively-in-julia-it-seems-not), I understand now way better the `==` and `===` operators. Thanks – GomsqB0T Nov 20 '20 at 13:29