# What's the difference between Inactive and HoldForm?

In version 10, Mathematica not only added Inactive / Activate but also highlighted this change in the "New in 10" page (in Core Language Enhancements). Thus, I suppose it should be something useful. However, I didn't understand in which sense it is better than the good old Hold (HoldForm) / ReleaseHold mechanism. I noticed a few differences, but all of those are minor:

(1) Inactive objects are printed in a lighter color. HoldForm objects are printed in normal color.

(2) There is an IgnoringInactive function to include inactive objects into pattern matching.

It would be nice to hear if there are more important differences.

-

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

Inactivate[Plus][1, 2, 3072]


Activate can similarly accept an optional second argument.

Activate[inactive, 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"}  - Thanks! But why don't they just add pattern matching or tags to Hold and ReleaseHold, but instead do something new and parallel? – Yi Wang Jul 11 at 17:39 I think it is just a design decision. In my opinion, the functionality is sufficiently different that it makes sense to use a different set of symbols. (Recall that Unevaluated also exists.) – mfvonh Jul 11 at 20:04 @YiWang Hold[A,B] Already has a working definition (it will hold the sequence of elements), so if you add some sort of tags functionality to Hold you need to either get really creative or break backwards compatibility. But really, I don't think that there is any reason why Inactivate couldn't just wrap holds around heads and activate remove these holds. But personally I prefer the distinction. – jVincent Jul 11 at 20:24 But couldn't the effect of Inactivate also be achieved using Hold with SetAttributes[MakeHeld, HoldAll]; MakeHeld[a_[b___]] := MakeHeld[a][b]; MakeHeld[a_] := Hold[a]? – celtschk Jul 21 at 20:34 @celtschk Certainly; with that I only meant to highlight that they are intended to be used differently, but how you use them is of course flexible. The more subtle advantages of a different head are nicely pointed out in the other answers, and of course by the OP (IgnoringInactive). – mfvonh Jul 23 at 13:23 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 at least two important points, which are both shown in the "Scope" and "Applications" section of the documentation:

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]*)


Both of these are very different from what Hold/ReleaseHold would produce. (As an aside, the documentation mentions yet another application, "Code transformation", which I haven't fully understood yet.)

-
(2) is very interesting. But I didn't get the point of (1). When I run Block[{e = HoldForm[23 + 11]}, e == ReleaseHold[e]], I get the same displayed result (though different InputForm). –  Yi Wang Jul 21 at 10:48
@YiWang Oops, good point :) I didn't think of HoldForm because I never use it. The real point is probably in a more elaborate example (see edit). Now I'm crossing my fingers that I didn't overlook something else... –  sebhofer Jul 21 at 10:54