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.

See Also

Math Operators as Commands
additional discussion
a closely-related feature that exposes math functions, as opposed to math operators, as Tcl commands.


official reference


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|0aa|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 ""}
% expr {1==0 && [puts hello] eq ""}
% expr {1==0 || [puts hello] eq ""}
% expr {1==1 || [puts hello] eq ""}

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]]


  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