Saturday, July 10, 2010

Mathematica Cookbook Attacked by a Troll: Jon Harrop

Recently I have had a very unpleasant experience with a known internet troll who has been attacking Mathematica Cookbook on the amazon.co.uk site. I posted the following review on amazon.co.uk by way of defending myself and my work. They may or may not allow it but I wanted to share it with you....


I would like to direct UK customers who may be interested in my book to a few facts.

1) Both of the previous reviewers (Edward and Jon Harrop) are actually the same person. I have very strong evidence this is the case. You may email me at mathematicacookbook@gmail.com if you want the details.

2) Jon Harrop is author of "F# for scientists" and about 2 years ago I blogged unfavorably about Mr. Harrop's book. You can see my comments here: .

3) Apparently I hurt Jon's feelings so badly that he could not wait to order my book just to give it a poor review. In fact, he has given it two!

4) Since then he has been using my own book as inspiration for several of his own blog posts so apparently he does not find it totally useless.

5) If you would like to see a more balanced treatment of my book please see these reviews: http://amzn.to/cKxJVh, http://oreil.ly/9ypIlX, http://bit.ly/b6HqFS and http://amzn.to/bQSr6Y.

6) I won't comment further on Mr. Harrops character because I think his actions speak for themselves. The interested reader can google "Jon Harrop Troll" and draw their own conclusions.

7) Finally, my book is not perfect. But I absolutely did not plagiarize anyone and link extensively to others work where they inspired my codes. I have been correcting issues as they are found and the O’Reilly site is where errata can be found. I think may readers in the UK who are fans of Mathematica can find a lot of value in my book and I don't want the bitter feelings of one individual to scare you away.

Tuesday, July 6, 2010

The Elegance of Rule-Based Programming in Mathematica


Not too long ago I had to take a programming test as part of the application process for a development position at a hedge fund. The test had two problems - one easy and one not so easy. The solutions to both problems had to be implemented in your choice of Java, C or C++. You had two hours to finish.


I have never been good at presure cooker coding tests like this. I personally don't think these kind of tests bring out the best in most developers but there are some good devlopers who work well under these conditions. I just am not one of them.


In any case I recently thought of the hard problem on this test and how trivial it would be to solve in Mathematica. Indeed I whipped up and tested this solution on my train ride home which is only about 45 mins!


The solution is very short and I am guessing is much shorter than the average solution you can find in Java or C in the equivalent amount of time. The brevity come form exploiting mathematica's powerful rule-based approach. Most of the code is comments!


Problem



A collection of particles is contained in a linear chamber. They all have the same speed, but some are headed toward the right and others are headed toward the left. These particles can pass through each other without disturbing the motion of the particles, so all the particles will leave the chamber relatively quickly.


You will be given the initial conditions by a string containing at each position an 'L' for a leftward moving particle, an 'R' for a rightward moving particle, or a '.' for an empty location. Initially, no location in the chamber contains two particles passing through each other.


Create an animation of the process. At each unit of time, you want a string showing occupied locations with an 'X' and unoccupied locations with a '.'. Create code that for a function animate that is given an integer speed and a string giving the initial conditions. The speed is the number of positions each particle moves in one time unit.


The function will return a list of strings in which each successive element shows the occupied locations at the next time unit. The first element of the return should show the occupied locations at the initial instant (at time = 0) in the 'X', '.' format. The last element in the return should show the empty chamber at the first time that it becomes empty.


Solution




ClearAll[simulation, step, L, R, r, l, rule1, rule2, rule3, animation];

(*
This function does most of the work. It simulates a single step in the animation.
It uses 3 rules which are initialized in the calling function and are visble
here via the dynamic scoping of Block.

There are 3 transformations performed within a Do. The Do's role is to run the
transformations velocity times as a means for making the particles move
that many steps.

The first transform takes the input and adds an empty cell to the start and end of the chamber.
This is done to avoid having special rules to deal with the
boundary conditions at the end of the chamber.

The second transformation uses rules that are applied repeatedly using ReplaceAll (//.).
I discuss the rules below.

Delete is used to remove the dummy empty cells added in the first step and
a third transformation maps lower case r and l back to upper case before the Do
repeats.

*)
step[chamber_List, velocity_Integer] := Module[{work = chamber},
Do[
work =
Delete[work /. {P__} :> {{}, P, {}} //. {rule1, rule2,
rule3}, {{-1}, {1}}] /. {r -> R, l -> L}, {velocity}];
work
]

(*
The simulation sets up 3 rules. It is not necessary to define the rules here in a
Block. The code is written this way largely because I incrementally developed the
rules in the global scope and grafted them into a program later on.

rule1 is responsible for moving a R partcle to the Right. NOTE: When a particle moves
I change its case from upper to lower to make it invisble to subsequent rules.

rule2 is responsible for handling an intermediate condition where a right moving
particle lands in a cell of another right moving particle that has not moved yet.

rule3 deals with left moving particles being careful to also handle the case where a
previously moved partcle Z may be in the same cell as the L.

The hardest aspect of this solution was distilling the transformations down to these
three rules. It took some trial and error. It is possible I missed some corner case
so let me know if you see a bug!!

The idea here is that FixedPointList drives the simulation until it reaches a steady
state and Most removes the repetitive last entry.

A final transformation maps particles to "X" as dicated by the specifications.
*)

simulation[chamber_List, velocity_Integer] :=
Block[
{rule1 = {X___, {R}, {P___}, Y___} :> {X, {}, {P, r}, Y} ,
rule2 = {X___, {R | r, r}, {P___}, Y___} :> {X, {r}, {P, r}, Y},
rule3 = {X___, {P___}, {L, Z___}, Y___} :> {X, {l, P}, {Z}, Y} },
Most[FixedPointList[
step[#, velocity] &, chamber]] //. {{(L | R) ..} -> "X", {} ->
"."}
]

(*
The main function does little but convert from the string encoding specified by the problem to a more convenent symbolic form where each position in the chamber is one of {L}, {R} or {} for empty and the chamber itself is a list rather than a string.
*)

animation[chamber_String, velocity_Integer] :=
simulation[
(Characters[chamber] //. {"." -> {}, a_String :> {Symbol[a]}}),
velocity]



The Test Cases




1) The single particle starts at the 3rd position, moves to the 5th, then 7th, and then out of the chamber.
In[360]:= animation["..R....",2]//Grid
Out[360]=
..X....
....X..
......X
.......

2) At time 1, there are actually 4 particles in the chamber, but two are passing through each other at the 4th position.

In[361]:= animation["RR..LRL",3]//Grid
Out[361]=
XX..XXX
.X.XX..
X.....X
.......


3) At time 0 there are 8 particles. At time 1, there are still 6 particles, but only 4 positions are occupied since particles are passing through each other.


In[362]:= animation["LRLR.LRLR",2]//Grid
Out[362]=
XXXX.XXXX
X..X.X..X
.X.X.X.X.
.X.....X.
.........


4) These particles are moving so fast that they all exit the chamber by time 1.
In[363]:= animation["RLRLRLRLRL",10]//Grid
Out[363]=
XXXXXXXXXX
..........

5) The empty chamber test

In[364]:= animation["...",1]//Grid
Out[364]=
...

6) A complicated test

In[365]:= animation["LRRL.LR.LRR.R.LRRL.",1]//Grid
Out[365]=
XXXX.XX.XXX.X.XXXX.
..XXX..X..XX.X..XX.
.X.XX.X.X..XX.XX.XX
X.X.XX...X.XXXXX..X
.X..XXX...X..XX.X..
X..X..XX.X.XX.XX.X.
..X....XX..XX..XX.X
.X.....XXXX..X..XX.
X.....X..XX...X..XX
.....X..X.XX...X..X
....X..X...XX...X..
...X..X.....XX...X.
..X..X.......XX...X
.X..X.........XX...
X..X...........XX..
..X.............XX.
.X...............XX
X.................X
...................




I'll post the Mathematica Notebook on MathematicaCookbook.com

Monday, June 28, 2010

Hold Everything!

In Mathematica Cookbook recipe 2.2 I discuss a "technique" for holding arbitrary arguments. Well truth be told, this recipe is pretty lame and was not supposed to make it into the final book. This post is intended to make of for that lameness and hopefully clarify some of the bewildering multitude of ways Mathematica offers for Holding.

The Hold Family of Attributes


Mathematica's default behavior is to evaluate every expression it sees. Here is an example.

In[1]:= a=1;b=2;c=3; d= c; e:= d; f :=e;
{a,b,c, d,e, f}
Out[2]= {1,2,3,3,3,3}

Here we associate symbols a, b, c with integers 1, 2,3. We then associate d with the value of symbol c and we associate e with symbol d telling Mathematica not to evaluate d just yet by using SetDelayed (:=). We also associate f with symbol d likewise delaying evaluation. Later, when we evaluate the list containing these symbols Mathematica keeps evaluating until there is nothing left to do and we get the result as integers. By using Trace we can see the steps Mathematica goes through.

In[3]:= Trace[{a,b,c, d,e, f}]
Out[3]= {{a,1},{b,2},{c,3},{d,3},{e,d,3},{f,e,d,3},{1,2,3,3,3,3}}

Okay, simple enough. However, occasionally you want to write functions that act on expressions before they are evaluated. In fact, even if you never had a reason for doing so, Mathematica itself needs this capability. For example, Mathematica could not implement the function SetDelayed if it did not have a way of saying "don't evaluate". Rather then creating certain functions with special no-evaluating behavior, Mathematica takes a general approach via the concept of attributes. You can inspect the attributes of a symbol using the command Attributes.

In[4]:= Attributes[SetDelayed]
Out[4]= {HoldAll,Protected,SequenceHold}

Here we see SetDelayed has two attributes in the hold-family: HoldAll and SequenceHold. Let's explore these using our own symbols and SetAttributes. Here I use symbols f1, f2 and so on without associating them with values because that is not necessary to illustrate the behavior of the attributes.

In[5]:= (* Make sure these symbols have no values or attributes*)
ClearAll[f1,f2,f3,f4,f5,f6,f7] ;

In[6]:= (* Here you can see that our list of symbols evalauates as before when we wrap f1 around it*)f1[{a,b,c,d,e,f}]
Out[6]= f1[{1,2,3,3,3,3}]

In[7]:= (*Here we use the HoldAll and associate it with f2. This says that no arguement of f2 should be evaluated*)
SetAttributes[f2, HoldAll]
In[8]:= f2[{a,b,c,d,e,f}]
Out[8]= f2[{a,b,c,d,e,f}]

In[9]:= (* It does not matter how many seperate arguments are passed, they are all held*)f2[a,b,c]
Out[9]= f2[a,b,c]

Notice the difference between evaluating f1 which has no attributes and f2 which has attribute HoldAll. In essence, f2 acts the same as the built-in Mathematica command Hold.

In[10]:= Attributes[Hold]
Out[10]= {HoldAll,Protected}

Sometimes you want only the first argument to a function to be held unevaluated. For that you use attribute HoldFirst.

In[11]:= SetAttributes[f3, HoldFirst]
f3[a,b,c]
Out[12]= f3[a,2,3]

Alternatively you may want all arguments but the first to be held. Here you use HoldRest.

In[13]:= SetAttributes[f4, HoldRest]
f4[a,b,c]
Out[14]= f4[1,b,c]

So far I think the mechanics of HoldAll, HoldFirst and HoldRest should be pretty clear. Don't worry yet if you don't get why you would want to use these in your own code, I'll get to that later. Just make sure you are comfortable with the idea of using attributes to suppress Mathematica's desire to evaluate before reading on.


Okay, now I want to point out some important exceptions. Well, not really exceptions but rather clarifications. HoldAll, HoldFirst and HoldRest do not suppress every action that Mathematica takes when it sees an expression. To illustrate this, please recall that Mathematica has a long hand way of specifying a sequence of things.

In[15]:= Sequence[1,2,3]
Out[15]= Sequence[1,2,3]

A sequence is different form a list in that Mathematica will magically flatten out sequences and splice the result into any function call.

In[16]:= f1[Sequence[1,2,3]]
Out[16]= f1[1,2,3]
In[17]:= f1[Sequence[1,2,Sequence[3,4,5]],7,8,9]
Out[17]= f1[1,2,3,4,5,7,8,9]

Now, recall that f2 has attributes HoldAll. What do you think Mathematica does if we give f2 a sequence?

In[18]:= f2[Sequence[1,2,Sequence[3,4,5]],7,8,9]
Out[18]= f2[1,2,3,4,5,7,8,9]

Ah! The automatic flatting is not suppressed by HoldAll nor is it suppressed by HoldFirst or HoldRest. The flattening out of sequences is something you usually don't want to suppress. This is why it is an exception to the rule for the standard hold family of attributes. However, you may recall that SetDelayed had another hold-like attribute called SequenceHold and you can probably guess what it does!

In[19]:= SetAttributes[f5, SequenceHold]
f5[Sequence[1,2,Sequence[3,4,5]],7,8,9]
Out[20]= f5[Sequence[1,2,3,4,5],7,8,9]

Notice how the outer sequence remains. Why did the inner sequence get flattened? Simply because it is evaluated within Sequence which naturally does not have the SequenceHold attribute.


Okay, lets review. HoldAll, HoldFirst and HoldRest are attributes that suppress evaluation of specific arguments but don't suppress sequence flattening. For that you use SequenceHold. You can use one of the hold attributes together with SequenceHold to get both behaviors.

In[21]:= SetAttributes[f6, {HoldAll,SequenceHold}]
f5[Sequence[a,b,c]]
f6[Sequence[a,b,c]]
Out[22]= f5[Sequence[1,2,3]]
Out[23]= f6[Sequence[a,b,c]]

But we are not done yet! There is even a stronger form of holding that suppresses normal evaluation, sequence flattening and more! First, recall that sometimes you want to tell Mathematica that you want something to evaluate despite the presence of HoldAll and friends. To see how there can be a stronger form of holding we must first consider Evaluate.

In[24]:= f2[Evaluate[a,b,c]]
Out[24]= f2[1,2,3]

Evaluate is a way of saying to Mathematica that you know what you are doing and you want evaluation to take place despite the presence of HoldAll, etc.. This typically arises when you want to plot a function that you obtain by integration (or other function generating operations).

In[25]:= Attributes[Plot]
Out[25]= {HoldAll,Protected}

In[26]:= Plot[Evaluate[Integrate[Sin[x],x]], {x, 0, 2Pi}]
Out[26]:=



The attribute HoldAllComplete has super-powers because it can even shield evaluation by Evaluate!

In[27]:= SetAttributes[f7,HoldAllComplete]
In[28]:= f6[Evaluate[{a,b,c}]]
f7[Evaluate[{a,b,c}]]
Out[28]= f6[{1,2,3}]
Out[29]= f7[Evaluate[{a,b,c}]]

The built in command HoldComplete is the counterpart to the Hold command.

In[30]:= Attributes[Hold]
Attributes[HoldComplete]
Out[30]= {HoldAll,Protected}
Out[31]= {HoldAllComplete,Protected}
In[32]:= HoldComplete[Evaluate[{a,b,c}]]
Out[32]= HoldComplete[Evaluate[{a,b,c}]]

Functions with attribute HoldAllComplete also suppress upvalue evaluation. I am not going to discuss up upvalues here but you can refer to the Mathematica documentation or my cookbook.


HoldForm, Unevaluated, Defer oh my!


At this point you might think we have exhausted all the ways you can suppress evaluation but no. Mathematica has some more subtle ways you can keep its evaluation engine in check. Perhaps the easiest to understand is HoldForm. This command suppresses evaluation just like Hold except the command gets hidden when display in output form. The following should make the difference clear.

In[33]:= Hold[1+2]
Out[33]= Hold[1+2]

In[34]:= ReleaseHold[%]
Out[34]= 3

In[35]:= HoldForm[1+2]
Out[35]= 1+2

In[36]:= ReleaseHold[%]
Out[36]= 3

Unevaluated can be thought of as a temporary or one-shot Hold. It suppresses evaluation the first time the Mathematica evaluator sees it but not subsequent times. The following examples are a good illustration of the difference.

In[37]:= (*first I create a simple list *)
list = {1,2,3}
Out[37]= {1,2,3}

In[38]:= (*Now lets see what happens if we try to make list list self-referential*)
list[[3]] = list; list
Out[38]= {1,2,{1,2,3}}

In[39]:= (* What happens if we doo this again using Hold? *)
list = {1,2,3};
list[[3]] = Hold[list];
list

Out[41]= {1,2,Hold[list]}

In[42]:= ReleaseHold[%]
Out[42]= {1,2,{1,2,Hold[list]}}

In[43]:= ReleaseHold[%]
Out[43]= {1,2,{1,2,{1,2,Hold[list]}}}

Okay, that is somewhat interesting. Each time we invoke ReleaseHold the list expands unveiling another nested version of itself. What do you think happens if we do this experiment with Unevaluated instead?

In[44]:= list = {1, 2, 3};
list[[3]] = Unevaluated[list];
list
During evaluation of In[44]:= $RecursionLimit::reclim: Recursion depth of 256 exceeded. >>
During evaluation of In[44]:= $RecursionLimit::reclim: Recursion depth of 256 exceeded. >>

Out[46]= {1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,{1,2,Hold[{1,2,list}]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}

Oops! We created an never ending evaluation that eventually blows up. The only way for Mathematica to finally display the "result" is for it to force a Hold into the output to put the breaks on this runaway evaluation train! The reason for this behavior is that Unevaluated allowed us to suppress evaluation of list up until the point where it made the symbol list the new third element of the List associated with the symbol list but after that step, evaluation is no longer suppressed. So we have a symbol which contains a reference to itself and the evaluator can never stop until recursion limit is reached.


Defer is another function that acts like Hold but will allow evaluation each time it is presented to the front-end for evaluation via the user action of hitting Shift-Enter or selection the expression and using Evaluation In Place. We can use the self-referential example to see this. Here each step in the expansion was created by hitting Shift-Enter on the prior output.

In[47]:= list = {1, 2, 3};
list[[3]] = Defer[list];
list
Out[49]= {1,2,list}

In[50]:= {1,2,list}
Out[50]= {1,2,{1,2,list}}

In[51]:= {1,2,{1,2,list}}
Out[51]= {1,2,{1,2,{1,2,list}}}

In[52]:= {1,2,{1,2,{1,2,list}}}
Out[52]= {1,2,{1,2,{1,2,{1,2,list}}}}


So you can see Mathematica has quite a rich repertoire of functions and attributes whose sole purpose is to keep it for doing what it was designed to do - evaluate! The novice Mathematica user may be mystified by this but these features are essential to the functionality of Mathematica. In other words, the rich sets of features Mathematica provides would not be there if Mathematica did not contain mechanisms for controlling itself. Programming after all is the act where an individual exerts control over a (abstract) machine. But perhaps this explanation is a bit too metaphysical for your tastes. So lets get to some concrete examples. Consider the rich family of Plot functions which take other functions as input. Notice that these all have HoldAll as attributes. Think for a second why this is the case before reading on.

In[53]:= Attributes[{Plot, ParametricPlot, Plot3D}]
Out[53]= {{HoldAll,Protected},{HoldAll,Protected},{HoldAll,Protected}}

Functions that rely on delayed evaluation are typically those that are in essence little evaluation engines themselves. Think about plotting. It must take a function and evaluate it at various points so that it can map the values at those points to the graphics coordinates of points (ultimately pixels on the display device). These evaluations can not be interfered with by the normal evaluation process because in many cases that will change the input before the evaluator can do its thing. If this reasoning is correct than any function in Mathematica which repeatedly evaluates another function should utilize the Hold family of attributes. One of the simplest of these is Table so let's see.

In[54]:= Attributes[Table]
Out[54]= {HoldAll,Protected}

Yep. Various forms of control flow (If, Do, Switch) also must use held arguments for similar reasons. Another class of functions that hold arguments unevaluated are those that must act on symbolic values themselves. Examples are Clear and AddTo (+=). The following little program lists all such symbols in the System` context that have an attribute in the Hold family.

In[55]:= Select[Names["System`*"],Length[Intersection[Attributes[#],{HoldAll,HoldFirst,HoldRest,HoldAllComplete}]]>0&]
Out[55]= {AbortProtect,AbsoluteTiming,AddTo,And,Animate,AppendTo,Arrow3DBox,ArrowBox,Assuming,Attributes,BezierCurve3DBox,BezierCurveBox,Block,BlockRandom,BSplineCurve3DBox,BSplineCurveBox,BSplineSurface3DBox,Button,CancelButton,Catch,Check,CheckAbort,CheckAll,ChoiceButtons,CircleBox,Clear,ClearAll,ClearAttributes,Compile,CompiledFunction,CompoundExpression,Condition,ConeBox,ConsoleMessage,Context,ContinuedFractionK,ContourPlot,ContourPlot3D,Control,ControlActive,ControllerManipulate,CuboidBox,CylinderBox,Debug,DebugTag,Decrement,DefaultButton,DefaultValues,Defer,Definition,DensityPlot,Dialog,DialogInput,DialogReturn,DiskBox,DivideBy,Do,DownValues,DumpSave,Dynamic,DynamicBox,DynamicModule,DynamicModuleBox,DynamicWrapper,DynamicWrapperBox,Exists,FileName,FindArgMax,FindArgMin,FindMaximum,FindMaxValue,FindMinimum,FindMinValue,FindRoot,For,ForAll,FormatValues,FullDefinition,Function,GeometricTransformation3DBox,GeometricTransformationBox,Graphics3DBox,GraphicsBox,GraphicsComplex3DBox,GraphicsComplexBox,GraphicsGroup3DBox,GraphicsGroupBox,Hold,HoldComplete,HoldForm,HoldPattern,If,Increment,Information,InsetBox,Interpretation,InterpretationBox,Line3DBox,LineBox,LineIntegralConvolutionPlot,Literal,MakeBoxes,Manipulate,MatchLocalNameQ,MemoryConstrained,MenuItem,Message,MessageName,MessagePacket,Messages,Module,Monitor,Nand,NCache,NIntegrate,Nor,NProduct,NSum,NValues,Off,On,Or,OwnValues,ParametricPlot,ParametricPlot3D,Parenthesize,Pattern,PatternTest,Piecewise,Play,Plot,Plot3D,Point3DBox,PointBox,Polygon3DBox,PolygonBox,PreDecrement,PreemptProtect,PreIncrement,PrependTo,Product,Protect,Quiet,RasterBox,Reap,RectangleBox,Refresh,RegionPlot,RegionPlot3D,Remove,RuleCondition,RuleDelayed,SampledSoundFunction,Save,Set,SetAttributes,SetDelayed,SphereBox,Stack,StackBegin,StackComplete,StackInhibit,StreamDensityPlot,StreamPlot,SubtractFrom,SubValues,Sum,Switch,SystemException,Table,TagSet,TagSetDelayed,TagUnset,Text3DBox,TextBox,TimeConstrained,TimesBy,Timing,Trace,TraceDialog,TracePrint,TraceScan,TubeBezierCurveBox,TubeBox,TubeBSplineCurveBox,Unevaluated,Unprotect,Unset,UpSet,UpSetDelayed,UpValues,ValueQ,VectorDensityPlot,VectorPlot,VectorPlot3D,WaitUntil,Which,While,With,$ConditionHold,$Failed}

Here you can see that the ultimate form of holding, HoldAllComplete, is more rarely used and when it is it is for rather low-level functions.

In[56]:= Select[Names["System`*"],Length[Intersection[Attributes[#],{HoldAllComplete}]]>0&]
Out[56]= {DebugTag,HoldComplete,InterpretationBox,MakeBoxes,Parenthesize,PreemptProtect,SystemException,Unevaluated}


Recipe 2.2 Reconsidered


In recipe 2.2 of Mathematica Cookbook I consider if it was possible to create functions that Hold other combinations of arguments than provided by HoldAll, HoldFirst and HoldRest. The solution proposed using Hold as a pattern within the function itself. This awkward construct thus required you to use Hold when you invoked the function. To further un-motivate this I presented a rather lame example in the solution.

In[57]:= array1 = Table[0, {10}]; array2 = Table[1, {10}];

arrayAssign[Hold[a_Symbol],aIndex_,Hold[b_Symbol],bIndex_]:=
Module[{},
a[[aIndex]] = b[[bIndex]];
a[[aIndex]]]

(*Assign elements 2 through 3 in array 2 to array1 *)
arrayAssign[Hold[array1],2;;3,Hold[array2],1];
array1

Out[60]= {0,1,1,0,0,0,0,0,0,0}

There are several reasons this solution is lame. First off, the example is not at all practical. There is little reason to create a function to do this when you can do the same in a one line expression. But that could be forgiven by virtue of being a purely pedagogical example. The real flaw is that this technique requires you to use Hold at the call site which is nothing at all like the behavior of functions with attributes HoldFirst, HoldRest or HoldAll. A more sensibly way to achieve the same effect is to simply use HoldAll and force evaluation where required. So to use this somewhat useless example again...

In[61]:= array1 = Table[0, {10}]; array2 = Table[1, {10}];

SetAttributes[arrayAssign2,HoldAll];arrayAssign2[a_Symbol,aIndex_,b_Symbol,bIndex_]:=
Module[{aIndex2,bIndex2},
{aIndex2,bIndex2} = Evaluate[{aIndex,bIndex}];
a[[aIndex2]] = b[[bIndex2]];
a[[aIndex2]]]

(*Assign elements 2 through 3 in array 2 to array1 *)
arrayAssign2[array1,2;;3,array2,1];
array1

Out[64]= {0,1,1,0,0,0,0,0,0,0}