On variables

Variables in Tcl are actually rather complicated. I find it easiest if you don't think of "variables" as first-class entities themselves, but instead think of "Names" and "Environments".

There are two different kinds of Environments: namespace contexts (including the global namespace) and stack frames (i.e., inside a procedure body). The former are static, the latter dynamic.

A Environment can map a Name to one of several things:

A Location is simply a place to store a Value (which is a String). An Element is a Location in an Array, and a Scalar is a Location in an Environment. A Location can also have a collection of attached Traces, which we will not discuss further here.

Note that you cannot create a Link to a Link; only one level of indirection is possible.

The Value is optional. For example, a Location with no Value can still have Traces. Arrays can also have Traces, which again, we will not discuss.

Finally: a Variable is a String which is used to find a Location (or sometimes an Array) starting from a given Environment. Variables consist of one or more Names, separated and optionally preceded by namespace separators (two or more colons), and optionally followed by an array Index in parentheses. See Rule #7 in Tcl(n) and Tcl_SetVar(3) for the precise (sort of) syntax.

Most operations on Variables (set, unset, trace, etc.) really operate on a Location. If the variable Name resolves to a Link, Tcl automatically follows the Link and operates on the resolved Location instead. That's why it's so hard to remove a binding from a Name to a Link in any Environment once one has been created with [upvar] or [variable].

The documentation is not very clear, and is quite possibly ambiguous or even wrong in several places. In particular, it's not at all clear what it means for a "variable" to "exist". As near as I can tell, for simple Variables (i.e., those which do not include an array index reference) it means that, after resolving namespace references and following Links, the variable denotes a Location (Scalar or Element) that currently holds a Value, or to an Array.


Revision History

7 Sep 2003
Originally posted to comp.lang.tcl
9 Sep 2003
Minor updates, web-ified.
16 Mar 2004
Changed "Context" to "Environment"; the term "Context" is used to mean something else in On namespaces and contexts. Bug fix:

Last updated: $Date: 2003/09/22 00:22:42 $