1
$\begingroup$

A function is defined with named arguments. How can this function be converted to a pure function that uses slots (#). As a simple example, how can the following:

f[x_]:=2x

be converted to:

f=(2#) &;

I need to have a simple command for this conversion regardless of the expression of the function f. This has useful applications because sometimes when a module is defined in such a way that it only recognizes functions defined by unnamed arguments, then functions defined by named arguments won't be recognized properly. The problem I'd like to resolve is for instance: given non-pure functions f(x) and g(x), I need to turn f(g(x))=fg(x) into a pure function like fg[#].

$\endgroup$
4
  • 3
    $\begingroup$ h = f[#] & and h /@ {1, Sqrt[2], 3/2, 2.4, 2 + 4 I} gives {2, 2 Sqrt[2], 3, 4.8, 4 + 8 I}. $\endgroup$
    – Syed
    Commented Mar 12, 2023 at 5:04
  • $\begingroup$ many thanks for the helpful tip. The problem I'd like to resolve is for instance: given non-pure functions f(x) and g(x), I need to turn f(g(x))=fg(x) into a pure function like fg[#]. $\endgroup$
    – feynman
    Commented Mar 12, 2023 at 8:13
  • 4
    $\begingroup$ Are you looking for (f@*g)@x? Look up Composition. $\endgroup$
    – Syed
    Commented Mar 12, 2023 at 8:17
  • $\begingroup$ Similar to your other question, you could use fg = Evaluate[f[g[#]]] &, if using the evaluated expression f[g[#]] presents no problems. $\endgroup$
    – Michael E2
    Commented Mar 12, 2023 at 13:11

1 Answer 1

2
$\begingroup$

Simple way (but result depends on f and g):

fFN = f[#] &
fg = f[g[#]] &

Risky way (evaluates body of f and g but result is independent of them):

f = Evaluate[f[#]] &
fg = Evaluate[f[g[#]]] &

Complicated way that deals with arbitrarily many Pattern[v, Blank[]] arguments and does not evaluate the body of the function:

ClearAll[f, g];
f[x_] := 2 x;
g[x_, y_] := x^2 + a y^3;

singleDVToPureFunctionRule =
  {Verbatim[HoldPattern][
       _[x : Verbatim[Pattern][_, Blank[]] ..]
       ] :> 
     body_} :>
   (body & /.
     Thread[
      Thread[HoldPattern[{x}][[All, All, 1]]] -> 
       Array[Slot, Length@{x}]
      ]);

x = 9; y = -7; a = 3;
Replace[DownValues[f], singleDVToPureFunctionRule]
Replace[DownValues[g], singleDVToPureFunctionRule]
(*
  2 #1 &
  #1^2 + a #2^3 &
*)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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