1

My question is clarification for the question here Define function using variable list

With doing this

variables = {a, b};
f = Function[Evaluate@variables, 2 a + b];

I can define a function of the array of variables. Now, I would like to define a function f2 which is a function of the previous one. Just writing

f2 = Function[Evaluate@variables, f1@@variables -2*a];

doesn't work. What is correct syntax for defining f2? I want to call it like f2[1,2] (and get 2 as an answer, obviously).

Roman
  • 47,322
  • 2
  • 55
  • 121
user15933
  • 173
  • 7

5 Answers5

4

Just add another Evaluate in the function body:

variables = {a, b};
f1 = Function[Evaluate@variables, 2 a + b];
f2 = Function[Evaluate@variables, Evaluate[f1 @@ variables - 2*a]];
Roman
  • 47,322
  • 2
  • 55
  • 121
3

How about defining things directly:

f[{a_, b_}] := 2 a + b;
f2[{a_, b_}] := f[{a, b}] - 2 a;

then

f2[{1, 2}]
2

and

variables = {1, 2};
f2[variables]

gives the same answer.

bill s
  • 68,936
  • 4
  • 101
  • 191
2

Applying the method I recommended in my answer to the Question you referenced:

variables = {a, b};

f1 = Function[Evaluate@variables, 2 a + b];
f2 = variables /. _[vars__] :> Function[{vars}, f1[vars] - 2*a];

f2[1, 2]   (* Out[]= 2 *)

As in that answer I would encourage the use of variables = Hold[a, b]; for robustness, but I want to show that the /. _[vars__] :> form also works on a raw List in case that is a concern.

With the method above the created definition of f2 is Function[{a, b}, f1[a, b] - 2 a]. If instead you want full evaluation of the function body, and you don't need variable holding, you can do this instead:

Function @@ {variables, f1 @@ variables - 2*a}
Function[{a, b}, b]

Or:

Function @@ {#, f1 @@ # - 2*a} &[variables]
Function[{a, b}, b]
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
2

I'd like to use this question to promote the ResourceFunction ExpressionToFunction I submitted recently, which is specifically designed to facilitate the creation of Functions from all sorts of expressions and to allow you to call them in a variety of ways.

Sjoerd Smit
  • 23,370
  • 46
  • 75
  • Sjoerd Smit, Do you know if there is a functionality to achieve something like this Function[{{x1, x2}, {y1, y2}}, {x1 - y1, x2 - y2}] instead of Function[{x1, x2, y1, y2}, {x1 - y1, x2 - y2}]? – E. Chan-López Oct 13 '22 at 01:18
  • @E.Chan-López not with Function in that specific way. The closest thing would be ResourceFunction["ExpressionToFunction"][{x1 - y1, x2 - y2}, {x1, x2} -> 1, {y1, y2} -> 2]. – Sjoerd Smit Oct 13 '22 at 08:12
0

This works:

variables = {a, b}; 
f1 = Function[Evaluate@variables, 2 a + b]; 
f2 = With[{f1 = f1, v = variables}, 
           Function[Evaluate@v, (f1 @@ v) - 2*a]]
Rolf Mertig
  • 17,172
  • 1
  • 45
  • 76