When you omit a parameter in the middle then Null
is passed. You can check for this, replace the value with a default value, and continue with the execution.
f[x_: "a", y_: "b", z_: "c"] := Module[{}, {x, y, z}]
As you already know, this gives you the standard default behaviour. You can omit parameters from the right. The use of Module
will become clear.
{f["i", "j"], f["i"], f[]}
(* {{"i", "j", "c"}, {"i", "b", "c"}, {"a", "b", "c"}} *)
We can add a sub-module that will check for the nulls and replace them.
ClearAll[f];
f[x_: "a", y_: "b", z_: "c"] :=
Module[{xi, yi, zi},
(* Default body *)
Module[{args = {x, y, z}, defaults = {"a", "b", "c"}},
MapIndexed[
Function[{item, index},
args[[First@index]] =
If[item === Null, defaults[[First@index]], item]], args, {1}];
{xi, yi, zi} = args;
];
(* Function body*)
{xi, yi, zi}
]
There is a duplication of the defaults in the submodule. We can't assign a value to the function parameter symbols so we have to change to some inner symbols {xi, yi, zi}
. However, it works as expected.
{f["i", "j"], f["i"], f[]}
(* {{"i", "j", "c"}, {"i", "b", "c"}, {"a", "b", "c"}} *)
f["i", , "k"]
(* {"i", "b", "k"} *)
This method should work for any combination of omitted parameters.
Hope this helps.