Wolfram Research

Function Repository Resource:

SameInstanceQ

Source Notebook

Determine if two Wolfram Language expressions come from the same instance

Contributed by: Jason Biggs  |  JasonB

ResourceFunction["SameInstanceQ"][expr1,expr2]

returns True if expr1 and expr2 share the same instance.

ResourceFunction["SameInstanceQ"][expr1,expr2,]

returns True if all the expri are the same instance.

Details and Options

Two expressions share the same instance if they represent pointers to the same data—in other words, if they occupy the same location in memory.

Examples

Basic Examples (3) 

Two expressions that are identical are considered SameQ:

In[1]:=
a = <|"key" -> 1|>;
b = <|"key" -> 1|>;
a === b
Out[3]=

However, they are different instances of the same data:

In[4]:=
ResourceFunction["SameInstanceQ"][a, b]
Out[4]=

By contrast, the value for c in the below is literally the same value for a, since both reference the same memory location:

In[5]:=
c = a;
ResourceFunction["SameInstanceQ"][a, c]
Out[6]=

Scope (1) 

SameInstanceQ can accept any number of arguments:

In[7]:=
ResourceFunction["SameInstanceQ"][f[x], f[x], f[x]]
Out[7]=
In[8]:=
ResourceFunction["SameInstanceQ"][x, x, x, x, x]
Out[8]=

Properties and Relations (5) 

SameInstanceQ always returns True for a single argument:

In[9]:=
ResourceFunction["SameInstanceQ"][x]
Out[9]=
In[10]:=
ResourceFunction["SameInstanceQ"][f[x]]
Out[10]=

Compare to SameQ:

In[11]:=
SameQ[x]
Out[11]=
In[12]:=
SameQ[f[x]]
Out[12]=

SameInstanceQ[] is defined to be True:

In[13]:=
ResourceFunction["SameInstanceQ"][]
Out[13]=

This matches the behavior of SameQ:

In[14]:=
SameQ[]
Out[14]=

Memory is typically allocated for each new expression that is created, even if it shares the same value as an existing expression:

In[15]:=
ClearAll[a, b];
MaxMemoryUsed[a = Range[100]; b = Range[100]; {a, b}]
Out[14]=

In this case, a and b have identical values:

In[16]:=
SameQ[a, b]
Out[16]=

However, their values are stored separately in memory, since each expression was created separately:

In[17]:=
ResourceFunction["SameInstanceQ"][a, b]
Out[17]=

Reusing expressions that are already created can save memory:

In[18]:=
ClearAll[a, b];
MaxMemoryUsed[a = Range[100]; b = a; {a, b}]
Out[19]=

The value for a is literally the same value for b, since both reference the same memory location:

In[20]:=
ResourceFunction["SameInstanceQ"][a, b]
Out[20]=

Many simple expressions are already preallocated in the kernel:

In[21]:=
ResourceFunction["SameInstanceQ"][123, 123]
Out[21]=
In[22]:=
ResourceFunction["SameInstanceQ"][<||>, <||>]
Out[22]=

These are not necessarily atomic values:

In[23]:=
ResourceFunction["SameInstanceQ"][{}, {}]
Out[23]=

Atomic expressions that are SameQ are not necessarily SameInstanceQ:

In[24]:=
AtomQ["x"]
Out[24]=
In[25]:=
SameQ["x", "x"]
Out[25]=
In[26]:=
ResourceFunction["SameInstanceQ"]["x", "x"]
Out[26]=

Possible Issues (2) 

Having all of the corresponding parts of expressions be SameInstanceQ does not imply the parent expressions are SameInstanceQ:

In[27]:=
expr1 = f[x, y, {}];
expr2 = f[x, y, {}];
In[28]:=
s1 = Cases[expr1, _, Infinity, Heads -> True]
Out[28]=
In[29]:=
s2 = Cases[expr2, _, Infinity, Heads -> True]
Out[29]=
In[30]:=
ResourceFunction["SameInstanceQ"] @@@ Transpose[{s1, s2}]
Out[30]=
In[31]:=
ResourceFunction["SameInstanceQ"][expr1, expr2]
Out[31]=

Small integers are already created in memory, so they are always the same instance:

In[32]:=
ResourceFunction["SameInstanceQ"][123, 123]
Out[32]=

Larger integers are created as needed:

In[33]:=
ResourceFunction["SameInstanceQ"][1234, 1234]
Out[33]=

Find the range of small integers that are preallocated in memory:

In[34]:=
ListLinePlot[
 Table[{i, Boole[ResourceFunction["SameInstanceQ"][i + 1 - 1, i + 1 - 1]]}, {i, -2000, 2000}], Filling -> Bottom]
Out[34]=

Neat Examples (1) 

Test modifications on expressions to see which lead to new instances:

In[35]:=
expr = 12345;
In[36]:=
ResourceFunction["SameInstanceQ"][expr, expr]
Out[36]=
In[37]:=
ResourceFunction["SameInstanceQ"][{expr}, {expr}]
Out[37]=
In[38]:=
ResourceFunction["SameInstanceQ"][expr + 0, expr + 0]
Out[38]=
In[39]:=
ResourceFunction["SameInstanceQ"][expr + 1, expr + 1]
Out[39]=
In[40]:=
ResourceFunction["SameInstanceQ"][expr, ++expr; --expr]
Out[40]=

Resource History

License Information