0 is integer, why can we use codes below?

Hello,

In Mathematica, 0 is an integer. So why can we write these codes:

evenodd[n_Integer] := If[EvenQ[n], Black, White]; evenodd[0] = Red

As 0 is an integer, the second half code is weird. The first part of codes includes 0.

How should I understand it?

This can be very tricky actually, the patterns of evenodd are sorted from very specific to least specific:

ClearAll[evenodd]
evenodd[n_Integer] := If[EvenQ[n], Black, White];
evenodd[0] := Red
DownValues[evenodd]

Any call to evenodd will be matched in the order of DownValues as far as I know.

0 is even too. So there is no chance to match.

evenodd[0]

In fact, it will be matched. So how understand it?

The call evenodd[0] matches both evenoff[0] and evenodd[n_Integer]. What happens on the right hand side of the definitions is not considered in the matching. But since these both match, the most-specific will be matched first (in the order of DownValues).

Try this experiment:

Clear[evenodd];

evenodd[n_Integer] := Brown;
evenodd[n_Integer?Positive] := Orange
evenodd[n_Integer?EvenQ] := Magenta;
evenodd[n_Integer /; Divisible[n, 4]] := Blue;
evenodd[0] := Red;

evenodd /@ Range[-5, 5]

Notice how Blue never shows up, and Magenta never shows up on the positive side. Why? To understand, look at the DownValues:

DownValues@evenodd

which gives you

{HoldPattern[evenodd[0]] :> Red, HoldPattern[evenodd[n_Integer?Positive]] :> Orange, HoldPattern[evenodd[n_Integer?EvenQ]] :> Magenta, HoldPattern[evenodd[n_Integer /; Divisible[n, 4]]] :> Blue, HoldPattern[evenodd[n_Integer]] :> Brown}

Notice that Mathematica automatically re-ordered the definitions from most specific to most general. But it couldn’t distinguish between the conditional rules, so it left them in the order in which they were evaluated.

Try the experiment again after re-ordering the conditional rules.

Clear[evenodd];

evenodd[n_Integer] := Brown;
evenodd[n_Integer?EvenQ] := Magenta;
evenodd[n_Integer?Positive] := Orange
evenodd[n_Integer /; Divisible[n, 4]] := Blue;
evenodd[0] := Red;

evenodd /@ Range[-5, 5]

All of this indicates that care should be taken when trying to define conditional rewrite rules.

Side note, this also shows that you could replace your definition using If with one using a Condition or a PatternTest.

I might be missing something. But:

Practical use of your code works as expected. What is the actual problem?

evenodd[n_Integer] := If[EvenQ[n], Black, White]
evenodd[0] := Red

Table[evenodd[i], {i, -3, 3}]

Colors.png