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

2 Answers 2

4
$\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$
2
  • $\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$ Commented Jan 14, 2014 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$ Commented Jan 14, 2014 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$
4
  • $\begingroup$ That's a lot of stuff I don't know yet :) Let's test it... $\endgroup$ Commented Jan 14, 2014 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$ Commented Jan 14, 2014 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$ Commented Jan 14, 2014 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$ Commented Jan 14, 2014 at 21:22

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.