Captures the current namespace context for later execution of the script script. It returns a new script in which script has been wrapped in a namespace inscope command. The new script has two important properties. First, it can be evaluated in any namespace and will cause script to be evaluated in the current namespace (the one where the namespace code command was invoked). Second, additional arguments can be appended to the resulting script and they will be passed to script as additional arguments. For example, suppose the command set script [namespace code {foo bar}] is invoked in namespace ::a::b. Then eval "$script x y" can be executed in any namespace (assuming the value of script has been passed in properly) and will have the same effect as the command ::namespace eval ::a::b {foo bar x y}. This command is needed because extensions like Tk normally execute callback scripts in the global namespace. A scoped command captures a command together with its namespace context in a way that allows it to be executed properly later.
PYK 2016-10-11: Over at the curry page there are two procedures, partial and curry, that use apply and tailcall instead of namespace code to partially apply and curry commands. They avoid adding the extra level to the evaluation stack that namespace code adds, and eliminate the need to use {*} to call the curried command. The remainder of this section is historical.
HistoricalFrom the Tcl chatroom on 2004-11-03:
dkf: You can probably hack something like autoexpansion with the help of namespace code
proc lambdaish args {uplevel 1 [list ::namespace code $args]} % [lambdaish format %.3f] [expr {atan2(0,-1)}] 3.142
suchenwi: Cool, Donal! It's not exactly lambdaish, as it doesn't take a parameter list... which is half a lambda. Why not just call it "curry"?
% [curry format %.3f] [expr {atan2(0,-1)}] 3.142
Somehow makes more sense to me...
dkf: Pop that on the wiki. It also should work with any version of Tcl from 8.0 onwards. (though to 8.5; feature removed after that)
jenglish: the 'namespace code' trick, alas, is not cool at all -- it relies on an undocumented, hairy, and almost-certainly-incorrect misfeature of unknown.
dkf: It's an intended feature of unknown. It's a crazy aunt and not just a bug. There's too much code enforcing it in namespace.test for me to believe it to be anything other than intended. namespace code is just a constructor for namespace inscope
In [L1 ], DGP has this to say about the "crazy aunt":
(DKF: The "feature" is gone from Tcl 8.6...)
AMG: That explains why I had to add an {*} expansion to Wibble [L2 ]. I was wondering why it wasn't needed previously.
HaO 2008-09-02: When using namespace code to reference a namespace local function, one may use concat to add parameter values from the current scope. If the reference gets any parameters, they are added after this parameter:
namespace eval mynamespace { namespace export getreference proc callback {fix variable} { puts "Called with: <$fix> <$variable>" } proc getreference {fix} { return [concat [namespace code callback] [list $fix]] } } namespace import mynamespace::* set Ref [getreference "fix value"] --> ::namespace inscope ::mynamespace callback {fix value} eval $Ref {"variable value"} --> Called with: <fix value> <variable value> eval $Ref {"another value"} --> Called with: <fix value> <another value>
The same result may be achieved by using only list (only differences to the upper example shown). The first argument is now within the command list which works too:
... proc getreference {fix} { return [namespace code [list callback $fix]] } ... set Ref [getreference "fix value"] --> ::namespace inscope ::mynamespace {callback {fix value}} ...
or the tcl 8.5 delist operator and list:
... proc getreference {fix} { return [list {*}[namespace code callback] $fix] } ... set Ref [getreference "fix value"] --> ::namespace inscope ::mynamespace callback {fix value} ...
HaO 2012-12-17: The following errorneous way worked until tcl 8.6. Here is the tcl8.6 error message:
... proc getreference {fix} { return [list [namespace code callback] $fix] } ... set Ref [getreference "fix value"] --> {::namespace inscope ::mynamespace callback} {fix value} ... after 10 "$Ref 1" --> bgerror: invalid command name "::namespace inscope ::mynamespace callback"
Here is the explanation on clt by Don Porter: