MathGroup Archive 2010

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

Search the Archive

Re: Foo /: Plus[b_Foo] := b

  • To: mathgroup at smc.vnet.net
  • Subject: [mg114567] Re: Foo /: Plus[b_Foo] := b
  • From: Andrzej Kozlowski <akoz at mimuw.edu.pl>
  • Date: Wed, 8 Dec 2010 06:40:04 -0500 (EST)

First, there is no bug.

Second: this is all due to the Flat and OneIdentity attributes of Plus, or rather the effect these attributes have on pattern matching. You can show this in two ways. One, just remove the OneIdentity attribute of Plus and the behaviour will go away (but of course Plus will no be seriously deranged):

ClearAttributes[Plus, OneIdentity]

Foo /: Plus[b_Foo] :== b;

In[6]:== 1 + Foo[1]

Out[6]== Foo(1)+1

Alternatively, define a new function plus with both of these attributes:

SetAttributes[plus, {Flat, OneIdentity}]

Foo /: plus[b_Foo] :== b;

Now

plus[1, Foo[1]]

produces the same behaviour as you saw with Plus.

The best explanation I know appeared a long time ago on this forum and was 
due to Allan Hayes. It is quite complex and I am not prepared to try to repeat it here. In any case, it should still be possible to find it in the archives. (It may perhaps also appear on other Mathematica related pages with or without attribution to Allan but it certainly was he who succeeded best in decoding this riddle).

The behaviour of these attributes is certainly not fully documented and probably will never be. Why? I guess it is because it belongs to the very foundations of the Mathematica language and I think there is nobody today at Wolfram who still thinks about such issues but this is, of course, just a guess. I think Allan's explanation will always remain as close as anyone will ever come to explaining this matter.

Andrzej Kozlowski



On 7 Dec 2010, at 12:46, kj wrote:

> An innocent-looking upvalue for a brand new symbol Foo:
>
> In[1]:== Foo /: Plus[b_Foo] :== b;
>
>
> Nothing shocking about this rule: it just recapitulates the default
> behavior of Plus when given a single argument.  And it seems to
> work:
>
> In[2]:== Plus[Foo[1]]
> Out[2]== Foo[1]
>
>
> ...but disaster lurks just around the corner:
>
> In[3]:== 1 + Foo[1]
> During evaluation of In[3]:== $IterationLimit::itlim: Iteration limit of 4096 exceeded. >>
> Out[3]== Hold[1 + Foo[1]]
>
>
> I was expecting that 1 + Foo[1] would evaluate to itself, not an
> infinite loop....  So I examined a trace:
>
> In[4]:== ToString[
>  StringForm["``",
>   FullForm /@ Take[Quiet[Trace[1 + Foo[1]]], 10] // ColumnForm]]
>
> Out[4]== "HoldForm[Plus[1, Foo[1]]]
> HoldForm[Plus[1, Foo[1]]]
> HoldForm[Plus[1, Foo[1]]]
> HoldForm[Plus[1, Foo[1]]]
> HoldForm[Plus[1, Foo[1]]]
> HoldForm[Plus[1, Foo[1]]]
> HoldForm[Plus[1, Foo[1]]]
> HoldForm[Plus[1, Foo[1]]]
> HoldForm[Plus[1, Foo[1]]]
> HoldForm[Plus[1, Foo[1]]]"
>
>
>
>
> Judging from the trace, the evaluator is attempting to evaluate
> the same expression over and over.  The evaluator is supposed to
> stop when it reaches a fixed point, and that looks like a fixed
> point if I ever saw one.  (In fact, in this case, we started at
> the fixed point to begin with!)  So either there's a very serious
> bug in the evaluator, or the documentation I read on the subject
> was wrong about how it's supposed to work.  (FWIW, this is Mathematica
> 7.)
>
>
> Whatever it is that I'm doing wrong, it seems to me *very fundamental*.
> IOW, this does not look to me like some obscure corner case.  If
> so, I can't understand how I could have missed it in all the reading
> I've done about Mathematica over the years.  It's occurrences like
> this that fuel my *paranoia* about the Mathematica documentation.
>
> If someone can tell me 1) what I'm doing wrong above, and hopefully
> 2) how to fix it, I'd much appreciate it.  Also, if you could point
> me to where in the documentation I would have learned the answers
> to these questions I'd be grateful.
>
> TIA!
>
> ~kj
>
>
>


  • Prev by Date: Re: Foo /: Plus[b_Foo] := b
  • Next by Date: Re: Are these bugs fixed in Mathematica 8 ?
  • Previous by thread: Re: Foo /: Plus[b_Foo] := b
  • Next by thread: Re: Foo /: Plus[b_Foo] := b