2

(Moved from this post as @Kuba's comment.)

Purpose

Only set one formal parameter in the function definition (f[...]), which can be passed like a List to the function body.

Code

f[k1_: x, k2___] := Plot[k1, {x, 0, 10}, k2]

f[]
f[Sinc[x], ColorFunction -> "DarkRainbow", Axes -> False]

Question

How can I implement the following form (using k[[...]])?

f[k___ : x] := Plot[k[[1]], {x, 0, 10}, k[[2]]]
ooo
  • 564
  • 3
  • 11
  • 4
    I am not sure but shouldn't you wrap the Sequence k in {} in order to use Part? I mean something like f[k___ : x] := Plot[{k}[[1]], {x, 0, 10}, {k}[[2]]] . – Henrik Schumacher Mar 17 '18 at 10:37
  • 1
    Note the triple-underscore pattern k___ matches an empty sequence, such as the arguments of f[], so the default x in k___ : x is never used; I think you want two underscores k__ : x. In the single argument case, e.g., f[x^2], you cannot use k[[2]] or {k}[[2]]. – Michael E2 Mar 17 '18 at 13:18

4 Answers4

7

Here's one way, but not using Part (cannot use Part[.., 2] when the first argument has length 1):

ClearAll[f];
f[k__: x] := Plot[# &[k], {x, 0, 10}, Evaluate[##2 &[k]]]

Some alternatives:

ClearAll[f];
f[k__: x] := ReleaseHold@Insert[Hold[Plot[k]], {x, 0, 10}, {1, 2}]

ClearAll[f];
f[k__: x] := Plot[# &[k], {x, 0, 10}, Evaluate@Drop[{k}, 1]]    (* see note 3 *)

Notes:

  1. The triple-underscore pattern k___ matches an empty sequence, such as the arguments of f[], so the default x in k___ : x is never used. With two underscores k__ : x, the default x is used when the length of the argument sequence is less than 1.

  2. In the single argument case, e.g., f[x^2], the expressed desire to use k[[2]] would result in an error if the length of k is less than 2, even if {k}[[2]] were used.

  3. In the last alternative, one might apply Sequence to the result of Drop (Evaluate[Sequence @@ Drop[{k}, 1]]) to be more exact. Since Plot accepts a List of options, the code works as is in this use case. In another application, Sequence may be necessary.

Michael E2
  • 235,386
  • 17
  • 334
  • 747
3

Here is how we can use Part:

Clear[f]
f[k___] := f[{k}]
f[k_List] := With[{
   k1 = k[[1]],
   k2 = Quiet@Check[k[[2]], ## &[]]
   },
  Plot[k1, {x, 0, 10}, k2]
  ]

## &[] is the vanishing function. Example:

f[x]

Mathematica graphics

f[x, PlotStyle -> {Dashed, Red}]

Mathematica graphics

C. E.
  • 70,533
  • 6
  • 140
  • 264
2

Also

ClearAll[f];
f[k__: x] := Plot[{k}[[1]], {x, 0, 10}, Evaluate[Rest[{k}]]]

f[]

enter image description here

f[Sin[x], ColorFunction -> "Rainbow", Frame -> True]

enter image description here

kglr
  • 394,356
  • 18
  • 477
  • 896
1

It appears to me that you want the simplicity of Slot syntax combined with features of pattern-based function definitions, and your acceptance of Michael's answer seems to confirm this.

If so I suggest a different format that the one shown. I recommend passing all arguments to a single Function rather than using multiple Functions throughout your right-hand-side.

f[k__: x] := Plot[#, {x, 0, 10}, ##2] &[k]

f[]

f[Sinc[x], ColorFunction -> "DarkRainbow", Axes -> False]

enter image description here

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371