Group Abstract Group Abstract

Message Boards Message Boards

0
|
3.6K Views
|
5 Replies
|
1 Total Like
View groups...
Share
Share this post:

0 is integer, why can we use codes below?

Posted 3 years ago

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?

POSTED BY: Zhenyu Zeng
5 Replies
Posted 3 years ago

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}]

enter image description here

POSTED BY: Hans Milton
Posted 3 years ago

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.

POSTED BY: Eric Rimbey

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.

POSTED BY: Sander Huisman
Posted 3 years ago

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

evenodd[0]

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

POSTED BY: Zhenyu Zeng

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).

POSTED BY: Sander Huisman
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard