<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE TIP SYSTEM "http://tcl.activestate.com/cgi-bin/tct/tip/tipxml.dtd">
<!-- Converted at Thu Feb 09 07:30:25 GMT 2012 -->
<!-- TIP AutoGenerator - written by Donal K. Fellows -->

<TIP number='92'>
<header><title>Move Package Load Decisions to Application Developer</title><author address="mailto:clif@cflynt.com">Clif Flynt</author><status type='project' state='withdrawn' tclversion="8.4" vote='prior'>$Revision: 1.3 $</status><history></history><created day='13' month='may' year='2002' /><keyword>{package require} namespace pkg_mkIndex</keyword></header>
<abstract>This TIP makes the loading of packages far more flexible, so as to better support their use by application authors in situations above and beyond those foreseen by the developer of the package.</abstract>
<body><section title="Overview">
<para>I believe that we&apos;ve been misdirecting our efforts in solutions to the Package issue.</para>
<itemize><item.i><para>The modifications to <emph style="italic">pkg_mkIndex</emph> give the library author (or package builder) the ability to define when a package will be loaded (immediate or deferred), which restricts an application developer to the decisions made by the library author.</para></item.i><item.i><para>If a package is built to be loaded immediately, it is loaded into the top-level namespace. This breaks previous tricks to force a package to load inside an existing namespace.</para></item.i></itemize>
<para>These techniques limit the application writer to the behavior (and uses) envisioned by the package author and is counter to the concept that application developer best understands how they need a tool to perform for their application. The Tcl community, in particular, has grown largely because the tools have had applications far beyond those imagined by their initial developers.</para>
<para>Moving the decisions about when and how to load a package from <emph style="italic">pkg_mkIndex</emph> to the <emph style="italic">package require</emph> command allows the application writer the freedom to find new styles of use that the package author may not have conceived.</para>
<para>Being able to force an immediate load into the current namespace rather than always loading packages into the global scope provides support for lightweight object style data structures without the need for extensions like Incr Tcl, OOTcl, etc.</para>
<para>Loading a package/namespace into the current namespace provides mechanisms for lightweight inheritance, and since namespaces can contain both code and data, loading a namespace multiple times (in separate namespaces) is a lightweight aggregation model.</para>
<para>I do not propose that this power removes the need for full object oriented programming models within the Tcl community. However, I believe that putting the power to develop these lightweight models into the application developer provides the developer with a more versatile tool kit than they currently have. (One that I&apos;ve been using for several years, with workarounds.)</para>
<para>This proposal is to add new flags to the package require command, allowing an application developer to determine when and how to load a package.</para>
<describe><item.d name='-current'><para>Load the package into the current namespace rather than the global space. Implies immediate.</para></item.d><item.d name='-multiple'><para>Allow loading multiple copies of this package, for use with <emph style="italic">-current</emph> when the application programmer wishes to create multiple nested copies of a package.</para></item.d><item.d name='-immediate'><para>Load immediately, rather than defer loading the package until needed. This is the default behavior with Tcl 8.3 and later.</para></item.d><item.d name='-defer'><para>Load package when required. The default with Tcl 8.2 and earlier, or when <emph style="italic">pkg_mkIndex -lazy</emph> used with Tcl 8.3.</para></item.d><item.d name='-exact'><para>No change to this option. Requires an exact Major/Minor revision match to be an acceptable package.</para></item.d></describe>
</section>
<section title="Script Example">
<para>The code below implements a simple stack object that can be merged into other namespaces to create objects that contain individual stacks.</para>
<verbatim><vline encoding='base64'>IHBhY2thZ2UgcHJvdmlkZSBzdGFjayAxLjA=</vline><vline encoding='base64'>IG5hbWVzcGFjZSBldmFsIHN0YWNrIHs=</vline><vline encoding='base64'>ICAgICBuYW1lc3BhY2UgZXhwb3J0IHB1c2ggcG9wIHBlZWsgc2l6ZQ==</vline><vline encoding='base64'>ICAgICB2YXJpYWJsZSBzdGFjayAiIg==</vline><vline encoding='base64'>ICAgICA=</vline><vline encoding='base64'>ICAgICBwcm9jIHB1c2gge3ZhbH0gew==</vline><vline encoding='base64'>ICAgICAgICAgdmFyaWFibGUgc3RhY2s7</vline><vline encoding='base64'>ICAgICAgICAgbGFwcGVuZCBzdGFjayAkdmFs</vline><vline encoding='base64'>ICAgICB9</vline><vline encoding='base64'>ICAgICAg</vline><vline encoding='base64'>ICAgICBwcm9jIHBvcCB7fSB7</vline><vline encoding='base64'>ICAgICAgICAgdmFyaWFibGUgc3RhY2s7</vline><vline encoding='base64'>ICAgICAgICAgc2V0IHJ0biBbbGluZGV4ICRzdGFjayBlbmRd</vline><vline encoding='base64'>ICAgICAgICAgc2V0IHN0YWNrIFtscmFuZ2UgJHN0YWNrIDAgZW5kLTFd</vline><vline encoding='base64'>ICAgICAgICAgcmV0dXJuICRydG4=</vline><vline encoding='base64'>ICAgICAgICAgfQ==</vline><vline encoding='base64'>IA==</vline><vline encoding='base64'>ICAgICBwcm9jIHBlZWsge3twb3MgZW5kfX0gew==</vline><vline encoding='base64'>ICAgICAgICAgdmFyaWFibGUgc3RhY2s7</vline><vline encoding='base64'>ICAgICAgICAgcmV0dXJuIFtsaW5kZXggJHN0YWNrICRwb3Nd</vline><vline encoding='base64'>ICAgICB9</vline><vline encoding='base64'>ICAgICAg</vline><vline encoding='base64'>ICAgICBwcm9jIHNpemUge30gew==</vline><vline encoding='base64'>ICAgICAgICAgdmFyaWFibGUgc3RhY2s7</vline><vline encoding='base64'>ICAgICAgICAgcmV0dXJuIFtsbGVuZ3RoICRzdGFja10=</vline><vline encoding='base64'>ICAgICB9</vline><vline encoding='base64'>ICAgICAg</vline><vline encoding='base64'>IH0=</vline><vline encoding='base64'>ICA=</vline></verbatim>
<para>With this data structure available, the guts of a Tower of Hanoi puzzle becomes simple:</para>
<verbatim><vline encoding='base64'>IG5hbWVzcGFjZSBldmFsIGxlZnQgew==</vline><vline encoding='base64'>ICAgICAgICAgcGFja2FnZSByZXF1aXJlIC1jdXJyZW50IC1tdWx0aXBsZSAgc3RhY2sgMS4w</vline><vline encoding='base64'>ICAgICAgICAgbmFtZXNwYWNlIGltcG9ydCBbbmFtZXNwYWNlIGN1cnJlbnRdOjpzdGFjazo6Kg==</vline><vline encoding='base64'>ICAgICB9ICAg</vline><vline encoding='base64'>IG5hbWVzcGFjZSBldmFsIGNlbnRlciB7</vline><vline encoding='base64'>ICAgICAgICAgcGFja2FnZSByZXF1aXJlIC1jdXJyZW50IC1tdWx0aXBsZSAgc3RhY2sgMS4w</vline><vline encoding='base64'>ICAgICAgICAgbmFtZXNwYWNlIGltcG9ydCBbbmFtZXNwYWNlIGN1cnJlbnRdOjpzdGFjazo6Kg==</vline><vline encoding='base64'>ICAgICB9</vline><vline encoding='base64'>IG5hbWVzcGFjZSBldmFsIHJpZ2h0IHs=</vline><vline encoding='base64'>ICAgICAgICAgcGFja2FnZSByZXF1aXJlIC1jdXJyZW50IC1tdWx0aXBsZSAgc3RhY2sgMS4w</vline><vline encoding='base64'>ICAgICAgICAgbmFtZXNwYWNlIGltcG9ydCBbbmFtZXNwYWNlIGN1cnJlbnRdOjpzdGFjazo6Kg==</vline><vline encoding='base64'>ICAgICB9</vline><vline encoding='base64'>ICAgICAg</vline><vline encoding='base64'>IHByb2MgbW92ZSB7ZnJvbSB0b30gew==</vline><vline encoding='base64'>ICAgICAgICAgJHt0b306OnB1c2ggWyR7ZnJvbX06OnBvcF0=</vline><vline encoding='base64'>ICAgICB9</vline></verbatim>
<para>This creates 3 &apos;objects&apos; each of which contains a private stack with the stack methods.</para>
</section>
<section title="Reference Implementation">
<para>A reference implementation of the <emph style="italic">-current</emph> and <emph style="italic">-multiple</emph> flags has been created for Tcl 8.4a4 and is available at <url ref="http://noucorp.com/PkgPatch8.4.zip"/></para>
<para>The implementation required these modifications to <emph style="italic">generic/tclPkg.c</emph>:</para>
<itemize><item.i><para><emph style="italic">Tcl_PackageObjCmd</emph> needs to be able to parse the new options and set the bitmapped flag.</para></item.i><item.i><para><emph style="italic">Tcl_PkgRequireEx</emph> is modified to accept a bitmapped flag instead of the <emph style="italic">exact</emph> option.</para></item.i><item.i><para>The 0x0001 bitmap position is used to map for <emph style="italic">exact</emph> preserving the existing behavior of the <emph style="italic">Tcl_PackageObjCmd</emph> and <emph style="italic">Tcl_PkgRequireEx</emph> functions.</para></item.i><item.i><para>These bitmapped flags are defined exact, current, and multiple:</para><verbatim><vline encoding='base64'>I2RlZmluZSBQS0dfRVhBQ1QgICAgMHgwMSAgIC8qIFVzZSB0aGUgZXhhY3QgdmVyc2lvbiAtIGFzIHVzZWQgZm9yIGV4YWN0ICov</vline><vline encoding='base64'>I2RlZmluZSBQS0dfQ1VSUkVOVCAgMHgwMiAgIC8qIExvYWQgaW50byBjdXJyZW50IG5hbWVzcGFjZSwgbm90IEdMT0JBTCAqLw==</vline><vline encoding='base64'>I2RlZmluZSBQS0dfTVVMVElQTEUgMHgwNCAgIC8qIEFsbG93IGxvYWRpbmcgbXVsdGlwbGUgY29waWVzIG9mIGEgcGFja2FnZSAqLw==</vline></verbatim></item.i><item.i><para><emph style="italic">Tcl_PkgRequireEx</emph> is modified to process the MULTIPLE and CURRENT flags.</para></item.i><item.i><para>The Tcl tests have been reworked to understand the new error returns, etc. Running &quot;make tests&quot; will accept the new code.</para></item.i></itemize>
<para>Minimal testing has been done using pure Tcl packages. </para>
</section>
</body></TIP>

