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. $\endgroup$0
pattern first or second. Hence my confusion. $\endgroup$x_/;blackbox1[x]
andx_/;blackbox2[x]
? $\endgroup$Needs["GeneralUtilities`"]; Information[GeneralUtilities`PatternOrder]
$\endgroup$