# How can I define an alias for OptionValue?

I want to define a function OV which acts as shorthand notation for OptionValue, so that I can use it as in

Options @ foo = {"a" -> 1};
foo[x_, OptionsPattern[]] := x + OV @ "a"


The naive definition of OV would be

OV[args___] := OptionValue[args]


The above, however, does not work as expected:

OV[args___] := OptionValue[args];
Options @ foo = {"a" -> 1};
foo[x_, OptionsPattern[]] := x + OV @ "a";
foo[x]
(* Out = x + OptionValue[a] *)


Tracing the evaluation of the above example and comparing with the regular usage of OptionValue quickly reveals where the problem lies:

OV[args___] := OptionValue[args];

Options@foo = {"a" -> 1};
foo[x_, OptionsPattern[]] := x + OV @ "a";

Options@foo2 = {"a" -> 1};
foo2[x_, OptionsPattern[]] := x + OptionValue @ "a";

Trace @ foo[x] // Column

Trace @ foo2[x] // Column


Now, this kind of non-standard evaluation is not news (see for example this question). However, from that questions I was left wondering if there is a way to define some kind of "alias" function for OptionValue. This nonstandard "macro-like" kind of evaluation makes it not trivial to me how to do it in general.

• You can always force that in with a With, if you're willing to do that. And then maybe define a package level macro that's like withMyHooks which hooks in lots of stuff like that implements an UpValues hook on SetDelayed so you can use it like withMyHooks@lhs:=rhs and it'll unwrap to With[{...}, lhs:=rhs]. Aug 3 '17 at 17:47
• @b3m2a1 I may be getting what you are saying, but maybe not. It looks like an interesting solution, care to make it into an answer? :)
– glS
Aug 3 '17 at 17:49
• Sure. Give me a moment. Aug 3 '17 at 17:50

So it took some finagling to get the replacement to be as nicely extensible as I wanted it, but this should work for you. Basically we define a set of replacements that we can change however we like ($myHooks) and a function that will inject them, using With (withMyHooks). Then stick an UpValue on that to determine if it's being used on the lhs of a function assignment, and if it is to expand to wrap on the whole assignment. Of course, that's a long description for a little bit of code: $myHooks =
HoldComplete@
{
OV = OptionValue,
OP = OptionsPattern
(*other hooks*)
};

withMyHooks // ClearAll;
withMyHooks[e_] :=
Replace[\$myHooks,
HoldComplete[l_] :>
With[l, e]
];
withMyHooks~SetAttributes~HoldAllComplete;
withMyHooks /:
HoldPattern[SetDelayed[withMyHooks[lhs : _[___]], rhs_]] :=

withMyHooks[lhs := rhs]


Then we'll use this on a function:

myF // Clear
withMyHooks@
myF[OP[Plot]] :=
OV[PlotRange]

myF[]

{Full, Automatic}

myF[PlotRange -> 1]

1


And it works as we want it to, because it just turned OV and OP into shortened forms.

• very interesting, and may be useful in some circumstances. However having to wrap all expressions with withMyHooks often kind of defeats the purpose of shortening the function name. Is there now way to avoid having to manually wrap all expressions in which we want to use the shorthand notation?
– glS
Aug 4 '17 at 10:49

In your program you can replace "a" by a to make it more general. As Mathematica is symbolic, you don't need to quote symbols.

Replacing x by OptionValue@x or even OV@x in a complex expression may make it unreadable.

I suspect you would actually like to get rid completely of OptionValue. Do this:

Options@foo = {a -> 1};
foo[x_, options___Rule] := x + a /. {options} /. Options@foo


It was the standard way of handling options before Mathematica v6.

• how does replacing "a" with a make it more general? It would argue it makes the code more prone to error, as for example if a has a DownValue before Options@foo={a->1} is used the options will not be set correctly
– glS
Mar 21 '20 at 18:11
• The symbol acan represent anything, including, in particular "a". The converse is not true. Consequently, indeed, you have to keep you symbols clean or protect them. Mar 21 '20 at 22:26
• This is how to protect: foo[x_, options___Rule] := ReleaseHold[Hold[x + a] /. {options} /. Options@foo]. Quote is poor man's Hold but finally it is good too. However, it obliges you to write "a" which looks strange in formulae. So if you want naked a you will follow me. Mar 21 '20 at 22:35
• The procedure is equivalent to With that was pointed out above. Usually I begin with With[{a=_},f[a]] and if I need I turn on the option system . The With for "private" parameter, the option system for "public" parameter. Finally option is a way to publish attributes of the expression. Mar 22 '20 at 10:53
• the fact that "a can represent anything" does not mean that the expressions using a and "a" are equivalent. I personally find it much easier to use strings rather than having to protect all the symbols used in the options.
– glS
Mar 22 '20 at 10:58