Language - Maple Help

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.
 Types specop and anyop
 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 )' );
 ${\mathrm{true}}$ (1)
 > type( a + b, 'specop( anything, + )' );
 ${\mathrm{true}}$ (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) );
 ${\mathrm{true}}$ (3)
 • The new type patfunc (see type/structure) is similar to the type anyfunc, except that only the first $n-1$ specified argument types are matched with the initial $n-1$ arguments of the functional form, and the last specified argument type is only matched with each of the remaining arguments, if they exist. The variation of this type patfunc[reverse] matches the last $n-1$ argument types with the first specified argument type matching any preceding arguments.
 > type( f(1,2,opt1,opt2), patfunc(numeric,numeric,name) );
 ${\mathrm{true}}$ (4)
 Types for indexed forms
 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));
 ${\mathrm{true}}$ (5)
 > type(a(p)[1,2],typeindex(integer,function));
 ${\mathrm{true}}$ (6)
 Type patlist
 The new type patlist (see type/structure) recognizes a particular list form, analogous to the functionality of type patfunc.  It matches the first $n-1$ 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 $n-1$ operand types with the first specified operand type matching any preceding list operands.
 > type( [3,"A","B"], patlist(integer,string) );
 ${\mathrm{true}}$ (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 )' );
 ${\mathrm{true}}$ (8)
 > subtype( 'polynom', '{ string, algebraic }' );
 ${\mathrm{true}}$ (9)
 > subtype( 'procedure[ ratpoly ]( rational )', 'procedure[ algebraic ]( integer )' );
 ${\mathrm{true}}$ (10)
 > subtype( 'procedure( integer )', 'procedure( algebraic )' );
 ${\mathrm{false}}$ (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' ) ) );
 $\left\{{x}{,}{F}{}\left({G}{}\left({x}{,}{y}\right){,}{H}{}\left({y}\right)\right){,}{G}{}\left({x}{,}{y}\right)\right\}$ (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:
 > type( 7, m:-mytype );
 ${\mathrm{true}}$ (13)
 > type( 9, m:-mytype );
 ${\mathrm{false}}$ (14)
 > type( 9, mytype ); # no global type namespace pollution

Other Types

 New RootOf 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 );
 ${a}{≔}{\mathrm{RootOf}}{}\left({{\mathrm{_Z}}}^{{2}}{-}{\mathrm{_Z}}{-}{2}{,}{\mathrm{index}}{=}{1}\right)$ (15)
 > type( a, abstract_rootof );
 ${\mathrm{false}}$ (16)
 > type( a, specified_rootof );
 ${\mathrm{true}}$ (17)
 Type attributed
 The new type attributed tests whether an expression has attributes or specified attributes.
 > type( sin, 'attributed( protected )' );
 ${\mathrm{true}}$ (18)
 > setattribute( x, green ):
 > type( x, attributed );
 ${\mathrm{true}}$ (19)
 Type record
 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.
 > type( x, global );
 ${\mathrm{true}}$ (20)
 > type( convert( x, local ), global );
 ${\mathrm{false}}$ (21)
 > type( convert( x, local ), local );
 ${\mathrm{true}}$ (22)

Changes to Debugging Facilities

 • It is now possible to trace the execution of procedures local to a module.

Miscellaneous

 Inert Representation
 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.
 Assign Function
 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(a, b, c, d);
 > assign((u, v, w) = (x, y, z));
 produce the same assignments as the following two statements:
 > a := b, c, d:
 > u, v, w := x, y, z:
 Convert to Global
 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;
 ${f}$ (23)
 > result := a(3);
 ${\mathrm{result}}{≔}{x}{}\left({3}\right){+}{\mathrm{sin}}{}\left({3}\right){+}{3}$ (24)
 > evalb(result = x(3) + sin(3) + 3);
 ${\mathrm{false}}$ (25)
 > evalb(convert(result, global) = x(3) + sin(3) + 3);
 ${\mathrm{true}}$ (26)
 > evalb(b = f);
 ${\mathrm{false}}$ (27)
 > f();
 ${f}{}\left(\right)$ (28)
 > evalb(convert(b, global, assign) = f);
 ${\mathrm{true}}$ (29)
 > f();  # the global 'f' is assigned what MyFunctions:-f is assigned
 ${x}{+}{\mathrm{sin}}{+}{3}$ (30)