Version 73 of return

Updated 2013-12-13 16:13:37 by pooryorick

return , a built-in Tcl command, returns a value, a code and other Commands%|%built-in] Tcl command, terminates a script, specifying its result.

Synopsis

Related Commands

source
eval
proc
uplevel
includes a TclChat discussion on the future of return
break
continue
error
throw
yield
yieldm
yieldTo

tailcall is also related to return in that it terminates execution of the current proc. However, unlike return, tailcall's continuation is not the caller. yieldTo is also related to tailcall in that it has a custom continuation.

See Also

Errors management
Script termination: results and control
namespace eval
Funky Tcl extensibility
tricks to play with return -code return and error on return -code error
try ... finally ...
KBK 2001-01-02: how to use return -code to implement a new control structure. Lars H: Other pages which do that kind of thing are breakeval (using -code 10) and returneval (using -code -1).
syntax
'return ?-code' code? ?result
'return' ?option value? ?result
'-errorcode' list
'-errorinfo' info
'-errorstack' list
added in Tcl8.6
'-level' level
'-leval' level
'-options' options

Documentation

Delivers a return code for some level to the interpreter, which then takes some Return immediately from the current procedure or script, with the specified result. The default result is the empty string.

When there is no `return` in a script, its value is the value of the last
command evaluated in the script.
The return value is either the final argument or the [empty string].  `[catch]`
Any additional ''option''/''value'' pairs are added to the options dictionary for the level. 



** Return Codes **
** Exceptional Returns **
Typically, `'''-code'''` isn't specified and the level returns a normally, i.e.
In the usual case where `'''-code'''` isn't specified, the procedure will
return normally (its completion code will be `TCL_OK`). However, `-code` may be
used to generate an exceptional return from the procedure.  Code may have any
of the following values: 
   '''`0`''':   
   `'''ok'''`:   Normal return:  same as if the option is omitted. 
   '''`1`''':   
   `'''error'''`:   Error return: same as if [`error`] were used to terminate the procedure, except for handling of `[errorInfo%|%$errorInfo]` and `[errorCode%|%$errorCode]` (see below). 
   '''`2`''':   
   `'''return'''`:   The current procedure will return with a completion code of `TCL_RETURN`, so that the procedure that invoked it will return also. 
   '''`3`''':   
   `'''break'''`:   The current procedure will return with a completion code of `TCL_BREAK`, which will terminate the innermost nested loop in the code that invoked the current procedure. 
`-code` is rarely used, as commands such as `[error]`, `[break]` and
   `'''continue'''`:   The current procedure will return with a completion code of `TCL_CONTINUE`, which will terminate the current iteration of the innermost nested loop in the code that invoked the current procedure. 

   `''value''`:   `''Value''` must be an integer;  it will be returned as the completion code for the current procedure. 

`-code` is rarely used. It is provided so that procedures that
implement new control structures can reflect exceptional conditions back to
their callers. 
Two additional options, '''`-errorinfo`''' and '''`-errorcode`''', may be used to
provide additional information during error returns. These options are ignored
unless `-code` is `error`. 

'''`-errorinfo`''' specifies an initial stack trace for
`'''-errorinfo'''` specifies an initial stack trace for
`[errorInfo%|%$errorInfo]` will include the call to the procedure and higher
levels on the stack but it will not include any information about the context
of the error within the procedure. Typically the `[info]` value is supplied
from the value left in `[errorInfo%|%$errorInfo]` when `[catch]` traps an error
within the procedure. 

If '''`-errorcode`''' is specified, ''`list`'' provides a value for
If `'''-errorcode'''` is specified, `''list''` provides a value for
default to `NONE`.  (from: [Tcl Help])



After `return`, your script can contain whatever, for instance comments:
** Misc **

proc foo {} {

    puts Foo
        puts Foo
        return
    may be  used for commenting...

} ;# RS

[DGP]:  In Tcl 7 and in recent enough Tcl 8.5 that is correct.  In the releases
in between, due to some limitations in the [bytecode] compiler/execution
machinery it could not be "whatever":

   * braces still needed to be balanced
   * Commands like `[set]` get byte-compiled early, so a syntax error is found if a line in that post-return comment starts with set and has more than two other words.
   * some commands like [set] get byte-compiled early, so a syntax error is found if a line in that post-return comment starts with set and has more than two other words.
[Joe English] also disagrees that "whatever" can appear after `return`.
`[proc]` interprets its third argument as a script.  It's therefore unwise, and
one could argue even illegal, to pass in something that's not at least
syntactically valid as a script, even if you know that parts of it will never
be executed.  By way of analogy: `[lindex]` interprets its first argument as a
list, so you'd better only pass it valid lists.  In Tcl 7.6 and earlier you
could actually get away with things like

lindex "a b c {bad{list" 1

as long as the ''examined'' part of the list was syntactically valid.  However,
this was more of an accidental artifact of implementation details than anything
guaranteed by the language, and in fact this raises an error in more recent Tcl
versions.  Similarly, if a command expects a script, you'd better pass it a
script.

[PYK] 2013-12-10:  However, if `[lindex]` is missing its second value, the
first value can still be any value, even one that isn't a valid [list].

[AMG]: There's a reason for this.  When [[lindex]] is given only one argument, it interprets that as instruction to not perform any list indexing.  No list indexing means no requirement to be a list.  It's that simple.
----
[jenglish]'s statement is correct, though it's more philosophical than practical.  If [[return]] is redefined, code following the [[return]] could certainly come into play.  Or perhaps the code isn't being executed but rather is being analyzed by [Nagelfar], which will surely take issue with the invalidity of the code.  One real possibility which would upset Tcl in any event is if the text following [[return]] contains mismatched braces.
`[array]` contents without specifying an array name. Let the file t.tcl
contain:

return {

    one 1
    two 2
    three 3

}

Then you can write it like this:

array set myArrayName source t.tcl ;# RS

[wdb]: This works, but being a purist, I prefer this text in the file to
`[source]`:

list one 1 two 2 three 3

[RS] 2006-06-23: sure. Just if you have hundreds and thousands of array
elements, with `[list]` you'd have to backslash-escape the newlines, while with
bracing they need not.

[DKF]: I'm of the kind of purist which doesn't insist on using [list] to indicate listishness; that's an illusion and the [list]-compiler knows it.
----
** Use in [pkgIndex.tcl] **
`[source]`'d scripts: The main use for `return` outside procedures is in
`[source]`'d scripts: The main use for return outside procedures is in

if {!package vsatisfies [package provide Tcl 8.4]} return if {!package vsatisfies [package provide Tcl 8.4]} {return}

which avoids presenting the package to interps that cannot use it.


you get a leaner error traceback which is possibly better to read:

% proc 1 x {if {$x<=0} {error              "too small"}}

% proc 2 x {if {$x<=0} {return -code error "too small"}}

% 1 0
too small
% set errorInfo
too small
   while executing
"error "too small""
   (procedure "1" line 1)
   invoked from within
"1 0"

% 2 0
too small
% set errorInfo
too small
   while executing
"2 0"

DKF: I find this is useful when distinguishing between problems with the values passed in by the caller (such as if the code really wants a string of length 37, has documented this, and yet the user has given a string of length 28), and problems internal to the code that it isn't reasonable for the caller to try to get right.


return to the Current Level

AMG: return -level 0 $x simply sets the interpreter result to $x; it doesn't cause the caller to return. expr {$x} and subst {$x} do the same, except that $x must be brace-quoted for safety. K $x "" is also valid, as is K* $x.

Let's say you have to pass a script to be eval'ed, and eval's return value is used somehow. What script do you pass if you want eval to simply return a constant, the result of a substitution, or a concatenated combination thereof? All of the above methods work, and [return -level 0] avoids the need for extra quoting or proc wrappers. AMG PYK: return -level 0 $x simply sets the interpreter result to $x. This is the canonical identity function; see the linked page for more information. Basically I have given a list of ways to perform Tcl substitution in a functional context. More ways exist, but these are the simplest I know of.

Update: I have just discovered single-argument lindex, which simply returns its argument. This is even easier than return -level 0.

Update 2: I found an example use on the if page:

Cancel an Error

set y [if {$x} {lindex a} else {lindex b}]

HaO: When a return code should be forwarded to the caller, one could remove Update 3: Here's another approach, on the switch page, thanks to RS (2005-05-30):

proc is x {set x}
set type [switch -- $num {
    1 - 9         {is odd}
    2 - 3 - 5 - 7 {is prime}
    0 - 4 - 6 - 8 {is even}
}]

It's possible to delete the proc line and replace is with lindex.

See "I Know Nothing" for more discussion of -level.


the level 0 to not directly trigger an eventual exception here:

if {[catch {script goes here} err options]} {
if {[catch {cmd} err options]} {
    return -options $options
}

This was useful to me in the context of Tk bind scripts, which return break if no further bind scripts should process.