Thank you for bringing this function to my attention! It lets us use ReplaceAll
without disturbing or even traversing held expressions. This is huge! I have little time at the moment and I intend to flesh out this answer later but I want to get some ink on the page lest I forget.
Many times Hold
or HoldForm
is used as a container to prevent automatic alteration of an expression (via evaluation) but as replacements traditionally operate independently of evaluation (which itself is extremely useful of course) one has to be particularly careful in using replacements for generation expression manipulation. With ReplaceAllUnheld
we can make these replacements without contaminating our containers. Previously one might use a skip rule(1)(2)(3) to pass over explicit appearances of the Hold
family:
skipHolds = skip : _Hold | _HoldForm | _HoldComplete | _HoldPattern :> skip;
{HoldForm[a^2], a^2} /. {skipHolds, a -> 5}
{a^2, 25}
This however does nothing for user containers or even system functions with HoldFirst
, HoldRest
etc. The Developer function lets us seamlessly handle both.
As a quickly contrived example (where also the skip rule would work) imagine we build a table like this:
foo = {a^Range[3], b^Range[3]};
table = TableForm[KroneckerProduct @@ foo, TableHeadings -> Map[HoldForm, foo, {2}]]

Later we would like to substitute values into the body of the table without affecting the headings. That can now be done with:
Developer`ReplaceAllUnheld[table, {a -> 3, b -> 7}]

This only touches on the potential utility of this function and again I hope to both explore and write more about it later.