# How is OptionsPattern[] defined? Can I replicate this?

I am writing several functions which all take similar input parameters (a complicated nested list structure). Is there some way for me to define a pattern that can be used in multiple places and allows me to extract the individual parameters?

(I find OptionsPattern[] interesting because its definition isn't really visible but somehow OptionValues[] is able to extract information from it.)

-
Why not use Options then? –  rm -rf Nov 27 '12 at 21:51
I don't really want Options — specifying -> rules for each argument will be even messier than the current definition using named patterns like var_. I just want a way to decrease the number of times I have the whole argument list written out. –  jtbandes Nov 27 '12 at 21:54

## 2 Answers

One thing you can do is to create a strong type. I have described one way to do it here, and this is also described at length in the Roman Maeder's book "Programming in Mathematica" (which is the original reference).

One other thing which comes to mind is the following: you can name the pattern, and use the alias for it, for example as follows:

ptrn = {a_, b : {c_Integer, d_Integer}, e_}
f[pt : ptrn] := {a, b, c, d, e}


Then, you get

?f
Globalf
f[pt:{a_,b:{c_Integer,d_Integer},e_}]:={a,b,c,d,e}


So the function ends up being the same as if you used the full pattern directly. You can use it to check that:

f[{1,{2,3},4}]

(* {1,{2,3},2,3,4} *)


Even though this works, I would probably take the strong type route, since with the second option it is less obvious from the code which defines f what those letters stand for, and easier to make a mistake.

As for the OptionsPattern, it seems to be a rather magical construct. I gave a very schematic possible implementation here, but I am not proud of it. I think it is wired quite deeply and it is hard to implement it cleanly with the top-level code.

-
Thanks for the answer. Why did you use pt and b and not pt_ and b_? I was under the impression that pt : ptrn would just specify a default value; is something else happening here? –  jtbandes Nov 27 '12 at 23:07
@jtbandes : is used for both Pattern and Optional (search for : in the docs). You're thinking of the latter usage. A simple way to distinguish between the two is as follows: Pattern usage has the structure name : pattern whereas Optional usage has the structure pattern : value. So x : _foo is pattern and x_ : foo is optional. –  rm -rf Nov 28 '12 at 0:18
@jtbandes pt:ptrn represents the pattern object ptrn given the name pt. So ptrn defines the form of pt. –  image_doctor Nov 28 '12 at 0:19

Mathematica argument sequences are just expressions, so they can be named and referenced by name just like other expressions. Suppose you wanted use the fairly complicated argument pattern

argPattern =
Sequence[data : {Except[_Complex, _?NumberQ] ..},
lbls : {_String, _String} : {"", ""}];


as the formal argument list of more than one function, then all you need do is use the name argPattern in each function definition, like so:

stdPlot[argPattern] := ListPlot[data, AxesLabel -> lbls, Filling -> Axis]

logPlot[argPattern] := ListLogPlot[data, AxesLabel -> lbls, Filling -> Axis]


Both functions will accept arguments according to the pattern:

data1 = RandomReal[{0., 1.}, 10];
stdPlot[data1, {"n", "Output"}]


data2 = RandomInteger[{0, 10^5}, 10];
logPlot[data2, {"n", "Output"}]
`

-