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]=
Image

Evaluate the polynomial at a given value:

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

Convert a multivariate PDF to a function:

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

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]=
Image
In[7]:=
N@pdfFun2[{0, 1}]
Out[7]=
Image

Bind arguments to keys in an Association:

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

Bind multiple symbols to a single slot:

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

Combine named slots with positional slots:

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

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]=
Image
In[16]:=
counter = 1
Out[16]=
Image
In[17]:=
addToSymbol[counter, 2]
Out[17]=
Image
In[18]:=
counter
Out[18]=
Image

Evaluated (4) 

By default, the function body remains unevaluated:

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

Use Evaluated True to evaluate the PDF:

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

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]=
Image

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]=
Image

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]=
Image
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]=
Image

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]=
Image
In[28]:=
parameterizedPDF[{2, 1}, 1/10]
Out[28]=
Image

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]=
Image
In[30]:=
dSolveFun = ResourceFunction["ExpressionToFunction"][sol, x, a, Evaluated -> True]
Out[30]=
Image
In[31]:=
dSolveFun[10, 1]
Out[31]=
Image

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]=
Image

Properties and Relations (3) 

The resource function ExpressionToFunctionOperator is the operator form of ExpressionToFunction:

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

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]=
Image
In[36]:=
PDF[BinormalDistribution[1/3], {x, y}] // ResourceFunction["ExpressionToFunctionOperator"][{x, y}]
Out[36]=
Image

With evaluation of the expression:

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

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]=
Image
In[40]:=
badFun[{x0, y0}]
Out[40]=
Image

The correct result would be:

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

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]=
Image

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