// This program simulates operator overloading for adding objects. class Rectangle { var width var length new[w,l] := { width = w length = l } getArea[] := width * length } class AreaObject { var area new[a] := area = a getArea[] := area } // Define transformation rule to add rectangles and create an AreaObject // as a result. //_a is Rectangle + _b is Rectangle <-> new AreaObject[_a.getArea[] + _b.getArea[]] _a is Rectangle + _b is Rectangle <-> new AreaObject[_a.getArea[] + _b.getArea[]] // Define another rule that adds a rectangle to an AreaObject. This allows // an arbitrary number of Rectangles to be added together commutatively! // The expression transformer also handles any ordering. _a is Rectangle + _b is Rectangle + _c <-> new AreaObject[_a.getArea[] + _b.getArea[]] + _c //_a is AreaObject + _b is Rectangle <-> new AreaObject[_a.getArea[] + _b.getArea[]] x = new Rectangle[10 ft, 1 ft] y = new Rectangle[100 ft, 20 ft] z = new Rectangle[5 ft, 7 ft] // This just gives an unevaluated Rectangle[] + Rectangle[] println[x+y] // This actually transforms and solves. c = transformExpression[x+y] println[c] println[eval[c]] // Try a commutative result println[eval[transformExpression[x+y+z]]]