Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preventing evaluation of Mathematica expressions

In a recent SO question three different answers were supplied each using a different method of preventing the evaluation of the Equal[] expression. They were

  1. Defer[]
  2. Unevaluated[]
  3. HoldForm[]

Sometimes I still have trouble choosing between these options (and judging by answers to the before mentioned question, the choice isn't always clear for other people either). Can someone write a clear exposition on the use of these three methods?


There are three other wrappers Hold[], HoldPattern[], HoldComplete[], and the various Attributes for functions HoldAll, HoldFirst, HoldRest and the numeric versions NHold* that can also be discussed if you wish!

Edit

I just noticed that this is basically a repeat of the old question (which I had already upvoted, just forgotten...). The accepted answer linked to this talk at the 1999 Mathematica Developer Conference, which doesn't discuss Defer since it is "New in 6". Defer is more closely linked to the frontend than the other evaluation control mechanisms. It is used to create an unevaluated output that will be evaluated if supplied in and Input expression. To quote the Documentation Center:

Defer[expr] returns an object which remains unchanged until it is explicitly supplied as Mathematica input, and evaluated using Shift+Enter, Evaluate in Place, etc.

like image 497
Simon Avatar asked Jan 31 '11 21:01

Simon


People also ask

How do you stop a cell evaluation in Mathematica?

To stop this computation, first select its cell bracket: Then select Abort Evaluation from the Evaluation menu: The Wolfram System then outputs $Aborted: If Abort Evaluation does not succeed in stopping the computation, you can do so by quitting the active kernel.

What does hold mean Mathematica?

Hold has attribute HoldAll and performs no operation on its arguments. Hold is removed by ReleaseHold. » Hold[e1,e2,…] maintains a sequence of unevaluated expressions to which a function can be applied using Apply.

How do you evaluate a notebook in Mathematica?

Re-launch Mathematica, and you should see F8 next to the Evaluate Notebook command.


2 Answers

Not touching Defer, since I did not work much with it and feel that in any given case its behavior can be reproduced by other mentioned wrappers, and discussing Hold instead on HoldForm (the difference is really in the way they are printed), here is the link to a mathgroup post where I gave a rather extensive explanation of differences between Hold and Unevaluated, including differences in usage and in the evaluation process (my second and third posts in particular).

To put the long story short, Hold is used to preserve an expression unevaluated in between several evaluations (for indefinite time, until we need it), is a visible wrapper in the sense that say Depth[Hold[{1,2,3}]] is not the same as Depth[{1,2,3}] (this is of course a consequence of evaluation), and is generally nothing special - just a wrapper with HoldAll attribute like any other, except being an "official" holding wrapper and being integrated much better with the rest of the system, since many system functions use or expect it.

OTOH, Unevaluated[expr] is used to temporarily, just once, make up for a missing Hold* attribute for a function enclosing expression expr. While resulting in behavior which would require this enclosing function to hold expr as if it had Hold* - attribute, Unevaluated belongs to the argument, and works only once, for a single evaluation, since it gets stripped in the process. Also, because it gets stripped, it often is invisible for the surrounding wrappers, unlike Hold. Finally, it is one of a very few "magic symbols", along with Sequence and Evaluate - these are deeply wired into the system and can not be easily replicated or blocked, unlike Hold - in that sense, Unevaluated is more fundamental.

HoldComplete is used when one wants to prevent certain stages of evaluation process, which Hold does not prevent. This includes splicing sequences, for example:

In[25]:= {Hold[Sequence[1, 2]], HoldComplete[Sequence[1, 2]]}

Out[25]= {Hold[1, 2], HoldComplete[Sequence[1, 2]]},

search for UpValues, for example

In[26]:= 
ClearAll[f];
f /: Hold[f[x_]] := f[x];
f[x_] := x^2;

In[29]:= {Hold[f[5]], HoldComplete[f[5]]},

Out[29]= {25, HoldComplete[f[5]]}

and immunity to Evaluate:

In[33]:= 
ClearAll[f];
f[x_] := x^2;

In[35]:= {Hold[Evaluate[f[5]]], HoldComplete[Evaluate[f[5]]]}

Out[35]= {Hold[25], HoldComplete[Evaluate[f[5]]]}   

In other words, it is used when you want to prevent any evaluation of the expression inside, whatsoever. Like Hold, HoldComplete is nothing special in the sense that it is just an "official" wrapper with HoldAllComplete attribute, and you can make your own which would behave similarly.

Finally, HoldPattern is a normal (usual) head with HoldAll attribute for the purposes of evaluation, but its magic shows in the pattern-matching: it is invisible to the pattern-matcher, and is very important ingredient of the language since it allows pattern-matcher to be consistent with the evaluation process. Whenever there is a danger that the pattern in some rule may evaluate, HoldPattern can be used to ensure that this won't happen, while the pattern remains the same for the pattern-matcher. One thing I'd stress here that this is the only purpose for it. Often people use it also as an escape mechanism for the pattern-matcher, where Verbatim must be used instead. This works, but is conceptually wrong.

One very good account on evaluation process and all these things is a book of David Wagner, Power programming with Mathematica - the kernel, which was written in 1996 for version 3, but most if not all of the discussion there remains valid today. It is out of print alas, but you might have some luck on Amazon (as I had a few years ago).

like image 106
Leonid Shifrin Avatar answered Oct 19 '22 03:10

Leonid Shifrin


Leonid Shifrin's answer is quite nice, but I wanted to touch on Defer, which is really useful for only one thing. In some instances, it's nice to be able to directly construct expressions that won't be evaluated, but that a user will be able to easily edit; the basic example for this kind of behavior is button palettes that you can use to insert expressions or expression templates into input cells which the user can then edit as needed. This isn't the only way to do this, and for some more sophisticated applications you'll need to get into the hairy world MakeBoxes, but for the basics Defer will serve nicely.

like image 39
Pillsy Avatar answered Oct 19 '22 03:10

Pillsy