2
$\begingroup$

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[].

$\endgroup$
  • 1
    $\begingroup$ Regarding the update, I doubt using Function[{...}, ...] can make your code shorter. $\endgroup$ – Silvia Nov 24 '14 at 14:54
1
$\begingroup$

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}}
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.