# Define a function that returns a function with a variable number of arguments

Previously, I've defined a function with a variable number of arguments with the following method.

x = {x1, x2, x3};
f1 = Function[
Evaluate[x],
x + 1 //
Evaluate
];
f1 @@ x
Output: {1 + x1, 1 + x2, 1 + x3}


Also, I've defined a function that returned a function as follows.

g[x_] := Function[
{z},
x + z //
Evaluate
];
f2 = g @@ {z};
f2 @@ {x1}
Output: x1 + z


But when I attempt to put these ideas together, I have an issue. The hang-up seems to be in passing the argument of the first function to the argument of the second. Note that in our second example, above, we weren't passing x as an argument to the inner function. However, this is exactly what we want to do:

h[x_] := Function[
Evaluate[x],
x + 1 //
Evaluate
];
f3 = h @@ x;
f3 @@ x
Output: h[x1, x2, x3][x1, x2, x3]


The desired output is {1 + x1, 1 + x2, 1 + x3}. My motivation for writing such a function is to bury it in a package.

-
Very closely related question (may be even a duplicate). –  Leonid Shifrin May 7 '14 at 11:36

x = {x1, x2, x3};

h[x_] := Function[Evaluate[x], x + 1 // Evaluate];
f3 = h@x
f3 @@ x

(* {1 + x1, 1 + x2, 1 + x3} *)

-
thanks! Can you explain why this works? –  Rico Picone May 7 '14 at 4:59
@RicoPicone: When you Apply (@@), think of it as basically turning your list into the arguments to the function. So in your example, you're trying to apply a function of one argument to three, so since it doesn't match, it returns unevaluated. In your next step, you're applying that to the list, giving you the h[x1, x2, x3][x1, x2, x3] nonsense. By changing your first operation to just @ (function invocation), the whole list is passed as the argument, allowing a function of three arguments to be returned, so the following Apply matches it, presto. If not clear, comment! –  ciao May 7 '14 at 5:09
Thanks, that clears it up. I had always been unclear on the difference between @ and @@. –  Rico Picone May 7 '14 at 5:46
The problem with this solution is that it will leak evaluation in cases where x1, etc. have prior values. But the real problem is how the question is formulated, because it is rather hard to partially evaluate the input to a list of symbols but not further. Put another way, what is asked for is a macro rather than a function, but Mathematica has no read-time, and so writing this sort of macros is hard, since macro-expansion gets mixed with evaluation. –  Leonid Shifrin May 7 '14 at 11:47
@RicoPicone The biggest problem is that you store a list of variables in another variable. If you'd be fine with always supplying it explicitly, then the following modification of Rasher's solution would do: SetAttributes[h, HoldAll]; h[vars:{___Symbol}]:=Block[vars, Block[vars, Function @@ {vars, vars + 1}]]. If you want to store your variable list somewhere, the best thing to do is to store them in some HoldAll / HoldAllComplete-attributes-carrying container (e.g. Hold[]), and then redefine h to work as h[Hold[sym___Symbol]]:=.... Otherwise, it gets harder. –  Leonid Shifrin May 7 '14 at 19:51