This is an offshoot and extension of: Is it safe to turn off Pattern::patv?
Many built-in Mathematica functions allow flexible arguments. In user-defined functions I have been using Alternatives
for this purpose, but comments and answers to the question referenced indicate that this is at least nonstandard, and perhaps undesirable.
Let me define a dummy function foo
as an example.
Off[Pattern::patv]
p = {_?NumericQ, _?NumericQ};
foo[
{x : p ..} | x : p,
{y__} | y__,
ops : OptionsPattern[]
] /; Max[y] <= 10 := bar[#, y, ops] & /@ {x}
foo
accepts, in order:
p
, or a list of such objects.OptionsPattern[]
If any of these conditions are not met, foo[args]
is returned unevaluated.
The two pattern using Alternatives
(|
) are the most common cases, but they are not exclusive.
I struggle to see how foo
should best be implemented.
What is the canonical way to accomplish this?
What are its advantages over using Alternatives
?
Is it objectively easier to read?
I believe that there are three canonical ways of dealing with flexible arguments:
f[x_]
, f[{x : p ..}]
and f[x:p]
, where one calls the other, andf[{x : p ..} | x : p]
.The primary difference is where you deal with the added complexity of flexible arguments. Each can have its advantages.
The primary advantage of anything goes is simplicity in creating the acceptable patterns, but this leaves the processing to the internals of the function which increases its complexity. See the ErrorBarPlots .m
file for a good example of this. Ultimately, though, ErrorListPlot
relies on the second method hidden behind the facade of the first method.
The multiple forms method pushes the complexity onto the dispatcher in choosing the correct alternative. It has the simplest functional form as one form usually calls another form with the "correct" layout of the data. The difficulty with this method is the exponential growth of function specifications with the number of parameters with alternatives. This can be limited by adopting a hybrid approach, like that found in ErrorListPlot
.
Alternation has the most complex pattern form, and may require special processing to extract the alternatives similar to anything goes. Also, the patterns themselves can be more difficult to construct, and because of the potential for extra processing, this method should be used least often of the three. However, in some cases, like in your code, this method can be the most straightforward implementation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With