tcl::mathop is a Tcl 8.5 namespace that contains commands equivalent to the [expr] operators. These commands are all bytecode compiled. Changing or adding to these commands does not change the expr operators themselves.
AMG: The following table lists all commands (operators) in this namespace and defines their behavior by showing their expression equivalents. Parentheses are used to indicate associativity.
Operation or test | Cmd | 0 | 1 | 2 | 3 or more arguments |
---|---|---|---|---|---|
Bitwise negation | ~ | err | ~a | err | err |
Logical negation | ! | err | !a | err | err |
Arithmetic negation | - | err | -a | ||
Addition | + | 0 | a | a+b | ((a+b)+c)+... |
Multiplication | * | 1 | a | a*b | ((a*b)*c)*... |
Shift left | << | err | err | a<<b | err |
Exponentiation | ** | 1 | a | a**b | a**(b**(c**...)) |
Subtraction | - | a-b | ((a-b)-c)-... | ||
Division | / | err | 1./a | a/b | ((a/b)/c)/... |
Remainder | % | err | err | a%b | err |
Arithmetic shift right | >> | err | err | a>>b | err |
Bitwise and | & | -1 | a | a&b | ((a&b)&c)&... |
Bitwise inclusive or | | | 0 | a | a|b | ((a|b)|c)|... |
Bitwise exclusive or | ^ | 0 | a | a^b | ((a^b)^c)^... |
Numeric equality | == | 1 | 1 | a==b | ((a==b)&&(b==c))&&... |
String equality | eq | 1 | 1 | a eq b | ((a eq b)&&(b eq c))&&... |
Numeric inequality | != | err | err | a!=b | err |
String inequality | ne | err | err | a ne b | err |
List membership | in | err | err | a in b | err |
List non-membership | ni | err | err | a ni b | err |
Strict increasing order | < | 1 | 1 | a<b | ((a<b)&&(b<c))&&... |
Increasing order | <= | 1 | 1 | a<=b | ((a<=b)&&(b<=c))&&... |
Strict decreasing order | > | 1 | 1 | a>b | ((a>b)&&(b>c))&&... |
Decreasing order | >= | 1 | 1 | a>=b | ((a>=b)&&(b>=c))&&... |
The - command is something of a changeling. In its unary form, it negates its first (and only) argument. For higher arity, it negates every argument except its first and returns the sum. While this may seem counterintuitive, it does match the behavior of the - expr operator.
Exponentiation (**) is right-associative.
Short-circuit logic (&&, ||) isn't supported because it cannot be implemented in Tcl. Tcl always eagerly determines the value of each argument before passing it to the command. For this, just keep using expr:
% expr {1==1 && [puts hello] eq ""} hello 1 % expr {1==0 && [puts hello] eq ""} 0 % expr {1==0 || [puts hello] eq ""} hello 1 % expr {1==1 || [puts hello] eq ""} 1
Shift right is arithmetic, not bitwise, meaning that the sign bit is unchanged by the operation. For two's-complement machines, arithmetic and bitwise shift left produce the same results.
A simple example, because I couldn't immediately work out the incantation to make mathops visible. Note that functions and operators come from different namespaces:
namespace import ::tcl::mathop::* namespace import ::tcl::mathfunc::* puts [* [sqrt 49] [+ 1 2 3]]
Alternatively:
namespace path {tcl::mathop tcl::mathfunc} puts [* [sqrt 49] [+ 1 2 3]]
There are better examples of the use of mathop scattered through the wiki; somebody should add links to some of the ones less obvious to non-lispers!
AMG: You can also use [namespace path ::tcl::mathop] to add to the namespace search path.
RS 2008-09-17: Should you only want to import the * multiplication operator, escape it with backslash, to distinguish from "*" meaning "all":
% namespace import tcl::mathop::\\* % + 2 3 invalid command name "+" % * 2 3 6