3

我想在 Tcl 中创建一个新的操作符,操作符是指可以按以下方式使用的 proc:

$a**2代替pow($a,2)

或者在我的情况下,我想要一个与浮点数相同的运算符,<=>=对于浮点数,意味着:

proc <f= {a b {epsilon 1e-15} {
  if {$a < $b} {return 1}
  return [expr abs($a - $b) < $epsilon]
}

但我想将其用作:

if {$a <f= $b} {...

代替”

if {[<f= $a $b]} {...

和同样的>f=

4

2 回答 2

7

您无法完全实现这一点,但有一个选项可能会有所帮助。

从 Tcl 8.5 开始,可以通过在命名空间中创建命令来为迷你语言定义任意函数,请注意:exprtcl::mathfunc

% set tcl::mathfunc::epsilon 1e-15
1e-15
% proc tcl::mathfunc::feq {a b} {
   variable epsilon
   expr {abs($a - $b) < $epsilon}
}
% expr { feq(1, 2) }
0
% expr { feq(1, 1) }
1
% expr { feq(1, 1 + 1e-16) }
1
% if {feq(1, 1 + 1e-16)} { puts OK } else { puts FAIL }
OK

并且通过一些导入/导出mumbo-jumbo,您可以愉快地使这个函数在您的根命名空间中作为命令可用:

% namespace eval tcl::mathfunc { namespace export feq }
% namespace import tcl::mathfunc::feq
% feq 1 1
1
% feq 1 [expr {1 + 1e-10}]
0
% feq 1 [expr {1 + 1e-16}]
1

(或者,您可以在任何方便的命名空间中创建命令,然后将其导入tcl::mathfunc命名空间。)

不完全是你想要的,但在我看来已经足够接近了。

另请注意,由于 8.5 Tcl 有一个特殊的命名空间,它将所有运算符tcl::mathop公开为命令,但您不能以任何方式真正修改此命名空间(但可以使用其中的命令)。expr

于 2012-10-04T17:26:15.303 回答
3

TCL 本身是严格的前缀表示法,所以肤浅的答案是不,你不能......

但是,您也可以用 unknown 做一些激进的事情,或者您可以实现自己的expr版本,它可以解析它的参数,无论它喜欢什么

于 2012-10-04T16:21:09.817 回答