My last question to the site resulted in several answers that involve using pattern matching in Mathematica, a feature I wasn't very familiar with at the time. I am currently reading Mathematica Navigator and am picking up a bit on patterns. Very powerful stuff! My question may not have a definite answer, but I am curious.
When performing pattern matching there are two ways that I see that seem to provide very similar functionality. First there are PatternTests, such as the following:
(* Replace all items in list that fall in the interval [0, 1] with 1 * using a PatternTest *) {1, 2, 3, 0.4, 0} /. x_?(0 <= # <= 1 &) -> 1 The PatternTest being the true/false test within the parenthesis after the question mark. Alternatively there are Conditions. Here I accomplish the same as the above but with a Condition:
(* Replace all items in list that fall in the interval [0, 1] with 1 * using a Condition *) {1, 2, 3, 0.4, 0} /. x_ /; 0 <= x <= 1 -> 1 Here the Condition is the same true/false test after the /; operator. I [mostly] understand how these work, but I am curious why both of these exist. I can see why one method would be preferable in some conditions while the other would be preferable in other conditions. For instance, a PatternTest seems to be preferable in situations where a simple test is involved:
f[x_Integer?EvenQ] := x+1 And a Condition seems preferable when a more complex condition is required:
f[x_Integer /; EvenQ[x] && Positive[x]] := x+1 Is this the only justification for having both operators? Are there additional details behind-the-scenes that should influence my decision of which one to use or is it purely a matter of preference?
As a bonus, are there any old timers that can give the history of these two methods of pattern matching? I.e, which of these two operators was implemented first in Mathematica?
EDIT
From the answers that have been posted so far, it appears that Conditions have a much wider and more general use case than PatternTests. I wonder if it would be correct to say that the use cases for PatternTest are a subset of the use cases for Condition, and hence PatternTests are merely a syntactic sugar of sorts and is more or less redundant (although still helpful and preferable is some circumstances.) This still begs the question of why PatternTests exist other than as a convenience. This is where a historian might be able to shine some light. If PatternTests were first implemented in Mathematica, then adding Conditions in a later version would add flexibility to the language. However, if the Condition shorthand syntax was first implemented, then was the PatternTest syntax later implemented as a shorthand convenience operator?
PatternTestthanCondition. Although, for complex conditions,Conditionis superior. $\endgroup$