Why no RationalQ or RealQ?

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?

• It's a good question, really, since we do have IntegerQ. If you need something like that, you can always use a curried form like RationalQ = MatchQ[_Rational]. Sep 12, 2018 at 13:36
• No good answer to this one ... but people regularly make the mistake of assuming that IntegerQ tests if an expression is mathematically an integer (what it does is that it checks if the datatype is Integer) Sep 12, 2018 at 13:38
• @HenrikSchumacher: How does that break it? I wouldn't expect a function like RationalQ to perform algebraic simplifications: it should just check the data type. If you want to simplify, you should use Simplify. Mathematica already has enough annoying simplification behaviours that are difficult to stop. Sep 12, 2018 at 13:44
• For the math (not datatype), one would use Element[x, Rationals] instead. That will often not evaluate, but it is Simplifyable. It doesn't check datatype. It's checks whether the value is rational. Sep 12, 2018 at 13:57
• If there were a RationalQ, I'd expect RationalQ[2] to be False because the datatype of 2 is Integer, not Rational. That has nothing to do with 2 being a rational number. Sep 12, 2018 at 13:58

There is a RealQ, see

DeveloperRealQ


Also relevant:

DeveloperMachineRealQ


The difference between the two:

DeveloperRealQ[1.20]
DeveloperMachineRealQ[1.20]


True

False

So, DeveloperRealQ is a test for arbitrary precision numbers, while DeveloperMachineRealQ checks whether its input is a double precision number.

Notice that both return

DeveloperRealQ[1]
DeveloperMachineRealQ[1]


False

False

Compare this to

IntegerQ[10^100000]
DeveloperMachineIntegerQ[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 AssumptionsARealQ:

AssumptionsARealQ[(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 AssumptionsARationalQ, quite a mysterious beast:

AssumptionsARationalQ[(1 - Sqrt[2]) (1 + Sqrt[2])]
AssumptionsARationalQ[1/2]
AssumptionsARationalQ[1]
AssumptionsARationalQ[I]
AssumptionsARationalQ[1.]


False

True

True

False

False

Not to mention ReduceRationalNumberQ which behaves similarly erratic.

• (1 - 3 I) + (I ArcSinh[7])/ArcSinh[1] is a real number, but DeveloperRealQ and MachineRealQ returns False. Jan 22, 2021 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., also DeveloperMachineRealQ[1] would return False. I think that  DeveloperMachineRealQ works as it should. I don't now however, why DeveloperRealQ does 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. Jan 22, 2021 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 expect RationalQ[2] to be False

But many other users would expect something like this:

For IntegerQ there aren't such conflicting expectations.