-1

I am writing a Tcl script that is executed by Cadence Encounter version 14.25 (or 14.20, depending on whether I look at the log file or the splash screen on startup...).

The version of the embedded Tcl interpreter appears to be

% package require Tcl
8.5.9

My script uses the ::tcl::mathfunc::min function, which, to my understanding, has a variable number of arguments, so for example the following should work (it does in my installation of tclsh which has version 8.6.4):

% ::tcl::mathfunc::min 1 2 3
1

However, when executed by Encounter, it seems that this is not the case and it only works for exactly two arguments:

% ::tcl::mathfunc::min 1 
too few arguments for math function "min"
% ::tcl::mathfunc::min 1 2
1
% ::tcl::mathfunc::min 1 2 3
too many arguments for math function "min"

Why is this so?

  • Does the Tcl version reported by Encounter lie?
  • Is Encounter's Tcl interpreter broken?
  • Does ::tcl::mathfunc::min only support two arguments in Tcl versions prior to 8.6? All sources that look reliable to me state that it always had a variable number of arguments, for example this, this, or that.

Further investigations triggered by Jackson's answer:

In Encounter:

% info args ::tcl::mathfunc::min
"::tcl::mathfunc::min" isn't a procedure

Great! ...

I discovered there is a min command in the global scope that has the same behaviour, but different error messages:

% min 1
wrong # args: should be "min x y"
% min 1 2
1
% min 1 2 3
wrong # args: should be "min x y"

Neither of the two (::min, ::tcl::mathfunc::min) is contained in the result of interp aliases.

Community
  • 1
  • 1
mkrieger1
  • 19,194
  • 5
  • 54
  • 65

3 Answers3

1

If you use the commands

info args ::tcl::mathfunc::min
info body ::tcl::mathfunc::min

in both the embedded and normal Tcl interpreters you should be able to see the parameters and code that makes up the min function in both places. If they are (as seems likely from your investigation) different you can just create your own min function with a different name, my_min say, or replace the existing min function in the ::tcl::mathfunc:: namespace. NB: In Tcl 8.5 and later functions that you create in the ::tcl::mathfunc namespace can be used inside expr functions.

Jackson
  • 5,627
  • 2
  • 29
  • 48
  • Thanks for the hint, I've updated the question with my findings. I already had written my own replacements before discovering that I could just copy the code from `info body`. – mkrieger1 Aug 07 '15 at 09:17
  • @mkrieger1 I suspect from what your seeing that the cadence developers have replaced the standard min function with their own version, probably in an extension library that they load from a .so or .dll when the application creates its Tcl interpreter. – Jackson Aug 07 '15 at 10:27
1

Does the Tcl version reported by Encounter lie?

Not necessarily. As with any command defined by Tcl, ::tcl::mathfunc::min can be redefined. Doesn't make it a good idea to do it, but it's legal to do so…

Is Encounter's Tcl interpreter broken?

In a minor way. I don't know why they did this.

Does ::tcl::mathfunc::min only support two arguments in Tcl versions prior to 8.6?

$ tclsh8.5
% expr min(1,2,3,4,5)
1

Looks like it works fine with many arguments in 8.5 too. (It didn't exist in 8.4; the min function was introduced at the same time as the general function-to-command dispatch mechanism.)

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
1

The TIP that introduced ::tcl::mathfunc has some interesting feature, which you could use to use the original ::tcl::mathfunc::min instead of the Cadence provided two arg version.

It says:

Namespaces will be able to define their own math functions that are not visible outside those namespaces. If a namespace defines a function [namespace current]::tcl::mathfunc::f, then calls to f in expressions evaluated in that namespace will resolve to it in preference to ::tcl::mathfunc::f. Not only does this rule allow two extensions both to define functions f without collision, but it also allows an extension to override a builtin function such as sin."

See: http://www.tcl.tk/cgi-bin/tct/tip/232.html

So inside your own code, you can simply redefine 'min' to be the normal one, by providing a proper implementation in your own namespace.

schlenk
  • 7,002
  • 1
  • 25
  • 29