Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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?

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

In[2]:= Inactivate[Print/@{1,2}, Print] /. Inactivate@Print[a_]:> a //Activate
1
2
Out[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
share|improve this question
up vote 7 down vote accepted

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} *)
share|improve this answer

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:

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.