Force evaluation of user-defined function - Mathematica Stack Exchange most recent 30 from mathematica.stackexchange.com 2019-09-22T04:55:19Z https://mathematica.stackexchange.com/feeds/question/188175 https://creativecommons.org/licenses/by-sa/4.0/rdf https://mathematica.stackexchange.com/q/188175 9 Force evaluation of user-defined function AGim https://mathematica.stackexchange.com/users/61988 2018-12-19T17:38:05Z 2018-12-19T18:05:10Z <p>Consider a function that sorts its arguments based on a function called <code>order</code></p> <pre><code>Clear[f, order] f[x_, y_] /; order[x] &gt; order[y] := f[y, x] order = 1; order = 2; expr1 = f[1, 2] expr2 = f[2, 1] (* f[1, 2] *) (* f[1, 2] *) </code></pre> <p>However, let's imagine that we change the ordering function</p> <pre><code>order = 2; order = 1; </code></pre> <p>Surprisingly, <code>expr1</code> and <code>expr2</code> still evaluate to <code>f[1,2]</code></p> <pre><code>expr1 expr2 (* f[1, 2] *) (* f[1, 2] *) </code></pre> <p>However, if we introduce <code>f[1, 2]</code> we obtain the correct result</p> <pre><code>f[1, 2] (* f[2, 1] *) </code></pre> <p>Is there a way to force the reevaluation of <code>expr</code> to obtain <code>f[2, 1]</code>? I am looking for a function along the lines of</p> <pre><code>ForceEvaluation@expr1 ForceEvaluation@expr2 (* f[2, 1] *) (* f[2, 1] *) </code></pre> https://mathematica.stackexchange.com/questions/188175/-/188178#188178 11 Answer by eyorble for Force evaluation of user-defined function eyorble https://mathematica.stackexchange.com/users/52935 2018-12-19T18:05:10Z 2018-12-19T18:05:10Z <p>Stumbled across the solution to this in <code>tutorial/ControllingInfiniteEvaluation</code> in the documentation. The last paragraph says:</p> <blockquote> <p>Some of the trickiest cases occur when you have rules that depend on complicated <code>/;</code> conditions (see "Putting Constraints on Patterns"). One particularly awkward case is when the condition involves a "global variable". The Wolfram Language may think that the evaluation is finished because the expression did not change. However, a side effect of some other operation could change the value of the global variable, and so should lead to a new result in the evaluation. The best way to avoid this kind of difficulty is not to use global variables in <code>/;</code> conditions. If all else fails, you can type <code>Update[s]</code> to tell the Wolfram Language to update all expressions involving <code>s</code>. <code>Update[]</code> tells the Wolfram Language to update absolutely all expressions. </p> </blockquote> <p>The symbol to updated in this case is <code>f</code>, rather than <code>order</code>, but:</p> <pre><code>Clear[f, order] f[x_, y_] /; order[x] &gt; order[y] := f[y, x] order = 1; order = 2; expr1 = f[1, 2]; expr2 = f[2, 1]; {expr1, expr2} </code></pre> <blockquote> <p>{f[1, 2], f[1, 2]}</p> </blockquote> <pre><code>order = 2; order = 1; Update[f]; {expr1, expr2} </code></pre> <blockquote> <p>{f[2, 1], f[2, 1]}</p> </blockquote> <p>Clunky, but it works.</p>