2

If a function has e.g. 5 input arguments (a,b,c,d,e), how can I omit to specify only argument c, so that its default value is taken, but the other arguments should be passed to the function?

E.g:

f[a_:1,b_:2,c_:3,d_:4,e_:5]:=a+b+c+d+e;

Is something like the following call possible? What has to to be used at place of Default?

f[7,8,Default,9,10]
mrz
  • 11,686
  • 2
  • 25
  • 81

2 Answers2

7

Here's another way to do it, don't go for default values, but use Options instead.

ClearAll@f;
Options[f] = {"a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4, "e" -> 5};
f[OptionsPattern[]] := 
 OptionValue["a"] + OptionValue["b"] + OptionValue["c"] + 
  OptionValue["d"] + OptionValue["e"]
f["a" -> 7, "b" -> 8, "d" -> 9, "e" -> 10]
(* 37 *)
Jason B.
  • 68,381
  • 3
  • 139
  • 286
5

I doubt that this is possible natively (although I'd be happy to be corrected on that and will delete my answer in that case). You can sort of roll your own, with a bunch of definitions of f:

Clear[f, dflt];
f[dflt, b_, c_, d_, e_] := f[1, b, c, d, e]
f[a_, dflt, c_, d_, e_] := f[a, 2, c, d, e]
f[a_, b_, dflt, d_, e_] := f[a, b, 3, d, e]
f[a_, b_, c_, dflt, e_] := f[a, b, c, 4, e]
f[a_, b_, c_, d_, dflt] := f[a, b, c, d, 5]
f[a_, b_, c_, d_, e_] := a + b + c + d + e

f[7, 8, dflt, 9, 10]
(* 37 *)
7 + 8 + 3 + 9 + 10
(* 37 *)

This is only meant as a starting point.

One can generate these automatically from a given pattern and definition. Doing so in a completely general way might be quite an undertaking, but here is a solution which at least works if all patterns are simple Blanks and they all have a default value:

ClearAll[dflt, generateDefaults]
SetAttributes[generateDefaults, HoldAll]
generateDefaults[pattern_, result_] := 
  Module[{head = Head@pattern, args = List @@ pattern, defs, vals},
    defs = head @@ (args /. Verbatim@# -> dflt) & /@ args;
    vals = head @@ (args[[All, 1, 1]] /. #[[1, 1]] -> Last@#) & /@ args;
    MapThread[SetDelayed, {defs, vals}];
    pattern := result
  ]

This will also set default values on the individual definitions, such that omitting elements from the end also works.

As the answers on the duplicate mention, instead of dflt you could use Null which would allow you to omit the argument altogether and call the function like

f[7, 8, , 9, 10]
Martin Ender
  • 8,774
  • 1
  • 34
  • 60