Function Repository Resource:

ExpandPureFunction

Source Notebook

Apply FunctionExpand to pure functions while preserving symbolic parameters

Contributed by: E. Chan-López & Sjoerd Smit

ResourceFunction["ExpandPureFunction"][Function[var,body]]

applies FunctionExpand to the body of the pure function.

ResourceFunction["ExpandPureFunction"][Function[{var1,},body]]

applies FunctionExpand within a multivariable pure function.

ResourceFunction["ExpandPureFunction"][f,var]

specifies var as the input variable.

ResourceFunction["ExpandPureFunction"][f,{var1,}]

specifies multiple variables.

Details and Options

ResourceFunction["ExpandPureFunction"] automatically detects the function variables.
ResourceFunction["ExpandPureFunction"] is analogous to FunctionExpand but operates directly on pure Function expressions, returning a new Function with the expanded body.
ResourceFunction["ExpandPureFunction"] uses Block to temporarily shield symbols that have global OwnValues from evaluation during the expansion process. This ensures that parameters like a in Function[x,a*x*Gamma[x]] are preserved symbolically.
User-defined functions (those with DownValues but no OwnValues) are allowed to evaluate during expansion. This is by design: only direct variable assignments are blocked.
ResourceFunction["ExpandPureFunction"] takes the same options as FunctionExpand, including Assumptions.
The 1-argument form ResourceFunction["ExpandPureFunction"][Function[var,body]] automatically detects the declared variables from the Function header.
For slot-based functions (Function[body] with #1,#2,), the variables must be supplied explicitly via the second argument.
ResourceFunction["ExpandPureFunction"] relies on the resource function ExpressionToFunction to reconstruct the output function with proper variable handling.

Examples

Basic Examples (4) 

Use ExpandPureFunction to expand a function involving Gamma:

In[1]:=
ResourceFunction["ExpandPureFunction"][Function[x, x Gamma[x]], x]
Out[1]=

Use the 1-argument form with automatic variable detection:

In[2]:=
ResourceFunction["ExpandPureFunction"][Function[x, x Gamma[x]]]
Out[2]=

Expand a ChebyshevT polynomial inside a Function:

In[3]:=
ResourceFunction["ExpandPureFunction"][Function[x, ChebyshevT[n, x]],
  x]
Out[3]=

Expand a trigonometric composition:

In[4]:=
ResourceFunction["ExpandPureFunction"][Function[x, Sin[2 ArcTan[x]]],
  x]
Out[4]=

Scope (4) 

ExpandPureFunction preserves symbolic parameters that have global values. Here, a has a global assignment but is correctly kept symbolic in the output:

In[5]:=
a = 1;
ResourceFunction["ExpandPureFunction"][Function[x, a*x Gamma[x]], x]
Out[6]=

User-defined functions (with DownValues) are expanded, while symbolic parameters (with OwnValues) are preserved:

In[7]:=
xGammax[x_] := x Gamma[x];
ResourceFunction["ExpandPureFunction"][Function[x, a*xGammax[x]], x]
Out[8]=

Expand a multivariable pure function with named variables:

In[9]:=
ResourceFunction["ExpandPureFunction"][
 Function[{x, y}, a*x Gamma[x] + y*(y + 1) Gamma[y]]]
Out[9]=

Expand a slot-based Function by supplying explicit variable names:

In[10]:=
ResourceFunction["ExpandPureFunction"][
 Function[a*#1 Gamma[#1] + #2*(#2 + 1) Gamma[#2]], {x, y}]
Out[10]=

Options (2) 

Use ExpandPureFunction with Assumptions to simplify ProductLog:

In[11]:=
ResourceFunction["ExpandPureFunction"][
 Function[x, ProductLog[x Log[x]]], x, Assumptions -> x > 1/E]
Out[11]=

Use Assumptions with BesselK and an integer parameter:

In[12]:=
ResourceFunction["ExpandPureFunction"][
 Function[\[Nu], BesselK[\[Nu], -x]], \[Nu], Assumptions -> \[Nu] \[Element] Integers]
Out[12]=

Applications (5) 

Define a pure function that computes the regularized incomplete Beta function and expand it to reveal its representation in terms of the incomplete Beta and Gamma functions:

In[13]:=
ResourceFunction["ExpandPureFunction"][
 Function[{x, a, b}, BetaRegularized[x, a, b]]]
Out[13]=

Expand the Sinc function (normalized Sin[x]/x) inside a pure function. FunctionExpand reduces it to its piecewise-free trigonometric form:

In[14]:=
ResourceFunction["ExpandPureFunction"][Function[x, Sinc[x]], x]
Out[14]=

Use ExpandPureFunction to expand the Struve function StruveH in terms of Bessel functions and elementary expressions:

In[15]:=
ResourceFunction["ExpandPureFunction"][Function[z, StruveH[1/2, z]],
  z]
Out[15]=

Expand a pure function involving the error function complement Erfc to obtain its representation in terms of Erfc itself (demonstrating the reflection identity):

In[16]:=
ResourceFunction["ExpandPureFunction"][Function[x, Erf[x] + Erfc[x]],
  x]
Out[16]=

Use ExpandPureFunction to transform the Fibonacci function into its closed-form expression involving the golden ratio:

In[17]:=
ResourceFunction["ExpandPureFunction"][Function[n, Fibonacci[n]], n]
Out[17]=

Properties and Relations (2) 

ExpandPureFunction uses FunctionExpand internally, while FullSimplifyFunction uses FullSimplify. This means ExpandPureFunction can achieve reductions that FullSimplify alone does not perform, and vice versa. In some cases, they give equivalent results:

In[18]:=
ResourceFunction["ExpandPureFunction"][Function[x, x Gamma[x]]]
Out[18]=
In[19]:=
ResourceFunction["FullSimplifyFunction"][Function[x, x Gamma[x]]]
Out[19]=

An equivalent way to obtain the same result is by manually applying ExpressionToFunction. First, FunctionExpand is applied to the expression xGamma[x], and then "ExpressionToFunction" reconstructs the pure function from the expanded result:

In[20]:=
ResourceFunction["ExpressionToFunction"][
 FunctionExpand@(x Gamma[x]), x, "Evaluated" -> True]
Out[20]=

ExpandPureFunction wraps this multi-step pattern into a single call, handling dummy variables and symbol blocking automatically. The key limitation of the manual approach is that it does not protect symbols with global OwnValues from being substituted — ExpandPureFunction adds that protection.

Possible Issues (3) 

When the variable name supplied to ExpandPureFunction conflicts with a symbol appearing in the function body, the output may shadow the original parameter:

In[21]:=
ResourceFunction["ExpandPureFunction"][Function[b*Gamma[#]], b]
Out[21]=

In the example above, the parameter b in the body is replaced by the function variable b, causing the multiplicative factor to disappear. Users should avoid naming the output variable the same as any symbolic parameter in the function body:

In[22]:=
ResourceFunction["ExpandPureFunction"][Function[b*Gamma[#]], c]
Out[22]=

By design, ExpandPureFunction blocks only symbols with OwnValues. If a parameter is defined via DownValues (e.g., f[x_] := ), it will be evaluated during the expansion:

In[23]:=
myFun[x_] := x^2;
ResourceFunction["ExpandPureFunction"][Function[x, myFun[x] Gamma[x]],
  x]
Out[24]=

This is intentional. If preservation of such definitions is desired, one may wrap them with Block externally.

In[25]:=
Block[{myFun},
 	ResourceFunction["ExpandPureFunction"][
  Function[x, myFun[x] Gamma[x]], x]
 ]
Out[25]=

When using ExpandPureFunction inside Table, keep in mind that the Function wrapper captures all symbols in its body lexically. If the table iterator variable appears inside the Function body, it will not be substituted by Table:

In[26]:=
Table[ResourceFunction["ExpandPureFunction"][
  Function[x, D[Gamma[x], {x, k}]]], {k, 1, 2}]
Out[26]=

Use With to inject the iterator value before constructing the Function:

In[27]:=
Table[With[{k = k}, ResourceFunction["ExpandPureFunction"][
   Function[x, D[Gamma[x], {x, k}]], x]], {k, 1, 2}]
Out[27]=

Neat Examples (5) 

Reveal closed-form representations of hypergeometric functions. Many special cases of Hypergeometric2F1 reduce to elementary functions when FunctionExpand is applied:

In[28]:=
ResourceFunction["ExpandPureFunction"][
 Function[x, Hypergeometric2F1[1, 1, 2, x]], x]
Out[28]=
In[29]:=
ResourceFunction["ExpandPureFunction"][
 Function[x, Hypergeometric2F1[1/2, 1/2, 3/2, x2]], x]
Out[29]=

Expand a pure function involving the Pochhammer symbol (rising factorial) to reveal the underlying Gamma function ratio:

In[30]:=
ResourceFunction["ExpandPureFunction"][
 Function[{a, n}, Pochhammer[a, n]]]
Out[30]=

Obtain the explicit Gamma function representation of the Beta function:

In[31]:=
ResourceFunction["ExpandPureFunction"][Function[{x, y}, Beta[x, y]]]
Out[31]=

Construct closed-form pure functions for the successive derivatives of the Gamma function. The With idiom ensures the derivative order k is injected before the Function wrapper captures it:

In[32]:=
Table[With[{k = k}, k \[RightArrow] ResourceFunction["ExpandPureFunction"][
     Function[x, D[Gamma[x], {x, k}]], x]], {k, 1, 4}] // Column
Out[32]=

Visualize how ExpandPureFunction transforms the Mittag-Leffler function at specific parameter values into elementary functions. MittagLefflerE[α, z] generalizes the exponential; at α = 1 it recovers Exp, and at α = 2 it gives Cosh:

In[33]:=
Table[With[{\[Alpha] = \[Alpha]}, \[Alpha] \[RightArrow] ResourceFunction["ExpandPureFunction"][
     Function[z, MittagLefflerE[\[Alpha], z]], z]], {\[Alpha], {1, 2, 1/2}}] // Column
Out[33]=

Publisher

Ramón Eduardo Chan López

Version History

  • 1.0.0 – 13 March 2026

Related Resources

Author Notes

This resource function originated from a discussion on Mathematica Stack Exchange in the post Handling ‘vars appears twice in a nested scoping construct’ Warning in Custom Function. In that thread, Sjoerd Smit demonstrated how his resource function ExpressionToFunction with the "Evaluated"True option could be used to safely reconstruct Function objects while blocking variable substitutions. This insight led E. Chan-López to propose ExpandPureFunction as a companion to FullSimplifyFunction. The goal was to address a limitation shared by FunctionExpand and FullSimplify: neither operates directly on Function[args, expr]. The collaboration between both authors resulted in the present implementation.

ExpandPureFunction applies FunctionExpand to the body, which reduces named special functions to more explicit forms — for instance, ChebyshevT[n, x] to Cos[n ArcCos[x]] or Pochhammer[a, n] to Gamma[a + n]/Gamma[a]. These are reductions that FullSimplify (and therefore FullSimplifyFunction) does not perform, making both resource functions complementary.
Internally, a custom auxiliary function with the HoldAllComplete attribute traverses the function body to safely detect all symbols carrying OwnValues. These symbols are then injected into Block via Apply with HoldAllComplete, ensuring that no premature evaluations occur during the expansion process.
By design, only symbols with OwnValues (direct variable assignments) are blocked during expansion. Symbols with DownValues (user-defined functions) are allowed to evaluate, so that custom function definitions like xGammax[x_] := x Gamma[x] are expanded as expected.
The idea of using the resource function ExpressionToFunction with the "Evaluated"True option was suggested by Sjoerd Smit, which provided a clean mechanism for reconstructing the Function output without premature evaluation of blocked symbols.

License Information