TIP:            44
Title:          Move Tk's Private Commands and Variables into ::tk Namespace
Version:        $Revision: 1.9 $
Author:         Don Porter <dgp@users.sourceforge.net>
State:          Final
Type:           Project
Vote:           Done
Created:        16-Jul-2001
Post-History:   
Tcl-Version:    8.4

~ Abstract

This TIP proposes that Tk's private commands and variables be moved
into the namespace ''::tk'' or its descendent namespace(s).

~ Background

Tk defines several commands and variables in the global namespace
that are not intended for public use.  Some of the commands are
used for widget bindings.  Some of the variables are used to maintain
widget state information.  The definition of these "private" commands
and variables in the global namespace is a legacy held over from Tk 4
and the pre-8 versions of Tcl in which there was only one namespace.

Fortunately, the coders of Tk have maintained good discipline in
naming these commands and variables intended for Tk's internal
use only.  The commands and variables matching the glob pattern
''::tk[[A-Z]]*'' are private.  Consider this interactive tktest session
with Tk 8.3.3:

| $ cd tk/unix
| $ make runtest
| ...
| % # Put Tk through its paces to define all commands and variables
| % source ./../tests/all.tcl
| ...
| % llength [info commands {tk[A-Z]*}]
| 183
| % llength [info vars {tk[A-Z]*}]
| 5

So, on Unix, there are 183 private commands and 5 private variables
polluting the global namespace.  The number and list of commands
and variables varies a bit from platform to platform due to
differences in widget bindings.

More recently, private commands in Tk have been added in the ''::tk''
namespace; two examples are ''tk::PlaceWindow'' and ''tk::SetFocusGrab''.
Likewise the private variable ''tk::FocusGrab'' has also been added
in the ''::tk'' namespace.

There are three reasons why it is better for Tk's private commands
and variables to be moved out of the global namespace and into the
''::tk'' namespace.

 1. The large number of commands and variable makes it more difficult
    to use interactive ''[[info commands]]'' and ''[[info vars]]'' or
    ''[[info globals]]'' introspection to learn about what application
    specific commands and variables are defined.

 2. Placing private commands and variables in the global namespace
    gives them a higher profile, and increases the likelihood that
    they will be used publicly, against the intent of Tk's interface.

 3. By making more use of its own namespace for keeping track of its
    own internals, Tk becomes a better example for authors of other
    packages to copy.

~ Proposal

All commands and variables created by Tk and matching the glob pattern
''::tk[[A-Z]]*'' shall be renamed to a name contained within the
''::tk'' namespace or one of the descendent namespaces of ''::tk''.

The global variable ''::histNum'' created by ''tk/library/console.tcl''
shall also be renamed to ''::tk::HistNum''.

All commands and variables created by the proposal will be given names
that begin with an uppercase character (''[[A-Z]]'') to indicate their
internal status according to the conventions of the Tcl Style Guide
[http://purl.org/tcl/home/doc/styleGuide.pdf].

~ Compatibility and Migration

This proposal only deals with the internals of Tk, so technically there
are no compatibility issues, because Tk users should not be depending
on these private commands and variables.

That said, because these commands and variables have had a high
profile in the global namespace, it seems likely that some users
have written code that depends on them.  To aid such users in a
migration away from that dependence, it is also proposed that
Tk provide two additional unsupported commands:

| ::tk::unsupported::ExposePrivateCommand commandName

and

| ::tk::unsupported::ExposePrivateVariable variableName

The command ''[[::tk::unsupported::ExposePrivateCommand commandName]]''
restores the existence of the Tk private command ''commandName'' in
the global namespace as it was before adoption of this proposal.
The command ''[[::tk::unsupported::ExposePrivateVariable variableName]]''
restores the existence of the Tk private variable ''variableName'' in
the global namespace as it was before adoption of this proposal.
For example, a Tk user who had written code that made use of the Tk
private command ''tkCancelRepeat'' can add the following code to
continue working with Tk after acceptance of this proposal:

| if {![llength [info commands tkCancelRepeat]]} {
|     tk::unsupported::ExposePrivateCommand tkCancelRepeat
| }

These migration commands are in the namespace ''tk::unsupported'',
a new namespace to be used for unsupported commands in Tk.  This
namespace may and should be used for any other unsupported commands
to be created in Tk.  Their implementation is in the new file
''tk/library/unsupported.tcl''.

~ Reference Implementation

This proposal has already been implemented and committed to Tk's
CVS repository on the branch tagged ''dgp-privates-into-namespace''.
That branch is up to date with Tk's HEAD branch as of July 16, 2001.

To make an anonymous checkout of the reference implementation into
a directory named ''tkprivate'', run the following CVS commands:

| $ cvs -d :pserver:anonymous@cvs.tktoolkit.sf.net:/cvsroot/tktoolkit \
|   login
| (Logging in to anonymous@cvs.tktoolkit.sf.net)
| CVS password: <Enter>
| $ cvs -z3 -d :pserver:anonymous@cvs.tktoolkit.sf.net:/cvsroot/tktoolkit \
|   co -r dgp-privates-into-namespace -d tkprivate tk

The reference implementation has the same results on the Tk
test suite as the HEAD revision.

In the tktest of the reference implementation:

| $ make runtest
| ...
| % source ./../tests/all.tcl
| ...
| % llength [info commands {tk[A-Z]*}]
| 0
| % llength [info vars {tk[A-Z]*}]
| 0

~ See Also

Feature Request 220936
[http://sf.net/tracker/?func=detail&aid=220936&group_id=12997&atid=362997]

~ Related Ideas / Future Work

The ideas in this section are ''not'' part of this proposal.  They are
related ideas mentioned here as explicitly outside the scope of this
proposal so they will not be counter-proposed.

 * ''Shouldn't Tk's public commands and variables be moved to ::tk too?''

 > Well, yes, I think they should, but that change clearly involves 
   sorting out more difficult compatibility/migration issues.  The
   current proposal is limited to the less controversial topic of
   Tk's private commands and variables.  We'll tackle the rest later.

 * ''Shouldn't Tk make use of [[namespace code]] in its bindings?''

 * ''Wouldn't it make Tk better organized if commands like
   [[tk::IconList_Add]] were further renamed [[tk::IconList::Add]]?''

 > Perhaps so.  There may be many ways in which Tk can and should 
   make better or more idiomatic use of namespaces.  That's not the
   point of this proposal, though.  The point is to get these commands
   and variables out of the global namespace.  Once that is accomplished,
   then these other matters are unquestionably internal and can proceed
   at the discretion of the maintainers without further TIP review.

~ Copyright

This document has been placed in the public domain.

