This result is unexpected:
Trace[MatchQ[{7}, {_?NumberQ, __}], NumberQ] (* -> {{NumberQ[7], True}} *)
Why evaluate NumberQ
if the pattern can't conceivably match? What kind of side-effect might change the expression arity during pattern-matching?
Precisely, due to the unbound side-effects and for performance reasons, I would have thought that the matcher would labor very hard to avoid invoking the evaluator.
Note that other cases are not surprising:
Trace[MatchQ[{7}, {_?NumberQ, _}], NumberQ] (* -> {} *)
Trace[MatchQ[{7}, {_?NumberQ, ___}], NumberQ] (* -> {{NumberQ[7], True}} *)
The combination of a constraint and BlankSequence
seems to make the pattern-matcher overly suspicious. So, "a list of two expressions, first one a number" bypasses the evaluator; "a list of two or more expressions, first one a number" triggers the evaluation of the restriction.
Optimization of pattern-matching is unresolved in general. In the context of expressions in the form head + n parts, however, trying to calculate the lower bound of n for the class of expressions represented by a pattern strikes me as one of the obvious problems to focus on.
Given the experience of these last weeks, though, the struggle between my intuition and Mathematica is always won by the latter. What am I missing, then?
Update:
Mr.Wizard and Leonid Shifrin discussed a few years ago about the uneasy relation between the evaluator and the pattern-matcher.
{}
in both V9.0.0 and the development version (Mac OS X 10.7.5). So it must've been a bug in 9.0.1. $\endgroup$Trace[MatchQ[{7}, {_?NumberQ, __}], NumberQ]
, notTrace[MatchQ[{7}, {_?OddQ, __}], NumberQ]
. I corrected this in the question. $\endgroup$BlankSequence
/BlankNullSequence
confusion. $\endgroup$