How can I get an object by id in Julia

In Julia, let's say I have a object_id

for a variable but forgot its name, how can I get an object using the id?

those. I want the opposite some_id = object_id(some_object)

.

+3


source to share


1 answer


As @DanGetz points out in the comments, it object_id

is a hash function and cannot be reversible. @phg is also true that it is ObjectIdDict

intended exactly for this purpose (this is documented , although it is not discussed in the manual):

ObjectIdDict([itr])

ObjectIdDict()

builds a hash table where keys are (always) object identifiers. In contrast, Dict

it is not parameterized on its key and value type and hence its eltype is always Pair{Any,Any}

.

For details see Dict

.

In other words, it hashes objects ===

using it object_id

as a hash function. If you have ObjectIdDict

and use the objects you come across as keys, you can save and restore them later by pulling them out ObjectIdDict

.

However, it looks like you want to do this without explicitly ObjectIdDict

, by simply asking which object has ever been created has a given one object_id

. If so, consider this thought experiment: if every object was always retrieved from it object_id

, the system can never discard any object, since it will always be possible to query that object by ID. This way, you can never collect garbage, and each program's memory usage will expand rapidly to use up all of your RAM and disk space. This is equivalent to having a single global ObjectIdDict

that you put on every object ever created. So inverting a function object_id

this way doesn't require freeing any objects, which means you need unlimited memory.

Even if we had endless memories, there are deeper problems. What does the existence of an object mean? With an optimizing compiler, this question has no clear answer. It often happens that an object, from a programmer's point of view, is created and works, but in reality - that is, from a hardware point of view - it is never created. Consider this function, which builds a complex number and then uses it for a simple calculation:

julia> function f(y::Real)
           z = Complex(0,y)
           w = 2z*im
           return real(w)
       end
f (generic function with 1 method)

julia> foo(123)
-246

      



From a programmer's point of view, this will build a complex number z

and then build 2z

, then 2z*im

and finally build real(2z*im)

and return that value. So all of these values ​​should be inserted into the Great Object in the Sky. But are they really built? Here's the LLVM code for this feature applies to Int

:

julia> @code_llvm foo(123)

define i64 @julia_foo_60833(i64) #0 !dbg !5 {
top:
  %1 = shl i64 %0, 1
  %2 = sub i64 0, %1
  ret i64 %2
}

      

Not Complex

values ​​are plotted at all! Instead, all work is built in and out, rather than actually done. The whole calculation is reduced to simply doubling the argument (by shifting it, one bit is left) and negating it (by subtracting it from zero). This optimization can be performed primarily because the intermediate steps have no observable side effects. The compiler knows that there is no way to tell the difference between actually constructing complex values ​​and working with them, and just do several whole operations - if the end result is always the same. The implicit in the idea of ​​the "Great Iddict Object in the Sky" is the assumption that all the objects that appear to be built are actually built and inserted into a large persistent data structure, which is a massive side effect. Thus,not only are objects recovered from their identifiers, which are incompatible with garbage collection, but are also incompatible with almost any possible program optimization.

The only other way that could be understood when accessed object_id

would be to compute its pre-image on demand instead of storing objects as they are created. This will solve memory and optimization issues. Of course, this is not possible, since there are infinitely many possible objects, but only a finite number of object identifiers. You are unlikely to actually come across two objects with the same identifier in a program, but the finiteness of the identification space means that inverting the hash function is basically impossible, since the preimage of each ID value contains an infinite number of potential objects.

I have probably disproved the possibility of inverse function object_id

much more thoroughly than necessary, but it has led to some interesting thought experiments, and I hope this was helpful, or at least provocative. The practical answer is that there is no way to work around explicitly pinning every object you might want to come back to later in ObjectIdDict

.

+7


source







All Articles