Re: Strange answer
- To: mathgroup at yoda.physics.unc.edu
- Subject: Re: Strange answer
- From: bert at netcom.com (Roberto Sierra)
- Date: Wed, 10 Nov 1993 17:04:32 -0800
Gigi Ventura (VENTURA at pd.infn.it) and Giacomo Torzo (TORZO at mvxpd5.pd.infn.it) pointed out the following 'strange' behavior of MMA: >In[1]:= > g1[x_]:=+x >In[2]:= > g1[2,3,4] >Out[2]= > 9 >In[3]:= > g2[x_]:=-x >In[4]:= > g2[2,3,4] >Out[4]= > -24 which can be 'corrected' by the following: >In[5]:= > g3[x_]:=-(+x) >In[6]:= > g3[2,3,4] >Out[6]= > -9 First of all, Giacomo appears to have mistyped Gigi's original definitions by leaving out an underscore. No doubt he meant g1[x__]:=+x g2[x__]:=-x g3[x__]:=-(+x) The reason that g2 behaves the way it does is not 'strange' at all, but results from two fairly obscure internal aspects of Mathematica which are being inadvertently misapplied. First of all, +x really means Plus[x], -x really means Times[-1,x], and -(+x) really means Times[-1,Plus[x]]. Though there is an operator Minus[x], it expands automatically to Times[-1,x], and also only accepts a single argument (thus Minus[a,b,c] would be illegal, unlike Plus[a,b,c]). Note that some other functions expand automatically, for example Sqrt[x] expands out to Power[x,Rational[1,2]] wherever it appears. Second, when a repeated pattern like x__ is used, a rather strange internal object representation is used to pass multiple arguments along to the 'right hand' side of the definition. Argument sequences like 2,3,4 are passed using Sequence objects, as in Sequence[2,3,4]. Unfortunately, the Sequence object is an undocumented internal object that few people know about. Its basic function appears to be to allow argument sequences to be 'spliced' into other function calls. For example, Foo[a,Sequence[b,c,d],e] is exactly equivalent to typing Foo[a,b,c,d,e] Thus, with g1[x__] defined as +x (or Plus[x]), the x argument is passed to Plus as a Sequence object, so that g1[2,3,4] is evaluated as Plus[Sequence[2,3,4]], which reduces to Plus[2,3,4], which reduces to 9. With g2[x__] defined as -x (or Times[-1,x]), the x argument is also passed as a Sequence object, so that g1[2,3,4] is exactly equivalent to Times[-1,Sequence[2,3,4]], or Times[-1,2,3,4], or -24. Though this is not what one would expect *mathematically* -x to do, this is what one would expect MMA to do from a *programmatic* standpoint, considering that the *pattern* x corresponds to a sequence of arguments to be directly spliced into the right hand equation, -x, which happens to be represented internally as Times[-1,x]. My experience is that you need to be careful when you use a repeated pattern which can match multiple arguments and not blindly paste them into right hand expressions. Typically, by introducing a 'fence' object -- something that will convert volatile Sequence objects into something safer, like a List -- you can work with multiple arguments with impunity. Once converted to a List, you can manipulate the list to produce whatever results are desired. Thus, a 'clean' (though ugly) way to compute the desired result might be g4[x__] := - (Plus @@ {x}) This results in the following evaluation of g4[2,3,4] Times[-1, Apply[Plus, List[Sequence[2,3,4]] ]] Times[-1, Apply[Plus, List[2,3,4] ]] Times[-1, Plus[2,3,4] ] Times[-1, 9] -9 Of course, Plus is also 'safe' to splice an argument sequence directly into, so a simpler way to do the same thing would be g3[x__] := -Plus[x] This looks odd, but is exactly equivalent to Gigi's original definition of g3, namely g3[x__]:=-(+x) which also produces the desired result, -9. Hope this clears up the mystery. Mathematica is strange, but not *that* strange when you get to know it. \\|// "Television is a medium -- it is - - neither rare nor well done." o o -- Ernie Kovacs J roberto sierra O tempered microdesigns NOTICE: \_/ san francisco, ca The ideas and opinions expressed bert at netcom.com herein are not those of the author.