Error processing request

Parameters

CONTENT_LENGTH0
REQUEST_METHODGET
REQUEST_URI/revision/uplevel?V=111
QUERY_STRINGV=111
CONTENT_TYPE
DOCUMENT_URI/revision/uplevel
DOCUMENT_ROOT/var/www/nikit/nikit/nginx/../docroot
SCGI1
SERVER_PROTOCOLHTTP/1.1
HTTPSon
REMOTE_ADDR172.70.38.220
REMOTE_PORT58684
SERVER_PORT4443
SERVER_NAMEwiki.tcl-lang.org
HTTP_HOSTwiki.tcl-lang.org
HTTP_CONNECTIONKeep-Alive
HTTP_ACCEPT_ENCODINGgzip, br
HTTP_X_FORWARDED_FOR54.166.223.204
HTTP_CF_RAY86b86fa42d260852-IAD
HTTP_X_FORWARDED_PROTOhttps
HTTP_CF_VISITOR{"scheme":"https"}
HTTP_ACCEPT*/*
HTTP_USER_AGENTclaudebot
HTTP_CF_CONNECTING_IP54.166.223.204
HTTP_CDN_LOOPcloudflare
HTTP_CF_IPCOUNTRYUS

Body


Error

Unknow state transition: CODE -> END

-code

1

-level

0

-errorstack

INNER {returnImm {Unknow state transition: CODE -> END} {}} CALL {my render_wikit uplevel {'''`[http://www.tcl.tk/man/tcl/TclCmd/uplevel.htm%|%uplevel]`''', a [Tcl Commands%|%built-in] Tcl command, evaluates a [script] at a previous [level].



** See Also **

   [namespace]:   

   [upvar]:   

   [tailcall]:   

   [downlevel]:   

   [yieldto]:   Includes a section about using `[yieldto]` to accomplish something like `uplevel` from a [coroutine].
   [yieldto]:   Includes a section about using `[yieldto]` to accomplish something like `uplevel` between coroutines.


** Documentation **

   [http://www.tcl.tk/man/tcl/TclCmd/uplevel.htm%|%official reference]:   



** Synopsis **

    :   '''uplevel''' ''?level? arg ?arg ...?''



** Description **

'''`uplevel`''' concatenates the ''arg'' arguments, in the same manner as
`[concat]`, into a single script, changes the current level to `$level`,
[eval%|%evaluates] the script, and returns the result.

If ''level'' is positive integer, `uplevel` evaluates the script that many
levels up from the current level.  If ''level'' is an integer preceded by `#`, `uplevel` evaluates the script at the level identified by that number, where the first level is `#0`, the next level `#1`, and so on.  If ''level'' is omitted, it defaults to '''1''', but it cannot be omitted if the first ''command'' argument starts with a digit or `#`.

[AMG]: The last sentence of the previous paragraph bears repeating.  For safety's sake, ''always'' give the level explicitly, even though it's `1`.  This is because there are many situations where the ''script'' argument of `uplevel` comes from elsewhere, for instance when creating [new control structures] (a major use for `uplevel`).  In those situations, the script argument could legitimately begin with a digit or `#`, such as when it starts with a comment.

[PYK] 2014-06-13: This advice only applies to `uplevel` with more than one argument.  When there is only one argument to `uplevel`, such as the example in [new control structures], there's no ambiguity.  

[AMG]: I wish you were right about that, but it's not so.  Also, please read the discussion surrounding the example you reference.  It says, "We can make this a little more robust by specifying the exact number of levels to `uplevel`, which may prevent `$body` from being misinterpreted."

======
% proc 1 {} {return hello}
% uplevel 1
bad level "1"
======

[PYK]: Issue [http://core.tcl.tk/tcl/tktview?name=1017884%|%1017884], "Make
''level'' arg to `uplevel`/`[upvar]` mandatory", discusses this. [Jeffrey
Hobbs%|%Jeff Hobbs] states that fixing it breaks existing code, and [MS] points
out that fixing it so that the 1-argument case did the right thing would only
affect code that is currently a syntax error.  So is the current behaviour a
[Tcl warts%|%wart]?

[PYK] 2016-05-04:  There's another effect to passing only one argument to
`uplevel`, i.e. not providing an explicit level:  If the argument is a list, a [pure value%|%string representation]
is generated for each item in the list.  This could potentially have a
significant memory/performance impact.  See also
[http://core.tcl.tk/tcl/tktview/b9ecf3ce9801c480620f83b34110f808bd11affb%|%this
ticket].

----

[AMG]: Executing a script in a different [level] means only that the script is given local access to that level's variables, plus the attendant change to `[info level]`.  It does not "make the caller do something."  I know of only one circumstance where this distinction matters, but it's critical:  `uplevel [return]` is the same as `return` with no `uplevel`; uplevel cannot be used to terminate the caller.  (Instead use return's -level option.)

[PYK]: In addition to local access to that level's variables, `uplevel`
also changes the command resolution context to that level.   Although
`uplevel [return]` causes the script `uplevel` is in to return, any substitutions in
the script occur in the context specified by `uplevel`:

======
set x goodbye

apply {{} {
        set x hello 
        uplevel {return $x}
}} ;# -> goodbye
======

Another such circumstance is `uplevel [tailcall]`, which replaces the caller of
`uplevel`, not the frame specified by `uplevel`.  This is part of the explanation for the `uplevel tailcall ...` trick:

======
proc p1 {} {
    puts 2
    uplevel tailcall puts 3 
    puts 4 
}

proc main {} {
    puts 1
    p1
    puts 5
}


main
======

The output of which is 

======
1
2
5
3
======

What just happened?  `[tailcall]` replaced the invocation of `p1` (not of
`main`), and then...  well, I don't really know what happened after that!  This
has been discussed in the [Tcl chatroom], so maybe there's a good explanation
somewhere in the history there.  

[MS] (to clarify what's happening, without saying anything about if this is as it should or not): [[tailcall a b c]]'s action can be thought as two steps:
   1. set things up so that [[a b c]] is run after the frame where [tailcall] was invoked returns
   2. [[return -code return]] immediately

In the above example, [uplevel] mixes and decouples things a bit: 
   1. due to [uplevel], [tailcall] is invoked in main's scope: it sets things up so that [[puts 3]] is run on main's return
   2. [[uplevel tailcall]] behaves as [[uplevel return]] and returns with ''-code return'', causing p1 to terminate

======
proc p1 {} {
    puts 2
    uplevel tailcall puts 3 
    puts 4 
}

proc main {} {
    puts 1
    p1
    puts 5
}


main
======

The documentation for `[tailcall]` currently
says that apart from the difference in command resolution, it is equivalent to
`uplevel 1 [[list command ?arg ...?]]`, but that's not so in this case:

======
proc p1 {} {
    puts 2
    uplevel {puts 3; return}
    puts 4 
}

proc main {} {
    puts 1
    p1
    puts 5
}


main

======

Output:

======
1
2
5
======


[PYK] 2016-01-01:  In [nxs], this turned out to be a solution for the question
of how to return from a deeply recursive command while still allowing all the
recursive calls to do their cleanup and return.

[APN] 2016-09-06: Is use of [tailcall] within `uplevel` even legal? The manpage
says

  This command may not be invoked from within an uplevel into a procedure or inside a catch inside a procedure or lambda.

Am I not interpreting it correctly?

[PYK] 2016-09-06:  The documention is 99% descriptive and 1% prescriptive.
That sentence is the sign on the mushroom that says, "Don't eat me."

----

[AMG]: `uplevel 0 $script` is the same as `eval $script`.



** Possible `uplevel` deficiencies **

[AMG]: Here's a nice, simple [C]-style ''do ... while'' loop implemented using `uplevel`.  Other implementations are available on the [New Control Structures] page.

======
proc do {body while condition} {
    if {$while ne {while}} {
        error "invalid argument \"$while\": must be while"
    }
    uplevel 1 $body
    uplevel 1 [list while $condition $body]
}
======

I'm curious about the [bytecode] compilation properties of this [control structure].  I don't think `$condition` and `$body` ever get compiled.  Right?  If so, is there any way to fix this?  Putting the code to be executed into a randomly named [proc] would enable bytecode compilation, but running the code in a new level defeats the whole purpose of uplevel!

So, does there exist a [Tcl_Obj] type for bytecode-compiled script snippets which are '''not''' given their own level?

I have another question.  Can `[do]` be enhanced such that `[return]` inside the `[do]` body (or condition!) will cause `[do]`'s caller to return?  Incrementing the `-level` option of `[return]` works, but this is not a change to `[do]`, it is a change to the arguments of `[do]`.

======
proc test1 {} {
    do {return success} while {1}
    return failure
}
proc test2 {} {
    do {return -level 2 success} while {1}
    return failure
}
test1 ;# returns failure
test2 ;# returns success
======

[AMG]: These are still burning questions...  Anyone have answers?

[steveb] Here is how I do this with Tcl8.5+ and Jim Tcl. Needs some small tweaks if you want to support break and continue properly.

======
proc do {body while condition} {
    if {$while ne {while}} {
        error "invalid argument \"$while\": must be while"
    }
    set rc [catch {
        uplevel 1 $body
        uplevel 1 [list while $condition $body]
    } msg opts]
    if {$rc} {
            dict incr opts -level
    }
    return {*}$opts $msg
}
======

[DKF]: With 8.6 (specifically, [tailcall]) you can do this:

======
proc do {body while condition} {
    if {$while ne {while}} {
        error "invalid argument \"$while\": must be while"
    }
    tailcall while 1 $body\n[list if $condition {} else break]
}
======

[AMG]: Neat!  These both work as-is in Tcl, and they pass the test1/test2 test case I posted above.  My remaining question is: how can I ensure that the code is [bytecode]d?  With DKF's approach it might happen, but the bytecodes will be regenerated each time [[do]] is called.

I need this for `[Wibble implementation%|%icc catch]`, currently implemented this way:

======
proc ::wibble::icc::catch script {
    try {
        uplevel 1 $script
    } on 7 events {
        return $events
    }
    return
}
======

I should be able to change it thus:

======
proc ::wibble::icc::catch {script} {
    tailcall try $script on 7 events {set events} on ok {} list
}
======

And hey!  This gets bytecoded!

======
set script {puts before; puts >[wibble::icc get myfeed foo]<; puts after}
tcl::unsupported::representation $script

source wibble.tcl
wibble::icc configure myfeed accept foo
wibble::icc put myfeed foo
wibble::icc put myfeed exception
wibble::icc catch $script

tcl::unsupported::representation $script
======

The first `[tcl::unsupported]::[representation]` says that $script is a pure string; the second says that it's a bytecode.  Success!

The script prints "before", then the [[wibble::icc catch]] returns "foo exception".  There are no reverse angle brackets around it, nor is "after" printed, therefore the script gets interrupted inside [[wibble::icc get]], as expected.

Thanks, guys!  The trick was to avoid `uplevel`. ;^)



**  Question: `uplevel` into Mini Langage **

[codeshot]: As a newcomer to Tcl wanting to build re-usable components with domain-specific mini languages, Tcl looks to be close to perfect. But there is a key feature missing from uplevel. I really want to be able to do:

======
namespace context-lift 1 ::ns $script
======

This would run each command in `$script` as normal, except that when the tcl interpreter performs expansion for each command in the script it would expand in the context of the caller, but then it would run the resulting command in the ::ns namespace. That would make it easy to create mini-languages:

======
minilang {
    cmd1 $a {
        $b
    }
    cmd2 $c [list $d $e]
}
======

In this example, two commands would be run in the ::ns namespace and they would each be able to uplevel into the minilanguage function `uplevel 1` or into the caller with `uplevel 2`:

======
cmd1 {*}{value-of-a} {
    $b
}
======

and

======
cmd2 {*}{value-of-c} {*}{{{*}{value-of-d} {*}{value-of-e}}}
======

As you can see, the quoting to do this outside of the Tcl interpreter is messy. Implementing it outside of the interpreter is practically impossible as far as I can see.

What forums should I join to raise a feature request and discuss the requirements?

[aspect]: sounds like a job for `[namespace inscope]` - try something like:

======
uplevel 1 [list namespace inscope ::ns $body]
======

Note that [namespace] inscope takes a script as an argument, where [uplevel] takes a command - going by your examples, a script is what you really need.

[PYK] 2014-06-14: Most Tcl [object orientation%|%object systems] provide some
means to do roughly what codeshot seems to be requiring.  I don't see the point
in the `{*}` syntax above.  Perhaps OP could explain what this syntax means to
him.  Community forums include the [Tcl Chatroom] and [comp.lang.tcl].



** When to use `uplevel` **

   * if tempted to use levels other than `1` or `#0`, make sure there is strong justification, then try to avoid other levels anyway

   * in a [coroutine] context, `#1` accesses the first level in the coroutine context, which can be useful.

   * fully-qualify variables and commands to avoid trouble

   * try to avoid doing `uplevel` with anything other than a script passed in by the caller, or a fixed string


[AMG]: `uplevel` provides access to another level's local variables.  In most cases, `[upvar]` is preferred over `uplevel`: it's simpler and it doesn't interfere with [bytecode] compilation.  However, if the script to be executed comes from elsewhere (e.g. it was passed as an argument), `uplevel` is required.

As [DKF] points out below, `[tailcall]` may be a superior alternative, when ''level'' is `1` (default) and the `uplevel`'ed code is the last thing done by the [proc].  `[tailcall]`'s argument is a command, which is different than a script.  If you want to execute a script, I suggest using single-argument `[try]` as a shim.  `[eval]` would also work, but it prevents [http://wiki.tcl.tk/1017#pagetoc5262d22e%|%bytecode compilation].



** Historical: `uplevel` and `[return]` **

The following conversation took place in 2002, prior to the implementation in
version [Changes in Tcl/Tk 8.5] of [TIP]
[http://www.tcl.tk/cgi-bin/tct/tip/90.html%|%90], "Enable `[return] -code` in
[Control Structure] Procs".

Harald Kirsch wrote in c.l.t:

''Question: Is it possible to have a command called `macro` as a counterpart to `[proc]` such that `macro` defines a "function" which is evaluated in the caller's level, i.e., which does not create its own level?''

So how's this:

======
proc macro {name body} {
    proc $name {} [list uplevel 1 $body]
    set name ;# not needed, but maybe helpful
} ;# RS
======
======none
0 % macro now {incr i; incr j}
now
0 % set j 10; set i 1
1
0 % now
11
======

As a variation, you might also have the body executed in global scope, if you want to avoid `[global]` commands (not recommended normally, since the variables you use are not cleaned up):

======
proc Sub {name body} {
    proc $name {} [list uplevel #0 $body]
}
======
======none
% Sub nenv {array size env}
% nenv
44
======





[DGP]: Due to some fundamental limitations in Tcl itself, `macro` is not able to handle a ''body'' that includes `[return]`. See tcllib::[control] documentation for some more details.

[Tcl chatroom] transcript:

'''suchenwi''': I'm not sure what you mean with "will not be able to handle a body that includes a return command." If there is one, it will cause the caller to return, I'd think. And that's like `#define BYE return;` in [C] - expected behavior for a macro. 

'''dgp''': No, it won't. Try it. 

'''suchenwi''': But Harald Kirsch already followed up, he wants ''macro'' to take arguments and have local variables. This is tricky indeed - you can't do a "downlevel".... 

'''dgp''': Important to remember that `uplevel` adjusts only the command and variable substitution context. It can't really do anything to the calling stack. 

'''suchenwi''': Ah - I see. Tried `macro foo {incr i; incr j;return;puts "oops"}`. 

'''dgp''': That doesn't test what needs testing.

'''suchenwi''': `foo` itself returns (the oops won't come), but does not terminate its caller. One would have to do

======
set body [string map {return {return -code return}} $body] ;# ;-)
======

'''dgp''':

======
macro mreturn return 
proc test {} {puts a; mreturn; puts b} 
test 
======

'''suchenwi''':
 
======
proc macro {name body} {
    proc $name {} [list uplevel 1 [string map {
        return {return -code return}
    } $body]]
} 
======

'''dgp''': Yes, that string map will handle more cases, but can't achieve `return] -code error`, etc. One way to fix this limitation would be to add a new status code to Tcl that caused the result to be evaluated in the caller's context by the caller.

======
return -code eval {set var val} 
======

Then you would just map all `[return] $arg $arg ...` to `return -code eval {return $arg $arg ...}` . Not completely sure what cans of worms get opened by that new feature though. Of course, with that status code available, `macro` would be much easier to write too.

'''kennykb''': I like `[return] -code eval` -- except for deciding whether Tcl_EvalObj and its friends should interpret it or return it to the [C] caller. 

'''rmax''': Hi Kevin. I think `[return] -code eval` would also help `[do]` to become complete for all possible cases.

'''kennykb''': Yes, dgp's comments make it obvious that it could do `return -code eval {return -code eval {return -code whatever {... }}}` to break out of multiple scopes.

'''dgp''': I still would not recommend that though. Just as it should always be `uplevel 1 ...`. 

'''kennykb''': Don: I wouldn't ''recommend'' it either, but a certain depth of nesting is needed for `[do%|%control::do]` to handle `[return] -code` within the loop body, right? 

'''rmax''': You won't of course create nested `[return] -code eval` constructs yourself, but they could emerge from nested `[do]` loops or macro calls. 

'''dgp''': I think `[catch]` needs extending too. 

======
catch {return -code error foo} msg --> 2 
set msg --> foo 
======

But where is the '1'? 
Add another argument to [catch] to get the '1'. 

'''kennykb''': Yes, also need a place to stash the `-errorcode` and `-errorInfo` options to `[return]`.

'''dgp''': I think you can just grab them from `[errorInfo%|%$::errorInfo]` and `errorCode%|%$::errorCode` directly. 

'''dgp''': ... but yes, status code `1` needs special handling, as always, to deal with `[errorInfo%|%$::errorInfo]` and `[errorCode%|%$::errorCode]`. 
For the rest,

======
set code {catch $body msg returncode}
if {$code == 2} { 
    # We caught a return 
    return -code eval [list return -code $returncode $msg] 
} 
======

'''dgp''': Ah! I think I see what you were getting at! 

'''kennykb''': Hmmmm, it occurs to me that `[return] -code eval` subsumes all the others. 

'''dgp''': If `$body` itself contains `[return] -code eval $script`. 

'''kennykb''': `return -code error -errorcode code -errorinfo into message` => `return -code eval [[list error message info code]]`
 
`return -code break` => `return -code eval break`

'''kennykb''': ... and the same for continue and return. 

'''suchenwi''': Looks like it would actually make the language smaller....

'''dgp''': ...except maybe for the differences in `[errorInfo%|%$::errorInfo]` construction. 

'''kennykb''': We'd have to keep the other syntax on return for back compatibility, but I think it could simplify the mechanism. Oh, yeah, `[errorInfo%|%$::errorInfo]` construction. OK, make it `return -code eval [[list error $message [[doTheRightThingWith $info]] $code]]`. 

'''suchenwi''': ..and if `eval` is the last remaining value for `-code`, one could shorten that to `-eval` ... 

'''kennykb''': Hmm, need a new command for those crazy enough to do `[return] -code 6`. 

'''dgp''': How about `-code ok` ? I guess that's the default case where no `[eval]` script is done. 
Note: that's different from `eval` of an empty script. 

Why a new command? 

'''kennykb''': I suppose if you wanted to be obsessive about it, you could say `return -code ok $value` -> `return -code eval [[list identity $value]]` where identity is a command that returns its arg, but I wouldn't go that far, myself. 

'''dgp''': We still need `return -code 6` if we want ability to create new status codes at the script level. 

'''rmax''': Isn't this possible to handle completely on the `[catch]` side? Doing it on the `[return]` side involves string operations on scripts, which hurts performance. 

'''dgp''': `proc niftyNewBreak {} {return -code 6}` 

'''kennykb''': `proc niftyNewBreak {} { return -code eval {::tcl::raiseException 6 }}` ? 8^) 

'''rmax''': ... and there is the danger of substituting a `[return]` that isn't really a `[return]`. 

'''dgp''': Ah, I see. 

'''kennykb''': Where are we doing string operations on scripts? 

'''dgp''': No substitution. catch and re-raise. 

'''rmax''': The implementation of `[do]` would have to substitute `return -code ...` by `return -code eval {return -code ...}` or am I wrong? 

'''kennykb''': Reinhard: Ah, but there's no string processing there. The new command is a pure list. 

'''dgp''': `[do]` includes the line: 

======
set code [[catch { uplevel 1 $body } result]]
======

Change to: 

======
set code [catch { uplevel 1 $body } result returnCode] 
======

Add a case to the `[switch]`

======
2 {return -code eval [list return -code $returnCode $result]}
======

'''kennykb''': Yes.. and note that the thing to be `eval`ed is a pure list.

'''dgp''': The use of `[eval]` might prevent bytecode, so that's a performance issue, but there should be no need to reparse the strings. 

'''rmax''': wouldn't `2 {return -code $returnCode $result}`
be sufficient? 

'''dgp''': No. The idea is that the `[return]` in `$body` should act as if it was evaluated in the caller. Hmmm. so far have taken care of the first pass through `[do]`. Remaining passes are handled by an `uplevel 1 {while ...}` That probably needs similar handling. Yes. Same changes there. 

'''rmax''': I still think it would be sufficient for `[do]` to be able to catch and pass on the `-code` argument to return. 

'''kennykb''': Gentleb[[e]]ings, I think we're excising one of the language's major warts here. 

'''rmax''': Can you give an example of usage for `[do]` where that wouldn't be enough? 

'''clock''': 1011891602 : Jan 24,2002 Thursday 5pm GMT 

'''kennykb''': What if the body of the `[do]` contains `return -code eval` ? 

'''dgp''': I think that case is handled above. 

'''rmax''': do will pass on `return -code eval` . 

'''dgp''': rmax: you don't want to return from `[do]`, you want to return from the caller of `[do]`. 

'''rmax''': Yes: 

======
do { 
    return -code return 
} 
======

inside do: 

======
set code [catch { uplevel 1 $body } result retCode]
... 
2 { return -code [list return $retCode] $result }
======

What about that?

'''dgp''': That will return from the caller of `[do]` when what is intended is to return from the caller of the caller of `[do]`.
 
* rmax is totally confused now... has to try some things... 

'''kennykb''': That's yet another new syntax for `[return]`. How is that preferable to `return -code eval [[list return -code $retCode $result]]` ? 

'''dgp''': Oh. I mis-read part of that last one. Given what we've described, that should be an error: 

'''rmax''': it is a bit shorter, and I haven't thought much about it... 

'''dgp''': unknown code: "return 2" 

'''kennykb''': Since we need `return -code eval` anyway -- in order to implement `macro`, I'm reluctant to invent still more syntax just to make `[do]` a tiny bit shorter. 

'''rmax''': Yep, Don. It implied another proposal of changing the syntax of `[return]`. OK, Kevin, you win. 
 
'''dgp''': The numeric code for eval should be `-1`. 

'''kennykb''': Why -1? 

'''dgp''': #define TCL_EVAL -1 

'''dgp''': It's an interesting status code in that it is completely internal. No command will actually return it, it will return the result of eval'ing the result instead. `return -code $integer` has been documented to allow any postive integer. `-1` won't interfere with previous extended status codes. 

'''kennykb''': OK, we have a compatibility issue with [C] code that calls commandProc's directly. (There are examples doing stuff like that in Brent's book, IIRC.) 

'''dgp''': hmmmm... take that back. I guess "positive" isn't in the docs after all. Are there any example doing that with *ObjCmd's? 

'''kennykb''': I don't think we have too much of a problem as long as we avoid whatever code [exp_continue] uses. 

'''dgp''': Any existing code is calling existing command procedures. None of which return the status code TCL_EVAL, so is there really a problem? 

'''bbh''': exp_continue seems to be -101 

'''kennykb''': Don: Doesn't Brent's code have a Tcl_GetCommandInfo so that it's actually calling a user-supplied command proc? 

'''dgp''': Anyhow look for a section "Bypassing Tcl_Eval". His code doesn't handle any extended return codes, so there's no new problem here. His routine is called Tcl_Invoke. Tcl_Invoke("break", NULL); would cause problems now. 

'''* suchenwi has to stop mirroring this debate on http://wiki.tcl.tk/1507 - real work calling...'''

----

2002-10-17:  [returneval] provides a Tcl-only implementation of something very similar to the above `return -code eval`.

[RHS]: TIP 90 doesn't cover the `-code eval` idea, does it? I read through it and it didn't seem to.

[Lars H]: No, but `-code eval` was considered as an alternative solution. Maybe it's not in the TIP itself, but in some of the surrounding discussion, however a good deal of thought was put into it.

**[[uplevel]] and [[namespace]]**
[AMG]: I don't think it's mentioned anywhere else in this page or in the man page, but [[uplevel]] has the effect of temporarily changing the effective current namespace to whatever the caller is using.  (I use [[::set]] explicitly throughout the namespace.)  This is a problem for me right now because I have a custom command called [[set]] in my namespace, and elsewhere in that same namespace I'm calling a command (incidentally, from another namespace) which uses [[uplevel]] to set a variable in its caller's frame.  Unfortunately, in this exact case, it's not using the standard [[set]] but rather the namespace-special [[set]].
======} regexp2} CALL {my render uplevel {'''`[http://www.tcl.tk/man/tcl/TclCmd/uplevel.htm%|%uplevel]`''', a [Tcl Commands%|%built-in] Tcl command, evaluates a [script] at a previous [level].



** See Also **

   [namespace]:   

   [upvar]:   

   [tailcall]:   

   [downlevel]:   

   [yieldto]:   Includes a section about using `[yieldto]` to accomplish something like `uplevel` from a [coroutine].
   [yieldto]:   Includes a section about using `[yieldto]` to accomplish something like `uplevel` between coroutines.


** Documentation **

   [http://www.tcl.tk/man/tcl/TclCmd/uplevel.htm%|%official reference]:   



** Synopsis **

    :   '''uplevel''' ''?level? arg ?arg ...?''



** Description **

'''`uplevel`''' concatenates the ''arg'' arguments, in the same manner as
`[concat]`, into a single script, changes the current level to `$level`,
[eval%|%evaluates] the script, and returns the result.

If ''level'' is positive integer, `uplevel` evaluates the script that many
levels up from the current level.  If ''level'' is an integer preceded by `#`, `uplevel` evaluates the script at the level identified by that number, where the first level is `#0`, the next level `#1`, and so on.  If ''level'' is omitted, it defaults to '''1''', but it cannot be omitted if the first ''command'' argument starts with a digit or `#`.

[AMG]: The last sentence of the previous paragraph bears repeating.  For safety's sake, ''always'' give the level explicitly, even though it's `1`.  This is because there are many situations where the ''script'' argument of `uplevel` comes from elsewhere, for instance when creating [new control structures] (a major use for `uplevel`).  In those situations, the script argument could legitimately begin with a digit or `#`, such as when it starts with a comment.

[PYK] 2014-06-13: This advice only applies to `uplevel` with more than one argument.  When there is only one argument to `uplevel`, such as the example in [new control structures], there's no ambiguity.  

[AMG]: I wish you were right about that, but it's not so.  Also, please read the discussion surrounding the example you reference.  It says, "We can make this a little more robust by specifying the exact number of levels to `uplevel`, which may prevent `$body` from being misinterpreted."

======
% proc 1 {} {return hello}
% uplevel 1
bad level "1"
======

[PYK]: Issue [http://core.tcl.tk/tcl/tktview?name=1017884%|%1017884], "Make
''level'' arg to `uplevel`/`[upvar]` mandatory", discusses this. [Jeffrey
Hobbs%|%Jeff Hobbs] states that fixing it breaks existing code, and [MS] points
out that fixing it so that the 1-argument case did the right thing would only
affect code that is currently a syntax error.  So is the current behaviour a
[Tcl warts%|%wart]?

[PYK] 2016-05-04:  There's another effect to passing only one argument to
`uplevel`, i.e. not providing an explicit level:  If the argument is a list, a [pure value%|%string representation]
is generated for each item in the list.  This could potentially have a
significant memory/performance impact.  See also
[http://core.tcl.tk/tcl/tktview/b9ecf3ce9801c480620f83b34110f808bd11affb%|%this
ticket].

----

[AMG]: Executing a script in a different [level] means only that the script is given local access to that level's variables, plus the attendant change to `[info level]`.  It does not "make the caller do something."  I know of only one circumstance where this distinction matters, but it's critical:  `uplevel [return]` is the same as `return` with no `uplevel`; uplevel cannot be used to terminate the caller.  (Instead use return's -level option.)

[PYK]: In addition to local access to that level's variables, `uplevel`
also changes the command resolution context to that level.   Although
`uplevel [return]` causes the script `uplevel` is in to return, any substitutions in
the script occur in the context specified by `uplevel`:

======
set x goodbye

apply {{} {
        set x hello 
        uplevel {return $x}
}} ;# -> goodbye
======

Another such circumstance is `uplevel [tailcall]`, which replaces the caller of
`uplevel`, not the frame specified by `uplevel`.  This is part of the explanation for the `uplevel tailcall ...` trick:

======
proc p1 {} {
    puts 2
    uplevel tailcall puts 3 
    puts 4 
}

proc main {} {
    puts 1
    p1
    puts 5
}


main
======

The output of which is 

======
1
2
5
3
======

What just happened?  `[tailcall]` replaced the invocation of `p1` (not of
`main`), and then...  well, I don't really know what happened after that!  This
has been discussed in the [Tcl chatroom], so maybe there's a good explanation
somewhere in the history there.  

[MS] (to clarify what's happening, without saying anything about if this is as it should or not): [[tailcall a b c]]'s action can be thought as two steps:
   1. set things up so that [[a b c]] is run after the frame where [tailcall] was invoked returns
   2. [[return -code return]] immediately

In the above example, [uplevel] mixes and decouples things a bit: 
   1. due to [uplevel], [tailcall] is invoked in main's scope: it sets things up so that [[puts 3]] is run on main's return
   2. [[uplevel tailcall]] behaves as [[uplevel return]] and returns with ''-code return'', causing p1 to terminate

======
proc p1 {} {
    puts 2
    uplevel tailcall puts 3 
    puts 4 
}

proc main {} {
    puts 1
    p1
    puts 5
}


main
======

The documentation for `[tailcall]` currently
says that apart from the difference in command resolution, it is equivalent to
`uplevel 1 [[list command ?arg ...?]]`, but that's not so in this case:

======
proc p1 {} {
    puts 2
    uplevel {puts 3; return}
    puts 4 
}

proc main {} {
    puts 1
    p1
    puts 5
}


main

======

Output:

======
1
2
5
======


[PYK] 2016-01-01:  In [nxs], this turned out to be a solution for the question
of how to return from a deeply recursive command while still allowing all the
recursive calls to do their cleanup and return.

[APN] 2016-09-06: Is use of [tailcall] within `uplevel` even legal? The manpage
says

  This command may not be invoked from within an uplevel into a procedure or inside a catch inside a procedure or lambda.

Am I not interpreting it correctly?

[PYK] 2016-09-06:  The documention is 99% descriptive and 1% prescriptive.
That sentence is the sign on the mushroom that says, "Don't eat me."

----

[AMG]: `uplevel 0 $script` is the same as `eval $script`.



** Possible `uplevel` deficiencies **

[AMG]: Here's a nice, simple [C]-style ''do ... while'' loop implemented using `uplevel`.  Other implementations are available on the [New Control Structures] page.

======
proc do {body while condition} {
    if {$while ne {while}} {
        error "invalid argument \"$while\": must be while"
    }
    uplevel 1 $body
    uplevel 1 [list while $condition $body]
}
======

I'm curious about the [bytecode] compilation properties of this [control structure].  I don't think `$condition` and `$body` ever get compiled.  Right?  If so, is there any way to fix this?  Putting the code to be executed into a randomly named [proc] would enable bytecode compilation, but running the code in a new level defeats the whole purpose of uplevel!

So, does there exist a [Tcl_Obj] type for bytecode-compiled script snippets which are '''not''' given their own level?

I have another question.  Can `[do]` be enhanced such that `[return]` inside the `[do]` body (or condition!) will cause `[do]`'s caller to return?  Incrementing the `-level` option of `[return]` works, but this is not a change to `[do]`, it is a change to the arguments of `[do]`.

======
proc test1 {} {
    do {return success} while {1}
    return failure
}
proc test2 {} {
    do {return -level 2 success} while {1}
    return failure
}
test1 ;# returns failure
test2 ;# returns success
======

[AMG]: These are still burning questions...  Anyone have answers?

[steveb] Here is how I do this with Tcl8.5+ and Jim Tcl. Needs some small tweaks if you want to support break and continue properly.

======
proc do {body while condition} {
    if {$while ne {while}} {
        error "invalid argument \"$while\": must be while"
    }
    set rc [catch {
        uplevel 1 $body
        uplevel 1 [list while $condition $body]
    } msg opts]
    if {$rc} {
            dict incr opts -level
    }
    return {*}$opts $msg
}
======

[DKF]: With 8.6 (specifically, [tailcall]) you can do this:

======
proc do {body while condition} {
    if {$while ne {while}} {
        error "invalid argument \"$while\": must be while"
    }
    tailcall while 1 $body\n[list if $condition {} else break]
}
======

[AMG]: Neat!  These both work as-is in Tcl, and they pass the test1/test2 test case I posted above.  My remaining question is: how can I ensure that the code is [bytecode]d?  With DKF's approach it might happen, but the bytecodes will be regenerated each time [[do]] is called.

I need this for `[Wibble implementation%|%icc catch]`, currently implemented this way:

======
proc ::wibble::icc::catch script {
    try {
        uplevel 1 $script
    } on 7 events {
        return $events
    }
    return
}
======

I should be able to change it thus:

======
proc ::wibble::icc::catch {script} {
    tailcall try $script on 7 events {set events} on ok {} list
}
======

And hey!  This gets bytecoded!

======
set script {puts before; puts >[wibble::icc get myfeed foo]<; puts after}
tcl::unsupported::representation $script

source wibble.tcl
wibble::icc configure myfeed accept foo
wibble::icc put myfeed foo
wibble::icc put myfeed exception
wibble::icc catch $script

tcl::unsupported::representation $script
======

The first `[tcl::unsupported]::[representation]` says that $script is a pure string; the second says that it's a bytecode.  Success!

The script prints "before", then the [[wibble::icc catch]] returns "foo exception".  There are no reverse angle brackets around it, nor is "after" printed, therefore the script gets interrupted inside [[wibble::icc get]], as expected.

Thanks, guys!  The trick was to avoid `uplevel`. ;^)



**  Question: `uplevel` into Mini Langage **

[codeshot]: As a newcomer to Tcl wanting to build re-usable components with domain-specific mini languages, Tcl looks to be close to perfect. But there is a key feature missing from uplevel. I really want to be able to do:

======
namespace context-lift 1 ::ns $script
======

This would run each command in `$script` as normal, except that when the tcl interpreter performs expansion for each command in the script it would expand in the context of the caller, but then it would run the resulting command in the ::ns namespace. That would make it easy to create mini-languages:

======
minilang {
    cmd1 $a {
        $b
    }
    cmd2 $c [list $d $e]
}
======

In this example, two commands would be run in the ::ns namespace and they would each be able to uplevel into the minilanguage function `uplevel 1` or into the caller with `uplevel 2`:

======
cmd1 {*}{value-of-a} {
    $b
}
======

and

======
cmd2 {*}{value-of-c} {*}{{{*}{value-of-d} {*}{value-of-e}}}
======

As you can see, the quoting to do this outside of the Tcl interpreter is messy. Implementing it outside of the interpreter is practically impossible as far as I can see.

What forums should I join to raise a feature request and discuss the requirements?

[aspect]: sounds like a job for `[namespace inscope]` - try something like:

======
uplevel 1 [list namespace inscope ::ns $body]
======

Note that [namespace] inscope takes a script as an argument, where [uplevel] takes a command - going by your examples, a script is what you really need.

[PYK] 2014-06-14: Most Tcl [object orientation%|%object systems] provide some
means to do roughly what codeshot seems to be requiring.  I don't see the point
in the `{*}` syntax above.  Perhaps OP could explain what this syntax means to
him.  Community forums include the [Tcl Chatroom] and [comp.lang.tcl].



** When to use `uplevel` **

   * if tempted to use levels other than `1` or `#0`, make sure there is strong justification, then try to avoid other levels anyway

   * in a [coroutine] context, `#1` accesses the first level in the coroutine context, which can be useful.

   * fully-qualify variables and commands to avoid trouble

   * try to avoid doing `uplevel` with anything other than a script passed in by the caller, or a fixed string


[AMG]: `uplevel` provides access to another level's local variables.  In most cases, `[upvar]` is preferred over `uplevel`: it's simpler and it doesn't interfere with [bytecode] compilation.  However, if the script to be executed comes from elsewhere (e.g. it was passed as an argument), `uplevel` is required.

As [DKF] points out below, `[tailcall]` may be a superior alternative, when ''level'' is `1` (default) and the `uplevel`'ed code is the last thing done by the [proc].  `[tailcall]`'s argument is a command, which is different than a script.  If you want to execute a script, I suggest using single-argument `[try]` as a shim.  `[eval]` would also work, but it prevents [http://wiki.tcl.tk/1017#pagetoc5262d22e%|%bytecode compilation].



** Historical: `uplevel` and `[return]` **

The following conversation took place in 2002, prior to the implementation in
version [Changes in Tcl/Tk 8.5] of [TIP]
[http://www.tcl.tk/cgi-bin/tct/tip/90.html%|%90], "Enable `[return] -code` in
[Control Structure] Procs".

Harald Kirsch wrote in c.l.t:

''Question: Is it possible to have a command called `macro` as a counterpart to `[proc]` such that `macro` defines a "function" which is evaluated in the caller's level, i.e., which does not create its own level?''

So how's this:

======
proc macro {name body} {
    proc $name {} [list uplevel 1 $body]
    set name ;# not needed, but maybe helpful
} ;# RS
======
======none
0 % macro now {incr i; incr j}
now
0 % set j 10; set i 1
1
0 % now
11
======

As a variation, you might also have the body executed in global scope, if you want to avoid `[global]` commands (not recommended normally, since the variables you use are not cleaned up):

======
proc Sub {name body} {
    proc $name {} [list uplevel #0 $body]
}
======
======none
% Sub nenv {array size env}
% nenv
44
======





[DGP]: Due to some fundamental limitations in Tcl itself, `macro` is not able to handle a ''body'' that includes `[return]`. See tcllib::[control] documentation for some more details.

[Tcl chatroom] transcript:

'''suchenwi''': I'm not sure what you mean with "will not be able to handle a body that includes a return command." If there is one, it will cause the caller to return, I'd think. And that's like `#define BYE return;` in [C] - expected behavior for a macro. 

'''dgp''': No, it won't. Try it. 

'''suchenwi''': But Harald Kirsch already followed up, he wants ''macro'' to take arguments and have local variables. This is tricky indeed - you can't do a "downlevel".... 

'''dgp''': Important to remember that `uplevel` adjusts only the command and variable substitution context. It can't really do anything to the calling stack. 

'''suchenwi''': Ah - I see. Tried `macro foo {incr i; incr j;return;puts "oops"}`. 

'''dgp''': That doesn't test what needs testing.

'''suchenwi''': `foo` itself returns (the oops won't come), but does not terminate its caller. One would have to do

======
set body [string map {return {return -code return}} $body] ;# ;-)
======

'''dgp''':

======
macro mreturn return 
proc test {} {puts a; mreturn; puts b} 
test 
======

'''suchenwi''':
 
======
proc macro {name body} {
    proc $name {} [list uplevel 1 [string map {
        return {return -code return}
    } $body]]
} 
======

'''dgp''': Yes, that string map will handle more cases, but can't achieve `return] -code error`, etc. One way to fix this limitation would be to add a new status code to Tcl that caused the result to be evaluated in the caller's context by the caller.

======
return -code eval {set var val} 
======

Then you would just map all `[return] $arg $arg ...` to `return -code eval {return $arg $arg ...}` . Not completely sure what cans of worms get opened by that new feature though. Of course, with that status code available, `macro` would be much easier to write too.

'''kennykb''': I like `[return] -code eval` -- except for deciding whether Tcl_EvalObj and its friends should interpret it or return it to the [C] caller. 

'''rmax''': Hi Kevin. I think `[return] -code eval` would also help `[do]` to become complete for all possible cases.

'''kennykb''': Yes, dgp's comments make it obvious that it could do `return -code eval {return -code eval {return -code whatever {... }}}` to break out of multiple scopes.

'''dgp''': I still would not recommend that though. Just as it should always be `uplevel 1 ...`. 

'''kennykb''': Don: I wouldn't ''recommend'' it either, but a certain depth of nesting is needed for `[do%|%control::do]` to handle `[return] -code` within the loop body, right? 

'''rmax''': You won't of course create nested `[return] -code eval` constructs yourself, but they could emerge from nested `[do]` loops or macro calls. 

'''dgp''': I think `[catch]` needs extending too. 

======
catch {return -code error foo} msg --> 2 
set msg --> foo 
======

But where is the '1'? 
Add another argument to [catch] to get the '1'. 

'''kennykb''': Yes, also need a place to stash the `-errorcode` and `-errorInfo` options to `[return]`.

'''dgp''': I think you can just grab them from `[errorInfo%|%$::errorInfo]` and `errorCode%|%$::errorCode` directly. 

'''dgp''': ... but yes, status code `1` needs special handling, as always, to deal with `[errorInfo%|%$::errorInfo]` and `[errorCode%|%$::errorCode]`. 
For the rest,

======
set code {catch $body msg returncode}
if {$code == 2} { 
    # We caught a return 
    return -code eval [list return -code $returncode $msg] 
} 
======

'''dgp''': Ah! I think I see what you were getting at! 

'''kennykb''': Hmmmm, it occurs to me that `[return] -code eval` subsumes all the others. 

'''dgp''': If `$body` itself contains `[return] -code eval $script`. 

'''kennykb''': `return -code error -errorcode code -errorinfo into message` => `return -code eval [[list error message info code]]`
 
`return -code break` => `return -code eval break`

'''kennykb''': ... and the same for continue and return. 

'''suchenwi''': Looks like it would actually make the language smaller....

'''dgp''': ...except maybe for the differences in `[errorInfo%|%$::errorInfo]` construction. 

'''kennykb''': We'd have to keep the other syntax on return for back compatibility, but I think it could simplify the mechanism. Oh, yeah, `[errorInfo%|%$::errorInfo]` construction. OK, make it `return -code eval [[list error $message [[doTheRightThingWith $info]] $code]]`. 

'''suchenwi''': ..and if `eval` is the last remaining value for `-code`, one could shorten that to `-eval` ... 

'''kennykb''': Hmm, need a new command for those crazy enough to do `[return] -code 6`. 

'''dgp''': How about `-code ok` ? I guess that's the default case where no `[eval]` script is done. 
Note: that's different from `eval` of an empty script. 

Why a new command? 

'''kennykb''': I suppose if you wanted to be obsessive about it, you could say `return -code ok $value` -> `return -code eval [[list identity $value]]` where identity is a command that returns its arg, but I wouldn't go that far, myself. 

'''dgp''': We still need `return -code 6` if we want ability to create new status codes at the script level. 

'''rmax''': Isn't this possible to handle completely on the `[catch]` side? Doing it on the `[return]` side involves string operations on scripts, which hurts performance. 

'''dgp''': `proc niftyNewBreak {} {return -code 6}` 

'''kennykb''': `proc niftyNewBreak {} { return -code eval {::tcl::raiseException 6 }}` ? 8^) 

'''rmax''': ... and there is the danger of substituting a `[return]` that isn't really a `[return]`. 

'''dgp''': Ah, I see. 

'''kennykb''': Where are we doing string operations on scripts? 

'''dgp''': No substitution. catch and re-raise. 

'''rmax''': The implementation of `[do]` would have to substitute `return -code ...` by `return -code eval {return -code ...}` or am I wrong? 

'''kennykb''': Reinhard: Ah, but there's no string processing there. The new command is a pure list. 

'''dgp''': `[do]` includes the line: 

======
set code [[catch { uplevel 1 $body } result]]
======

Change to: 

======
set code [catch { uplevel 1 $body } result returnCode] 
======

Add a case to the `[switch]`

======
2 {return -code eval [list return -code $returnCode $result]}
======

'''kennykb''': Yes.. and note that the thing to be `eval`ed is a pure list.

'''dgp''': The use of `[eval]` might prevent bytecode, so that's a performance issue, but there should be no need to reparse the strings. 

'''rmax''': wouldn't `2 {return -code $returnCode $result}`
be sufficient? 

'''dgp''': No. The idea is that the `[return]` in `$body` should act as if it was evaluated in the caller. Hmmm. so far have taken care of the first pass through `[do]`. Remaining passes are handled by an `uplevel 1 {while ...}` That probably needs similar handling. Yes. Same changes there. 

'''rmax''': I still think it would be sufficient for `[do]` to be able to catch and pass on the `-code` argument to return. 

'''kennykb''': Gentleb[[e]]ings, I think we're excising one of the language's major warts here. 

'''rmax''': Can you give an example of usage for `[do]` where that wouldn't be enough? 

'''clock''': 1011891602 : Jan 24,2002 Thursday 5pm GMT 

'''kennykb''': What if the body of the `[do]` contains `return -code eval` ? 

'''dgp''': I think that case is handled above. 

'''rmax''': do will pass on `return -code eval` . 

'''dgp''': rmax: you don't want to return from `[do]`, you want to return from the caller of `[do]`. 

'''rmax''': Yes: 

======
do { 
    return -code return 
} 
======

inside do: 

======
set code [catch { uplevel 1 $body } result retCode]
... 
2 { return -code [list return $retCode] $result }
======

What about that?

'''dgp''': That will return from the caller of `[do]` when what is intended is to return from the caller of the caller of `[do]`.
 
* rmax is totally confused now... has to try some things... 

'''kennykb''': That's yet another new syntax for `[return]`. How is that preferable to `return -code eval [[list return -code $retCode $result]]` ? 

'''dgp''': Oh. I mis-read part of that last one. Given what we've described, that should be an error: 

'''rmax''': it is a bit shorter, and I haven't thought much about it... 

'''dgp''': unknown code: "return 2" 

'''kennykb''': Since we need `return -code eval` anyway -- in order to implement `macro`, I'm reluctant to invent still more syntax just to make `[do]` a tiny bit shorter. 

'''rmax''': Yep, Don. It implied another proposal of changing the syntax of `[return]`. OK, Kevin, you win. 
 
'''dgp''': The numeric code for eval should be `-1`. 

'''kennykb''': Why -1? 

'''dgp''': #define TCL_EVAL -1 

'''dgp''': It's an interesting status code in that it is completely internal. No command will actually return it, it will return the result of eval'ing the result instead. `return -code $integer` has been documented to allow any postive integer. `-1` won't interfere with previous extended status codes. 

'''kennykb''': OK, we have a compatibility issue with [C] code that calls commandProc's directly. (There are examples doing stuff like that in Brent's book, IIRC.) 

'''dgp''': hmmmm... take that back. I guess "positive" isn't in the docs after all. Are there any example doing that with *ObjCmd's? 

'''kennykb''': I don't think we have too much of a problem as long as we avoid whatever code [exp_continue] uses. 

'''dgp''': Any existing code is calling existing command procedures. None of which return the status code TCL_EVAL, so is there really a problem? 

'''bbh''': exp_continue seems to be -101 

'''kennykb''': Don: Doesn't Brent's code have a Tcl_GetCommandInfo so that it's actually calling a user-supplied command proc? 

'''dgp''': Anyhow look for a section "Bypassing Tcl_Eval". His code doesn't handle any extended return codes, so there's no new problem here. His routine is called Tcl_Invoke. Tcl_Invoke("break", NULL); would cause problems now. 

'''* suchenwi has to stop mirroring this debate on http://wiki.tcl.tk/1507 - real work calling...'''

----

2002-10-17:  [returneval] provides a Tcl-only implementation of something very similar to the above `return -code eval`.

[RHS]: TIP 90 doesn't cover the `-code eval` idea, does it? I read through it and it didn't seem to.

[Lars H]: No, but `-code eval` was considered as an alternative solution. Maybe it's not in the TIP itself, but in some of the surrounding discussion, however a good deal of thought was put into it.

**[[uplevel]] and [[namespace]]**
[AMG]: I don't think it's mentioned anywhere else in this page or in the man page, but [[uplevel]] has the effect of temporarily changing the effective current namespace to whatever the caller is using.  (I use [[::set]] explicitly throughout the namespace.)  This is a problem for me right now because I have a custom command called [[set]] in my namespace, and elsewhere in that same namespace I'm calling a command (incidentally, from another namespace) which uses [[uplevel]] to set a variable in its caller's frame.  Unfortunately, in this exact case, it's not using the standard [[set]] but rather the namespace-special [[set]].
======}} CALL {my revision uplevel} CALL {::oo::Obj879442 process revision/uplevel} CALL {::oo::Obj879440 process}

-errorcode

NONE

-errorinfo

Unknow state transition: CODE -> END
    while executing
"error $msg"
    (class "::Wiki" method "render_wikit" line 6)
    invoked from within
"my render_$default_markup $N $C $mkup_rendering_engine"
    (class "::Wiki" method "render" line 8)
    invoked from within
"my render $name $C"
    (class "::Wiki" method "revision" line 31)
    invoked from within
"my revision $page"
    (class "::Wiki" method "process" line 56)
    invoked from within
"$server process [string trim $uri /]"

-errorline

4