Function Repository Resource:

GetUnboundSymbols

Source Notebook

Get all the non-local symbols that appear in an expression

Contributed by: Richard Hennigan (Wolfram Research)

ResourceFunction["GetUnboundSymbols"][expr]

gets all the non-local symbols that appear in expr.

ResourceFunction["GetUnboundSymbols"][expr,wrapper]

wraps each symbol in wrapper before returning the result.

Examples

Basic Examples (3) 

Get the unbound symbols in an expression:

In[1]:=
ResourceFunction["GetUnboundSymbols"][x_ :> x + y]
Out[1]=

Supply a head to be applied to each symbol:

In[2]:=
ResourceFunction["GetUnboundSymbols"][{x, y, z}, h]
Out[2]=

Use Unevaluated and a wrapper such as Hold to prevent evaluation:

In[3]:=
ResourceFunction["GetUnboundSymbols"][
 Unevaluated[Module[{x = y = 1}, x]], Hold]
Out[3]=
In[4]:=
ResourceFunction["GetUnboundSymbols"][
 Unevaluated[f[x_, y_] := x + y + z], HoldForm]
Out[4]=

Scope (5) 

Ignore symbols that are locally bound by Function:

In[5]:=
ResourceFunction["GetUnboundSymbols"][Function[x, x + y], HoldForm]
Out[5]=

GetUnboundSymbols ignores symbols bound by scoping constructs such as Block, With and Module:

In[6]:=
ResourceFunction["GetUnboundSymbols"][
 Unevaluated[Block[{x = 1}, y = 2; x + y]], HoldForm]
Out[6]=
In[7]:=
ResourceFunction["GetUnboundSymbols"][
 Unevaluated[With[{x = 1}, y = 2; x + y]], HoldForm]
Out[7]=
In[8]:=
ResourceFunction["GetUnboundSymbols"][
 Unevaluated[Module[{x = 1}, y = 2; x + y]], HoldForm]
Out[8]=

RuleDelayed has local bindings:

In[9]:=
ResourceFunction["GetUnboundSymbols"][x_ :> x + y, HoldForm]
Out[9]=

SetDelayed also has local bindings:

In[10]:=
ResourceFunction["GetUnboundSymbols"][
 Unevaluated[f[x_] := x + y], HoldForm]
Out[10]=

The x on the right-hand side of the Set is unbound:

In[11]:=
ResourceFunction["GetUnboundSymbols"][
 Unevaluated[With[{x = x}, 1]], HoldForm]
Out[11]=

Options (4) 

ExcludedContexts (4) 

Get all unbound symbols, regardless of context:

In[12]:=
ResourceFunction["GetUnboundSymbols"][x_ :> x + y, HoldForm, "ExcludedContexts" -> None]
Out[12]=

Exclude specific contexts:

In[13]:=
ResourceFunction["GetUnboundSymbols"][
 MyContext`x + Other`y + MyContext`Private`z, HoldForm, "ExcludedContexts" -> {"MyContext`"}]
Out[13]=

Excluded contexts using string patterns:

In[14]:=
ResourceFunction["GetUnboundSymbols"][
 MyContext`x + Other`y + MyContext`Private`z, HoldForm, "ExcludedContexts" -> {"MyContext`" ~~ ___, "System`"}]
Out[14]=

Exclude specified contexts in addition to the defaults:

In[15]:=
ResourceFunction["GetUnboundSymbols"][
 MyContext`x + Other`y + MyContext`Private`z, HoldForm, "ExcludedContexts" -> {"Other`", Automatic, "*`Private`"}]
Out[15]=

Applications (1) 

Get dependent symbols in a definition while excluding local symbols:

In[16]:=
z = "The definition of z isn't really needed for f.";
f[x_] := Module[{z = x + y}, z + 1];
In[17]:=
definition = Language`ExtendedDefinition[f]
Out[17]=
In[18]:=
ResourceFunction["GetUnboundSymbols"][definition, HoldForm]
Out[18]=

Possible Issues (2) 

GetUnboundSymbols doesn’t predict future scoping:

In[19]:=
expr = HoldComplete[Function @@ HoldComplete[x, x + y]]
Out[19]=
In[20]:=
ResourceFunction["GetUnboundSymbols"][expr, HoldForm]
Out[20]=

When evaluated, x becomes a local symbol:

In[21]:=
ReleaseHold[expr]
Out[21]=
In[22]:=
ResourceFunction["GetUnboundSymbols"][%, HoldForm]
Out[22]=

Requirements

Wolfram Language 11.3 (March 2018) or above

Version History

  • 1.1.0 – 07 June 2021
  • 1.0.0 – 11 March 2019

Related Resources

License Information