I am trying to call a function f, that has either 1 or 2 (or multiple) parameters, from a function g that uses optional arguments

Clear[f, g]

f[x_] := "foo"
f[x_, y_] := {x, y}

Options[g] = {"y" -> 5};
g[m_, OptionsPattern[]] := f[3*m, OptionValue["y"]]

g[2] (* {6,5} *)
g[2, "y" -> -6] (* {6,-6}*)

I want be able call f with 1 parameter from g to get

g[2, "y"->someMagicMethod] = "foo"

I have tried

g[2, "y" -> Blank[]] (* {6,_} *)
g[2, "y" -> Nothing] (* {6} *)
g[2, "y" -> None] (* {6,None} *)
g[2, "y" -> Null] (* {6,Null} *)
g[2, "y" -> Identity] (* {6,Identity} *)

Possible Solution

An idea is to place the arguments into a list and take advantage of the fact that Nothing disappears when in a list and then using Apply

Options[g2] = {"y" -> 5};
g2[m_, OptionsPattern[]] := f@@{3*m, OptionValue["y"]}; (* arguments in a list *)

g2[6, "y" -> Nothing] (* "foo" *)

I'm not sure that this is the best method as you need to ensure that the list is ordered correctly before applying f.

Is there a more general solution that scales well with f or g increasing in complexity of arguments / optional values?

Am I missing a better "Option" way to set up g using FilterRules etc. or patterns ?

  • $\begingroup$ @HighPerformanceMark Not sure if this helps but the actual case I am working on is where f is an inbuilt function, FindClusters. I have a function g that calls FindClusters[data,n] but sometimes wants to call it with FindClusters[data]. $\endgroup$ Sep 7 '21 at 11:38
  • $\begingroup$ @HighPerformanceMark I think that is the issue I am trying to solve? i.e How to get g to pick between the two versions of f. PS :I fixed a typo, not sure if that helps? $\endgroup$ Sep 7 '21 at 13:53
  • 1
    $\begingroup$ Just checking, are you confusing optional arguments (see Optional, denoted by e.g. x_:default or x : patt : default) with Options? you're calling options "optional arguments" and wanted to make sure this was simply casual usage rather than an indication you were conflating them :) $\endgroup$
    – thorimur
    Sep 7 '21 at 21:07
  • 3
    $\begingroup$ Also, with your function as-is, I believe you're looking for "y" -> Sequence[] :) A more robust version though might ask for a special token, e.g. Automatic, and then check the option value (e.g. If[OptionValue["y"] === Automatic, f[x], f[x, OptionValue["y"]]) $\endgroup$
    – thorimur
    Sep 7 '21 at 21:08
  • $\begingroup$ @thorimur thanks for your feedback the functions I am looking at in real life both use Optional and have default arguments, I don't think I have conflated the two., ie optional arguments refers to Options. Your comment on Sequence looks like it might the right thing I am looking for? Would it be possible to submit an answer please? $\endgroup$ Sep 8 '21 at 8:35