18
$\begingroup$

How can I determine if two mutable data structures (DataStructure) are truly the same? I do not mean checking if they have the same value. I mean checking if they are the same data structure, i.e. whether they both respond to mutation.

Example:

a = CreateDataStructure["Value", 1];

b = a["Copy"];

c = b;

Now b and c are the same, but a and b are different. They merely hold the same value. a === b tests if the value if the same, and therefore returns True.

But mutating a does not mutate b. The variables a and b do not point to the same data structure.

a["Set", 2]
(* 2 *)

{a["Get"], b["Get"]}
(* {2, 1} *)

b and c do point to the same data structure:

b["Set", 5]
(* 5 *)

{b["Get"], c["Get"]}
(* {5, 5} *)
$\endgroup$
2
  • 2
    $\begingroup$ Maybe try something like GroupBy[{a, b, c}, Hash] $\endgroup$
    – ilian
    Apr 1, 2020 at 13:58
  • $\begingroup$ If you're in a <12.1 environment you can use any internal function that knows about this distinction, e.g. make a Language`ExpressionStore (the memory will clean itself up automatically if you do) and then attach a UUID to each Expr that you can check against. $\endgroup$
    – b3m2a1
    Apr 1, 2020 at 21:53

2 Answers 2

18
$\begingroup$

This way of comparison is not directly exposed in top-level at the moment.

However, it could be done through the compiler, for example

sameInstanceQ = 
  FunctionCompile[Function[{Typed[e1, "Expression"], Typed[e2, "Expression"]}, 
    Native`SameInstanceQ[e1, e2]]];

a = CreateDataStructure["Value", 1];
b = a["Copy"];
c = b;

SameQ[a, b, c]

(* True *)

sameInstanceQ[a, b]

(* False *)

sameInstanceQ[b, c]

(* True *)
$\endgroup$
4
$\begingroup$

A new entry in the function repository, SameInstanceQ, can also be used here:

In[31]:= a = CreateDataStructure["Value", 1];
b = a["Copy"];
c = b;

In[34]:= ResourceFunction["SameInstanceQ"][a, b]

Out[34]= False

In[36]:= ResourceFunction["SameInstanceQ"][b, c]

Out[36]= True

It can also work with normal Wolfram Language expressions and is not limited to data structures:

In[42]:= a = <|"a" -> 1|>;
b = <|"a" -> 1|>;
c = b;

In[45]:= ResourceFunction["SameInstanceQ"][a, b]

Out[45]= False

In[46]:= ResourceFunction["SameInstanceQ"][b, c]

Out[46]= True

This function exposes some internal implementation details that are interesting, like the fact that there is only one version of an empty association:

In[47]:= ResourceFunction["SameInstanceQ"][<||>, <||>]

Out[47]= True

Other corner cases are discussed on the ref page.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.