The :- Operator
The binary member selection operator, :−, is used to name module exports outside the scope in which they are defined. It is a non-commutative, left-associative operator. The first (left) operand is evaluated and must evaluate to a module. The second (right) operand is not evaluated and must be a symbol exported by the module to which the first operand evaluates.
Important: It is a syntax error for the second operand of the :− operator to be other than a symbol. It is a runtime error for the first operand of the :− operator to evaluate to anything other than a module.
The :− operator can also be used as a unary, prefix operator, whose sole operand is a symbol. The expression :-sym evaluates to the global instance of sym, even if there is a local binding for sym in scope.
The fact that the second operand of the :− operator is not evaluated can be problematic when you want to construct the member selection expression dynamically using an export name that is provided at runtime. For this reason, the indexing operation () has been overloaded in such a way that, for a module m, the expression m[e] evaluates to the member selection expression m:−f after first evaluating the expression e, resulting in f.
Since the subexpression e in m[e] is evaluated, it is often necessary to use unevaluation (right) quotes when accessing module members using this syntax, with e a name. Moreover, if a local name with the same external representation is in scope, the unary prefix form of the :− operator must be used (assuming that the index is supposed to be a global name). For example, to call the exported procedure Chi of the combinat package, use combinat[':-Chi']. (Alternatively, since the combinat package is implemented as a module, you could equally use combinat:-Chi, but the latter syntax works only with module-based packages.) See also UsingPackages.
m ≔ module_export⁡e;e ≔ 2end module:
Since numeric constants are not symbols, the command m:-3; would give a syntax error. Similarly, an error results from the following, since m does not export the symbol f.
Error, module does not export `f`
S ≔ SimpleStack⁡a,b,c:
In the following example, to not call the exported procedure Chi from the combinat package, you must use the unary prefix form of the :− operator.
Error, (in combinat:-Chi) two partitions of the same sum expected
r ≔ Record⁡'a'=2,'b'=3,'c'=4:
slots ≔ seq⁡re,e=a,b,c
Prefix form of :- for writing an export that uses and shadows a pre-defined global symbol. Note its use on both QUAT and `+`.
Q := module()
`+` := proc( a, b )
if andmap(type,[a,b],'specfunc( algebraic, :-QUAT )' )
and map( nops, [ a, b ] ) = [ 4, 4 ] then
answer := ':-QUAT'( seq( op( i, a ) + op( i, b ), i = 1 .. 4 ) );
if andmap( Testzero, [op]( 2 .. 4, answer ) ) then
op( 1, answer )
elif type(a,'specfunc( algebraic, :-QUAT )' ) then
procname( a, ':-QUAT'( b, 0, 0, 0 ) )
elif type(b,'specfunc( algebraic, :-QUAT )' ) then
procname( ':-QUAT'( a, 0, 0, 0 ), b )
# Call the global `+`
:-`+`( a, b )
These examples illustrate the need to use unevaluation quotes and the prefix form of the :- operator when accessing package exports. The quotes are always necessary, since you have no control over what is assigned at the top level. The use of a :- prefix is needed only when there is a local name that provides a conflicting binding.
midpoint ≔ 2:
p1 := proc(a, b)
midpoint := 3;
2 * student[ ':-midpoint' ]( a, b ) / midpoint
p2 := proc(a, b)
midpoint := 3;
2 * student[ 'midpoint' ]( a, b ) / midpoint
p3 := proc(a, b)
midpoint := 3;
2 * student[ :-midpoint ]( a, b ) / midpoint
Of these three routines, only p1 operates correctly.
Download Help Document