# Is it impossible to implement “parameter self-referencing” in the function body?

(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]]]

• 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
• 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

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]


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.

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]


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


Also

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

f[]


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