5
$\begingroup$

I have a list of variables variables={a,b} and a list with values values={1,2}. I'd like to define a function using the variables in variables like so:

f=Function[variables,2a+b];

Then, I'd like to call it in a way like

result=f@@values  

or

result=f@@variables/.(Rule@@@Transpose@{variables,values})

or something similar.

Is there a way to create a function where the names of the variables are in a given list?

$\endgroup$
3
$\begingroup$

Taking the question at face value you merely need to add Evaluate:

variables = {a, b};
values = {1, 2};

f = Function[Evaluate @ variables, 2 a + b];
f @@ values
4

However, I recommend that you keep the Symbols in a Hold expression rather than a List to prevent unwanted evaluation. You will then need something like this to "inject" those values into the Function:

{a, b} = {"fail!", "fail!"}; (* prove it works even with a and b assigned *)

variables = Hold[a, b];
values = {1, 2};

f = variables /. _[vars__] :> Function[{vars}, 2 a + b];
f @@ values
4
$\endgroup$
  • $\begingroup$ Nice solution! I just got the solution of the other answer to work, so I won't change it now. What exactly is the pattern _[vars__]? (I suppose _[] matches the Hold[], and __ for the list of variables, because we want the whole list, not just one element.) $\endgroup$ – Ragnar Jan 14 '14 at 21:44
  • 1
    $\begingroup$ @Ragnar vars__ is a pattern that represents an arbitrary sequence of expression named vars (see BlankSequence in the docs) -- it matches a, b in Hold[a, b]. This sequence is then inserted in the place of vars on the right-hand-side of :> (SetDelayed), forming Function[{a, b}, . . .]. See this for another example. $\endgroup$ – Mr.Wizard Jan 14 '14 at 21:49
1
$\begingroup$

Perhaps something like this?

ClearAll[def];
Attributes[def]={HoldAll};
def[f_Symbol,vars_List,body_] := With[{x=vars}, f = Function[vars,body]];

used as follows:

def[f, {a, b}, a + b]

to define the function f:

f @@ {1, 2}

3

$\endgroup$
  • $\begingroup$ That's a lot of stuff I don't know yet :) Let's test it... $\endgroup$ – Ragnar Jan 14 '14 at 20:56
  • $\begingroup$ It works when I remove the HoldAll line. Otherwise, I can't use v={a,b} as the second argument, because it will still be interpreted as a symbol instead of a list of symbols. Thanks! $\endgroup$ – Ragnar Jan 14 '14 at 21:04
  • 1
    $\begingroup$ You can read the reply by Leonid Shifrin to this post: Pure Functions with Lists as arguments, which contains much better material than mine $\endgroup$ – user8074 Jan 14 '14 at 21:14
  • $\begingroup$ Thanks for the link, but I like your solution better, because it doesn't involve in-depth programming (and I have to show my code to my teachers, who wouldn't understand it easily I guess). Also, I changed HoldAll to HoldFirst, and added another definition, where f is not a symbol, which clears it before assignment. $\endgroup$ – Ragnar Jan 14 '14 at 21:22

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.