Re: An open letter
- To: mathgroup at smc.vnet.net
- Subject: [mg16792] Re: An open letter
- From: "Johan Gunnarsson" <johan at kestrel.edu>
- Date: Tue, 30 Mar 1999 02:35:05 -0500
- Organization: Concentric Internet Services
- References: <7cleqb$9oh@smc.vnet.net> <7ct1oq$82d@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
The responces to this letter have given a good illustration to the problem of "Hold"-programming in Mathematica. Jack Goldberg wrote: > I am fairly confident that this type of problem can be solved by > a judicious combination of "holds" and "releaseholds" and "evaluates". Mark Kraus wrote: >And HoldForms and all the stuff related (I remember Unevaluated and >Literal, but never was able to apply these things in a sensible way). My answer to this is: Forgett about ReleaseHold, Evaluate, and Unevaluated since these don't really help the idea of how to do Hold-programming in a structured way. The answer is simpel pattern matching with Replace. I will give an alternative implementation of the ByParts. This one will produce the left hand side only and not the whole equation which makes ByParts a mapping from expressions to expression which is prefereable. SetAttributes[ByParts,HoldAll]; ByParts[HoldForm[Integrate[f_, x_]] | Integrate[f_, x_], HoldForm[g_] | g_ ] := Module[{int, nf}, int = Integrate[g, x]; nf = f/g; Replace[Simplify[{nf*int, int*D[nf, x]}], {term_, integrand_} :> HoldForm[term - Integrate[integrand, x]] ] ] Here how it works: 1. To be able to write or past expression into ByParts we need to prevent evaluation by the HoldAll attribute. 2. ByParts returns the whole result wrapped in HoldForm which makes it more systematic compared to have HoldForm scattered everywhere in the expression. The fix to put HoldForm on the head of Integrate like HoldForm[Integrate][....] will look nice on the output but the structure is destroyed since the pattern Integrate[_,_] will not match on that. No good. 3. To make the function output fit its input for being able to apply functions several times, the function input must be able to accept HoldForm on top. The input to ByParts above can be both with or without HoldForm. 4. Now the most important, Replace! To produce the result of the function without worring about Hold, Evaluate, Unevaluated .... think as follows: Since Replace do rule replacement first and then evaluation you can't do Replace[HoldForm[....], pattern:>rhs] if the rhs contains things that you hope to evaluate. Instead put the structure of the result (or result template) as the rhs of the rule and put all the things that needs to be evaluated in the first position of the Replace and use the rule to put the evaluated expression in place within the HoldForm, like Replace[{exp1,exp2,...}, {x1_, x2_, ...}:>HoldForm[....] ] It is clear from my experiance (which is code transformation) that Replace used like this will make the code much easier to read compared to all these trix with Evaluate etc. Test it In[102]:= ByParts[Integrate[x^2 Sin[x], x], Sin[x]] // OutputForm Out[102]//OutputForm= 2 -(x Cos[x]) - Integrate[-2 x Cos[x], x] Regards /Johan Gunnarsson MathCore, http://www.mathcore.com