5
$\begingroup$

I am new to OptionsPattern. Consider

ClearAll[r`f, n];
r`f[x1_, OptionsPattern[{n -> 100}]] := Module[{N},
  N = OptionValue@n;
  Print@{x1, OptionValue@n};
  ]
r`f[99, n -> "typeViolator!"]
(*{99,typeViolator!}*)

A simple function r'f is defined with an option nof default value 100. n is meant to be an int.

  1. As seen in the example, during invocation, n can be set to any type. How to ensure type safety while defining OptionsPattern? (something like n_Integer?)

  2. One had to ClearAll[n] before using it within OptionsPattern. Is there a way to avoid this i.e some better way to writing OptionsPattern without worrying about pre-definitions of its args?

  3. Note that my module speciically makes available n, as N. (Yes, it hides the in-built function N, but assume that in the present scenario, variable names like N,D,I etc are necessary within the module and don't lead to code conflicts). I was forced to do this as using

r`f[...,OptionsPattern[N->100,...]]:=Module[{N},
                       ^                     ^
                       |                     |
                       1                     2
OptionValue@N    

]

causes collision between the shown positions 1 and 2 rendering OptionValue@N useless. Also note that re-writing OptionsPattern@N within the module every time isn't feasible.
How does one define an OptionsPattern resembling OptionsPattern[{N_Integer->4,D_Integer->4}] while keeping all this and the above questions in mind ?

All clarifications are appreciated.

$\endgroup$
1
  • 3
    $\begingroup$ f[x_, opts: OptionsPattern[]] /; checkOpts[opts] := Module[..]? f[x_, opts: OptionsPattern[]] := With[{optvals = processOpts[opts]}, Module[..] /; FreeQ[optvals, $Failed]]? (Here, processOpts might construct an association of option values, so that optvals@n would yield the value.) $\endgroup$
    – Michael E2
    Dec 18 '20 at 22:53
1
$\begingroup$

Consider this alternative that more easily enforces type on n using two alternative definitions, the first one with the integer type, the second "default" one when n is not an integer, essentially similar to an error handler. You could also omit the second one and r`f would simply not evaluate when there is a type mismatch.

ClearAll[r`f, n];
r`f[x1_, n_Integer: 100] := {x1, n}
r`f[x1_, n_] := "mismatched option type!"

Let's try explicit values for both parameters:

r`f[3, 2]                  (* Out: {3, 2} *)

Now let's use the default value for n:

r`f[3]                     (* Out: {3, 100} *)

And finally a mismatch:

r`f[99, "typeViolator!"]   (* Out: "mismatched option type!" *)
$\endgroup$
2
  • $\begingroup$ this doesn't help...though thanks for illustrating overloading. The problem is I am using 10's of function arguments and really do want to redefine most into Options. Writing multiple overloaded forms for these many arguments isn't really practical $\endgroup$
    – lineage
    Dec 18 '20 at 20:33
  • $\begingroup$ @lineage I understand. However, as far as I know you may be forced to explicitly type-check those option values within your implementation function. Automated "type-checking" would be the main advantage of the multiple-definition approach. $\endgroup$
    – MarcoB
    Dec 18 '20 at 21:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.