11
$\begingroup$

If you define a function g, like so:

g[x_?EvenQ] := "even"    
g[x_?NumberQ] := "number"

why will Mathematica always return g[2] == "Even", even though NumberQ[2] == True?

More specifically, is there a defined order in which Mathematica will try to match function cases? Does it evaluate the most specific match first?

$\endgroup$
5
  • $\begingroup$ g[x_NumberQ] means to match arguments with the head NumberQ. What you want is to match arguments such that NumberQ[x] is True, which is g[x_?NumberQ]. Look up PatternTest[]. (Before you make this correction, make sure to run Clear[g] first.) $\endgroup$ Feb 27, 2019 at 0:47
  • $\begingroup$ That's right---fixed. $\endgroup$
    – wgoodall01
    Feb 27, 2019 at 0:49
  • 3
    $\begingroup$ Once you have made this fix, evaluate DownValues[g]; that should give a hint as to which case gets applied first. Generally, it tries to put special cases first before general ones. $\endgroup$ Feb 27, 2019 at 0:51
  • $\begingroup$ Or just execute ?g to see the order of the definitions. $\endgroup$
    – Roman
    Feb 27, 2019 at 2:04
  • 1
    $\begingroup$ At least closely related: How is pattern specificity decided? Ask $\endgroup$
    – Kuba
    Jun 9, 2020 at 5:52

1 Answer 1

15
$\begingroup$

The Ordering Of Definitions

  • ... The Wolfram System follows the principle of trying to put more general definitions after more specific ones. This means that special cases of rules are typically tried before more general cases.
  • Although in many practical cases, the Wolfram System can recognize when one rule is more general than another, you should realize that this is not always possible. For example, if two rules both contain complicated /; conditions, it may not be possible to work out which is more general, and, in fact, there may not be a definite ordering. Whenever the appropriate ordering is not clear, the Wolfram System stores rules in the order you give them.

ClearAll[g]
g[x_?EvenQ] := "even"
g[x_?NumberQ] := "number"
g /@ {1, 2}

{"number", "even"}

ClearAll[h]
h[x_?NumberQ] := "number"
h[x_?EvenQ] := "even"
h /@ {1, 2}

{"number", "number"}

$\endgroup$
2
  • $\begingroup$ Your link seems to be out of date. I believe this is the new one: reference.wolfram.com/language/tutorial/… $\endgroup$
    – Ivan
    Jun 9, 2020 at 5:08
  • $\begingroup$ Thank you @IvanMartinez. Updated with the correct url. $\endgroup$
    – kglr
    Jun 9, 2020 at 5:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.