What's the difference between Inactive and HoldForm?
Updated
Both Hold
and Inactive
block evaluation; the key difference is that Inactive
is meant to be wrapped around heads rather than a whole expression. Inactivate
does this.
Inactivate[1 + 2 + 3 * 4 ^ 5 ] // FullForm
Inactive[Plus][1, 2, Inactive[Times][3, Inactive[Power][4, 5]]]
It is of course possible to use Inactive
directly, and it will behave like any symbol with holding attributes.
Inactive[1 + 2 + 3 * 4 ^ 5] // FullForm
Inactive[Plus[1, 2, Times[3, Power[4, 5]]]]
But in general there is no reason to use it this way. Note that while Activate
and ReleaseHold
are comparable, there is no analog to Inactivate
. The point is to use these auxiliary functions.
Because Inactivate
wraps heads, it can accept an optional second argument constraining which heads to inactivate.
Inactivate[1 + 2 + 3 * 4 ^ 5, Plus] // FullForm
Inactive[Plus][1, 2, 3072]
Activate
can similarly accept an optional second argument.
Inactivate[1 + 2 + 3 * 4 ^ 5];
Activate[%, Power] // FullForm
Inactive[Plus][1, 2, Inactive[Times][3, 1024]]
Another interesting consequence of using Inactivate
is that atomic symbols will get evaluated.
Hold @ {$WolframUUID}
Hold[{$WolframUUID}]
Inactivate @ {$WolframUUID}
{"0e2497dc-9281-48f3-8e84-14b5e2587446"}
One difference is that NDSolve
directly supports Inactive
. It can be used to specify operators such as divergence ($\nabla\cdot$) without automatically evaluating them to components. This is described here.
Although mfvonh's answer is a nice summary of Inactive
formal properties, I think it misses several important points, which are both shown in the "Scope" and "Applications" section of the documentation. For me the main point seems to be (2), as I don't know how this could be achieved using Hold
.
1) Inactive
can be used to illustrate formal mathematical identities, e.g.,
Table[Block[{e = Inactivate[n + m]}, e == Activate[e]], {n, 0, 3}, {m,
0, 3}] // Grid // TraditionalForm
2) It can be used in formal mathematical manipulations (as hinted at by Szabolcs' answer), e.g.,
D[Inactive[Integrate][f[x], {x, a[x], b[x]}],x]
(*-f[a[x]] Derivative[1][a][x] + f[b[x]] Derivative[1][b][x]*)
3) It can be used for easy programmatic code transformation, as Inactivate
automatically wraps around all heads:
def = Inactivate[for[f_, max_] := For[x = 1, x < max, x++, Print@x]];
def/.Inactivate[For[i_ = init_, i_ < max_, i_++, body_] :> Do[body, {i, init, max}]]
(*forSquares[f_,max_]:=Do[Print[f[x^2]],{x,1,max}]*)
So the use cases are quite different from the ones of Hold
/ReleaseHold
. I don't think (2) could be easily achieved with Hold
, and (3) is definitely more elegantly solved by using Inactivate
.