Function Repository Resource:

NoEntry

Source Notebook

Hold an expression and make its content inaccessible to other functions

Contributed by: Sjoerd Smit

ResourceFunction["NoEntry"][expr]

returns a Hold object that maintains expr in an unevaluated form and prevents access even from functions like ReplaceAll and Part.

Examples

Basic Examples (2) 

NoEntry returns a special Hold object:

In[1]:=
ResourceFunction["NoEntry"][1 + 1]
Out[1]=

NoEntry prevents its contents from being modified by ReplaceAll, unlike normal Hold:

In[2]:=
{1, ResourceFunction["NoEntry"][2], Hold[3], "a"} /. _Integer -> "x"
Out[2]=

NoEntry objects cannot be accessed by Part:

In[3]:=
ResourceFunction["NoEntry"][2][[1]]
Out[3]=

Remove the Hold wrapper again to access the contents:

In[4]:=
ReleaseNoEntry[expr_] := expr /. Hold[e___]?AtomQ :> e
In[5]:=
ReleaseNoEntry[{1, ResourceFunction["NoEntry"][2], Hold[3], "a"}]
Out[5]=

The FullForm is the same as a regular Hold object:

In[6]:=
FullForm[%]
Out[6]=

Scope (1) 

Use Evaluate to evaluate the contents of NoEntry before making them inaccessible:

In[7]:=
ResourceFunction["NoEntry"][Evaluate[1 + 1]]
Out[7]=

Applications (5) 

NoEntry can be used in ragged expressions to make it easy to find the lowest-level elements if those elements still have some internal structure. Consider the following linked list of symbolic numbers:

In[8]:=
lst1 = Fold[List, {1, Sqrt[2], 3^Pi, Log[5], E + Pi}]
Out[8]=

Mapping a function to the numbers inside the linked list can be difficult because the {-1} level specification doesn't correspond to the list elements:

In[9]:=
Level[lst1, {-1}]
Out[9]=
In[10]:=
Map[f, lst1, {-1}]
Out[10]=

NoEntry hides the internal structure of the elements:

In[11]:=
lst2 = Fold[List, ResourceFunction["NoEntry"] /@ {1, Sqrt[2], 3^Pi, Log[5], E + Pi}]
Out[11]=
In[12]:=
Level[lst2, {-1}]
Out[12]=

Map the function to the numbers:

In[13]:=
Map[Replace[#, Hold[e_] :> f[e]] &, lst2, {-1}]
Out[13]=

Use a Listable Function to apply NoEntry at the bottom of ragged arrays:

In[14]:=
Function[e, ResourceFunction["NoEntry"][e], Listable][lst1]
Out[14]=

Properties and Relations (2) 

NoEntry objects are atoms:

In[15]:=
AtomQ@ResourceFunction["NoEntry"][1]
Out[15]=

The contents of NoEntry objects are accessible by pattern matching the whole Hold object:

In[16]:=
Replace[ResourceFunction["NoEntry"][1, 2, 3], Hold[args___] :> Plus[args]]
Out[16]=
In[17]:=
fun[Hold[args___]] := Plus[args]
In[18]:=
fun[ResourceFunction["NoEntry"][1, 2, 3]]
Out[18]=

Possible Issues (2) 

ReleaseHold doesn't work on objects created by NoEntry:

In[19]:=
ReleaseHold @ {ResourceFunction["NoEntry"][2], Hold[2]}
Out[19]=

NoEntry needs to evaluate before it becomes inaccessible, so it doesn't work directly when placed inside another inert wrapper like Hold:

In[20]:=
Hold[{ResourceFunction["NoEntry"][1], ResourceFunction["NoEntry"][2]}] /. _Integer -> "x"
Out[20]=

The following replacement rule can be used to force all NoEntry objects to evaluate inside an expression:

In[21]:=
expr = ReplaceAll[
   Hold[{ResourceFunction["NoEntry"][1], ResourceFunction["NoEntry"][2]}],
   e_ /; Head[Unevaluated@e] === ResourceFunction["NoEntry"] :> With[{eval = e},
    eval /; True
    ]
  ]
Out[21]=

Now the contents of NoEntry are inaccessible:

In[22]:=
expr /. _Integer -> "x"
Out[22]=

Publisher

Sjoerd Smit

Requirements

Wolfram Language 14.0 (January 2024) or above

Version History

  • 1.0.0 – 04 September 2024

Related Resources

License Information