RE: Unexpected behaviour of HoldRest
- To: mathgroup at smc.vnet.net
- Subject: [mg45707] RE: [mg45678] Unexpected behaviour of HoldRest
- From: "Wolf, Hartmut" <Hartmut.Wolf at t-systems.com>
- Date: Wed, 21 Jan 2004 04:54:52 -0500 (EST)
- Sender: owner-wri-mathgroup at wolfram.com
John, you'r right, as Sequence[] should be used with care. Up to Version 4 it was an undocumented function and the only mention to it I found was from Roman Maeder (who is, or was an insider; and Carl Woll certainly had read his books). Almost ever the use of Sequence can be avoided (although it might come handy), and in this group its use has been popularized more than it deserves. Even OrderedUnion -- which was a stroke of genius at its time -- nowadays with the modern versions of Mathematica (packed arrays, improved Split, Ordering) clearly no longer is the fastest way to do it! Sequence should be used with care and presupposes an exact knowledge and understanding of the Mathematica evaluation sequence. (Further comments interspersed) >-----Original Message----- >From: John Tanner [mailto:john at janacek.demon.co.uk] To: mathgroup at smc.vnet.net >Sent: Monday, January 19, 2004 11:15 AM >To: mathgroup at smc.vnet.net >Subject: [mg45707] [mg45678] Unexpected behaviour of HoldRest > > >Inspired by Carl Woll's OrderedUnion (for which many, many thanks!) I >have found similar uses for Sequence[], such as using >replacement rules: > >In[1]:= {{0,1,2,3,2},3,2} /. 2->Sequence[] > >Out[1]= {{0, 1, 3}, 3} > The right way to do that: In[2]:= DeleteCases[{{0, 1, 2, 3, 2}, 3, 2}, 2, 2] Out[2]= {{0, 1, 3}, 3} >But I recently found an "unexpected" result: > >In[1]:= If[1 == 1, Sequence[], 2] > >Out[1]= 2 > Well, it should be expected, Sequence will be "flattened out" when the arguments are evaluated _before_ the expression If itself is being evaluated (unless it had the SequenceHold or HoldAllComplete attribute, but it has neither of them) In[4]:= Attributes[If] Out[4]= {HoldRest, Protected} Such in a first step If[1 == 1, Sequence[], 2] is evaluated to If[True, Sequence[], 2] now Sequence objects will be flattened out irrespectively of HoldRest, therefore the expression is transformed to If[True, 2] only then rules for If are applied, hence Out[1] >Now when presented in this form it is "obvious", that Sequence[] is >being "flattened out" of the arguments to If. The wanted behaviour of >If in this case can be restored if SequenceHold is applied: > >In[3]:= Unprotect[If]; > SetAttributes[If, SequenceHold]; > Protect[If]; > >In[6]:= If[1 == 1, Sequence[], 2] > >Out[6]= Sequence[] > Dont't do that! We cannot overview the consequences of such a global intervention. Instead act locally: In[7]:= If[1 == 1, Unevaluated[Sequence[]], 2] Out[7]= Sequence[] This now allows to do other things, e.g. In[3]:= Map[If[# === 2, Unevaluated[Sequence[]], #] &, {{0, 1, 2, 3, 2}, 3, 2}, 2] Out[3]= {{0, 1, 3}, 3} >But If has (I now find) the Attribute HoldRest, and Hold does not >flatten out Sequence[] so I don't understand why that does not apply >here also. > Hold has the attributes In[6]:= Attributes[Hold] Out[6]= {HoldAll, Protected} hence it flattens out Sequence[..] In[5]:= Hold[Sequence[], If[1 == 1, Sequence[], 2]] Out[5]= Hold[If[1 == 1, Sequence[], 2]] (Of course there will be no operation for and _within_ the held expression.) >In[7]:= xx[1+2,2+3,3+4] > >Out[7]= xx[3,5,7] > >In[8]:= SetAttributes[xx,HoldRest] > >In[9]:= xx[1+2,2+3,Sequence[],3+4] > >Out[9]= xx[3,2+3,3+4] > You just showed that HoldRest has nothing to do with all that. >Relatively few built-in functions have SequenceHold applied: > >{AbsoluteTiming, Rule, RuleDelayed, Set, SetDelayed, TagSet, >TagSetDelayed, Timing, UpSet, UpSetDelayed} > >And also relatively few built-in functions have HoldRest applied: > >{Assuming, DumpSave, If, PatternTest, RuleDelayed, Save, Switch} > Yes, the main reason is for so-called lazy evaluation. Would you imagine what happend when If lacked this attribute? Not only that many parts of the expression had to be evaluated in vain, and never used for the result, also side effects would become completely unpredictable (more than is anyway). >I will therefore now be much more careful of the use of Sequence! At >present I don't want to be more daring and apply these attributes >wholesale without understanding why this is happening. There must be >other cases where Sequence can have unexpected effects - I now >understand some of the problems I had when trying to use [mg13201] to >modify $Post - >reallyBig needs to cope with Sequence[] and Sequence[__]. > >-- > from- John Tanner email- john at janacek.demon.co.uk > mantra- curse Microsoft, curse... web - >http%##www.janacek.demon.co.uk/ >I hate this 'orrible computer, I really ought to sell it: >It never does what I want, but only what I tell it. > I agree, see also the Book about evaluation (e.g. §A.4.1) -- Hartmut Wolf
- Follow-Ups:
- Re: RE: Unexpected behaviour of HoldRest
- From: Andrzej Kozlowski <akoz@mimuw.edu.pl>
- Re: RE: Unexpected behaviour of HoldRest