overview of objects overloading builtins - Maple Help

Online Help

All Products    Maple    MapleSim


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

Objects Overloading builtins - overview of objects overloading builtins

Overloading builtin Routines

• 

An object may override a routine by exporting a method of the same name. Any routine implemented in Maple code can be overridden.  However, not all routines of type builtin can be overridden.  This page discusses how to override those builtin routines. Operators that can be overridden are discussed on the page object,operators.

Overridable builtin Routines

• 

The following builtin functions can be overridden by object methods:

abs

anames

conjugate

convert

diff

eval

evalhf

evalf

expand

has

hastype

Im

indets

length

lowerbound

map, map[n], map2

max

member

min

normal

numboccur

Re

subs

trunc

type

upperbound

 

 

 

 

 

 

Special Considerations

• 

If an object implements a method to override a builtin routine, that method is still a procedure that follows the normal binding rules within the object declaration.  This means that Maple may call the override even when the programmer wanted to call the top-level routine.  To make sure that a function call invokes the top-level routine, use the fully qualified name. (Even when using the fully qualified name, if any of the arguments are objects exporting that name, the override will typically be called from within the builtin function.)

Overriding Particular Routines

• 

Special considerations for overriding particular operators are described in the object,operators help page.

and, or, xor, and not

• 

When evaluating an expression involving the operator form and an object (myObject and something), this will result in a call to the corresponding method. When evaluating the function form (`and`(myObject, something)), this initially results in the operator form being constructed but not evaluated. When the operator form is later evaluated (e.g. by evalb or in the condition of an if statement) the method is invoked.

convert

• 

A convert method needs to be able to deal with three possibilities: converting to the object from another type, converting from an object to another type, and applying a conversion where the object is an extra parameter (the third or later argument).

diff

• 

A diff method needs to handle three possibilities: differentiating an object, differentiating with respect to an object, or both.

• 

If an object exports a diff method, it should also export a has method.  Maple uses has to determine if an expression contains the variable of differentiation.  If has returns false, 0 is returned immediately.  The built-in version of has does not look inside of objects, and thus will return false.

eval

• 

There are two calling sequences for the built-in eval.

eval( expr );

eval( expr, substitutions );

• 

An object's eval method only overrides the second calling sequence.

• 

As eval works recursively, if expr contains an object that implements eval, that object's eval method will be called.

• 

In the second calling sequence of the built-in eval, the substitutions can be specified in various ways.  The eval method will have each equation passed as a separate argument.

evalhf

• 

Implementing an evalhf method allows an object to be used in Maple's evalhf subsystem.  An evalhf method should convert the object into one of the types that evalhf can manipulate.  For the best performance, one of the following should be returned:

– 

A hardware float

– 

An hfarray

– 

A Maple procedure that does not use lexical scoping

evalf

• 

An evalf method should convert the object into a floating point value.

• 

The evalf method is often called with an index (evalf[digits]) to specify the number of digits the expression should be evaluated to.  When the object method is called, the value of the Digits environment variable will have been set if a value was given.

has

• 

The has method checks to see if an object contains an expression, if an expression contains an object, or if one object is contained in another.

• 

When declaring an object that exports a has method that uses the object name as a type, the named object syntax

module Obj()
   ...
end module:

should be used.  Using the assignment syntax

Obj := module()
   ...
end module:

will cause an error to be raised during the assignment if the has method uses Obj as a type. The has routine is invoked when a top-level assignment occurs, to check if the name being assigned to is contained in the value being assigned to it. This is an attempt to avoid recursive assignments.  The has method will be called for this assignment, but as the object's name has not been assigned, the type checks will fail.

lowerbound, upperbound, and ?[]

• 

These three can be used together to implement iteration over an object, as an alternative to implementing a ModuleIterator procedure. See ModuleIterator for more details, and object,operators for special considerations when implementing `?[]`.

map, map2, and map[n]

• 

The map, map2 and map[n] functions are all overridden by a single map method.  The calling sequence of the map method is:

export map::static := proc( oindex::integer, inplace::truefalse, func )
   ...
end proc:

 

oindex: corresponds to the index of the expression to be mapped over.

inplace: determines if the map should occur in-place.  If in-place mapping is not supported, then an exception should be raised if inplace is true.

func: the function to be mapped.

• 

If the parameter declaration given above is used, then the special sequence _rest are the arguments to be passed to func and the element _rest[oindex] is the element to be mapped over.  If e is an element of _rest[oindex] then the mapped value should be:

func( _rest[..oindex-1], e, _rest[oindex+1..] )

max and min

• 

To override the max and min routines, export methods with the following declaration:

export max::static := proc( definedOnly::truefalse, a, b:=NULL, $ )
   ...
end proc;

export min::static := proc( definedOnly::truefalse, a, b:=NULL, $ )
   ...
end proc;

 

definedOnly: corresponds to max['defined']( .. ) and determines the behavior when undefined values are compared.  When definedOnly is true, undefined values should be ignored (that is, a defined value should be returned).  When definedOnly is false, the routines should return FAIL when an undefined value is encountered.

• 

In Maple the max and min routines work on a combination of containers and elements.  To handle these cases, the methods must be able to handle the case where b is NULL, indicating that it should return the maximum (or minimum) value stored in a container object or just the object itself, if it is not a container.  In the general case, a and b will have a value and at least one of a or b is an object.  If the object is a container, then the maximum (or minimum) value between the elements in the object and the other argument should be returned.  Otherwise the maximum (or minimum) value of a and b should be returned.

• 

If an object does not define min or max, Maple will attempt to determine the correct element using an overloaded < operator, if it is defined.

member

• 

The member method determines if a container contains a value.  If the container does contain the value, member should return the index that can be used by ?[] to retrieve that element.  If the container does not contain the value, 0 should returned.

• 

If an object wants to implement member but does not implement the ?[] method, it should return undefined if the value is in the container, and 0 if it is not.

• 

More information on the consequences of implementing ?[] can be found in object,operators.

• 

Evaluating an expression of the form a&in;b can result in a call to member. More details can be found in object,operators.

normal

• 

The normal method has the following signature:

export normal::static := proc( self, { expanded::truefalse = false }, $ )
   ...
end proc:

 

expanded: true or false depending on if the expanded option was given to normal.

subs

• 

The subs method has the following signature:

export subs :: static := proc( inplace::truefalse, eqns::{list,MyObject}, expr::anything, $ )
   ...
end proc:

 

inplace: determines if the substitutions should happen in-place if possible.

eqns: either a list of substitutions or an object whose subs method was invoked.

• 

If eqns is a list, then the third argument (expr) is the object whose subs method was invoked.  If the second argument is an object with a subs method, then the third parameter can be anything.

type

• 

Objects can be used directly as types and an Object can define a ModuleType method to further refine this test.  However, this does not allow an object to be tested by types that are not aware of the object. You can accomplish this by overriding the type method.

• 

When the first argument of a call to type is an object that exports a type method and the second argument is not a module type and not the name `module`, then the type override will be called.

export type :: static := proc( self::MyObject, t, $ )
   :-type( self:-value, t )
end proc:

• 

The first argument is the object, the second argument is the given type.

• 

The type override should return one of three values:

– 

true : the object does match the given type

– 

false : the object does not match the given type

– 

NULL : undecided, the type checking continues as if the type override had not been written.

See Also

module, Object, object, object,create, object,method, object,operators


Download Help Document

Was this information helpful?



Please add your Comment (Optional)
E-mail Address (Optional)
What is ? This question helps us to combat spam