# Plus pattern matching quirkiness

Posted 10 years ago
4160 Views
|
2 Replies
|
3 Total Likes
|
 What is it about Plus that accounts for this behavior (note the middle (non)match)?  In[228]:= ClearAll[Bar];            x = Plus[Bar[1, 2], Bar[3, 4]];  In[230]:= MatchQ[x, Plus[_Bar, _]]  Out[230]= True   In[231]:= MatchQ[x, Plus[_Bar, _Bar]]  Out[231]= False   In[232]:= MatchQ[x, Plus[a_Bar, _Bar]] Out[232]= True I thought it might be something about the attributes: In[233]:= Attributes[Plus] Out[233]= {Flat, Listable, NumericFunction, OneIdentity, Orderless, Protected} especially having read the docs about Flat/OneIdentity. But with a dummy function of equivalent attributes:  In[234]:= ClearAll[Foo];            SetAttributes[Foo, Attributes[Plus]];            x = Foo[Bar[1, 2], Bar[3, 4]];   In[237]:= MatchQ[x, Foo[_Bar, _]]  Out[237]= True   In[238]:= MatchQ[x, Foo[_Bar, _Bar]]  Out[238]= True In[239]:= MatchQ[x, Foo[a_Bar, _Bar]] Out[239]= True
2 Replies
Sort By:
Posted 10 years ago
 The reason is that before doing the pattern match,  Plus[_Bar, _Bar] is transformed to 2*_Bar. Therefore you must prevent the evaluation of Plus, with HoldPattern:ClearAll[x, Bar];x = Plus[Bar[1, 2], Bar[3, 4]];MatchQ[x, HoldPattern[Plus[_Bar, _Bar]]]Hope that helps
Posted 10 years ago
 Yes, indeed HoldPattern is very useful. A classic example from documentation which I personally use quite a bitCases[{a -> b, c -> d}, HoldPattern[a -> _]]Out = {a -> b} versus Cases[{a -> b, c -> d}, a -> _]Out = {} the last one fails because Cases[e, patt->rhs] finds elements that match patt, and there is no patt (a) in the list.