\documentclass[]{article}
\usepackage{amsmath,graphicx,supertabular,hyperref,tabularx,ifthen}
\title{TIP \#44: Move Tk's Private Commands and Variables into ::tk Namespace}
\date{July 16, 2001}
\author{Don Porter}
\urlstyle{sf}
\setlength{\parskip}{1ex}
\setlength{\parindent}{0pt}
\def\tipversion$#1${\texttt{\$#1\$}}
\def\tiplangle#1{\ensuremath{<}}
\def\tiprangle#1{\ensuremath{>}}
\def\tipbar#1{\ensuremath{|}}
\def\tipmail#1#2{\(\langle\){\small\expandafter\url{#1@#2}}\(\rangle\)}
\ifx\pdfoutput\undefined
\newcommand{\tipimage}[2]{\typeout{Make sure you download #1.eps}\ifthenelse{\lengthtest{0.8\textwidth>#2}\and\lengthtest{0pt<#2}}{\includegraphics{#1.eps}}{\includegraphics[width=0.8\textwidth]{#1.eps}}}
\newcommand{\tipxref}[1]{}
\newcommand{\tipxrefend}{}
\else
\newcommand{\tipimage}[2]{\typeout{Make sure you create #1.pdf}\ifthenelse{\lengthtest{0.8\textwidth>#2}\and\lengthtest{0pt<#2}}{\includegraphics{#1.pdf}}{\includegraphics[width=0.8\textwidth]{#1.pdf}}}
\pdfcatalog{/PageMode /UseOutlines}
\newcommand{\tipxref}[1]{\pdfannotlink attr {/C [0.5 0.5 1.0] /Border [0 0 1]} goto name {#1}}
\newcommand{\tipxrefend}{\pdfendlink}
\fi
\newenvironment{tipabstract}{\begin{abstract}}{\end{abstract}}
\begin{document}\maketitle
\begin{center}\begin{tabularx}{\linewidth}{|r@{: }X|}\hline
\textbf{TIP \#44}&\textbf{Move Tk's Private Commands and Variables into ::tk Namespace}\\\hline
Author&

Don Porter \tipmail{dgp}{users.sourceforge.net}
\\
Created&Monday, \(\text{16}^{\text{th}}\) July 2001\\
Type&Project\\
Tcl Version&\(8.4\)\\
State&Final\\
Vote&Done\\
Version&\tipversion$Revision: 1.9 $\\
Post History&\\
\hline\end{tabularx}\end{center}
\thispagestyle{empty}\pagestyle{empty}
\begin{tipabstract}

This TIP proposes that Tk's private commands and variables be moved into the namespace \textit{::tk} or its descendent namespace(s).
\end{tipabstract}
\tableofcontents\setcounter{page}{0}\clearpage\pagestyle{plain}

\section{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 \textit{::tk[A-Z]*} are private. Consider this interactive tktest session with Tk 8.3.3:
\begingroup\small\begin{verbatim}
 $ 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
\end{verbatim}
\endgroup

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 \textit{::tk} namespace; two examples are \textit{tk::PlaceWindow} and \textit{tk::SetFocusGrab}. Likewise the private variable \textit{tk::FocusGrab} has also been added in the \textit{::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 \textit{::tk} namespace.
\begin{enumerate}
\item{}
The large number of commands and variable makes it more difficult to use interactive \textit{[info commands]} and \textit{[info vars]} or \textit{[info globals]} introspection to learn about what application specific commands and variables are defined.
\setcounter{enumi}{1}
\item{}
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.
\setcounter{enumi}{2}
\item{}
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.
\end{enumerate}

\section{Proposal}

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

The global variable \textit{::histNum} created by \textit{tk/library/console.tcl} shall also be renamed to \textit{::tk::HistNum}.

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

\section{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:
\begingroup\small\begin{verbatim}
 ::tk::unsupported::ExposePrivateCommand commandName
\end{verbatim}
\endgroup

and
\begingroup\small\begin{verbatim}
 ::tk::unsupported::ExposePrivateVariable variableName
\end{verbatim}
\endgroup

The command \textit{[::tk::unsupported::ExposePrivateCommand commandName]} restores the existence of the Tk private command \textit{commandName} in the global namespace as it was before adoption of this proposal. The command \textit{[::tk::unsupported::ExposePrivateVariable variableName]} restores the existence of the Tk private variable \textit{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 \textit{tkCancelRepeat} can add the following code to continue working with Tk after acceptance of this proposal:
\begingroup\small\begin{verbatim}
 if {![llength [info commands tkCancelRepeat]]} {
     tk::unsupported::ExposePrivateCommand tkCancelRepeat
 }
\end{verbatim}
\endgroup

These migration commands are in the namespace \textit{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 \textit{tk/library/unsupported.tcl}.

\section{Reference Implementation}

This proposal has already been implemented and committed to Tk's CVS repository on the branch tagged \textit{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 \textit{tkprivate}, run the following CVS commands:
\begingroup\small\begin{verbatim}
 $ 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
\end{verbatim}
\endgroup

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

In the tktest of the reference implementation:
\begingroup\small\begin{verbatim}
 $ make runtest
 ...
 % source ./../tests/all.tcl
 ...
 % llength [info commands {tk[A-Z]*}]
 0
 % llength [info vars {tk[A-Z]*}]
 0
\end{verbatim}
\endgroup

\section{See Also}

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

\section{Related Ideas / Future Work}

The ideas in this section are \textit{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.
\begin{itemize}
\item{}
\textit{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.
\item{}
\textit{Shouldn't Tk make use of [namespace code] in its bindings?}
\item{}
\textit{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.
\end{itemize}

\section{Copyright}

This document has been placed in the public domain.

\section{Colophon}

\textit{TIP AutoGenerator --- written by Donal K. Fellows}
\end{document}
