| Ticket UUID: | 1017884 | ||
| Title: | make 'level' arg to uplevel/upvar mandatory | ||
| Type: | RFE | Created on: | 2004-08-27 20:58:44 |
| Submitter: | dvrsn | Assigned to: | msofer |
| Subsystem: | 22. [proc] and [uplevel] | Severity: | Minor |
| Priority: | 5 Medium | Last modified: | 2020-09-19 17:04:08 |
| Status: | Closed | Closed by: | dgp |
| Resolution: | Wont Fix | Closed on: | 2020-09-19 17:04:08 |
| Version: | None | ||
| Description: | ||||
uplevel always converts its first argument into a
string in order to check if it is the optional ?level?
argument. If the optional argument is not present, the
first argument is converted anyway, which can take
significant time and loses the benefit of direct list
evaluation.
set l [list]
for {set c 0} {$c < 10000} {incr c} {
lappend l 12345
}
proc t1 {l} {
set cmd [list llength $l]
uplevel $cmd
}
proc t2 {l} {
set cmd [list llength $l]
uplevel 1 $cmd
}
puts [time {t1 $l} 100]
puts [time {t2 $l} 100]
| ||||
| User Comments: | ||||
msofer added on 2004-08-28 04:14:06:
Logged In: YES
user_id=148712
My first reaction to this is: always specify the level, do
not rely on the default!
My second reaction is: how do you think this could be fixed?
One idea is to assume that, if there is just one argument to
uplevel and it is a pure list, it has to be a script and we
could avoid parsing it. But then the following script would
have a different behaviour:
% proc 1 {} {puts hi}
% proc a {} {uplevel [list 1]}
% a
wrong # args: should be "uplevel ?level? command ?arg ...?"
So now the question is: is this just a performance bug, or a
real bug? Ie, should that script print "hi" or return an
error as it does now?
dgp added on 2004-08-28 04:29:24:
Logged In: YES user_id=80530 The docs indicate that [uplevel 1] ought to be equivalent to [uplevel 1 1] It doesn't appear to be true. Looks like a bug to me. Either the docs or the code needs correcting. In practical terms. one should always provide an explicit level argument to [uplevel] and avoid any ambiguity or inefficiency. msofer added on 2004-08-28 05:30:55:
Logged In: YES user_id=148712 dgp later noticed that the docs say that [uplevel 1] is a syntax error: "Level cannot be defaulted if the first command argument starts with a digit or #." So: when there is a single argument, its string rep has to be examined to check that id does not start with a digit or #. The present behaviour is mandated by the docs. msofer added on 2004-08-28 05:35:00:
Logged In: YES user_id=148712 Keeping this as an RFE for making the level argument mandatory, both for the performance reasons cited here and to avoid possible confusion. As a first step, the docs could state that omitting the 'level' argument is deprecated. hobbs added on 2005-05-31 08:53:41:
Logged In: YES user_id=72656 Rejecting this request as impractical due to incompatability. You can file for a doc clarification, but you can't just break existing code. pooryorick added on 2020-09-19 15:08:20:
Part of this issue has been fixed in ticket [b9ecf3ce9801c480]: If a single argument is given and that argument is a list containing more than one item, it can not be a level specification, so it is interpreted as the script to evaluate. Morever, no string representation is generated. The part of this issue that requires a TIP, as discussed in [1017884], remains outstanding. dgp added on 2020-09-19 17:04:08:
Please also note that the list internal rep implementation has been improved in the many years since this ticket was opened. A canonical list is recognized now even after a string rep is generated. The cost of string rep generation now lmited to that actual cost of that processing step. It no longer disables the benefits of direct evaluation of lists without reparsing as scripts. That makes this issue far far less important, and that has been true for a very very long time now. | ||||
