I am building lots of functions that use Options
and OptionValue
and wanted to reduce the redundancy in the expressions that define the functions. I will show a tiny example, here, but please imagine that instead of a couple of options with names like a
and b
, my real examples have dozens of options with names like
blancmangeWithRaisinsAndPartiallyHydrogenatedChocolateSauce
and you will easily understand why I want to do what I want to do.
What do I want to do? My functions fit the following pattern:
The following defines the acceptable optional parameters for foo
: they are a
and b
, and they have default values 1 and 2, respectively. The acceptable options are defined separately from the body of the function. A caller may supply values for a
or b
or both or neither, using option syntax below.
ClearAll[foo];
Options[foo] = {"a" -> 1, "b" -> 2};
The following defines the body of the function. This function produces an association object with attributes corresponding to the values of the optional parameters.
foo[OptionsPattern[]] :=
<|"a" -> OptionValue["a"],
"b" -> OptionValue["b"]|>;
The following is a call that supplies only the optional value for a.
foo["a" -> 42]
<|"a" -> 42, "b" -> 2|>
The following is a call that supplies both a and b; notice that the order does not matter.
foo["b" -> 43, "a" -> 42]
<|"a" -> 42, "b" -> 43|>
The following is a call that supplies neither a nor b.
foo[]
<|"a" -> 1, "b" -> 2|>
I want to reduce the redundancy in the definition expression for foo
. I define a helper:
ClearAll[opt];
opt[nym_] := Rule[nym, OptionValue[nym]];
Hoping for a new style of definition for foo
:
foo[OptionsPattern[]] = <|opt["a"], opt["b"]|>
Notice that I used Set
and not SetDelayed
because I wanted the right-hand side to be evaluated at definition time, not at call time. But still no dice: foo
doesn't work any more
foo[]
<|"a" -> OptionValue["a"], "b" -> OptionValue["b"]|>
Its options are still in-force
Options[foo]
{a -> 1, b -> 2}
Why doesn't my little trick work? Why doesn't opt
rewrite in the context of the definiing expression for foo
?