# TagSet for symbol inside NumericQ behaves differently than in other fooQ functions

I am trying to define some symbols as being numeric by using TagSet and encountered the following different behaviors between NumericQ and e.g. IntegerQ.

TagSet with IntegerQ, together with other built-in functions I've tried, also works when the symbol takes an argument.

f/:IntegerQ[f[_]]=True;
IntegerQ[f]
IntegerQ[f[1]]
(* ==>
False
True
*)


However, while trying to do the same with NumericQ it does not work.

g/:NumericQ[g[_]]=True;
NumericQ[g]
NumericQ[g[1]]
(* ==>
False
False
*)


Note though that h/:NumericQ[h]=True; NumericQ[h] gives True as expected.

Furthermore, Definition gives different output when applied to f compared to g, h above:

Definition[f]
Definition[g]
Definition[h]
(* ==>
IntegerQ[f[_]]^=True
Null
Null
*)


This is very puzzling to me. Why is there this difference?

• Consider using SetAttributes[g, NumericFunction] instead. – J. M.'s technical difficulties Aug 17 '17 at 15:28
• @J.M.: Thanks a lot! Although it doesn't answer the question, it does solve my underlying problem. That ought to be more important but it's hard to let go of a puzzle once you started wonder... :-) Note also that it makes both NumericQ[g] and NumericQ[g[1]] evaluate to True and does not offer the flexibility of leaving NumericQ[q] as False, should one ever want that... I don't but worth mentioning for sake of generality. :-) Thanks again! – Stalpotaten Aug 17 '17 at 16:00

...Set... functions are overridden for NumericQ. That's why your assignment g /: NumericQ[g[_]] = True does not work as expected.

I guess that the fact that above assignment doesn't complain with an error message, and just does nothing, might be considered a bug.

You could try to manually add necessary UpValues to your g:

g // ClearAll
g // UpValues = {HoldPattern@NumericQ@g@_ :> True};


This will work when NumericQ is called directly on g[...].

NumericQ@g       (* False *)
NumericQ@g[1]    (* True *)
NumericQ@g[1, 2] (* False *)


But it will not work when g[...] is deeper in some other expression:

NumericQ@Sin@g[1] (* False *)


For NumericQ to recognize g[...] with numeric arguments arbitrarily deep inside other numeric functions you could set NumericFunction attribute (as suggested in comment by J. M.), but this does not give you precise control on pattern for which g[...] will be considered numeric:

g // ClearAll
g // Attributes = NumericFunction;

NumericQ@g            (* False *)
NumericQ@g[a]         (* False *)
NumericQ@g[1]         (* True *)
NumericQ@g[1, 2]      (* True *)
NumericQ@Sin@g[1, Pi] (* True *)


Overridden assignments involving NumericQ allow defining custom symbols representing numerical constants like E, or Pi, in a way that Mathematica will recognize them as numerical. E.g:

NumericQ@Sin@myNumConst     (* False *)
NumericQ@myNumConst = True;
NumericQ@Sin@myNumConst     (* True *)
NumericQ@myNumConst = False;
NumericQ@Sin@myNumConst     (* False *)


You can also force Mathematica to forget that a built-in constant is numerical:

NumericQ@Sin@E      (* True *)
NumericQ@E = False;
NumericQ@Sin@E      (* False *)


Mathematica seems to store some internal collection of such numerical symbols since results of such assignments are not visible neither in LanguageExtendedDefinition@NumericQ nor in LanguageExtendedDefinition@myNumConst. Unfortunately I don't know how to access it.

• Thank you for an illuminating and almost complete answer! Gotta love this forum! :-D The only remaining strange part is why h/: NumericQ[h]=True works fine (as expected) but yet doesn't show up in Definition[h]. – Stalpotaten Aug 17 '17 at 17:45
• @Stalpotaten Effects of this assignment are neither in LanguageExtendedDefinition@h nor in LanguageExtendedDefinition@NumericQ, there must be some internal collection of symbols for which NumericQ gives True, like E, or Pi. Overridden assignments involving NumericQ probably add symbols directly to that collection. Unfortunately I don't know how to access it. – jkuczm Aug 17 '17 at 18:38
• Thank you! I guess that is as far as we get in this mystery, but it's far enough for me! – Stalpotaten Aug 17 '17 at 18:50
• For constants, you can do SetAttributes[myNumConst, Constant] @Stalpotaten. – J. M.'s technical difficulties Aug 18 '17 at 3:30