It seems that D's operator overloading is a bit silly in some cases w.r.t. opAddAssign, opSubAssign, etc. Consider the following example:
struct Foo { Foo opAdd(Foo rhs) { return this; } } void main() { Foo foo; Foo bar; foo = foo + bar; // Works. foo += bar; // Doesn't work. } I'm thinking (not sure if this was proposed here before a while back and I just forgot where I heard it from) that the default behavior of someObject.opXAssign(otherStuff); should be to expand into someObject = someObject.opX(otherStuff); if opXAssign is not overloaded. Besides the programmer being too lazy to explicitly overload opXAssign, I just found another use case. Suppose you have a bunch of classes and you're overloading operators such that each call builds another layer of decorators. For example: class SomeClass { SomeClass opAdd(SomeClass rhs) { // SomeDecorator is a subclass of SomeClass. return new SomeDecorator(this, rhs); } } In this case, you *can't* overload SomeClass.opAddAssign in any reasonable way because you can't assign SomeDecorator to this, but translating someInstance.opAddAssign(someOtherInstance) into someInstance = someInstance.opAdd(someOtherInstance) makes perfect sense.