Function Repository Resource:

ExpressionToFunction

Source Notebook

Convert an expression to a pure function by specifying which symbols should be used as input arguments

Contributed by: Sjoerd Smit

ResourceFunction["ExpressionToFunction"][expr,var1,var2,]

returns Function[{var1,var2,},expr].

ResourceFunction["ExpressionToFunction"][expr,,{vari,1,vari,2,},]

bundles {vari,1,vari,2,} together in one function slot as a vector argument.

ResourceFunction["ExpressionToFunction"][expr,varspec1index1,varspec2index2,]

binds variables specified by varspeci to Slot[indexi].

Details and Options

ResourceFunction["ExpressionToFunction"] can be used as an alternative to ReplaceAll (/.) or Block for evaluating symbolic formulas at given variable values.
ResourceFunction["ExpressionToFunction"] holds all of its arguments and should work even when the variables already have definitions.
You can use ResourceFunction["ExpressionToFunction"][Evaluate[expr],] if you want to pass expr in evaluated form.
Indexed is used to vectorize variables together.
ResourceFunction["ExpressionToFunction"] takes the following options:
AttributesNoneattributes that the pure function should have
EvaluatedFalsewhether to evaluate the function body
With Evaluated True, the function body will be evaluated with the specified variables blocked. This is useful for simplifying expressions before turning them into functions.
In ResourceFunction["ExpressionToFunction"][expr,varspec1 index1,varspec2 index2,], the indexi can be either integers or strings. String indices can be used together with associations. If strings are used as indices, it is up to the user to make sure the strings do not contain illegal characters (see Slot).
When using indexed slots, the returned function is of the form Function[Null,expr,{attribute1, }]. This form makes it possible to use Function attributes in a Function that uses Slot for slotting the arguments.

Examples

Basic Examples (5) 

Create a function from a simple polynomial:

In[1]:=
polyFun = ResourceFunction["ExpressionToFunction"][1 + 2 x + x^2, x]
Out[1]=

Evaluate the polynomial at a given value:

In[2]:=
polyFun[1]
Out[2]=

Convert a multivariate PDF to a function:

In[3]:=
pdf = PDF[BinormalDistribution[1/3], {x, y}]
Out[3]=
In[4]:=
pdfFun = ResourceFunction["ExpressionToFunction"][Evaluate[pdf], x, y]
Out[4]=
In[5]:=
N@pdfFun[0, 1]
Out[5]=

Bind x and y to the first slot of the function as a vector:

In[6]:=
pdfFun2 = ResourceFunction["ExpressionToFunction"][Evaluate[pdf], {x, y}]
Out[6]=
In[7]:=
N@pdfFun2[{0, 1}]
Out[7]=

Bind arguments to keys in an Association:

In[8]:=
powerFun = ResourceFunction["ExpressionToFunction"][x^y, x -> "Base", y -> "Exponent"]
Out[8]=
In[9]:=
powerFun[<|"Base" -> 2, "Exponent" -> 3|>]
Out[9]=

Bind multiple symbols to a single slot:

In[10]:=
ResourceFunction["ExpressionToFunction"][x + y, {x, y}][{E, Pi}]
Out[10]=
In[11]:=
powerFun2 = ResourceFunction["ExpressionToFunction"][x^
  y, {x, y} -> "BaseExponentTuple"]
Out[11]=
In[12]:=
powerFun2[<|"BaseExponentTuple" -> {2, 3}|>]
Out[12]=

Combine named slots with positional slots:

In[13]:=
powerFun3 = ResourceFunction["ExpressionToFunction"][z*x^y, z -> "z", {x, y} -> 2]
Out[13]=
In[14]:=
powerFun3[<|"z" -> Pi|>, {E, 2}]
Out[14]=

Options (5) 

Attributes (1) 

Use the Attributes option to return a function that holds its arguments:

In[15]:=
addToSymbol = ResourceFunction["ExpressionToFunction"][var = var + val, var, val, Attributes -> HoldFirst]
Out[15]=
In[16]:=
counter = 1
Out[16]=
In[17]:=
addToSymbol[counter, 2]
Out[17]=
In[18]:=
counter
Out[18]=

Evaluated (4) 

By default, the function body remains unevaluated:

In[19]:=
ResourceFunction["ExpressionToFunction"][
 PDF[BinormalDistribution[1/3], {x, y}], {x, y}]
Out[19]=

Use Evaluated True to evaluate the PDF:

In[20]:=
ResourceFunction["ExpressionToFunction"][
 PDF[BinormalDistribution[1/3], {x, y}], {x, y}, Evaluated -> True]
Out[20]=

When x has a value, using Evaluate directly on the first argument gives the wrong result:

In[21]:=
x = 1.;
ResourceFunction["ExpressionToFunction"][
 Evaluate@PDF[BinormalDistribution[1/3], {x, y}], {x, y}]
Out[21]=

Use Evaluated True to Block x while the body is being evaluated:

In[22]:=
ResourceFunction["ExpressionToFunction"][
 PDF[BinormalDistribution[1/3], {x, y}], {x, y}, Evaluated -> True]
Out[22]=

Applications (3) 

Group x and y together as a vector argument and map over a list of points:

In[23]:=
pdfVectorFun = ResourceFunction["ExpressionToFunction"][
  PDF[BinormalDistribution[1/3], {x, y}], {x, y}, Evaluated -> True]
Out[23]=
In[24]:=
dataRange = {{-3, 3}, {-3, 3}};
In[25]:=
points = Map[pdfVectorFun, CoordinateBoundsArray[dataRange, 0.1], {2}];
In[26]:=
ListContourPlot[points, DataRange -> dataRange]
Out[26]=

Add a parameter of the PDF as an argument:

In[27]:=
parameterizedPDF = ResourceFunction["ExpressionToFunction"][
  PDF[BinormalDistribution[\[Rho]], {x, y}],
  {x, y},
  \[Rho],
  Evaluated -> True
  ]
Out[27]=
In[28]:=
parameterizedPDF[{2, 1}, 1/10]
Out[28]=

Convert the solution of a differential equation to a function:

In[29]:=
sol = DSolveValue[{y'[x] + y[x] == a Sin[x], y[0] == 0}, y[x], x]
Out[29]=
In[30]:=
dSolveFun = ResourceFunction["ExpressionToFunction"][sol, x, a, Evaluated -> True]
Out[30]=
In[31]:=
dSolveFun[10, 1]
Out[31]=

Represent the function at parameter value a=10 with OperatorApplied, then map over a range of x values:

In[32]:=
AssociationMap[
  OperatorApplied[dSolveFun][10],
  Range[0, 10, 0.1]
  ] // ListPlot
Out[32]=

Properties and Relations (3) 

The resource function ExpressionToFunctionOperator is the operator form of ExpressionToFunction:

In[33]:=
ResourceFunction["ExpressionToFunction"][x^y, {x, y}]
Out[33]=
In[34]:=
x^y // ResourceFunction["ExpressionToFunctionOperator"][{x, y}]
Out[34]=

Note, in particular, that both functions hold the expression that's being transformed into a function unless EvaluatedTrue is used:

In[35]:=
ResourceFunction["ExpressionToFunction"][
 PDF[BinormalDistribution[1/3], {x, y}], {x, y}]
Out[35]=
In[36]:=
PDF[BinormalDistribution[1/3], {x, y}] // ResourceFunction["ExpressionToFunctionOperator"][{x, y}]
Out[36]=

With evaluation of the expression:

In[37]:=
ResourceFunction["ExpressionToFunction"][
 PDF[BinormalDistribution[1/3], {x, y}], {x, y}, Evaluated -> True]
Out[37]=
In[38]:=
PDF[BinormalDistribution[1/3], {x, y}] // ResourceFunction["ExpressionToFunctionOperator"][{x, y}, Evaluated -> True]
Out[38]=

Possible Issues (3) 

ExpressionToFunction is meant for expressions that do not already contain functions and may malfunction for such expressions if the replacement variables exist inside such functions:

In[39]:=
badFun = ResourceFunction["ExpressionToFunction"][
  Function[#1 + x]@y, {x, y} -> 1]
Out[39]=
In[40]:=
badFun[{x0, y0}]
Out[40]=

The correct result would be:

In[41]:=
ReleaseHold[
 Hold[Function[#1 + x]@y] /. {x -> x0, y -> y0}
 ]
Out[41]=

The problem can sometimes be avoided by evaluating the inner function away:

In[42]:=
ResourceFunction["ExpressionToFunction"][
  Function[#1 + x]@y, {x, y} -> 1, Evaluated -> True][{x0, y0}]
Out[42]=

Publisher

Sjoerd Smit

Requirements

Wolfram Language 11.3 (March 2018) or above

Version History

  • 2.0.3 – 03 April 2024
  • 2.0.2 – 20 July 2021
  • 2.0.1 – 04 March 2021
  • 2.0.0 – 01 April 2019
  • 1.0.0 – 27 March 2019

Related Resources

License Information