# How to define a function to be numeric when the input is purely symbolic

My goal is to have NumericQ[h[j]]=True for any j regardless of whether j may be symbolic with no defined value.

Setting NumericQ[h[j_]]=True does not work and as I understand the NumericFunction attribute only works when the input is also numeric.

One solution might be to unprotect NumericQ and then set NumericQ[h[j_]]=True but I have not tried this as I am afraid of using Unprotect. Another solution might be to define my own NumericQ function, that I can call numericq for example, and set numericq[h[j_]]=True but I would have to replace all previous NumericQ with numericq in my code and test that everything works.

• edit *

I want to do this because I want my code to ignore certain symbols. My solution was to treat these symbols as numeric but this does not work for symbols like h[j] when j is a generic symbol. Any other function that works like NumericQ could work although I would have to change my code a bit.

• This gives off the impression of an XY problem. Surely there is a way to solve your actual problem that does not involve doing fragile things like redefining NumericQ[]. Jul 25 at 17:02
• @J.M. I agree that my question is on my current solution rather than the problem. I added an edit under * edit * to explain what the problem is. Jul 25 at 17:17
• Instead of unprotecting NumericQ, you could use an upvalue as in h/:HoldPattern[NumericQ[h[_]]]=True. I am not saying that it is a good idea. Btw: Somewhat surprisingly to me, even something like NumericQ[undefinedsymbol]=True gives no error. I do not understand why it gives no error, NumericQ is protected, not sure what I am missing. Jul 25 at 17:33
• @user293787, that is a slick solution. I did not think of using an upvalue. I am quite inexperienced with upvalues. If you want to copy-paste your comment into a solution I will accept it. Jul 25 at 17:41

## 2 Answers

Instead of unprotecting NumericQ, one can define an upvalue for h:

h/:HoldPattern[NumericQ[h[_]]]=True;


This means that the definition is stored with h rather than with NumericQ:

UpValues[h]
(* {HoldPattern[HoldPattern[NumericQ[h[_]]]]:>True} *)


When an expression such as NumericQ[h[4]] is evaluated, then upvalue definitions for h are tried before downvalue definitions for NumericQ, hence we get True. See this tutorial.

Warning. Though I have used upvalues before with NumericQ, I do not know if it can break something.

This is an extended comment and not strictly an answer. But I thought I put this here, since people that end up here for whatever reason might find it useful. For reference, I am currently using Version 12.3.

While writing the other answer, I was surprised to find that the assignment

NumericQ[undefinedsymbol] = True


gives no warning, despite NumericQ having the attribute Protected. And it works, meaning now

NumericQ[undefinedsymbol]
(* gives True *)


By contrast

NumericQ[undefinedsymbol2] = "seriously"


gives the error message

Cannot set NumericQ[undefinedsymbol2] to seriously; the lhs argument must be a symbol and the rhs must be True or False

This error would suggest that

NumericQ[undefinedsymbol3[789]] = True


would fail since undefinedsymbol3[789] is not a symbol, but it gives no error or warning. However,

NumericQ[undefinedsymbol3[789]]
(* gives False *)


I find this a bit misleading. Probably NumericQ[undefinedsymbol3[789]] = True should give an error, since without error, one assumes that the definition was recorded, when in fact it was not.

I do not know if people use this feature of NumericQ. I do not see it mentioned in the documentation.

Comment. I can understand how NumericQ[undefinedsymbol] = True can work despite the protection. For example, NumericQ could be using something similar to the following code to circumvent the protection:

myNumericQ/:Set[myNumericQ[x_Symbol],tf:(True|False)]:=(
Unprotect[myNumericQ];
AppendTo[DownValues[myNumericQ],HoldPattern[myNumericQ[x]]:>tf];
Protect[myNumericQ];
tf);
Protect[myNumericQ];

• As far as I know NumericQ[symbol]=True is a well-known way to attach the numeric property to a symbol and as far as I know, it is a mystery how it works. Szabolcs discusses his guess here where he also discusses why ClearAll[symbol] does not remove the numeric property from symbol. Jul 26 at 19:25
• @userrandrand Thank you very much, I had not seen that post! I see that Scabolcs' guess for how it works is similar to mine (but maybe mine has some obvious flaw, not sure). I think I will leave the post here for now, if only to point out the questionable behavior for NumericQ[undefinedsymbol3[789]] = True. Jul 26 at 19:36
• For a better alternative to the AppendTo used above, see this answer. Jul 29 at 5:06