# Creating my own function AtomQ and NumericQ

I want to create my own functions AtomQ and NumericQ. For example, I already create some functions (IntegerQ,EvenQ,OddQ,PrimeQ):

meuIntegerQ[_Integer] := True
meuIntegerQ[_] := False

meuEvenQ[n_Integer] /; Divisible[n, 2] := True
meuEvenQ[_] := False

meuOddQ[n_Integer] /; Divisible[n, 2] := True
meuOddQ[_] := False

meuPrimeQ = False;
meuPrimeQ = True;
meuPrimeQ[n_Integer /; n > 2] := Length[Divisors[n]] == 2


How can I create a function that does the same at AtomQ and NumericQ like the examples.

Ps: This is just for exercise.

• What are the traits you expect out of something that gives True for AtomQ? – Jason B. Aug 31 '18 at 20:10
• "yields True if expr is an expression which cannot be divided into subexpressions, and yields False otherwise. " @JasonB. – Mateus Aug 31 '18 at 20:42
• Just keep in mind that definition doesn't even really apply to AtomQ – Jason B. Aug 31 '18 at 20:46
• Can you explain why you want to re-implement AtomQ and NumericQ? It is not possible to do this perfectly. These functions are too deeply intertwined with the rest of Mathematica. E.g. did you know you could assign to NumericQ and that it would affect other functions too? – Szabolcs Sep 1 '18 at 9:51
• "How can I create a function that does the same at AtomQ and NumericQ like the examples." In the strict sense, the answer is: you can't. If your actual question is: "What do these functons really do?" then please ask that instead. – Szabolcs Sep 1 '18 at 9:52

For NumericQ you could try:

numericQ[n_] := MatchQ[n//N, _Real|_Complex]


Example:

numericQ[Pi]


True

Here's an attempt at recognizing atoms:

atomQ[x_] := Head[List @@ x] =!= List || Quiet[Head[x] @@ List @@ x =!= x]


First, try to Apply List to the expression. With non-atoms this yields a List of their content, but with the simpler atoms it silently fails, yielding the atom. If that happens, you have an atom. For complicated "atoms" like SparseArray and Association, this yields a List. For a normal, non-atomic object, this List is just the original object with a different Head, so you may reconstruct the original by Applying the original head. This fails, often noisily, with complex atoms, so that's the second test. Quiet suppresses the noise.

AtomQ[expr] yields True if expr is an expression which cannot be divided into subexpressions, and yields False otherwise.

A simple enough function,

atomQ[obj_] := Length[obj] === 0


That this sometimes disagrees with the system function AtomQ seems like an issue with the documentation.

• True for non-atomic objects that are empty, like {}. False for complicated "atoms" like SparseArray and Association when they have contents. So, this doesn't work. – John Doty Sep 1 '18 at 1:50
• @JohnDoty If SparseArray and Association don't follow the documentation for AtomQ, I can't be blamed for that. – Jason B. Sep 1 '18 at 1:55
• But the machinery to divide expressions into subexpressions doesn't work for SparseArray and Association. It yields data, but that data is incomplete, inadequate to reconstruct the original expression. – John Doty Sep 1 '18 at 2:16
• I stand by my answer to this question. I'm available in chat if you want to talk more about the inconsistencies in the language. – Jason B. Sep 1 '18 at 2:21
• It would be very sad if the following weren't true: Length @ Range == Length @ SparseArray @ Range. Basically, some structural functions have been overloaded to handle atomic objects. This doesn't mean that the atomic object can be subdivided into subexpressions. – Carl Woll Sep 1 '18 at 4:01