<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE TIP SYSTEM "http://www.tcl.tk/cgi-bin/tct/tip/tipxml.dtd">
<!-- Converted at Wed Mar 17 20:15:39 GMT 2010 -->
<!-- TIP AutoGenerator - written by Donal K. Fellows -->

<TIP number='189'>
<header><title>Tcl Modules</title><author address="mailto:akupries@shaw.ca">Andreas Kupries</author><author address="mailto:jcw@equi4.com">Jean-Claude Wippler</author><author address="mailto:jeffh@activestate.com">Jeff Hobbs</author><author address="mailto:dgp@users.sourceforge.net">Don Porter</author><author address="mailto:lvirden@yahoo.com">Larry W. Virden</author><author address="mailto:das@users.sourceforge.net">Daniel A. Steffen</author><author address="mailto:dgp@users.sf.net">Don Porter</author><status type='project' state='final' tclversion="8.5" vote='after'>$Revision: 1.13 $</status><history></history><created day='24' month='mar' year='2004' /></header>
<abstract>This document describes a new mechanism for the handling of packages by the Tcl Core which differs from the existing system in important details and makes different trade-offs with regard to flexibility of package declarations and to access to the filesystem. This mechanism is called &quot;Tcl Modules&quot;.</abstract>
<body><section title="Background and Motivation">
<para>The current mechanism for locating and loading packages employed by the Tcl core is very flexible, but suffers from a number of drawbacks as well. These are at least partially the result of the flexibility, and thus not easily solved without giving up something.</para>
<para>One problem with the current mechanism is that it extensively searches the filesystem for packages, and that it has to actually read a file (<emph style="italic">pkgIndex.tcl</emph>) to get the full information for a prospective package. All of these operations take time. The fact that &quot;index scripts&quot; are able to extend the list of paths searched tends to heighten this cost as it forces rescans of the filesystem. Installations where directories in the <emph style="italic">auto_path</emph> are large or mounted from remote hosts are hit especially hard by this (network delays). All of this together causes a slow startup of tclsh and Tcl-based applications.</para>
<para>&quot;<emph style="bold">Tcl Modules</emph>&quot; on the other hand is designed with less flexibility in mind and to allow implementations to glean as much information as possible without having to perform lots of accesses to the filesystem.</para>
<para>Additional benefits of the proposed design are a simplified deployment of packages, akin to the way starkits made application deployment simple, and from that an easier implementation and management of repositories.</para>
<para>It does not come without penalties however.</para>
<itemize><item.i><para>The simplified design has no &quot;index scripts&quot;. While this does away with extending the list of paths for searching, it also does away with the ability of packages to check preconditions, like the version of the currently executing Tcl interpreter. Dependencies of packages (in module form) on particular versions of Tcl have to be managed differently and outside of them.</para></item.i><item.i><para>&quot;Tcl Modules&quot; is defined to be an extension of the existing package mechanism and does <emph style="italic">not</emph> replace it. This means that any failure to find a package as a module <emph style="italic">has to</emph> cause a fall back to the regular package mechanism. It also sets a limit on how much of our goals we can reach: searching for packages which are not installed will stay relatively slow, and dominated by the filesystem scan of the regular search. This implies that &quot;Tcl Modules&quot; will be best suited in installations where the number of regular packages is low, and contained in a small part of the overall filesystem.</para><para>On the gripping hand, the only regular packages required will be packages supporting the virtual filesystems employed by modules (more on that later), so a transformation of a installation based on a set of regular packages to the form above is quite feasible.</para></item.i></itemize>
</section>
<section title="Specification">

<subsection title="Introduction">
<para>Modules are regular Tcl Packages, in a different guise. To ease explanations, first a summary of the existing mechanism:</para>
<itemize><item.i><para>Packages are identified through &quot;<emph style="italic">pkgIndex.tcl</emph>&quot; files and the &quot;index script&quot; they contain. These files are read and define the &quot;provide script&quot;, which tells Tcl how to actually load the package. In other words, the provide script tells whether to use the &quot;<emph style="bold">source</emph>&quot; or &quot;<emph style="bold">load</emph>&quot; command, which file to specify as an argument to that command, etc. However as &quot;<emph style="italic">pkgIndex.tcl</emph>&quot; contains a regular tcl script, it can do more than that and actually influence the environment, i.e., the package search itself, in several ways:</para><itemize><item.i><para>It may choose to not register the package if conditions for the package are not met, like being run by a too old version of Tcl.</para></item.i><item.i><para>It may extend the list of paths used to search for packages. This implies that a package is able to modify the behaviour of the package search (usually extending the search) even before it is loaded, and even if it will not be loaded at all.</para></item.i></itemize></item.i></itemize>
<para>The above is very flexible, but comes at a price. The filesystem is not only searched, but files have to be read as well to build up the in-memory index of packages. And this is iterated if index files change/extend the list of paths to search.</para>
<para>Tcl Modules simplifies the above considerably, by cutting down on the number of indirections involved. It only searches for module files and records their location, but does not read them. The search is only performed when required, on a limited part of the filesystem. This makes locating and importing packages in module form easier and faster. The price is that packages in module form cannot prevent registration in an interpreter not of their choice, nor can they influence the package search itself before they are actually used.</para>
<para>The remainder of this document will cover the following topics</para>
<itemize><item.i><para>What constitutes a Tcl Module ?</para></item.i><item.i><para>How are they found ?</para></item.i><item.i><para>How are they indexed, i.e. entered into the package database ?</para></item.i></itemize>
</subsection>
<subsection title="Module Definition">
<para>A Tcl Module is a Tcl Package contained in a <emph style="italic">single</emph> file, and no other files required by it. This file has to be <emph style="bold">source</emph>able. In other words, a Tcl Module is always imported via:</para>
<verbatim><vline encoding='base64'>IHNvdXJjZSBtb2R1bGVfZmlsZQ==</vline></verbatim>
<para>The &quot;load&quot; command is not directly used. This restriction is not an actual limitation, as we may believe. Ever since 8.4 the Tcl <emph style="bold">source</emph> command reads only until the first ^Z character. This allows us to combine an arbitrary Tcl script with arbitrary binary data into one file, where the script processes the attached data in any it chooses to fully import and activate the package. Please read <tipref type="text" tip="190"/> &quot;Implementation Choices for Tcl Modules&quot; for more explanations of the various choices which are possible.</para>
<para>The name of a module file has to match the regular expression</para>
<verbatim><vline encoding='base64'>IChbWzphbHBoYTpdX11bOls6YWxudW06XV9dKiktKFtbOmRpZ2l0Ol1dLiopXC50bQ==</vline></verbatim>
<para>The first capturing parentheses provides the name of the package, the second clause its version. In addition to matching the pattern, the extracted version number must not raise an error when used in the command</para>
<verbatim><vline encoding='base64'>IHBhY2thZ2UgdmNvbXBhcmUgJHZlcnNpb24gMA==</vline></verbatim>
<para>This additional check has several benefits. The regular expression pattern is a bit simpler, and the full version check is based on the official definition of version numbers used by the Tcl core itself.</para>
</subsection>
<subsection title="Finding Modules">
<para>Remember the check for a valid module in last section, and notice that any filename matching this name pattern is going to be treated by the TM system as if it&apos;s a Tcl module, whether it really is or not. This means it&apos;s a bad idea for any non-Tcl module files that might match that pattern to end up in a directory where TM will be scanning. This suggests that the directory tree for storing Tcl modules ought to be something separate from other parts of the filesystem. This further implies that a new search path over just these separate storage areas would be better than Yet Another Use of <emph style="italic">$::auto_path</emph>.</para>
<para>Therefore: Modules are searched for in all directories listed in the result of the command &quot;<emph style="bold">::tcl::tm::path list</emph>&quot; (See also section &apos;API to &quot;Tcl Modules&quot;&apos;). This is called the &quot;Module path&quot;. Neither &quot;<emph style="italic">auto_path</emph>&quot; nor &quot;<emph style="italic">tcl_pkgPath</emph>&quot; are used.</para>
<para>All directories on the module path have to obey one restriction:</para>
<itemize><item.i><para>For any two directories, neither is an ancestor directory of the other.</para></item.i></itemize>
<para>This is required to avoid ambiguities in package naming. If for example the two directories</para>
<verbatim><vline encoding='base64'>IGZvby8=</vline><vline encoding='base64'>IGZvby9jb29s</vline></verbatim>
<para>were on the path a package named &apos;cool::ice&apos; could be found via the names &apos;cool::ice&apos; or &apos;ice&apos;, the latter potentially obscuring a package named &apos;ice&apos;, unqualified.</para>
<para>Before the search is started, the name of the requested package is translated into a partial path, using the following algorithm:</para>
<itemize><item.i><para>All occurrences of &apos;::&apos; in the package name are replaced by the appropriate directory separator character for the platform we are on. On Unix, for example, this is &apos;/&apos;.</para></item.i></itemize>
<para>Example:</para>
<itemize><item.i><para>The requested package is <emph style="italic">encoding::base64</emph>. The generated partial path is</para><verbatim><vline encoding='base64'>IGVuY29kaW5nL2Jhc2U2NA==</vline></verbatim></item.i></itemize>
<para>After this translation the package is looked for in all module paths, by combining them one-by-one, first to last with the partial path to form a complete search pattern. The exact pattern and mechanism is left unspecified, giving the implementation freedom of choice as to what glob searches to perform, how much of them, and when.</para>
<para>Independent of that, the implemented algorithm has to reject all files where the filename does not match the regular expression given in the previous section. For the remaining files &quot;provide scripts&quot; are generated and added to the <emph style="bold">package ifneeded</emph> database.</para>
<para>The algorithm has to fall back to the previous unknown handler when none of the found module files satisfy the request. If the request was satisfied no fall-back is required.</para>
</subsection>
<subsection title="Provide and Index Scripts">
<para>Packages in module form have no control over the &quot;index&quot; and &quot;provide script&quot;s entered into the package database for them. For a module file <emph style="italic">MF</emph> the &quot;index script&quot; is</para>
<verbatim><vline encoding='base64'>IHBhY2thZ2UgaWZuZWVkZWQgUE5BTUUgUFZFUlNJT04gW2xpc3Qgc291cmNlIE1GXQ==</vline></verbatim>
<para>and the &quot;provide script&quot; embedded in the above is</para>
<verbatim><vline encoding='base64'>IHNvdXJjZSBNRg==</vline></verbatim>
<para>Both package name <emph style="bold">PNAME</emph> and package version <emph style="bold">PVERSION</emph> are extracted from the filename <emph style="bold">MF</emph> according to the definition below:</para>
<verbatim><vline encoding='base64'>IE1GID0gL21vZHVsZV9wYXRoL1BOQU1FJy1QVkVSU0lPTi50bQ==</vline></verbatim>
<para>Where <emph style="bold">PNAME&apos; </emph>is the partial path of the module as defined in section &apos;Finding Modules&apos; before, and translated into <emph style="bold">PNAME</emph> by changing all directory separators to &apos;::&apos;, and <emph style="bold">module_path</emph> is the path (from the list of paths to search) that we found the module file under.</para>
<para><emph style="italic">Note</emph> that we are here creating a connection between package names and paths. Tcl is case-sensitive when it comes to comparing package names, but there are filesystems which are not, like NTFS. Luckily these filesystems do store the case of the name, despite not using the information when comparing.</para>
<para>Given the above we allow the names for packages in Tcl modules to have mixed-case, but also require that there are no collisions when comparing names in a case-insensitive manner. In other words, if a package &apos;Foo&apos; is deployed in the form of a Tcl Module, packages like &apos;foo&apos;, &apos;fOo&apos;, etc. are not allowed anymore.</para>
<para>Regular packages have no problem with the names of their files, as their entry point has a standard name (&quot;<emph style="italic">pkgIndex.tcl</emph>&quot;) and its contents can be adjusted according to the filesystem they are stored in.</para>
</subsection>
<subsection title="API to &quot;Tcl Modules&quot;">
<para>&quot;Tcl Modules&quot; is implemented in Tcl, as a new handler command for <emph style="bold">package unknown</emph>. This command calls the previously installed handler when its own search fails, thereby ensuring proper fall-back to the regular package search.</para>
<para>All code and data structures implementing &quot;Tcl Modules&quot; reside in the namespace &quot;<emph style="italic">::tcl::tm</emph>&quot;.</para>
<para>A namespace variable holds the list of paths to search for modules, but is not officially exported. All access to this variable is done through the following public commands:</para>
<itemize><item.i><para><emph style="bold">::tcl::tm::path add</emph> <emph style="italic">PATH</emph></para><para>The path is added at the head to the list of module paths.</para><para>The command enforces the restriction that no path may be an ancestor directory of any other path on the list. If the new path violates this restriction an error will be raised.</para><para>If the path is already present as is, no error will be raised and no action will be taken.</para><para>Paths are searched in the order of their appearance in the list. As they are added to the front of the list they are searched in reverse order of addition. In other words, the paths added last are looked at first.</para></item.i><item.i><para><emph style="bold">::tcl::tm::path remove</emph> <emph style="italic">PATH</emph></para><para>Removes the path from the list of module paths. The command is silently ignored if the path is not on the list.</para></item.i><item.i><para><emph style="bold">::tcl::tm::path list</emph></para><para>Returns a list containing all registered module paths, in the order that they are searched for modules.</para></item.i><item.i><para><emph style="bold">::tcl::tm::roots</emph> <emph style="italic">PATH_LIST</emph></para><para>Similar to <emph style="italic">path add</emph>, and layered on top of it. This command takes a list of paths, extends each with <emph style="italic">tclX/site-tcl</emph>, and <emph style="italic">tclX/X.y</emph>, for major version X of the tcl interpreter and minor version y less than or equal to the minor version of the interpreter, and adds the resulting set of paths to the list of paths to search.</para><para>This command is used internally by the system to set up the system-specific default paths. See section <emph style="italic">Defaults</emph> for their definition, and that their structure matches what this command does.</para><para>The command has been exposed to allow a buildsystem to define additional root paths beyond those defined by this document.</para></item.i></itemize>
<para>We do <emph style="italic">not</emph> provide APIs for rescanning directories, clearing internal state and such. The official interface to this functionality is &quot;package forget&quot; and special interfaces are neither required nor desirable.</para>
</subsection>
</section>
<section title="Discussion">

<subsection title="Restriction to &quot;source&quot;">
<para>This has already been discussed in the specification above.</para>
<para>For more discussion I again refer to <tipref type="text" tip="190"/> &quot;Implementation Choices for Tcl Modules&quot; which explains the various implementation choices in much more detail.</para>
</subsection>
<subsection title="Preconditions">
<para>It has already been mentioned in section &apos;Background and Motivation&apos; that preconditions in &quot;index scripts&quot; are lost, one of the penalties of the simplified scheme specified here.</para>
<para>Their existence was most important to installations with multiple versions of Tcl coexisting with each other as they could share the directory hierarchy containing packages between the various Tcl cores. This is not possible anymore, at least not in a simple manner.</para>
<para>For the majority of installations however, i.e. those without only one version of Tcl installed, or controlled environments like the inside of starkits and starpacks, this loss is irrelevant and of no consequence.</para>
<para>For more discussion please see <tipref type="text" tip="191"/> &quot;Managing Tcl Package and Modules in a Multi-Version Environment&quot; which explains the various choices a sysadmin has in much more detail.</para>
</subsection>
<subsection title="Package Metadata">
<para>An area possibly made harder by Tcl Modules is the storage and query of package metadata. <tipref type="text" tip="59"/> was one way of handling such information, by storing them in the binary library of packages which have such. Another approach was to store them in the package index script, using a hypothetical <emph style="bold">package about</emph> command.</para>
<para>The latter approach has the definite advantage that it was possible to query the database of metadata for a particular package without having to actually load said package, as a load may fail if the Tcl shell used to query the database does not fulfil the preconditions for that package.</para>
<para>Both approaches listed above assume that it makes sense to query the database of metadata for all installed packages from a plain Tcl shell. In other words, to use the standard Tcl shell also as the tool to directly manage an installation.</para>
<para>It is possible to extend the proposal made in this document to handle metadata as well. We already reserved the namespace <emph style="bold">::tcl::tm</emph> for use by us, so it is no problem to extend the public API with commands to locate all installed packages, their metadata, and to perform queries based on this. This will require an additional specification as to how metadata is stored in/by Tcl Modules, and it will have to be understood that these extended management operations can take considerably more time than a <emph style="bold">package require</emph>, as they will have to scan all defined search paths and all their sub directories for Tcl Modules, and have to extract the metadata itself as well.</para>
</subsection>
<subsection title="Deployment">
<para>The fact that a Tcl Module consists only of a single file makes its deployment quite easy. We only have to ensure correct placement in one of the searched directories when installing it locally, but nothing more.</para>
<para>Regarding the usage of Tcl Modules in a wrapped application, please see <tipref type="text" tip="190"/> &quot;Implementation Choices for Tcl Modules&quot;. This is highly dependent on the implementation chosen for a specific Tcl Module and thus not discussed here, but in the referred document.</para>
</subsection>
<subsection title="Package Repositories">
<para>At a very basic level, the physical storage, any directory tree containing properly placed files for a number of modules can serve as a package repository for the modules in it. In other words, from that point of view an installation is virtually indistinguishable from a repository, and their creation and maintenance is very easy</para>
<para>Note however that the higher levels of a repository, like indexing package metadata in general, or dependence tracking in particular, licensing, documentation, etc. are not addressed here and by this.</para>
<para>This requires standards for package metadata, format and content, topics with which this document will not deal.</para>
</subsection>
<subsection title="Defaults">
<para>The default list of paths on the module path is computed by a tclsh as follows, where <emph style="italic">X</emph> is the major version of the Tcl interpreter and <emph style="italic">y</emph> is less than or equal to the minor version of the Tcl interpreter.</para>
<itemize><item.i><para>System specific paths</para><itemize><item.i><para><emph style="bold">file normalize</emph> [<emph style="bold">info library</emph>]/../tcl<emph style="italic">X</emph>/<emph style="italic">X</emph>.<emph style="italic">y</emph></para><para>In other words, the interpreter will look into a directory specified by its major version and whose minor versions are less than or equal to the minor version of the interpreter.</para><describe><item.d name='Example'><para>For Tcl 8.4 the paths searched are</para></item.d></describe><itemize><item.i><para>[<emph style="bold">info library</emph>]/../tcl8/8.4</para></item.i><item.i><para>[<emph style="bold">info library</emph>]/../tcl8/8.3</para></item.i><item.i><para>[<emph style="bold">info library</emph>]/../tcl8/8.2</para></item.i><item.i><para>[<emph style="bold">info library</emph>]/../tcl8/8.1</para></item.i><item.i><para>[<emph style="bold">info library</emph>]/../tcl8/8.0</para><para>This definition assumes that a package defined for Tcl <emph style="italic">X.y</emph> can also be used by all interpreters which have the same major number <emph style="italic">X</emph> and a minor number greater than <emph style="italic">y</emph>.</para></item.i></itemize></item.i><item.i><para><emph style="bold">file normalize</emph> <emph style="italic">EXEC</emph>/tcl<emph style="italic">X</emph>/<emph style="italic">X</emph>.<emph style="italic">y</emph></para><para>Where <emph style="italic">EXEC</emph> is [<emph style="bold">file normalize</emph> [<emph style="bold">info nameofexecutable</emph>]/../lib] or [<emph style="bold">file normalize</emph> [<emph style="bold">::tcl::pkgconfig get</emph> libdir,runtime]]</para><para>This sets of paths is handled equivalently to the set coming before, except that it is anchored in <emph style="italic">EXEC_PREFIX</emph>. For a build with <emph style="italic">PREFIX</emph> = <emph style="italic">EXEC_PREFIX</emph> the two sets are identical.</para></item.i></itemize></item.i><item.i><para>Site specific paths.</para><itemize><item.i><para><emph style="bold">file normalize</emph> [<emph style="bold">info library</emph>]/../tcl<emph style="italic">X</emph>/site-tcl</para></item.i></itemize></item.i><item.i><para>User specific paths.</para><itemize><item.i><para><emph style="bold">$::env</emph>(TCL<emph style="italic">X</emph>.<emph style="italic">y</emph>_TM_PATH)</para><para>A list of paths, separated by either <emph style="bold">:</emph> (Unix) or <emph style="bold">;</emph> (Windows). This is user and site specific as this environment variable can be set not only by the user&apos;s profile, but by system configuration scripts as well.</para><para>These paths are seen and therefore shared by all Tcl shells in the <emph style="bold">$::env</emph>(PATH) of the user.</para><para>Note that <emph style="italic">X</emph> and <emph style="italic">y</emph> follow the general rules set out above. In other words, Tcl 8.4, for example, will look at these 5 environment variables</para><itemize><item.i><para><emph style="bold">$::env</emph>(TCL8.4_TM_PATH)</para></item.i><item.i><para><emph style="bold">$::env</emph>(TCL8.3_TM_PATH)</para></item.i><item.i><para><emph style="bold">$::env</emph>(TCL8.2_TM_PATH)</para></item.i><item.i><para><emph style="bold">$::env</emph>(TCL8.1_TM_PATH)</para></item.i><item.i><para><emph style="bold">$::env</emph>(TCL8.0_TM_PATH)</para></item.i></itemize></item.i></itemize></item.i></itemize>
<para><emph style="italic">All</emph> the default paths are added to the module path, even those paths which do not exist. Non-existent paths are filtered out during actual searches. This enables a user to create one of the paths searched when needed and all running applications will automatically pick up any modules placed in them.</para>
<para>The paths are added in the order as they are listed above, and for lists of paths defined by an environment variable in the order they are found in the variable.</para>
</subsection>
<subsection title="Installation">
<para>The installation of a Tcl module for a particular interpreter is basically done like this:</para>
<verbatim><vline encoding='base64'>ICMhIC9wYXRoL3RvL2Nob3Nlbi90Y2xzaA==</vline><vline encoding='base64'>ICMgRmlyc3QgYXJndW1lbnQgaXMgdGhlIG5hbWUgb2YgdGhlIG1vZHVsZS4=</vline><vline encoding='base64'>ICMgU2Vjb25kIGFyZ3VtZW50IGlzIHRoZSBiYXNlIGZpbGVuYW1l</vline><vline encoding='base64'>IHNldCBtcGF0aHMgWzo6dGNsOjp0bTo6cGF0aCBsaXN0XQ==</vline><vline encoding='base64'>IC4uLiByZW1vdmUgYWxsIHBhdGhzIHRoZSB1c2VyIGhhcyBubyB3cml0ZSBwZXJtaXNzaW9ucyBmb3Iu</vline><vline encoding='base64'>IC4uLiB0aHJvdyBhbiBlcnJvciBpZiB0aGVyZSBhcmUgbm8gcGF0aHMgbGVmdC4=</vline><vline encoding='base64'>IC4uLiBwcm92aWRlIHRoZSB1c2VyIHdpdGggc29tZSBVSSBpZiBtb3JlIHRoYW4gb25lIHBhdGggaXMgbGVmdA==</vline><vline encoding='base64'>IC4uLiBzbyB0aGF0IHNoZSBjYW4gc2VsZWN0IHRoZSBwYXRoIHRvIHVzZS4=</vline><vline encoding='base64'>IHNldCBzZWxtcGF0aCBbdWlfc2VsZWN0ICRtcGF0aHNd</vline><vline encoding='base64'>IGZpbGUgY29weSBbbGluZGV4ICRhcmd2IDFdIFw=</vline><vline encoding='base64'>ICAgICBbZmlsZSBqb2luICRzZWxtcGF0aCBc</vline><vline encoding='base64'>ICAgICBbZmlsZSBkaXJuYW1lIFtzdHJpbmcgbWFwIHs6OiAvfSBc</vline><vline encoding='base64'>ICAgICBbbGluZGV4ICRhcmd2IDBdXV1d</vline></verbatim>
</subsection>
</section>
<section title="Glossary">
<para>The following terms and definitions are used throughout the document</para>
<itemize><item.i><para><emph style="italic">index script</emph></para><para>A script used to index a package, or not. Usually contained in a file named &quot;<emph style="italic">pkgIndex.tcl</emph>&quot;. Can check preconditions for a package and contains package specific code for setting up the package specific <emph style="italic">provide script</emph>.</para></item.i><item.i><para><emph style="italic">provide script</emph></para><para>This is a package specific script and tells Tcl exactly how to import it. In the existing package system it is generated and registered by the <emph style="italic">index script</emph>. Tcl Modules on the other hand generates it based on information gleaned from filenames.</para></item.i></itemize>
</section>
<section title="Reference Implementation">
<para>A reference implementation is available in Patch 942881 [<url ref="http://sf.net/tracker/?func=detail&amp;aid=942881&amp;group_id=10894&amp;atid=310894"/>]</para>
</section>
<section title="Questions">

</section>
<section title="Comments">
<para>[ Add comments on the document here ]</para>
<para>A feature asked for during discussion is to allow a directory as a Tcl Module. I am opposed to this, because behind Tcl Modules is the same idea/vision as for starkit and starpacks, namely that of deploying something in the simplest possible manner, without any overhead. Sometimes I call Tcl Modules package kits, short pakits (and then twist that then spoken into &apos;packet&apos; :). [<url ref="http://groups.google.ca/groups?hl=en&amp;lr=&amp;ie=UTF-8&amp;frame=right&amp;th=78764d499cc4e4a&amp;seekm=c6tshf030c6%40news4.newsguy.com#link19"/>]</para>
</section>
<section title="Copyright">
<para>This document has been placed in the public domain.</para>
</section>
</body></TIP>
