Tcl Source Code

View Ticket
Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to [email protected]
or submit via the online form by Sep 9.
Ticket UUID: 1017884
Title: make 'level' arg to uplevel/upvar mandatory
Type: RFE Version: None
Submitter: dvrsn Created on: 2004-08-27 20:58:44
Subsystem: 22. [proc] and [uplevel] Assigned To: msofer
Priority: 5 Medium Severity:
Status: Closed Last Modified: 2005-05-31 08:53:41
Resolution: Wont Fix Closed By: hobbs
    Closed on: 2005-05-31 01:53:41
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: 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.

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.

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.

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