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 PatternTest
s, 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 Condition
s. 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 Condition
s have a much wider and more general use case than PatternTest
s. 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 PatternTest
s 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 PatternTest
s exist other than as a convenience. This is where a historian might be able to shine some light. If PatternTest
s were first implemented in Mathematica, then adding Condition
s 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?
PatternTest
thanCondition
. Although, for complex conditions,Condition
is superior. $\endgroup$