1
$\begingroup$

This code:

In[76]:= Trace[MatchQ[{1,2,3}, {_?NumberQ}]]

gives:

Out[76]= {MatchQ[{1,2,3},{_?NumberQ}],False}


This code:

In[77]:= Trace[MatchQ[{1,2,3}, {__?NumberQ}]]

gives:

Out[77]= {MatchQ[{1,2,3},{__?NumberQ}],{NumberQ[1],True},{NumberQ[2],True},{NumberQ[3],True},True}


Question:

Why does _?NumberQ just gives False but __?NumberQ make actual comparrision {NumberQ[1],True},{NumberQ[2],True},{NumberQ[3],True}?

$\endgroup$

closed as off-topic by Daniel Lichtblau, Henrik Schumacher, m_goldberg, Edmund, eyorble Sep 18 '18 at 4:34

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "This question arises due to a simple mistake such as a trivial syntax error, incorrect capitalization, spelling mistake, or other typographical error and is unlikely to help any future visitors, or else it is easily found in the documentation." – Daniel Lichtblau, Henrik Schumacher, m_goldberg, Edmund, eyorble
If this question can be reworded to fit the rules in the help center, please edit the question.

  • $\begingroup$ Which one is that you find surprising? {1,2,3} does not match {_} so further tests do not make sense. $\endgroup$ – Kuba Sep 17 '18 at 13:31
  • $\begingroup$ @Kuba Trace[] just gives False. Why Trace[] does not shows that MatchQ tries to match but it did not match? Something like: {MatchQ[{1,2,3},{_?NumberQ}],{NumberQ[{1,2,3}],False},False}? $\endgroup$ – vasili111 Sep 17 '18 at 13:40
  • 1
    $\begingroup$ No, not just False, MatchQ[{1, 2, 3}, {_?NumberQ}] too. and already this step fails because {1,2,3} is not a list of one element as {_} indicates. Compare with Trace[MatchQ[{1, 2, 3}, _?NumberQ]] $\endgroup$ – Kuba Sep 17 '18 at 13:42
  • $\begingroup$ @Kuba. So {_} is for the list of 1 element, {__} is for any number of elements but not empty list, {___} is for any number of elements including empty list. Is it right? $\endgroup$ – vasili111 Sep 17 '18 at 13:59
  • 1
    $\begingroup$ Yes, check documentation examples in Blank, BlankSequence, BlankNullSequence $\endgroup$ – Kuba Sep 17 '18 at 14:08
2
$\begingroup$

Kubas and Sjoerd Smits comments helped to get the answer

_ matches any valid expression while __ matches a sequence of expressions. However, a sequence of expressions is not actually a valid expression, so _ does not match sequences. That's why 1, 2, 3 in {1,2,3} does not get matched by _.

{_}is for the list of 1 element but not the sequence of elements, {__} is for a list with any number of elements but not the empty list (0 elements), {___} is for any number of elements including empty list.

Here is some code that can help to understand how exactly pattern matching works in MatchQ:

In[108]:= Trace[MatchQ[FullForm[1],FullForm[_?NumberQ]]]

Out[108]= {MatchQ[1,PatternTest[Blank[],NumberQ]],{NumberQ1,True},True}

In[109]:= Trace[MatchQ[FullForm[1],FullForm[{_?NumberQ}]]]

Out[109]= {MatchQ[1,List[PatternTest[Blank[],NumberQ]]],False}

In[101]:= Trace[MatchQ[FullForm[{1}],FullForm[_?NumberQ]]]

Out[101]= {MatchQ[List1,PatternTest[Blank[],NumberQ]],{NumberQ[{1}],False},False}

In[102]:= Trace[MatchQ[FullForm[{1}],FullForm[{_?NumberQ}]]]

Out[102]= {MatchQ[List1,List[PatternTest[Blank[],NumberQ]]],{NumberQ1,True},True}

In[103]:= Trace[MatchQ[FullForm[{1,2,3}],FullForm[_?NumberQ]]]

Out[103]= {MatchQ[List[1,2,3],PatternTest[Blank[],NumberQ]],{NumberQ[{1,2,3}],False},False}

In[110]:= Trace[MatchQ[FullForm[{1,2,3}],FullForm[{_?NumberQ}]]]

Out[110]= {MatchQ[List[1,2,3],List[PatternTest[Blank[],NumberQ]]],False}

In[104]:= Trace[MatchQ[FullForm[{1}],FullForm[__?NumberQ]]]

Out[104]= {MatchQ[List1,PatternTest[BlankSequence[],NumberQ]],{NumberQ[{1}],False},False}

In[105]:= Trace[MatchQ[FullForm[{1}],FullForm[{__?NumberQ}]]]

Out[105]= {MatchQ[List1,List[PatternTest[BlankSequence[],NumberQ]]],{NumberQ1,True},True}

In[96]:= Trace[MatchQ[FullForm[{1,2,3}],FullForm[__?NumberQ]]]

Out[96]= {MatchQ[List[1,2,3],PatternTest[BlankSequence[],NumberQ]],{NumberQ[{1,2,3}],False},False}

In[97]:= Trace[MatchQ[FullForm[{1,2,3}],FullForm[{__?NumberQ}]]]

Out[97]= {MatchQ[List[1,2,3],List[PatternTest[BlankSequence[],NumberQ]]],{NumberQ1,True},{NumberQ2,True},{NumberQ[3],True},True}

In[106]:= Trace[MatchQ[FullForm[{1}],FullForm[___?NumberQ]]]

Out[106]= {MatchQ[List1,PatternTest[BlankNullSequence[],NumberQ]],{NumberQ[{1}],False},False}

In[107]:= Trace[MatchQ[FullForm[{1}],FullForm[{___?NumberQ}]]]

Out[107]= {MatchQ[List1,List[PatternTest[BlankNullSequence[],NumberQ]]],{NumberQ1,True},True}

In[98]:= Trace[MatchQ[FullForm[{1,2,3}],FullForm[___?NumberQ]]]

Out[98]= {MatchQ[List[1,2,3],PatternTest[BlankNullSequence[],NumberQ]],{NumberQ[{1,2,3}],False},False}

In[99]:= Trace[MatchQ[FullForm[{1,2,3}],FullForm[{___?NumberQ}]]]

Out[99]= {MatchQ[List[1,2,3],List[PatternTest[BlankNullSequence[],NumberQ]]],{NumberQ1,True},{NumberQ2,True},{NumberQ[3],True},True}

$\endgroup$
  • $\begingroup$ I am not sure I understand the problem. Isn't documentation clear about _, __, ___? $\endgroup$ – Kuba Sep 17 '18 at 14:37
  • $\begingroup$ @Kuba From the documentation I read "_ or Blank[] is a pattern object that can stand for any Wolfram Language expression." I understand "any Wolfram Language expression" as _ equal{_} because I understand it as any kind of list any kind of number or any kind of other expression. $\endgroup$ – vasili111 Sep 17 '18 at 14:48
  • 2
    $\begingroup$ Yes _ matches {whatever} but you had {_} and wanted it to match {1,2,3}. Which is a different thing. $\endgroup$ – Kuba Sep 17 '18 at 14:53
  • 1
    $\begingroup$ @Kuba Indeed. The thing to understand here is that _ matches any valid expression while __ matches a sequence of expressions. However, a sequence of expressions is not actually a valid expression, so _ does not match sequences. That's why 1, 2, 3 in {1,2,3} does not get matched by _ $\endgroup$ – Sjoerd Smit Sep 18 '18 at 9:43

Not the answer you're looking for? Browse other questions tagged or ask your own question.