Why does Plot[Hold[x], {x,0,1}] work?

It appears that, counter to my expectation, all of these (and probably many others) seem to work fine:

Plot[Hold[x], {x, 0, 10}]

FindRoot[Hold[x^2 == 2], {x, 1}]

NMinimize[Hold[x^2], x]


I would expect Plot or NMinimize to complain that e.g. Hold[0] is not a number.

These were mentioned a few times on this site but didn't get any attention: (1) (2).

Doing this does appear to solve problems which would normally require _?NumericQ.

Is this usage of Hold supported? Is it meant to work this way, does it work by design, or is it accidental?

My guess is that these work accidentally because these functions use ReleaseHold internally.

-
NMinimize[Hold[Print["hi"]; x^2], x] causes my kernel to crash. NMinimize[Hold[x]^2, x] complains and NMinimize[Hold@Hold[x^2], x] works; however, NMinimize[Hold@Hold@Hold[x^2], x] does not. I suppose it could be ReleaseHold, but not in the ordinary way. –  Michael E2 Mar 4 '14 at 0:09
@MichaelE2 That pretty much settles that this is not supported functionality. I think it is good to have this information in a Q/A. You could consider answering. –  Szabolcs Mar 4 '14 at 0:12
I would absolutely agree with your guess that it is the internal handling of evaluation control which make these work accidentially. The question remains whether that indicates that these internally do more ReleaseHolds than necessary and whether that is intended or a lack of attention. In any case it seem to not cause much problems, I think? –  Albert Retey Mar 4 '14 at 10:41
I noticed this a while ago and suspected it to be due to the behavior of the ExperimentalNumericalFunction, which is definitely used by NMinimize and probably by the others. But I don't really know anything about this undocumented function and so can't elaborate further. –  Oleksandr R. Mar 4 '14 at 23:50

I took a rather shotgun approach to the question and got a range of behaviors. The range is rather confusing, so I agree with Szabolcs's conclusion that using Hold this way is not supported.

First, NMinimize[Hold[Print["hi"]; x^2], x] prints "hi" and then crashes the kernel, while NMinimize[Print["hi"]; x^2, x] prints "hi" and returns {0., {x -> 0.}}.

Next consider the sequence

NMinimize[x^2, x]                  (* -> {0., {x -> 0.}} *)
NMinimize[Hold[x^2], x]            (* -> {5.55112*10^-17, {x -> -7.45058*10^-9}} *)
NMinimize[Hold@Hold[x^2], x]       (* -> {5.55112*10^-17, {x -> -7.45058*10^-9}} *)
NMinimize[Hold@Hold@Hold[x^2], x]  (* -> NMinimize::nnum error *)


as well as

NMinimize[Hold[x]^2, x]            (* -> NMinimize::nnum error *)


One or two Holds prevent symbolic analysis but allow the numeric function to be evaluated. You have to really, really Hold the argument to stop evaluation. A Hold inside the function is not released, so it is not a simple application of ReleaseHold to the argument that allows minimization of Hold[x^2].

With Plot, you have to wrap the function five times with Hold to stop the function from being plotted. FindRoot behaves similar to NMinimize`, except that it does not crash the kernel.

-