# Surprising behavior when OptionsPattern is part of a larger pattern

Say we have a pattern defined as:

pattern = {foo[OptionsPattern[]] ...};


We can then use MatchQ to see whether an expression matches pattern, and some simple results work as I expect:

In[2]:= MatchQ[{foo[a -> b]}, pattern]
Out[2]= True

In[3]:= MatchQ[{foo[]}, pattern]
Out[3]= True

In[4]:= MatchQ[{foo[a -> b], foo[a -> b]}, pattern]
Out[4]= True


However, other things don't work as I'd expect:

In[5]:= MatchQ[{foo[a -> b], foo[]}, pattern]
Out[5]= False

In[6]:= MatchQ[{foo[a -> b], foo[a -> c]}, pattern]
Out[6]= False


As far as I can tell, different occurrences of OptionsPattern[] all have to match the same thing for the pattern as a whole to match, much like named patterns, where {x_, x_} will match {a, a}, but not {a, b}. However, there doesn't seem to be anything about this in the documentation, and it's hard to be certain that's what's going on.

FWIW, there's an easy workaround, where you use

pattern = {foo[___?OptionQ]...}


We can see that unlike {x_, x_} two occurrences of OptionsPattern[] do not need to have the same content:

pattern = {foo[OptionsPattern[]], foo[OptionsPattern[]]};

MatchQ[{foo[a -> b], foo[a -> c]}, pattern]

True


We can also see that Repeated can in some cases work with OptionsPattern[]:

MatchQ[
{foo[a -> b], foo[a -> c]},
{_[OptionsPattern[]] ..}
]

True

MatchQ[
{foo[a -> b], foo[]},
{_[OptionsPattern[]] ..}
]

True


Curiously this also works:

MatchQ[
{foo[a -> b], foo[a -> c]},
{foo[OptionsPattern[]], foo[OptionsPattern[]] ..}
]

True


I shall continue to explore this but it might be a bug in pattern matcher, or at least an edge case since this isn't the normal use of OptionsPattern.

• We also believe this might be a bug, and are investigating. – Stefan R May 6 '15 at 17:19
• @Stefan Thank you! – Mr.Wizard May 6 '15 at 22:25