Language and System changes in Maple 7
|
Maple 7 includes the following language and system changes.
|
|
Linking and Calling External Routines
|
|
|
Wrapperless External Calling
|
|
The external calling mechanism no longer requires the generation and use of an external C wrapper function. In most cases, data conversion can be done by Maple itself without need of a compiler. This functionality is now the default behavior, however, C wrappers can be used or generated by providing the WRAPPER option to define_external.
|
|
|
New and Enhanced Programming Features
|
|
•
|
Procedures can now have return types. The closing bracket of the argseq may optionally be followed by :: and a type, followed by a ;. This is not a type declaration, but rather an assertion. If kernelopts(assertlevel) is set to 2, the type of the returned value will be checked as the procedure returns. If the type violates the assertion, then an exception is raised.
|
•
|
Equations can now have attributes.
|
•
|
The record constructor has been renamed Record. The name record is now deprecated and will be removed in a future release of Maple. Please use the new name Record in all new code and update any existing use of record.
|
•
|
The Record constructor now accepts typed slot names and initializers.
|
•
|
The coefficients of the polynomial argument of maxnorm can now be complex. For complex coefficients, maxnorm finds the maximum of the absolute values of the real and imaginary parts.
|
•
|
If any of cpulimit, datalimit, and stacklimit is explicitly set to zero via, for example, kernelopts(cpulimit=0), this is now understood to mean "no restriction".
|
•
|
Three new infix operators have been added: subset, xor, and implies.
|
•
|
One new infix operator has been added to support the new local assume facility: assuming.
|
•
|
The dot operator (`.`) has been extended to represent the usual dot product between Vectors having the same orientation.
|
|
|
Changes to the Type System
|
|
|
New Structured Types
|
|
|
Several new structured types (see type/structure) have been introduced.
|
|
The new types specop and anyop (see type/structure) are similar to the types specfunc and anyfunc, except that they recognize an extended range of structured forms involving infix operators in addition to functional forms.
|
>
|
type( F( 2, 3 ), 'specop( anything, F )' );
|
| (1) |
>
|
type( a + b, 'specop( anything, `+` )' );
|
| (2) |
|
Types typefunc and patfunc
|
•
|
The new type typefunc (see type/structure) is similar to the type specfunc, except that the type of the function name is checked rather than the name itself.
|
>
|
type( f[1](x), typefunc(name,indexed) );
|
| (3) |
>
|
type( f(1,2,opt1,opt2), patfunc(numeric,numeric,name) );
|
| (4) |
|
The new types specindex, anyindex, typeindex, and patindex (see type/structure) recognize various indexed forms and are analogous to the types specfunc, anyfunc, typefunc, and patfunc .
|
>
|
type(a[1,2],specindex(integer,a));
|
| (5) |
>
|
type(a(p)[1,2],typeindex(integer,function));
|
| (6) |
|
The new type patlist (see type/structure) recognizes a particular list form, analogous to the functionality of type patfunc. It matches the first specified types with the initial list operands and the last specified type with any remaining list operands. The variation of this type patlist[reverse] matches the last operand types with the first specified operand type matching any preceding list operands.
|
>
|
type( [3,"A","B"], patlist(integer,string) );
|
| (7) |
|
|
The subtype function
|
|
|
A new command subtype has been added that can determine the subtyping relationship between some pairs of types. A type A is a subtype of a type B if every expression of type A is also of type B. While primarily intended for comparing the types of procedures and modules, it can determine subtyping relationships among many structured and built-in types.
|
>
|
subtype( 'vector( 2, integer )', 'vector( rational )' );
|
| (8) |
>
|
subtype( 'polynom', '{ string, algebraic }' );
|
| (9) |
>
|
subtype( 'procedure[ ratpoly ]( rational )', 'procedure[ algebraic ]( integer )' );
|
| (10) |
>
|
subtype( 'procedure( integer )', 'procedure( algebraic )' );
|
| (11) |
|
|
Type satisfies
|
|
|
The new type satisfies may be used to embed arbitrary predicates in Maple's structured type system. This has two important consequences:
|
|
- it avoids having to pollute the global type namespace with inappropriate types, and
|
|
- it allows you to leverage the namespace management facilities provided by Maple's module system to implement ``local types''.
|
•
|
Since indets does not accept arbitrary predicates as its second (optional) argument, type satisfies may be used to construct ``one of'' types that need not be permanently installed in the type system (where they do not belong).
|
>
|
indets( F( G( x, y ), H( y ) ), 'satisfies'( rcurry( has, 'x' ) ) );
|
| (12) |
•
|
A module can define computed types embracing arbitrary predicates (which need not be exported!) using type satisfies.
|
>
|
m := module()
export mytype;
local mypredicate;
mytype := 'satisfies'( mypredicate );
mypredicate := e -> type( e, 'odd' ) and numtheory[ 'issqrfree' ]( e );
end module:
|
| (13) |
| (14) |
>
|
type( 9, mytype ); # no global type namespace pollution
|
|
|
Other Types
|
|
|
The new types abstract_rootof and specified_rootof distinguish between RootOf data structures that represent, respectively, all the roots of an equation and a specific root of an equation.
|
>
|
a := RootOf( x^2-x-2, index=1 );
|
| (15) |
>
|
type( a, abstract_rootof );
|
| (16) |
>
|
type( a, specified_rootof );
|
| (17) |
>
|
type( sin, 'attributed( protected )' );
|
| (18) |
>
|
setattribute( x, green ):
|
| (19) |
|
Records, which are simply modules without locals and having the option record, are recognized by the new type record. It performs the same type checking as type `module` does, but requires the module to be a record as well.
|
|
Type `local` and `global`
|
|
The types `local` and `global` check whether a symbol is either a local variable or a global variable.
|
| (20) |
>
|
type( convert( x, `local` ), `global` );
|
| (21) |
>
|
type( convert( x, `local` ), `local` );
|
| (22) |
|
|
|
Changes to Debugging Facilities
|
|
•
|
It is now possible to trace the execution of procedures local to a module.
|
|
|
Miscellaneous
|
|
|
In some situations, it is convenient to work with an inert representation of an expression. The new functions ToInert and FromInert perform conversions between Maple expressions and corresponding inert forms.
|
|
The assign function has been updated to accept similar calling sequences as the assignment statement. For example, the following calls to the assign procedure:
|
>
|
assign((u, v, w) = (x, y, z));
|
|
produce the same assignments as the following two statements:
|
|
The conversion to global has been updated to allow more localized conversion of local or exported variables to global variables. For example, the following example takes all locals and exports from the module MyFunctions and converts them to global, assigning the global names the values the locals and exports held:
|
>
|
MyFunctions := module()
export f;
f := proc() local x; x + sin + 3 end;
end module:
|
>
|
use MyFunctions in
a := f();
b := f;
end use;
|
| (23) |
| (24) |
>
|
evalb(result = x(3) + sin(3) + 3);
|
| (25) |
>
|
evalb(convert(result, `global`) = x(3) + sin(3) + 3);
|
| (26) |
| (27) |
| (28) |
>
|
evalb(convert(b, `global`, assign) = f);
|
| (29) |
>
|
f(); # the global 'f' is assigned what MyFunctions:-f is assigned
|
| (30) |
|
|