Memory address of a set, array, string,

I run the following and get error

pointer_from_objref(Set([1,2,3])) 
#error  pointer_from_objref cannot be used on immutable objects

however as I understand, Sets are mutable.
About the strings and arrays, pointer() actually works. But what is objectid() then which works for anything? Is it the memory address?
I searched but failed to get a coherent picture of what pointer_from_objref, pointer, objectid, hash … are doing.
Appreciate your answers.

These functions are typically only used when calling foreign functions, e.g. C, Fortran, etc. Technically a julia Set{Int} is an immutable struct containing a Dict{Int, Nothing}, and immutable structs don’t have a memory address. They can live on the stack, in registers or in memory, as the compiler sees fit. You should use Ref(...) to obtain a reference to a julia object.

julia> s = Set([1,2,3])
Set{Int64} with 3 elements:
  2
  3
  1

julia> s.dict
Dict{Int64, Nothing} with 3 entries:
  2 => nothing
  3 => nothing
  1 => nothing

julia> s.dict = Dict([2=>nothing])
ERROR: setfield!: immutable struct of type Set cannot be changed
Stacktrace:
...

julia> s.dict[4] = nothing
julia> s
Set{Int64} with 4 elements:
  4
  2
  3
  1

3 Likes

Thank you for the answer. Now I understand the situation about sets.

There will surelly be good practical reasons for it… but it remains it is a very odd implementation of a set…

1 Like

This is also how sets are implemented in Java, and I think a bunch of other languages.
You need almost all the same code for a HashSet as you do for a HashMap (a dictionary).
So once you have implemented the dictionary you can just reuse it.

Cool thing about Julia in this case, is julia doesn’t actually store Singltons like nothing, so there is basically no scaling memory overhead for doing this.

julia> Base.summarysize([nothing, nothing, nothing])
40

julia> Base.summarysize([nothing, nothing, nothing, nothing])
40

julia> Base.summarysize([nothing, nothing, nothing, nothing, nothing])
40
3 Likes