7

The documentation for Inactivate makes the function sound really powerful because it gives granular control over which kind of expressions specifically not to evaluate.

Inactivate[expr,patt]

inactivates all symbols in expr that match the pattern patt.

Can then anyone explain to me this behavior of Inactivate?

Inactivate[{Print@1,Print@2}, Print] /. Inactivate@Print[a_]:> a //Activate

{1,2}

Inactivate[Print/@{1,2}, Print] /. Inactivate@Print[a_]:> a //Activate
1
2

{Null, Null}

A more useful application for this kind of scenario would be a workaround to make Flatten handle lists containing atoms. (Which does not work)

Inactivate[Flatten/@{1, {2, {3}}}, Flatten] 
/. Inactivate@Flatten[a_?AtomQ]:> a //Activate

while this works again:

Inactivate[{Flatten@1,Flatten@{2, {3}}}, Flatten] 
/. Inactivate@Flatten[a_?AtomQ]:> a //Activate
LCarvalho
  • 9,233
  • 4
  • 40
  • 96
Sascha
  • 8,459
  • 2
  • 32
  • 66

2 Answers2

8

This statement from documentation might be misleading. It should be read in conjunction with first statement:

Inactivate[expr]

replaces all instances of f with Inactive[f] for symbols f used as heads in expr.

So Inactivate[expr, patt] really inactivates all symbols used as heads in expr, that match the pattern patt.

That's why in e.g. f[] expression f is inactivated:

ClearAll[f]
Inactivate[f[], f] // FullForm
(* Inactive[f][] *)

and in f expression - it's not:

Inactivate[f, f] // FullForm
(* f *)

In expression you passed to Inactivate:

Print /@ {1, 2} // Hold // FullForm
(* Hold[Map[Print, List[1, 2]]] *)

Print is not used as head of expression, so it's not inactivated.

Instead of Inactivate[Print/@{1,2}, Print] you could manually wrap Print with Inactive head:

Inactive[Print] /@ {1, 2} /. Inactivate@Print[a_] :> a // Activate
(* {1, 2} *)
jkuczm
  • 15,078
  • 2
  • 53
  • 84
5

jkuczm already explained your example, but pragmatically I think you may be looking for Block instead:

Block[{Flatten},
 Flatten /@ {1, {2, {3}}} /. Flatten[a_?AtomQ] :> a
]
{1, {2, 3}}

Of course there are other ways to perform this specific operation, e.g.

Flatten@*List @@@ {1, {2, {3}}}
{1, {2, 3}}

This one works because Apply does not modify atoms(1).


Note: Block may fail when using Packed Arrays, as some functions trigger low-level optimized code that Block does not affect. See:

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371