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