I wanted to understand how Mathematica parses function definitions in rules-based programming, so I started with the simple code:
Clear[f];
f[x /; MatchQ[x, {_?NumericQ, _?NumericQ}]] := Total@x;
f[x_] := -1;
f[{1, 2.3}]
f[{4}]
As expected, the output is:
3.3
-1
Then I added another line:
Clear[f];
f[x /; MatchQ[x, {_?NumericQ, _?NumericQ}]] := Total@x;
f[x ;/ MatchQ[x, {_?NumericQ, 0}]] := (2 * x)[[1]];
f[x_] := -1;
f[{1, 2.3}]
f[{1, 0}]
f[{4}]
Interestingly, the output is now:
3.3
1
-1
So the second rule specification did not really override the first rule. But now, if I put that second rule before the first rule, like so:
Clear[f];
f[x ;/ MatchQ[x, {_?NumericQ, 0}]] := (2 * x)[[1]];
f[x /; MatchQ[x, {_?NumericQ, _?NumericQ}]] := Total@x;
f[x_] := -1;
f[{1, 2.3}]
f[{1, 0}]
f[{4}]
I get the expected output:
3.3
2
-1
So, I am guessing if I want multiple rules, I should put the more restrictive ones before the general ones. This way, Mathematica will be able to use the first match to execute the appropriate function. But now consider this:
Clear[f];
f[x_] := -1;
f[x /; MatchQ[x, {_?NumericQ, _?NumericQ}]] := Total@x;
f[x ;/ MatchQ[x, {_?NumericQ, 0}]] := (2 * x)[[1]];
f[{1, 2.3}]
f[{1, 0}]
f[{4}]
The most general rule is at the top, yet the output is:
3.3
2
-1
Can someone please explain why Mathematica didn't just see every input as matching f[x_] and simply return -1?
Thanks in advance.
x_is the least specific and{_?NumericQ, 0}is more specific than{_?NumericQ, _?NumericQ}because the latter contains a wildcard for the second argument whereas the first does not. – mfvonh Aug 27 '14 at 18:510pattern first or second. Hence my confusion. – Shredderroy Aug 27 '14 at 19:04x_/;blackbox1[x]andx_/;blackbox2[x]? – Simon Woods Aug 27 '14 at 20:18Needs["GeneralUtilities`"]; Information[GeneralUtilities`PatternOrder]– Michael E2 Aug 27 '14 at 21:24