3
$\begingroup$

If I define, for example,

f[OptionsPattern[{}]] := OptionValue[a]

Then the output for f[a -> 1] is 1.

However, in my code, I have a function that must be called using the syntax f[some parameters][some other parameters], and I want to add options to the second set of square brackets. So I tried:

g[][OptionsPattern[{}]] := OptionValue[a]

But then, the output for g[][a -> 1] is OptionValue[a] instead of 1. I'm not sure why this is not working. Shouldn't OptionsPattern[{}] match any set of options, no matter where they are located?

How can I add options that can be provided in the second set of square brackets instead of the first?

$\endgroup$
4
  • 1
    $\begingroup$ I believe that this cannot be achieved. For the example you provided one could additionally define g[OptionsPattern[{}]] := OptionValue[a] and then g[][a -> 1] "works". I think it is generally advised to stay clear of SubValues (which g[x][y] implies). Is it possible to refactor the function? $\endgroup$
    – Natas
    Commented Jul 13, 2020 at 19:18
  • $\begingroup$ Unfortunately it would be impossible to avoid this syntax without rewriting the entire code from scratch. I'm considering simply "simulating" options by looking for explicit patterns in the form of option->value and then parsing the options manually. Is there any simple / built-in way to do so without using OptionsPattern[]? $\endgroup$
    – user73765
    Commented Jul 13, 2020 at 19:38
  • $\begingroup$ PS: What exactly are SubValues? $\endgroup$
    – user73765
    Commented Jul 13, 2020 at 20:19
  • $\begingroup$ Re SubValues have a look at Section 2.2.5 Composite variables and SubValues of Leonid Shifrin's excellent book. $\endgroup$
    – Natas
    Commented Jul 14, 2020 at 7:16

2 Answers 2

2
$\begingroup$

You can use the more explicit 3-argument form of OptionValue:

ClearAll[g];
Options[g] = {a -> 1};
g[][opts : OptionsPattern[]] := OptionValue[g, {opts}, a];
g[][]
g[][a -> 2]

1

2

Or:

ClearAll[g];
g[][opts : OptionsPattern[{}]] := OptionValue[{}, {opts}, a];
g[][a -> 2]

2

Or if you want default option values without defining options for g:

ClearAll[g];
With[{rules = {a -> 1}},
  g[][opts : OptionsPattern[rules]] := OptionValue[rules, {opts}, a]
];
g[][]
g[][a -> 2]

1

2

$\endgroup$
2
$\begingroup$

OptionsPattern apparently does not work for SubValues.

One possible solutions is to use an Association for option-like behavior

g[][opts_Association] := opts["a"]
g[][<|"a" -> 1|>]
(* 1 *)

Of course, if you desire the more complex features of options then this will not be too helpful (unless you want to re-implement all the features for this hack).

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.