This is not necessarily the current version of this TIP.
| TIP: | 112 |
| Title: | Ensembles are Namespaces are Commands |
| Version: | $Revision: 1.1 $ |
| Author: | Donal K. Fellows <donal dot k dot fellows at man dot ac dot uk> |
| State: | Draft |
| Type: | Project |
| Tcl-Version: | 9.0 |
| Vote: | Pending |
| Created: | Thursday, 10 October 2002 |
This TIP proposes unifying the concept of ensembles (from [Incr Tcl]) with namespaces and commands.
Tcl's subcommand-style command collections (e.g. array, info, string, interp, etc.) are a very intuitive and popular way of structuring collections of related commands. However, it is quite awkward to write Tcl code that behaves that way. Users of [Incr Tcl] have access to ensembles which provide that, but it would be a very useful feature for many other uses too.
At the same time, it is becoming clear that many applications want to commonly refer to commands inside other namespaces directly (instead of through the [namespace import] mechanism) but the syntax for doing this is verbose and not as elegant as it might be.
I believe that the same solution can address these two problems in one go, and make the language stronger and more usable for it.
I propose altering Tcl so that for every namespace (except the top-level one) there is a command in the parent namespace that allows ensemble-like access to the exported commands of the namespace. It will also provide suitable error messages when the given subcommand is not an exported command of the namespace (either because it is not a command at all, or because it is not exported), following the well-known Tcl style as enforced by Tcl_GetIndexFromObj().
With respect to sub-namespaces, there are two consequences. Firstly, sub-namespaces will only be visible where they are exported by their parent (though anyone knowing the colon path will be able to examine anything they want, as at present). Secondly, where such exports are done, you can get a chain of ensembles, one nested inside another.
No namespaces will be placed on the stack as part of expansion of the ensemble(s) so as to facilitate the use of [uplevel] to access the caller's stack frame/namespace.
namespace eval carrot { ;# Creates command ::carrot
namespace export foo bar potato
proc foo {} {puts 1} ;# Exported
proc bar {} {puts 2} ;# Exported
proc boo {} {puts 3} ;# Not exported
namespace eval turnip { ;# Not exported
namespace export alpha
proc alpha {} {puts 4} ;# Exported
proc beta {} {puts 5} ;# Not exported
}
namespace eval potato { ;# Exported
namespace export north
proc north {} {puts 6} ;# Exported
proc south {} {puts 7} ;# Not exported
}
}
carrot foo ;# Prints 1
carrot bar ;# Prints 2
carrot b ;# Also prints 2 ("boo" not exported)
carrot ? ;# Alternatives "bar", "foo" and "potato"
carrot potato ;# Complains about missing argument
carrot potato ? ;# Suggests you might try "north" instead
carrot potato north ;# Prints 6
carrot turnip alpha ;# Complains about "turnip" being not known
carrot::turnip alpha ;# Prints 4
carrot::turnip::beta ;# Prints 5
Many commands in both Tcl and Tk would benefit from leveraging this, and it would enable straight-forward implementations of things like TIP #65 in pure Tcl code. It would also make doing things like partial exposure of ensemble-like commands in safe interpreters much easier.
This document has been placed in the public domain.
This is not necessarily the current version of this TIP.