next | previous | forward | backward | up | index | toc

# installing augmented assignment methods

In most cases, the default behavior of augmented assignment gives the desired result. But in some situations, it may be useful to override this behavior and install a custom method for a given type.

Consider the following example.

 i1 : Foo = new SelfInitializingType of MutableList; i2 : net Foo := x -> net x#0; i3 : Foo + Foo := (x, y) -> Foo {x#0 + y#0}; i4 : x = Foo {1} o4 = 1 o4 : Foo i5 : y = Foo {2} o5 = 2 o5 : Foo i6 : x += y o6 = 3 o6 : Foo

Note that an intermediate Foo object was created and then assigned to x. Instead, it would be more efficient if x was modified directly.

The first two lines below do exactly the same thing; the second line is syntactic sugar for the first.

 i7 : installMethod(symbol +=, Foo, (x, y) -> (x#0 += y#0; x)); i8 : Foo += (x, y) -> (x#0 += y#0; x); i9 : x += y o9 = 5 o9 : Foo

In some cases, it may be useful to fall back on the default behavior of the given operator. When this is desired, the installed method should return the Default symbol.

 i10 : Bar = new SelfInitializingType of List; i11 : net Bar := x -> net x#0#0; i12 : Bar * Bar := (x, y) -> Bar {{x#0#0 * y#0#0}}; i13 : Bar *= (x, y) -> if isMutable x#0 then ( print "using custom method"; x#0#0 *= y#0#0; x) else Default; i14 : x = Bar {new MutableList from {3}} o14 = 3 o14 : Bar i15 : y = Bar {{4}} o15 = 4 o15 : Bar i16 : x *= y using custom method o16 = 12 o16 : Bar i17 : y *= x o17 = 48 o17 : Bar