The : Operator

Calling Sequence


m:e
:e


Description


•

The binary member selection operator, , is used to name module exports outside the scope in which they are defined. It is a noncommutative, leftassociative 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.

•

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 order of the numtheory package, use numtheory[':order']. (Since the numtheory package is implemented as a module, you could equally use numtheory:order, but the latter syntax works only with modulebased packages.)



Examples


>


>


 (1) 
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 .
>


>


 (2) 
>


 (3) 
In the following example, to call the exported procedure order from the numtheory package, you must use the unary prefix form of the operator.
>


>


>


 (4) 
>


>


 (5) 
>


 (6) 
Prefix form of : for writing an export that uses and shadows a predefined global symbol. Note its use on both QUAT and `+`.
>

Q := module()
export `+`;
`+` := proc( a, b )
local answer;
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 )
else
answer
end if
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 )
else
# Call the global `+`
:`+`( a, b )
end if;
end proc;
end module:

>


 (7) 
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.
>


>

p1 := proc(a, b)
local midpoint;
midpoint := 3;
2 * student[ ':midpoint' ]( a, b ) / midpoint
end proc:

>

p2 := proc(a, b)
local midpoint;
midpoint := 3;
2 * student[ 'midpoint' ]( a, b ) / midpoint
end proc:

>

p3 := proc(a, b)
local midpoint;
midpoint := 3;
2 * student[ :midpoint ]( a, b ) / midpoint
end proc:

Of these three routines, only p1 operates correctly.
>


 (8) 
>


 (9) 
>


 (10) 

