I have a problem using optional arguments before an OptionsPattern:

Options[f] = {"Opt" -> None};
f[x_, y_:Automatic, OptionsPattern[]] := {x, y, OptionValue["Opt"]}
f[1, "Opt"->"wrong"] (* returns {1, "Opt" -> "wrong", None} *)

As you can see, mma assigns y the option rule, not Automatic!

What is the fix here?

This might be a known bug, as I remember encountering this type of thing before, or maybe I just forgot how to handle it?


Make the pattern explicitly not match:

Options[f] = {"Opt" -> None};
f[x_, y : Except[_?OptionQ] : Automatic, OptionsPattern[]] := {x, y, OptionValue["Opt"]}
f[1, "Opt" -> "wrong"]

I have to say, though, mixing both optional args and Options has always felt wrong to me. In my mind, optional arguments are the lazy-person's Options (although it is nice that they can do the pattern matching up front). Is there any reason not to make y an option?

| improve this answer | |
  • $\begingroup$ The only real problem with mixing options and optional arguments is when the optional argument might be a Rule, so I try to avoid that. I do view options as generally distinct from arguments with default values. Options should be for parameters that rarely need changed, and things that are tangential to what you are really doing. Arguments are more central to the task at hand. $\endgroup$ – Jason B. Feb 24 at 15:53
  • 1
    $\begingroup$ @JasonB. I'd say that the determining what is tangential and what is central to the task at hand is a pretty subjective call. So much so that I often find myself rewriting an interface to take only Options and required arguments after initially writing it to take optional args. For the most part I find myself wishing I had just made things options from the get-go. $\endgroup$ – b3m2a1 Feb 24 at 16:02
  • $\begingroup$ Obviously it's subjective, but I still think it's a meaningful distinction. $\endgroup$ – Jason B. Feb 24 at 16:23

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