MathGroup Archive 2007

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Re: What is the purpose of the Defer Command?


On 8 Oct 2007, at 13:04, Vince Virgilio wrote:

> On Oct 7, 5:55 am, Andrzej Kozlowski <a... at mimuw.edu.pl> wrote:
>> On 6 Oct 2007, at 17:46, Vince Virgilio wrote:
>>
>>
>>
>>
>>
>>> On Oct 5, 5:01 am, "David Park" <djmp... at comcast.net> wrote:
>>>> I do not understand the utility of the new Defer statement in
>>>> Mathematica
>>>> Version 6. Also, it seems to me to be similar to, but not as good
>>>> as, the
>>>> HoldTemporary command introduced by Ted Ersek on MathSource a few
>>>> years ago.
>>
>>>> The help for Defer says: "Defer[expr] yields an object that
>>>> displays as the
>>>> unevaluated form of expr, but which is evaluated if it is
>>>> explicitly given
>>>> as Mathematica input." What does 'given as Mathematica input'
>>>> mean? The
>>>> examples seem to only involve copying and pasting, which I don't
>>>> consider a
>>>> great method for doing mathematics, or evaluation in place.
>>
>>>> I would like to understand how Defer might be used in expository
>>>> notebooks
>>>> to clarify some piece of mathematics. The problem is that it
>>>> requires an
>>>> interactive action, which would be invisible to a reader of a
>>>> notebook.  I
>>>> think the idea of 'modification in place' is poor in technical
>>>> communication
>>>> because it destroys the record of what was done.
>>
>>>> (In the examples below, whenever an output resulted in an
>>>> expression that
>>>> copied as a box structure, I converted to InputForm to simplify the
>>>> posting.)
>>
>>>> Here is a simple example:
>>
>>>> y = Defer[1 + 1]
>>>> 1 + y                                               giving
>>
>>>> 1 + 1
>>
>>>> 1 + (1 + 1)
>>
>>>> I would prefer that the Defer expression would have evaluated in
>>>> the second
>>>> statement but I guess it is logical that it didn't. If I write:
>>
>>>> 1 + y
>>
>>>> then select the y and Evaluate In Place I obtain the following,
>>>> which must
>>>> then be further evaluated to obtain 3.
>>
>>>> 1 + 1 + 1
>>
>>>> 3
>>
>>>> A second example. I want to show an integral without evaluation
>>>> and then the
>>>> evaluated result. I have to write the following expression, then
>>>> select the
>>>> second line of output, evaluate in place, and then I obtain the
>>>> result - but
>>>> as an Input cell. This is certainly a place where HoldForm would
>>>> be better.
>>
>>>> Defer[Integrate[x^2 Exp[-x], {x, 0, 1}]]
>>>> %
>>>> giving
>>
>>>> Integrate[x^2/E^x, {x, 0, 1}]
>>
>>>> 2 - 5/\[ExponentialE]                        (which is an Input  
>>>> cell)
>>
>>>> Here is third example. Defer does not evaluate and we obtain an  
>>>> error
>>>> message.
>>
>>>> numb = Defer[2^67 - 1]
>>>> FactorInteger[numb]                                       giving
>>
>>>> 2^67 - 1
>>
>>>> FactorInteger::"exact" :  "\"Argument \!\(\*SuperscriptBox[\"2\", \
>>>> \"67\"]\) - 1 in FactorInteger[\!\(\*SuperscriptBox[\"2\", \"67\"]
>>>> \) \
>>>> - 1] is not an exact number\""
>>
>>>> FactorInteger[2^67 - 1]
>>
>>>> But it works if I copy and paste into FactorInteger.
>>
>>>> Now, look at the behavior of Ted's MathSource package.
>>
>>>> Needs["Enhancements`HoldTemporary`"]
>>
>>>> y = HoldTemporary[1 + 1]
>>>> 1 + y                                                        giving
>>
>>>> 1 + 1
>>
>>>> 3
>>
>>>> The expression is evaluated if it is an argument of some function.
>>
>>>> HoldTemporary[Integrate[x^2 Exp[-x], {x, 0, 1}]]
>>>> Identity[%]
>>>> giving
>>
>>>> Integrate[x^2/E^x, {x, 0, 1}]
>>
>>>> 2 - 5/\[ExponentialE]       (which is an Output cell)
>>
>>>> numb = HoldTemporary[2^67 - 1]
>>>> FactorInteger[numb]                                             
>>>> giving
>>
>>>> 2^67 - 1
>>
>>>> {{193707721, 1}, {761838257287, 1}}
>>
>>>> Much better. I might be missing the point, but I don't think that
>>>> Defer is
>>>> at all well designed.
>>
>>>> There is another Hold that is very useful. This is one that  
>>>> holds an
>>>> operation but evaluates the arguments. We have a HoldOp statement
>>>> in the
>>>> Tensorial package.
>>
>>>> Needs["TensorCalculus4V6`Tensorial`"]
>>
>>>> ?HoldOp
>>
>>>> HoldOp[operation][expr] will prevent the given operation from being
>>>> evaluated in expr. Nevertheless, other operations within expr  
>>>> will be
>>>> evaluated. Operation may be a pattern, including alternatives, that
>>>> represents heads of expressions. The HoldOp can be removed with
>>>> ReleaseHold.
>>
>>>> One reason we want the arguments to evaluate is that the arguments
>>>> often
>>>> contain tensor shortcut expressions and we want them evaluated to
>>>> show the
>>>> full tensor expression inside some operation. However, there are
>>>> many other
>>>> uses.
>>
>>>> f[x_] := Sin[x] \[ExponentialE]^x
>>
>>>> We would like f[x] to be evaluated inside the Integrate statement,
>>>> but hold
>>>> the actual itegration.
>>
>>>> Integrate[f[x], {x, 0, \[Pi]}] // HoldOp[Integrate]
>>>> % // ReleaseHold
>>>> giving
>>
>>>> HoldForm[Integrate[E^x*Sin[x], {x, 0, Pi}]]
>>
>>>> 1/2 (1 + \[ExponentialE]^\[Pi])
>>
>>>> For exposition purposes we might want to keep the following
>>>> expression in
>>>> the input order.
>>
>>>> \[Pi]  Sin[x] \[ExponentialE]^x // HoldOp[Times]
>>>> % // ReleaseHold
>>>> giving
>>
>>>> HoldForm[Pi*Sin[x]*E^x]
>>
>>>> \[ExponentialE]^x \[Pi] Sin[x]
>>
>>>> Often we will have cases where some operation has automatic built-
>>>> in rules,
>>>> such as linear and Leibnizian breakouts with differentiation.
>>>> Again, for
>>>> exposition purposes, we might want to show the expression before
>>>> these rules
>>>> are applied.
>>
>>>> g[x_] := x^2
>>
>>>> D[a f[x] g[x], x] // HoldOp[D]
>>>> % // ReleaseHold                                    giving
>>
>>>> HoldForm[D[a*E^x*x^2*Sin[x], x]]
>>
>>>> a \[ExponentialE]^x x^2 Cos[x] + 2 a \[ExponentialE]^x x Sin[x] +
>>>>  a \[ExponentialE]^x x^2 Sin[x]
>>
>>>> --
>>>> David Park
>>>> djmp... at comcast.nethttp://home.comcast.net/~djmpark/
>>
>>> Perhaps Defer is a kind of better-behaved Unevaluated:
>>
>>> 1. That disappears even when not an argument to another function
>>> 2. And that terminates infinite evaluation immediately.
>>
>>> ?
>>
>>> Vince Virgilio
>>
>> Better-behaved Unevaluated ?  I can't see any (or almost any)
>> relation between the two, and certianly no "better behavior".
>>
>> Head[Unevaluated[1 + 1]]
>> Plus
>>
>> Head[Defer[1 + 1]]
>> Defer
>>
>> That's a pretty basic difference.
>>
>> Andrzej Kozlowski- Hide quoted text -
>>
>> - Show quoted text -
>
> Your example doesn't go far enough. It shows only an incidental
> syntactic difference.
>
> Now that I've read the documentation for Defer, I think my comparison
> is quite apt, and that the semantics between Defer and Unevaluated
> align much more than their syntax differs. And yet there is
> significant difference, that is not essentially syntax.
>
> The documentation uses Defer in an example to create cells with
> unevaluated contents. Before, one might try the same with Unevaluated
> (hence the strong relation). But that would give cells with contents
> wrapped in Unevaluated, since Unevaluated is not removed when it's
> Head of "Mathematica input" (Level 0, I suppose). (Substitute
> Unevaluated for Defer in the example to see this.) This is the
> idempotent behavior of Unevaluated. Defer, while it remains as Head of
> Level 0 (your difference), does not show such idempotent behavior (my
> "better-behaved" difference).
>
> Interesting, and apparently a fix. For why would one ever want
> Unevaluated to linger? (Anyone?) I think Robby Villegas issued a
> related caveat in his notebook on Unevaluated expressions.
>
> Vince Virgilio
>
>

I could hardly agree less. There is an obvious similarity between  
Defer and HoldForm and this is the only apt comparison. Unevaluated  
is entirely different. Between the two, Unevaluated and HoldForm  
cover all possible uses not involving copying and pasting or  
evaluation in place. The need for the latter is all that  
distinguishes Defer from HoldForm. Note also that the documentation  
for Defer mentions HoldForm but never Unevaluated. Of course you are  
free to insist that to you "Defer" is just like "Unevaluated" (but  
better) but then some people claim that tofu is just like ice-cream  
but more healthy.  At this level of discussion all such comparisons  
are equally "valid". But if one turns concrete examples, one can  
observe two things.

1. Unevaluated is an extremely useful function, and there is not  
other function that can fully replace it in its use (certainly not  
Defer). Just search the archive of this list and you will find many  
examples of its use. On the other hand, Defer is a good candidate for  
the most useless function in Mathematica there is. If you do not  
agree, please post one example of its use (Jens Kuska has posted the  
only plausible candidate so far but in my opinion even that it is  
hardly something any one will ever use). I suspect that Defer exists  
only because someone at WRI found himself (probably temporarily) with  
too much free time and it took him about 3 minutes to implement this.

2. Similarity with Unevaluated and HoldForm (or Hold) Here is just  
one simple example of using Unevaluated:

Unevaluated[1 + 2*I] /. HoldPattern[I] -> 3

7

We can do it with HoldForm but the code will have to be longer:

ReleaseHold[HoldForm[1 + 2*I] /. HoldPattern[I] -> 3]
7

Now, if you tried to use Defer here you could, of course, do:

Defer[1 + 2*I] /. HoldPattern[I] -> 3
  1 + 2 3

and then use evaluation in place. But that is an extra step and one  
that not many will find this approach to their liking. Hardly worth a  
new function. Of course you could do:

Defer[1 + 2*I] /. HoldPattern[I] -> 3 /. Defer -> Identity
  7

but then you could have used HoldForm or Hold here with the same effect.

In this example clearly Defer works simply like Hold or HoldForm  
except that you need to use evaluation in place or copying and  
pasting instead of ReleaseHold. Unevaluated is quite different. It  
would you seem not to agree with this. So please then post a concrete  
example where Defer works more like Unevaluated than HoldForm and  
does not require copying and pasting or evaluation is place.  Or even  
better, please answer the original poster and show us an example  
where it is actually useful.


Andrzej Kozlowski


  • Prev by Date: Re: Plot3D with NDSolve
  • Next by Date: RE: Plot3D with NDSolve
  • Previous by thread: Re: What is the purpose of the Defer Command?
  • Next by thread: Re: What is the purpose of the Defer Command?