Procedure Parameter Modifiers
•
|
Parameter modifiers change the way that arguments are evaluated and or assigned to procedure parameters. There are several modifiers available, and they appear as part of the parameter's type declaration. The modifiers are:
|
|
The expects Modifier
|
|
•
|
This modifier changes an optional ordered parameter to an expected ordered parameter, indicating that an argument in the function call can be omitted only if all further arguments are also omitted. If there is an argument available, it must match the declared type of the parameter or an exception is raised.
|
>
|
f := proc(b::expects(integer) := 100.1) b^2 end proc:
|
| (1) |
| (2) |
|
|
The seq Modifier
|
|
•
|
The seq modifier allows the parameter to match multiple arguments. When a parameter with a declared type of seq(memberType) is encountered, it consumes all arguments starting from the next available one until an argument not of type memberType is encountered.
|
|
Note: It is entirely possible for no arguments to match the memberType. In that case, the parameter takes on one of two values:
|
–
|
If the parameter is a required positional parameter, it takes on the value NULL, which is Maple's name for the empty sequence.
|
–
|
If the parameter is an optional ordered parameter, it takes on the specified default value.
|
•
|
Because seq matches even when no arguments match the memberType, this modifier cannot be used together with the expects modifier. Expecting zero or more of something is always satisfied.
|
•
|
The seq modifier cannot be used with a keyword parameter.
|
•
|
Care must be taken when working with the value of a seq parameter because it might have just one element in it. Such a value is no longer a sequence, thus indexing it will not select the element. The safest way to use a seq parameter is to turn it into a list as soon as possible (for example xList := [xSeq];).
|
>
|
f := proc( x::seq(integer), other::seq(anything) )
local max, n;
max := -infinity;
for n in [x] do
if n > max then max := n end if
end do;
max, [other]
end:
|
| (3) |
>
|
f(4,7,"not an integer",8,2,1);
|
| (4) |
|
|
The depends Modifier
|
|
•
|
Usually, the type of a parameter is predetermined when the procedure is written. When Maple matches arguments to parameters, it does not evaluate the parameter's type, since this is not expected to yield anything different than what was written.
|
•
|
There are cases where this is too restrictive, and the depends modifier tells Maple that the parameter's type is dependent on something else which may change, and that it is to be evaluated each time it is used for argument matching. Most commonly, the dependency is on another parameter. For example, one might want to write a procedure to find the roots of a polynomial.
|
>
|
one_sol := proc( p::depends(polynom(integer,v)), v::symbol )
local sols;
sols := [ solve(p=0,v) ];
if sols = [] then
error "no solution"
else
sols[1]
end if
end proc:
|
| (5) |
•
|
This procedure expects as its first parameter, p, a polynomial in the variable specified by the second parameter, v. If the depends modifier were omitted, the procedure would only accept polynomials in the global variable, v.
|
•
|
The depends modifier can only be used with required parameters. It cannot be used for optional or expected ordered parameters, nor keyword parameters. If the depends modifier is used together with the seq modifier, it must appear inside the other modifier. That is, the declaration must be written: seq(depends(type)).
|
|
Note: The type in the depends modifier must evaluate to a proper Maple type. It cannot evaluate to anything containing additional modifiers.
|
|
|
The uneval Modifier
|
|
•
|
Unlike all the other modifiers discussed so far, the uneval modifier takes no arguments. What uneval does is prevent evaluation of the corresponding argument at function call time, as if the argument had been enclosed in unevaluation quotes, ('...').
|
•
|
Like evaln, uneval can only be used for required positional parameters. It also cannot be used in conjunction with any other modifiers, or in a parameter declaration after one with the seq modifier.
|
>
|
f := proc(x::uneval) x^2 end proc:
|
| (6) |
| (7) |
|
|
The evaln Modifier
|
|
•
|
This modifier can be used in two different forms, evaln or evaln(valueType). A parameter declared with the evaln modifier expects an argument that can be evaluated to a name (like the Maple function evaln would do). If a valueType was specified, the resulting name is expected to have a value matching that type.
|
•
|
In effect, declaring a parameter with the evaln modifier is equivalent to enclosing the argument with an evaln call at function call time, and allows procedures to be written where the user of the procedure does not have to remember to do so.
|
•
|
The evaln modifier may only be used for required positional parameters.
|
•
|
The only supported case of using evaln with other modifiers is depends(evaln(valueType)), which declares that valueType depends on some other parameter(s). The depends(evaln) combination is not permitted, since it is meaningless.
|
•
|
A parameter using either form of evaln may not appear after any parameter using the seq modifier.
|
•
|
Note: Use of an evaln or uneval modifier alters the usual argument processing sequence. Keyword arguments are not recognized until after all required positional parameters up to and including the rightmost one with such a modifier have been assigned arguments.
|
>
|
f := proc(x::evaln(integer)) x^2 end proc:
|
| (8) |
>
|
accumulate := proc(r::evaln(numeric), n::numeric)
r := eval(r) + n
end proc:
|
| (9) |
| (10) |
| (11) |
| (12) |
|
|
The coercion Modifiers
|
|
•
|
Coercion refers to the ability to pass one type of data to a procedure and have it receive a different type. The passed data is coerced or converted to the new type behind the scenes. The user of the procedure benefits by being able to use a larger variety of data types, which may all look alike. The author of the procedure benefits by being able to focus on handling only the best data type suited to the task.
|
•
|
Coercion can be enabled in a procedure in one of two ways.
|
|
Coercion Using ~Type
|
|
•
|
A programmer can use built-in coercion functions named with a tilde (~) prefix follwed by a type. For example, the command, ~Matrix will accept, among other things, a listlist and return a Matrix. Such a ~ function can be used in place of the type in a procedure parameter declaration. This tells Maple to try testing if the passed parameter is of that type, and if not, call the ~ function to turn it into (or coerce it into) that type. Users can write their own ~ procedures at the top-level or as a module export.
|
>
|
p := proc( m::~Matrix )
whattype( m );
end;
|
| (13) |
>
|
p( Array( [ [ 1, 2 ], [ 3, 4 ] ] ) );
|
| (14) |
>
|
p( Vector[row]( [ 5,6,7 ] ) );
|
| (15) |
>
|
p( [ [ 1,2,3 ], [ 4,5,6 ], [7,8,9] ] );
|
| (16) |
|
|
Explicit Coercion
|
|
•
|
Explicit coercion allows the procedure to declare how different types should be converted. To enable explicit coercion, the coerce() modifier should be used. The coerce modifier allows a programmer to specify a sequence of types and coercion procedures. A coercion procedure is a procedure that accepts a single typed parameter and converts that parameter into a new expression. When the main procedure is called the argument is type checked against the coercion procedure's parameter types. The first coercion procedure whose parameter's type matches the type of the argument is called. This is similar to how overloaded procedures work. The return value of the matching coercion procedure is then used as the parameter's value.
|
>
|
p_string := proc( s::coerce( string, (s::name)->convert(s,string) ) )
s;
end;
|
| (17) |
>
|
p_string( "a string" );
|
| (18) |
| (19) |
•
|
In the example above, the first call to p_string succeeded in matching the type string, so the argument was passed to the procedure unchanged. The second call matched the type name declared as the input type of the in-line arrow procedure. This caused the convert(s,string) command to be invoked resulting in a new value -- nolonger a name, to be passed as the argument. In both cases the body of the procedure, p_string sees the parameter s as having a string type.
|
•
|
If there is no matching coercion procedure, then an error is raised
|
|
•
|
For a complete discussion of data type coercion, see the coercion help page.
|
|
|
Details
|
|
|
For further information on parameters, see
|
|
|