Function Repository Resource:

MapAtEvaluate

Source Notebook

A version of MapAt that evaluates even within held expressions

Contributed by: Nikolay Murzin

ResourceFunction["MapAtEvaluate"][f,expr,pos]

maps function f at position pos of the expression expr with evaluation.

ResourceFunction["MapAtEvaluate"][f,expr,pos,patt]

specifies a pattern to delete after evaluation.

ResourceFunction["MapAtEvaluate"][f,pos]

represents an operator form that can be applied to an expression.

Details

In ResourceFunction["MapAtEvaluate"][f,expr,pos,patt], patt is taken to be Unevaluated by default.

Examples

Basic Examples (2) 

Map a function at a single position of an expression and evaluate in-place:

In[1]:=
ResourceFunction["MapAtEvaluate"][10 # &, Hold[1, 2, 3], {3}]
Out[1]=

Map at multiple positions:

In[2]:=
ResourceFunction["MapAtEvaluate"][10 # &, Hold[1, 2, 3], {{1}, {3}}]
Out[2]=

Scope (8) 

Use All and Span to map over multiple subexpression parts:

In[3]:=
ResourceFunction["MapAtEvaluate"][10 # &, Hold[1, 2, 3], {All}]
Out[3]=
In[4]:=
ResourceFunction["MapAtEvaluate"][10 # &, Hold[1, 2, 3], {2 ;; 3}]
Out[4]=
In[5]:=
ResourceFunction["MapAtEvaluate"][10 # &, Hold[{1, 2}, {2, {3, 4}}, {3, 4}], {2 ;; 3, 2}]
Out[5]=

Prevent evaluation of the function output with Unevaluated:

In[6]:=
ResourceFunction["MapAtEvaluate"][Unevaluated[# + 3] == # + 3 &, Hold[1, 2], {{2}}]
Out[6]=

The Unevaluated is not present in the result:

In[7]:=
ResourceFunction["MapAtEvaluate"][Unevaluated[# + 3] == # + 3 &, Hold[1, 2], {{2}}]
Out[7]=

Specify a different subexpression to delete after evaluation:

In[8]:=
ResourceFunction["MapAtEvaluate"][wrap[Unevaluated[# + 3]] == # + 3 &,
  Hold[1, 2], {{2}}, wrap]
Out[8]=
In[9]:=
ResourceFunction["MapAtEvaluate"][Inactive[Plus][#, 3] == # + 3 &, Hold[1, 2], {{2}}, Inactive]
Out[9]=

Prevent evaluation of subexpressions using a function with held arguments:

In[10]:=
ResourceFunction["MapAtEvaluate"][
 Function[x, Unevaluated[x + 4], HoldFirst], Hold[1, 2 + 3], {{2}}]
Out[10]=

Evaluate subexpressions:

In[11]:=
ResourceFunction["MapAtEvaluate"][Identity, HoldComplete[1 + 2, 3 + 4], {{1}}]
Out[11]=
In[12]:=
ResourceFunction["MapAtEvaluate"][Evaluate, HoldComplete[1 + 2, 3 + 4], {{2}}]
Out[12]=

Map at a held Sequence:

In[13]:=
ResourceFunction["MapAtEvaluate"][Hold, HoldComplete[1, Sequence[2, 3]], {{2}}]
Out[13]=
In[14]:=
ResourceFunction["MapAtEvaluate"][HoldComplete, HoldComplete[1, Sequence[2, 3]], {{2}}]
Out[14]=

Map at a held Evaluate:

In[15]:=
ResourceFunction["MapAtEvaluate"][Hold, HoldComplete[1, Evaluate[2, 3]], {{2}}]
Out[15]=
In[16]:=
ResourceFunction["MapAtEvaluate"][HoldComplete, HoldComplete[1, Evaluate[2, 3]], {{2}}]
Out[16]=

Unevaluated function evaluates at each position:

In[17]:=
ResourceFunction["MapAtEvaluate"][Unevaluated@Echo[f], Hold[1, 2, 3], All]
Out[17]=
In[18]:=
ResourceFunction["MapAtEvaluate"][Echo[f], Hold[1, 2, 3], All]
Out[18]=

Properties and Relations (4) 

MapAt does not evaluate the function it is mapping inside held arguments:

In[19]:=
MapAt[# + 10 &, Hold[1, 2], {{2}}]
Out[19]=

MapAtEvaluate does:

In[20]:=
ResourceFunction["MapAtEvaluate"][# + 10 &, Hold[1, 2], {{2}}]
Out[20]=

MapAt fails if any position is invalid:

In[21]:=
MapAt[# + 10 &, Hold[1, 2], {{1}, {3}}]
Out[21]=

MapAtEvaluate silently ignores invalid positions:

In[22]:=
ResourceFunction["MapAtEvaluate"][# + 10 &, Hold[1, 2], {{1}, {3}}]
Out[22]=

The resource function ReplaceAt with a _/;True condition can achieve the same results:

In[23]:=
ResourceFunction[
ResourceObject[<|"Name" -> "ReplaceAt", "ShortName" -> "ReplaceAt", "UUID" -> "73d6853d-88b7-41b6-89f3-2e4d88b8984f", "ResourceType" -> "Function", "Version" -> "1.0.0", "Description" -> "Replace parts of an expression using replacement rules and a part specification", "RepositoryLocation" -> URL[
     "https://www.wolframcloud.com/obj/resourcesystem/api/1.0"], "SymbolName" -> "FunctionRepository`$afcb7bc0f2404e26ad4460411122e0e8`ReplaceAt", "FunctionLocation" -> CloudObject[
     "https://www.wolframcloud.com/obj/d36a0ff8-6751-427d-92ec-4c39a5f79557"]|>, {ResourceSystemBase -> "https://www.wolframcloud.com/obj/resourcesystem/api/1.0"}]][Hold[1, 2, 3], x_ :> With[{y = x + 10}, y /; True], {All}]
Out[23]=
In[24]:=
ResourceFunction["MapAtEvaluate"][# + 10 &, Hold[1, 2, 3], {All}]
Out[24]=

With MapAtEvaluate, one can control which subexpressions not to evaluate without producing an additional wrapper:

In[25]:=
ResourceFunction[
ResourceObject[<|"Name" -> "ReplaceAt", "ShortName" -> "ReplaceAt", "UUID" -> "73d6853d-88b7-41b6-89f3-2e4d88b8984f", "ResourceType" -> "Function", "Version" -> "1.0.0", "Description" -> "Replace parts of an expression using replacement rules and a part specification", "RepositoryLocation" -> URL[
     "https://www.wolframcloud.com/obj/resourcesystem/api/1.0"], "SymbolName" -> "FunctionRepository`$afcb7bc0f2404e26ad4460411122e0e8`ReplaceAt", "FunctionLocation" -> CloudObject[
     "https://www.wolframcloud.com/obj/d36a0ff8-6751-427d-92ec-4c39a5f79557"]|>, {ResourceSystemBase -> "https://www.wolframcloud.com/obj/resourcesystem/api/1.0"}]][Hold[1, 2, 3], x_ :> RuleCondition[Unevaluated[x + 10] == x + 10], {All}]
Out[25]=
In[26]:=
ResourceFunction["MapAtEvaluate"][Unevaluated[# + 10] == # + 10 &, Hold[1, 2, 3], {All}]
Out[26]=

The resource function MapCases with the option "EvaluateCases"True has similar behavior to MapAtEvaluate, except that it takes patterns instead of positions:

In[27]:=
ResourceFunction["MapAtEvaluate"][10 # &, Hold[2*2, 2 + 2, 3*3], {2}]
Out[27]=
In[28]:=
ResourceFunction["MapCases"][10 # &, Hold[2*2, 2 + 2, 3*3], _Plus, "EvaluateCases" -> True]
Out[28]=

Version History

  • 1.0.0 – 03 May 2022

Related Resources

License Information