Interesting pattern came up as I go through the homework replies of my students. Why is there no RationalQ or RealQ? We have Rational and Real as type restrictors / heads in pattern matching, like _Rational or _Real. Why no Qs for them?
- 13,452
- 2
- 47
- 78
- 4,009
- 22
- 20
2 Answers
There is a RealQ, see
Developer`RealQ
Also relevant:
Developer`MachineRealQ
The difference between the two:
Developer`RealQ[1.`20]
Developer`MachineRealQ[1.`20]
True
False
So, Developer`RealQ is a test for arbitrary precision numbers, while Developer`MachineRealQ checks whether its input is a double precision number.
Notice that both return
Developer`RealQ[1]
Developer`MachineRealQ[1]
False
False
Compare this to
IntegerQ[10^100000]
Developer`MachineIntegerQ[10^100000]
True
False
As Szabolcs and Sjoerd pointed out, these tests are for data types and not tests in mathematical sense. For example, we also have the following:
IntegerQ[(1 - Sqrt[2]) (1 + Sqrt[2])]
IntegerQ[Simplify[(1 - Sqrt[2]) (1 + Sqrt[2])]]
False
True
A somewhat more mathematical test seems to be Assumptions`ARealQ:
Assumptions`ARealQ[(1 - Sqrt[2]) (1 + Sqrt[2])]
True
But as it is undocumented, I really don't know what does it do.
And on top of that, we have Assumptions`ARationalQ, quite a mysterious beast:
Assumptions`ARationalQ[(1 - Sqrt[2]) (1 + Sqrt[2])]
Assumptions`ARationalQ[1/2]
Assumptions`ARationalQ[1]
Assumptions`ARationalQ[I]
Assumptions`ARationalQ[1.]
False
True
True
False
False
Not to mention Reduce`RationalNumberQ which behaves similarly erratic.
- 68,381
- 3
- 139
- 286
- 106,770
- 7
- 179
- 309
-
(1 - 3 I) + (I ArcSinh[7])/ArcSinh[1]is a real number, but Developer`RealQ and MachineRealQ returns False. – expression Jan 22 '21 at 13:22 -
Of course it is not a machine real, because it is an exact number. Only
Re[N[(1 - 3 I) + (I ArcSinh[7])/ArcSinh[1]]]would turn it into a machine real. E.g., alsoDeveloper`MachineRealQ[1]would returnFalse. I think thatDeveloper`MachineRealQworks as it should. I don't now however, whyDeveloper`RealQdoes not classify it as a real number. Both functions are undocument and thus so not meant for the public. We just cannot tell what the designers intendended and whether they work correctly in that regard. – Henrik Schumacher Jan 22 '21 at 13:54
Why no RationalQ or RealQ?
Probably because it isn't unambiguous what such a function should do. From the comments above:
If there were a
RationalQ, I'd expectRationalQ[2]to beFalse
But many other users would expect something like this:
For IntegerQ there aren't such conflicting expectations.
- 68,381
- 3
- 139
- 286

IntegerQ. If you need something like that, you can always use a curried form likeRationalQ = MatchQ[_Rational]. – Sjoerd Smit Sep 12 '18 at 13:36IntegerQtests if an expression is mathematically an integer (what it does is that it checks if the datatype isInteger) – Szabolcs Sep 12 '18 at 13:38RationalQ[(1 - Sqrt[2]) (1 + Sqrt[2])]. ;) – Henrik Schumacher Sep 12 '18 at 13:39RationalQto perform algebraic simplifications: it should just check the data type. If you want to simplify, you should useSimplify. Mathematica already has enough annoying simplification behaviours that are difficult to stop. – Sjoerd Smit Sep 12 '18 at 13:44IntegerQcannot simplify that. – Henrik Schumacher Sep 12 '18 at 13:48Element[x, Rationals]instead. That will often not evaluate, but it isSimplifyable. It doesn't check datatype. It's checks whether the value is rational. – Szabolcs Sep 12 '18 at 13:57RationalQ, I'd expectRationalQ[2]to beFalsebecause the datatype of2isInteger, notRational. That has nothing to do with2being a rational number. – Szabolcs Sep 12 '18 at 13:58_Rationalis not sufficient asRational[x,y]with (x,ysymbols) is not an atomicRational. There should be aRationalQ. – Szabolcs Apr 17 '19 at 22:09