196.md at [9ef6399497]

Login

File tip/196.md artifact 8024c76386 part of check-in 9ef6399497


# TIP 196: Tcl Commands as Values
	Author:		Robert Suetterlin <[email protected]>
	State:		Withdrawn
	Type:		Project
	Tcl-Version:	8.5
	Vote:		Pending
	Created:	11-May-2004
	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 [[187]](187.md) and [[194]](194.md).  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.  \([[187]](187.md) 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 [[187]](187.md).  Compare
this example with the one in [[187]](187.md):

	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.