# How to make a function from body with variable number of arguments?

Suppose I have an UNKNOWN function, which generates formulas with given number of x[i].

In[132]:= p[n_Integer] := (* some expression*) ;
p[10]

Out[]= (* some expression, containing x[1], x[2], ... , x[10] *)


Now, how can I regard generated output as a body for a Function with variable number of arguments and create that function?

In other words, I would like to write a function

In[163]:= pf[xs___] := Block[{n, rep, x},
n = Length[{xs}];
rep = Flatten[Table[{x[i - 1] -> {xs}[[i]]}, {i, 1, n}]];
p[n - 1] /. rep
];

pf[p]
Out[]= (*an expression where x[1] replaced for p*)

pf[p, q]
Out[]= (*an expression where x[1] replaced for p and x[2] replaced for q *)


but shorter.

Is it possible?

UPDATE

There is a function named Function, which does NEARLY what I need, but for constant expressions. May be it is possible to "unhold" it's arguments somehow, or somehow change evaluation order?

UPDATE 2

Required expression should contain p[] call, otherwise it is not a problem. The problem is that body of resulting function is generated by another function p[].

• Regarding the update, I doubt using Function[{...}, ...] can make your code shorter. Nov 24, 2014 at 14:54

If you don't like the ReplaceAll approach, you can do it with Block and Set:

Clear[f]
f[n_Integer] := {x[0], Array[x, n]}

Clear[fp]
fp[var__] :=
Block[{x},
MapIndexed[Set[x[#2[[1]] - 1], #1] &, {var}];
f[Length@{var} - 1]
]

f[3]
fp[a, c, 3, w]

{x[0], {x[1], x[2], x[3]}}

{a, {c, 3, w}}


In case you even don't like Length:

Clear[fp2]
fp2[var__] :=
Block[{x},
MapIndexed[(Set[x[#2[[1]] - 1], #1]; #2[[1]] - 1) &, {var}][[-1]] // f
]

fp2[a, c, 3, w]

{a, {c, 3, w}}