Function Repository Resource:

NameValuePattern

Source Notebook

Define a pattern expression for matching optional arguments with defaults

Contributed by: Nik Murzin

ResourceFunction["NameValuePattern"][a1_,a2_,,an_,b1_:def1,b2_:def2,,bn_:defn]

makes a pattern for required arguments a1,a2,,an and optional arguments b1,b2,,bnwith corresponding defaults defi.

Details

ResourceFunction["NameValuePattern"] matches a sequence of required arguments followed by optional arguments.
Absent optional arguments bind to their default values.
Required arguments are ordered, optional arguments are orderless.
Optional arguments may be specified either with Optional, Rule or RuleDelayed
Python users may recognize this pattern as *args and **kwargs.

Examples

Basic Examples (2) 

Construct a name-value pattern with one required argument and two optional ones:

In[1]:=
ResourceFunction["NameValuePattern"][a_, b_ : "B", c_ : "C"]
Out[1]=

Use NameValuePattern as any other pattern with functions like MatchQ or Replace:

In[2]:=
MatchQ[{1, "c" -> 3, "b" -> 2}, {ResourceFunction["NameValuePattern"][a_, b_ : "B", c_ : "C"]}]
Out[2]=
In[3]:=
Replace[{1, "c" -> 3, "b" -> 2}, {ResourceFunction["NameValuePattern"][a_, b_ : "B", c_ : "C"]} :> {a, b, c}]
Out[3]=

Scope (6) 

Use head patterns:

In[4]:=
Replace[{"b" -> 2., "a" -> 1}, {ResourceFunction["NameValuePattern"][a_Integer : 1, b_Real : "B"]} :> {a, b}]
Out[4]=

Arguments with no default values bind to Sequence[]:

In[5]:=
Replace[{1}, {ResourceFunction["NameValuePattern"][a_, b_., c_ : "C"]} :> HoldComplete[a, b, c]]
Out[5]=

Rule can be used instead of Optional (:) to specify optional arguments:

In[6]:=
Replace[{"b" -> 2, "a" -> 1}, {ResourceFunction["NameValuePattern"][a_, b_ -> "B"]} :> {a, b}]
Out[6]=

RuleDelayed can be used to delay default values:

In[7]:=
Replace[{"b" :> 1 + 1}, {ResourceFunction["NameValuePattern"][a_ :> Echo["A"], b_ : "B"]} :> Hold[a, b]]
Out[7]=

NameValuePattern matches the longest sequence:

In[8]:=
Replace[{"b" -> 2, "a" -> 1, "b" -> 3}, {ResourceFunction["NameValuePattern"][a_, b_ -> "B"], opts___} :> {a, b, {opts}}]
Out[8]=
In[9]:=
Replace[{1, "c" -> 3, "b" -> 2, "d" -> 4}, {ResourceFunction["NameValuePattern"][a_, b_ -> "B", c_ : "C"], opts___} :> {a, b, c, {opts}}]
Out[9]=

Bind to NameValuePattern as a sequence of arguments:

In[10]:=
Replace[{1, "c" -> 3, "b" -> 2, "k" -> 5}, {nvp : ResourceFunction["NameValuePattern"][a_, b_ : "B", c_ : "C"], opts___} :> {{nvp}, a, b, c, {opts}}]
Out[10]=

Applications (1) 

Define a function with flexible control over its arguments:

In[11]:=
compute[ResourceFunction["NameValuePattern"][x_, y_., f_ : Plus]] := f[x, y]
In[12]:=
compute[1]
Out[12]=
In[13]:=
compute[1, 2]
Out[13]=
In[14]:=
compute[2, 3, Power]
Out[14]=
In[15]:=
compute[4, "f" -> Factorial]
Out[15]=
In[16]:=
compute["f" -> Times, "x" -> 2, "y" -> 5]
Out[16]=

Properties and Relations (3) 

NameValuePattern can be used as an alternative to OptionsPattern:

In[17]:=
f[x_, OptionsPattern["a" -> 1]] := {x, OptionValue["a"]}
In[18]:=
f[7]
Out[18]=
In[19]:=
f[7, "a" -> 13]
Out[19]=
In[20]:=
g[ResourceFunction["NameValuePattern"][x_, a_ : 1]] := {x, a}
In[21]:=
g[7]
Out[21]=
In[22]:=
g[7, "a" -> 13]
Out[22]=

But it also allows specifying required arguments by name and in any order:

In[23]:=
g["a" -> 13, "x" -> 7]
Out[23]=

It can also be used at any depth:

In[24]:=
Replace[{{{"a" -> 13, "x" -> 7}}}, {{{ResourceFunction["NameValuePattern"][x_, a_ : 1]}}} :> {x, a}]
Out[24]=

Possible Issues (1) 

In certain situations rules can be interpreted literally:

In[25]:=
Replace[{1, "d" -> 4, "c" -> 3}, {ResourceFunction["NameValuePattern"][a_, b_ : "B", c_ : "C"]} :> Hold[a, b, c]]
Out[25]=
In[26]:=
Replace[{1, "d" -> 4}, {ResourceFunction["NameValuePattern"][a_, b_ : "B", c_ : "C"]} :> Hold[a, b, c]]
Out[26]=
In[27]:=
Replace[{1, "c" -> 3, 123}, {ResourceFunction["NameValuePattern"][a_, b_ : "B", c_ : "C"]} :> Hold[a, b, c]]
Out[27]=
In[28]:=
Replace[{1, "c" -> 2, "c" -> 3}, {ResourceFunction["NameValuePattern"][a_, b_ : "B", c_ : "C"]} :> Hold[a, b, c]]
Out[28]=
In[29]:=
Replace[{1, "a" -> 2, "c" -> 3}, {ResourceFunction["NameValuePattern"][a_, b_ : "B", c_ : "C"]} :> Hold[a, b, c]]
Out[29]=

Neat Examples (1) 

All of the expressions here match the same pattern with bindings of symbols to their corresponding defaults:

In[30]:=
With[{lhs = HoldForm@{ResourceFunction["NameValuePattern"][a_, b_., c_ -> "C", d_ -> "D"]}, rhs = {a, b, c, d}},
 Grid[{#, Replace[
       #,
       ReleaseHold@lhs :> rhs
       ]} & /@ {{1, 2, 3, 4}, {1}, {1, 2}, {1, "d" -> 40}, {1, 2, "c" -> 30}, {2, 1, "c" -> 30}, {1, 2, "d" -> 40}, {1, 2, "d" -> 40, "c" -> 30}, {1, "d" -> 40, "b" -> 20}, {"d" -> 40, "a" -> 10, "b" -> 20}} // Prepend[{lhs, rhs}], Alignment -> Left, Dividers -> {{False, True}, {False, True}}]
 ]
Out[30]=

Requirements

Wolfram Language 13.0 (December 2021) or above

Version History

  • 1.0.1 – 12 September 2023
  • 1.0.0 – 30 August 2023

Related Resources

License Information