Object Operator Methods - Maple Programming Help

Home : Support : Online Help : Programming : Objects : object/operators

Object Operator Methods

overview of object operators

Operators

 • Maple objects can implement methods to allow objects to be used with the standard Maple operator syntax.  The following example shows how an object can implement the ^ operator.
 > module MyInteger()    option object;    local value := 0;    export ModuleCopy::static := proc( mi::MyInteger, proto::MyInteger, v::integer, $) if ( _npassed = 3 ) then mi:-value := v; else mi:-value := proto:-value; end if; end proc; export ModuleApply::static := proc( ) Object( MyInteger, _passed ); end proc; export toInt::static := proc( mi::MyInteger,$ )        mi:-value;    end proc;    export ModulePrint::static := proc( mi::MyInteger )        mi:-value;    end proc;    export ^::static := proc( i1::MyInteger, i2::MyInteger )        MyInteger( i1:-value ^ i2:-value );    end proc; end module:
 > i1 := MyInteger( 1 ):
 > toInt( i1 );
 ${1}$ (1)
 > i2 := MyInteger( 2 ):
 > toInt( i2 );
 ${2}$ (2)
 > i3 := MyInteger( 3 ):
 > toInt( i3 );
 ${3}$ (3)
 > i8 := i2^i3:
 > toInt( i8 );
 ${8}$ (4)

Supported Operators

 • The following operators can be implemented by an object:
 • +, -, *, /, ^, !, .
 • =, <>, <, <=, >, >=
 • and, or, not, xor, implies
 • intersect, union, minus, subset, in
 • [], {}, ?[]
 • &*
 • &name
 • The following operators, in particular, cannot be overridden:
 • ::, ?(), :-, ,, ->, :=
 • Note: These lists are not the same as the operators that can and cannot be overridden using a use statement.

Implementing Operators

 • In general, implementing operators is similar to implementing any object method.  See the Overview of Object Methods page for more details.
 • Whenever an object with an overloaded operator appears in an expression using that operator the overloaded operator will be used, including within the definition of the operator itself.  Thus one must be careful to avoid writing an infinitely recursive routine.  To use a different version of the operator, the fully qualified functional form should be used.

Special Considerations

The + and  Operators

 • The + and * operators are n-ary as opposed to binary. In other words, a large sum or product containing objects will be converted to a single call to the + or * method, with each term passed as an argument.  Thus the operator should be able to accept more than two arguments.
 • By accepting more than two arguments, the operator can analyze the entire statement at once and work intelligently on multiple objects in a single expression.
 • The following + operator implements addition for any number of MyInteger objects:
 > export +::static := proc( ints::seq(MyInteger), \$ )     local x;     MyInteger( add( toInt(x), x in [ints] ) ); end proc:
 • These two operators may also return a sequence instead of a single value. In this case, the sequence will be converted into a unevaluated sum or product DAG.  This only occurs when the function is called as an operator or method, but not if called as a fully qualified function.
 • For example:
 > module Obj()    option object;    export ModuleApply::static := proc( )        'Obj';    end proc;    export *::static := proc( )         local x;         op( map( x->f(x), [_passed] ) );    end proc; end module;
 ${\mathbf{module}}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{Obj}}\left({}\right)\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{option}}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{object}}{;}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{end module}}$ (5)
 • When the * operator defined above is called with multiple elements, it returns an expression sequence instead of a single element.  When used as an operator, the expression sequence is converted to a product.
 > Obj * x * y;
 ${f}{}\left({\mathbf{module}}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{Obj}}\left({}\right)\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{option}}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{object}}{;}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{end module}}\right){}{f}{}\left({x}\right){}{f}{}\left({y}\right)$ (6)
 • Likewise when the operator is called as a member function:
 > *( Obj, x, y );
 ${f}{}\left({\mathbf{module}}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{Obj}}\left({}\right)\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{option}}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{object}}{;}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{end module}}\right){}{f}{}\left({x}\right){}{f}{}\left({y}\right)$ (7)
 • However, when called as a fully qualified function, the conversion does not occur.
 > Obj:-*( Obj, x, y );
 ${f}{}\left({\mathbf{module}}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{Obj}}\left({}\right)\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{option}}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathrm{object}}{;}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{}\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}{\mathbf{end module}}\right){,}{f}{}\left({x}\right){,}{f}{}\left({y}\right)$ (8)

The = and <> Operators

 • An object can implement the = and <> operators.  If an object implements the = operator but not the <> operator, the = operator will be used when <> is called in the following way:
 – true becomes false
 – false becomes true
 – FAIL remains unchanged
 – other values x are returned as not x

Consequences of Implementing ?[]

 • The indexing operator, ?[], is called when an object is indexed (for example, object[index]).  As objects are implemented on top of modules, the indexing syntax has a default functionality for accessing module members, module[member].  If an object overloads the indexing operator, this default behavior is lost, and the module:-member syntax must be used instead. It is up to the implementer to decide whether to support the module[member] syntax in the ?[] export.
 • Together with lowerbound and upperbound, the indexing operator can be used for implementing iteration over an object, as an alternative to implementing a ModuleIterator procedure. See ModuleIterator for more details.

 • The || operator is the name concatenation operator.  Thus the left hand side of a || statement evaluates to a name.  This means that if a name whose value is an object appears on the left hand side of a || statement, that object will not be searched for an overloaded ||.
 • The || operator is used when evaluating the cat routine.  As cat uses the normal evaluation rules, a name with an object for a value will be searched for an overloaded ||, regardless of where it appears in the argument sequence.

The in Operator

 • The operator in (displayed as $\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}∈\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}$) can be used to test membership in lists and sets. If an object does not export in but does export member, then Maple will use member to decide membership: evaluation of the expression $a\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}∈\phantom{\rule[-0.0ex]{0.5em}{0.0ex}}b$ in a Boolean context, where $a$ or $b$ (or both) are objects exporting member results in a call to that procedure. Evaluation in a Boolean context happens, for example, in the condition of an if statement or in a call to evalb.
 • The help page Object,builtin explains the details of writing a member export.