TIP #196: TCL COMMANDS AS VALUES ================================== Version: $Revision: 1.2 $ Author: Robert Suetterlin State: Withdrawn Type: Project Tcl-Version: 8.5 Vote: Pending Created: Tuesday, 11 May 2004 URL: https://tip.tcl-lang.org196.html Post-History: ------------------------------------------------------------------------- ABSTRACT ========== This TIP proposes making command procedures first-class values in Tcl. It also changes the command binding scheme to recognize these values before performing old-style name lookup indirection. RATIONALE =========== A Tcl script is a string containing one or more commands separated by semicolons or newlines. The evaluation of the script breaks these commands into words. Currently the string value of the first such word is used to lookup a command procedure (effectively a function pointer) and some clientData (per-command instance state). These will then be used by the virtual machine. For example, in the case of pure Tcl procedures created with *proc* command, this is /TclProcInterpProc/ with an associated /procPtr/ that basically references the procedure body (as a string) and its formal argument list. Because of the name lookup indirection, Tcl does not support anonymous commands. (There is quite some interest in using such with Tcl, please compare [TIP #187] and [TIP #194]. Several other languages (even C) support anonymous commands. They seem to be quite useful, just compare their use in Tcl's C code.) This can be changed by allowing for a new kind of word (i.e. a new *Tcl_Obj* /commandObject/) that can be immediately interpreted as a command. ([TIP #187] proposes the use of special Tcl lists, but this is too limiting for the scope of this document.) The evaluation checks if the first word is a /commandObject/, if not it does the old style name lookup (with *unknown* fallback). A /commandObject/ should store information equivalent to what is provided with the *Tcl_CreateCommand()* API and stored in the global name lookup table. Thus it can reference any command procedure and any clientData, allowing the creation of arbitrary anonymous commands in C extensions for example. Having such /commandObject/s available will allow for *proc* to return these instead of an empty string and to skip registration of a command when its name is provided as the empty string. EXAMPLES ========== This will allow to reproduce all of the features of [TIP #187]. Compare this example with the one in [TIP #187]: proc filter {list proc} { set res {} foreach e $list { if {![$proc $e]} { lappend res $e } } } set a [list 1 10 100 4 5] set b [filter $a [proc x {expr $x<10}]] This sets the variable b to the list {/10 100/}. In addition this TIP still allows: proc {list lambda x {body}} {var} {puts $var} if we really want to. And we can use /commandObject/s that have not been created by *proc* in the first place - think OOP for example. These /commandObject/s could also be used as data structure for the command namespace, which would then become a dictionary, if I recall correctly. Allowing for registering an anonymous command with a name (via *rename*) by putting the name and the commandObject into the dictionary. SPECIFICATION =============== This document proposes at least the following changes to the Tcl core: 1. Include a new /Tcl_Obj/ *commandObj* that contains information equivalent to the arguments /proc/, /clientData/ and /deleteProc/ to *Tcl_CreateObjCommand()*. (Maybe interp is necessary, too. But I don't understand the byte compiler and execute stuff good enough to judge.) 2. Change *Tcl_GetCommandFromObj()* to check if /objPtr/ references a /commandObj/ first, otherwise check if it finds a named command. 3. Have the *proc* command return a /commandObj/ that is equivalent to the *Tcl_Create(Obj)Command()* calls in *Tcl_ProcObjCmd()*. i.e. the /proc/ is equal to *Tcl(Obj)InterpProc()* and the /clientData/ is the /procPtr/. COPYRIGHT =========== This document is in the public domain. ------------------------------------------------------------------------- TIP AutoGenerator - written by Donal K. Fellows