How to easily match a list of symbols?

Say you have a function with an argument that should be a 1-dimensional list of pure symbols. How to setup this argument in an easy way?

f[x_, syms_List] := ...

is not enough since f would accept any list.

With other words: What is a simple pattern for a list of symbols (or integers or anything else)? What if it should match a table (2-dimensional) with symbols only?

Werner,

You can do this:

In[13]:= mi[list_] := yes /; VectorQ[list, IntegerQ]

In[25]:= mi[{1, 2, 3, 4, 5}]

Out[25]= yes

In[15]:= mi[{1, 2, 3, 4, 5, t}]

Out[15]= mi[{1, 2, 3, 4, 5, t}]

In[21]:= 
mi[list_] := yes /; VectorQ[list, IntegerQ[#] || Head[#] == Symbol &]

In[22]:= mi[{1, 2, 3, 4, 5, t}]

Out[22]= yes

In[23]:= 
mi[list_] := yes /; VectorQ[list, IntegerQ[#] || MatchQ[#, _Symbol] &]

In[24]:= mi[{1, 2, 3, 4, 5, t}]

Out[24]= yes

Also works with ArrayQ for 2 dimensions. See some other good examples here and look at putting constraints on patterns.

Regards,

Neil

In addition to the approach shown by Neil Singer, one might use Repeated for this task. The examples below should give the main idea.

In[23]:= MatchQ[{a, b, v}, {_Symbol ..}]

(* Out[23]= True *)

In[24]:= MatchQ[{a, b, v, 3}, {_Symbol ..}]

(* Out[24]= False *)

In[25]:= MatchQ[{a, b, v, 3}, {(_Symbol | _Integer) ..}]

(* Out[25]= True *)

Thanks Neil & Daniel. Those solutions are not really “easy” and not really easy to read, but they work. BTW: I think putting the constraints after the body end is less readable then putting them directly into the “function declaration”.

Hence I will write according to Neil:

ClearAll[f, x, a, b];
f[x_, syms_List /; VectorQ[syms, Head[#] == Symbol &]] := 
  Style[x*syms, Red];
{f[2, 3], f[2, a], f[2, {a, 4}], f[2, {a, b}]}

= {f[2,3],f[2,a],f[2,{a,4}],{2 a,2 b}}

or Daniel’s proposal, which is a bit shorter but perhaps less readable:

ClearAll[f, x, a, b];
f[x_, syms_List /; MatchQ[syms, {_Symbol ..}]] := Style[x*syms, Red];
{f[2, 3], f[2, a], f[2, {a, 4}], f[2, {a, b}]}

={f[2,3],f[2,a],f[2,{a,4}],{2 a,2 b}}

Extending those constarints to anything else is clear.

You can incorporate the pattern from Danny’s code without using a Condition like

f[x_, syms:{_Symbol ..}] := ...

although in this case I would use a BlankSequence rather than Repeated:

f[x_, syms:{__Symbol}] := ...

Great! It gets nicer and nicer.