CompiledFunction showing its contents

This has to do, AFAIR, with whether the expression is marked internally as "evaluated" or perhaps "valid object." If it is so marked, it will be typeset by the Front End in the summary-box way; if it is not evaluated (or not valid), you will get the input form. This happens for other functions besides CompiledFunction, too. I don't believe there is a way at the user level to access the flag(s) that indicate the "evaluated" status of an expression. @WReach's traceView* functions seem to infer it from the evaluation sequence and marks them "inert", if you wish to explore the difference between Hold[Evaluate[comp]] and Hold[Evaluate[comp]] // Replace[#1, {}, Infinity] &.

What seems to happen is that when Replace scans the expression, it must do something that marks the expression as needing reevaluation, even if it does nothing:

Hold[Evaluate[comp]] // Replace[#1, {}, Infinity] &

Mathematica graphics

In fact, in the case in question, any level specification of 5 or higher triggers the behavior:

Hold[Evaluate[comp]] // Replace[#1, {}, {5}] &

To get the summary box back, the CompiledFunction needs to be reevaluated. One way is with the following replacement:

Hold[Evaluate[comp]] // Replace[#1, {}, {5}] &
% /. cf_CompiledFunction :> Evaluate@cf /; True

Mathematica graphics

Here's the same thing applied to InterpolatingFunction:

ifn = Interpolation[N@Range[4]^2];
Hold[Evaluate[ifn]] // Replace[#1, {}, Infinity] &
% /. f_InterpolatingFunction :> Evaluate@f /; True

Mathematica graphics

Here are the outputs of traceView2[] on the two examples. The important difference is in the second-to-last line, which shows whether the CompiledFunction is marked "inert" or not:

Mathematica graphics

Mathematica graphics


This has everything to do with a special bit called ValidQ that is used all over the place in Mathematica. Replace by dint of its scanning and likely unpacking of some array of bytes forces a copy of the expression and thus removes this bit.

Just to check that this is the issue:

CompiledFunction // FormatValues // Keys

{HoldPattern[
  MakeBoxes[ElisionsDump`cf : CompiledFunction[BoxForm`args__], 
    BoxForm`fmt_] /; 
   BoxForm`UseIcons && 
    System`Private`ValidQ[Unevaluated[ElisionsDump`cf]]]}

We can see it is indeed checking for ValidQ.

Here's another example:

Extract[
 Replace[Hold[Evaluate[comp]], {Hold[x_] :> x}, Infinity], 
 1, 
 System`Private`HoldValidQ
 ]

False

We can also use this to make invalid input behave like a CompiledFunction:

System`Private`HoldSetValid[
   CompiledFunction["asdasdasd", "asdasdasd", "asdasdasd", 
    "asdasdasd", "asdasdasd", "asdasdasd", "asdasdasd", "asdasdasd"]]@
  1;

CompiledFunction::cfct: Number of arguments 1 does not match the length 8314036833820636001 of the argument template.

It actually thinks that's a CompiledFunction because of this bit. It's powerful.

This is also one of those sneaky places where the object-oriented nature of Mathematica's implementation sneaks through, too:

Replace[Hold[Evaluate[comp]], {}, Infinity] === Hold[Evaluate@comp]

True

But one isn't ValidQ and the other is.


Replace[x, ..., All] is documented. See section "Details and Options" in the documentation of Replace.

There we read that Infinity is equivalent to level spec {1, Infinity} so that the head of the expression is ignored. So in your example, just no replacement is happening.

However, All is equivalent to level spec {0, Infinity}, taking care also if the head of the expression.

But tell me: Why do you not use ReplaceAll with the very nice postfix syntax /. in the first place?

Hold[Evaluate[comp]] /. Hold[x_] :> x