13
$\begingroup$

Bug (of Interval) introduced in 10, persisting through 12.2.


As we know we can assign special addition rules to symbols by using UpValues:

ClearAll[mySymbol]
mySymbol /: mySymbol + x_ := {mySymbol, x}

They are used when we directly add something to mySymbol

mySymbol + 5
(* {mySymbol, 5} *)
mySymbol + mySymbol
(* {mySymbol, mySymbol} *)

but also when we use some other functions as += (AddTo):

ClearAll[tmp]
tmp = mySymbol;
tmp += 5
(* {mySymbol, 5} *)
tmp
(* {mySymbol, 5} *)

In Mathematica versions 8 and 9 it also worked when we added expression to itself:

$Version
(* "9.0 for Linux x86 (64-bit) (February 7, 2013)" *)
ClearAll[tmp]
tmp = mySymbol;
tmp += mySymbol
(* {mySymbol, mySymbol} *)
tmp
(* {mySymbol, mySymbol} *)

In versions 10.0, 10.1 and 10.2 it doesn't work like that anymore and AddTo, when adding same expressions, always returns 2 times expression even if Plus was overridden.

$Version
(* "10.0 for Linux x86 (64-bit) (December 4, 2014)" *)
ClearAll[tmp]
tmp = mySymbol;
tmp += mySymbol
(* 2 mySymbol *)
tmp
(* 2 mySymbol *)

Is this a bug, or should we not rely on overridden Plus when using functions like AddTo and override them separately?


Edit

It seems some built-ins, like Interval, relied on this and are broken in v10:

$Version
(* "10.0 for Linux x86 (64-bit) (December 4, 2014)" *)
ClearAll[tmp]
tmp = Interval[{0, 1}, {4, 5}];
tmp + tmp
(* Interval[{0, 2}, {4, 6}, {8, 10}] *)
tmp += tmp
(* Interval[{0, 2}, {8, 10}] *)
$\endgroup$
10
  • 6
    $\begingroup$ I'd say the latter, because relying on AddTo picking up Plus overloading is relying on implementation details, namely that AddTwo uses Plus behind the scene. This may be so (as it was before), or may be not (as it apparently is now), but one can't really rely on this relation. $\endgroup$ Commented Sep 9, 2015 at 14:24
  • $\begingroup$ @Leonid While I don't disagree regarding user defined functions. There seems to be a bug related to this in Interval implementation. $\endgroup$
    – jkuczm
    Commented Sep 9, 2015 at 14:35
  • 3
    $\begingroup$ As @Leonid says, before version 10, AddTo used the top-level equivalents of Set and Plus, thus calling the evaluator, which caused serious inefficiencies. They have now been corrected. $\endgroup$
    – ilian
    Commented Sep 9, 2015 at 14:35
  • $\begingroup$ Well, then ask a question about that bug :) Oh, I see you did. $\endgroup$ Commented Sep 9, 2015 at 14:39
  • 4
    $\begingroup$ Yes, I think the Interval example is a bug and filed a report. Thank you for pointing it out. $\endgroup$
    – ilian
    Commented Sep 9, 2015 at 14:48

1 Answer 1

6
$\begingroup$

You can use Hold to simulate the behavior you originally had

$Version

(* "10.2.0 for Mac OS X x86 (64-bit) (July 7, 2015)" *)

ClearAll[mySymbol]
mySymbol /: mySymbol + x_ := {mySymbol, x}
mySymbol /: mySymbol + Hold[x_] := {mySymbol, x}

tmp = mySymbol;
tmp += 5

(* {mySymbol, 5} *)

tmp = mySymbol;
tmp += Hold[mySymbol]

(* {mySymbol, mySymbol} *)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.