Konventionen in LaTeX und teilweise auch in plainTeX
====================================================
`\newbox` ist eine Low-Level-Anweisung vergleichbar zu `\newskip`, `\newdimen` oder auch `\def` und `\let`. Auf LaTeX-Ebene sollte man stattdessen `\newsavebox` verwenden. Dies arbeitet ähnlich zu `\newbox` stellt aber wie `\newcommand` sicher, dass der Name noch nicht belegt ist. So ergibt beispielsweise:
\newsavebox\documentclass
ebenso eine Fehlermeldung wie
\newsavebox\mybox
\newsavebox\mybox
Dadurch wird effektiv verhindert, dass derselbe Name versehentlich mehrfach verwendet wird.
Darüber hinaus bietet LaTeX für die Belegung und Verwendung von Boxen auch noch die Anweisungen `\savebox`, `\sbox` und `\usebox`. Auch diese sollte man nach Möglichkeit verwenden.
Klarstellungen zur Frage
========================
Mir ist aber ehrlich gesagt der Sinn der Frage nicht ganz klar. Um Missverständnisse zu vermeiden sei daher auf einige mögliche Irrtümer hingewiesen.
So benötigt man beispielsweise kein neues Boxregister, wenn man lediglich an eine vorhandene Box etwas anhängen möchte. Tatsächlich kann man eine Box mit ihrem bisherigem und zusätzlich neuem Inhalt belegen. Je nach Anwendungsfall kann das beispielsweise mit (hier wieder teilweise Low-Level-TeX):
\sbox\mybox{\unhbox\mybox\ und neuer Inhalt}
oder
\sbox\mybox{\box\mybox\ und neuer Inhalt}
erfolgen. Näheres zu diesen Anweisungen und den Unterschiedenen ist beispielsweise [TeX by Topic][1] zu entnehmen.
Ebenso sei darauf hingewiesen, dass `\ifvoid` nicht testet, ob ein Boxregister bereits reserviert wurde. Damit testet es auch nicht, ob ein Boxregister bereits anderweitig in Verwendung ist oder ob es zur allgemeinen Verwendung bereit steht. Vielmehr testet `\ifvoid`, ob ein Boxregister derzeit leer ist. Wobei ein leeres Boxregister wiederum nicht dasselbe wie eine leere `\hbox` oder eine leere `\vbox` ist, sondern ein Boxregister, das derzeit nichts enthält. LaTeX selbst hat beispielsweise mit `\voidb@x` ein Boxregister belegt, das aber niemals etwas enthalten darf. Dies wird beispielsweise verwendet, um mit `\unhbox\voidb@x` vom vertikalen in den horizontalen Modus zu wechseln, ohne dabei Inhalt in den Ausgabestrom einzufügen oder um ein anderes Boxregister wie `\@tempboxa` mit Hilfe von `\setbox\@tempboxa\box\voidb@x` wiederum zu leeren, ohne den bisherigen Inhalt in irgend einer Form zu verwenden. Dabei würde übrigens gleichzeitig auch `\voidb@x` leer, falls es nicht bereits leer wäre.
Ebenso reserviert man nicht zunächst ein Boxregister per `\newbox\foo`, um anschließend `\foo` per `\chardef` auf eine feste Nummer zu setzen. Vielmehr wird `\foo` mit Hilfe von `\newbox\foo` bereits auf die Nummer eines freien Boxregisters definiert, falls überhaupt noch ein freies Boxregister existiert. Eine anschließende Umdefinierung von `\foo` gibt auch keineswegs die Reservierung wieder auf. Vielmehr verliert man damit lediglich die klar definierte Zugriffsmöglichkeit auf das reservierte Register, falls man die zugehörige Nummer nicht anderweitig, etwa durch ein vorheriges `\let\bar\foo` speichert.
Fazit
=====
Um es abschließend ganz deutlich zu sagen: *Weder kann man mit `\\ifvoid` testen, ob ein Boxregister bereits reserviert ist, noch kann man in einer sinnvollen Anwendung verhindern, dass Boxregister über ihre Nummer angesprochen werden.*
Genau aus diesem Grund sollte man sich an die Konvention halten: **Nur Boxregister verwenden, die man zuvor selbst mit den im Format dafür vorgesehenen Anweisungen reserviert hat oder für die eine bestimmte Form der freien Verwendbarkeit dokumentiert ist.**
Wie kann man mehrere Register auf einen Schlag reservieren?
===========================================================
In einigen wenigen Fällen benötigt man mehrere Register auf einmal und möchte diese unter fortlaufenden Namen ansprechen können. Hier ein Beispiel dafür:
\documentclass{article}
\makeatletter
% Argument 1: Basisname für die neuen Register
% Argument 2: Art des Registers; erlaubt sind: count, dimen, skip, muskip,
% box, toks, read oder write
% Argument 3: Anzahl der Register
%
% Mögliche Fehlermeldungen:
%
% No romm for a new …
% – Es gibt keine Register der angeforderten Art mehr.
%
% LaTeX Error: Command … already defined.
% Or name \end... illegal, see p.192 of the manual.
% – Ein aus dem angegebenen Basisnamen und der fortlaufenden kleinen
% römischen Zahl gebildeter Name wird bereits anderweitig verwendet.
\newcommand*{\newregisters}[3]{%
\@tempcnta\z@
\@whilenum\@tempcnta <#3 \do{%
\advance\@tempcnta by \@ne
\expandafter\@ifdefinable\csname #1\romannumeral\the\@tempcnta\endcsname{%
\csname new#2\expandafter\endcsname
\csname #1\romannumeral\the\@tempcnta\endcsname
}%
}%
}
\makeatother
\newregisters{MeineBox}{box}{10}% zehn Boxregister anfordern
\begin{document}
% Die 10 Boxregister mit Inhalt füllen:
\sbox\MeineBoxi{Das ist Box i}
\sbox\MeineBoxii{Das ist Box ii}
\sbox\MeineBoxiii{Das ist Box iii}
\sbox\MeineBoxiv{Das ist Box iv}
\sbox\MeineBoxv{Das ist Box v}
\sbox\MeineBoxvi{Das ist Box vi}
\sbox\MeineBoxvii{Das ist Box vii}
\sbox\MeineBoxviii{Das ist Box viii}
\sbox\MeineBoxix{Das ist Box ix}
\sbox\MeineBoxx{Das ist Box x}
% Die 10 Boxregister ausgeben:
Hier die 10 Boxen: \frame{\usebox\MeineBoxi}, \frame{\usebox\MeineBoxii},
\frame{\usebox\MeineBoxiii}, \frame{\usebox\MeineBoxiv}, \frame{\usebox\MeineBoxv},
\frame{\usebox\MeineBoxvi}, \frame{\usebox\MeineBoxvii}, \frame{\usebox\MeineBoxviii},
\frame{\usebox\MeineBoxix}, \frame{\usebox\MeineBoxx}.
\end{document}
In dem Beispiel werden alle Register sauber per `\new…` angefordert und darüber hinaus wird sichergestellt, dass die Namen für die Register wirklich neu sind, also nicht bereits anderweitig verwendet werden. So würde beispielsweise
\newregisters{MeineBoxen}{box}{5}
\newregisters{MeineBoxen}{box}{2}
zu einer Fehlermeldung:
! LaTeX Error: Command \MeineBoxeni already defined.
Or name \end... illegal, see p.192 of the manual.
See the LaTeX manual or LaTeX Companion for explanation.
Type H <return> for immediate help.
...
l.30 \newregisters{MeineBoxen}{box}{2}
führen.
Konventionen in LaTeX3
======================
In LaTeX3 ist die TeX-Ebene von der LaTeX-Ebene durch wesentlich klarere Konventionen getrennt. Zum einen gibt es die plainTeX-Ebene zwischen der TeX-Ebene und der LaTeX-Ebene offiziell nicht mehr. Zum anderen ist es durch Konvention verboten, TeX-Primitive direkt zu verwenden. Stattdessen sind die entsprechenden Makros der TeX-Basisebene zu verwenden, beispielsweise `\tex_iftrue` and Stelle von `\iftrue`. Diese TeX-Basisebene mit beispielsweise `\tex_iftrue` gilt allerdings auch nur für diejenigen, die LaTeX3 implementieren. Darüber liegt dann die LaTeX-Basisebene, die dann beispielsweise `\if_true` bereit stellt. Jeder, der nicht die Sprache LaTeX3 selbst implementiert, sollte min. diese Ebene einhalten. Wird dieses Schichtmodell eingehalten, ist es theoretisch möglich beispielsweise TeX selbst durch ein anderes Programm zu ersetzen. Dieses andere Programm könnte dann auch Möglichkeiten bereitstellen, um die Einhaltung der Konvention zu überwachen.
Derzeit existiert LaTeX3 noch nicht als von LaTeX2ε unabhängiges Format. Stattdessen gibt es derzeit nur einige Kernbestandteile in Form von Paketen, die mit LaTeX2ε verwendet werden können. Daraus bedingt ist es auch vielfach leider noch nicht möglich, komplett innerhalb der LaTeX3-Schichten zu operieren. Stattdessen muss zumindest teilweise auch auf LaTeX2ε zurückgegriffen und damit das klar strukturierte Schichtenmodell verlassen werden.
Kritik an Konventionen
======================
In Deinen Fragen durchbrichst Du all diese Konventionen. Tatsächlich ermöglicht TeX als Sprache nicht, das effektiv zu verhindern. Selbst wenn man zur Verhinderung etwas wie
\let\secret@box\box
\let\box\undefined
\let\secret@copy\copy
\let\copy\undefined
usw. in LaTeX einbauen würde, könnte man nicht verhindern, dass dann jemand `\secret@copy` statt `\usebox` verwendet. Auf der anderen Seite kann man beispielsweise auch nicht verhindern, dass jemand den Quelltext einer C-Library nimmt und auf eine Funktion, die nicht über die Header-Datei offiziell als Teil der Schnittstelle definiert ist, per eigener Prototyp-Definition im eigenen Programm trotzdem zugreift. Selbst das Heraussuchen eines Einsprungpunktes in einer Library wäre theoretisch denkbar.
Nur weil Dinge möglich sind, heißt es noch lange nicht, dass man sie tun sollte. Natürlich kann man den Vorwurf in den Raum stellen, dass sie nicht möglich sein sollten. Wenn aber bereits dieser Vorwurf zulässig ist, ist dann nicht umso mehr ein Vorwurf zulässig, wenn jemand wider besseren Wissens die Konventionen verletzt?
Historische Begründung für Einschränkungen
==========================================
Bei aller Liebe zu TeX ist zu bedenken, dass es eine sehr alte Sprache ist. Zu der Zeit, als TeX entworfen wurde, war gerade einmal Pascal als Leersprache im Kommen. Vielfach wurde noch in Assembler programmiert. Die erste Implementierung von TeX erfolge noch in einer wenig leistungsfähigen Script-Sprache. Maschinenunabhängige Programmierung war noch ein kaum beachteter Traum. Sicherheitsmechanismen bei der Programmierung waren gerade erst im Aufkeimen.
Gleichzeitig war TeX ein Entwurf und eine Implementierung für einen sehr speziellen Einsatzzweck: Das Setzen von Büchern in einer ganz bestimmten Reihe. Dabei war im Übrigen noch gedacht, dass für jede Buchreihe oder eventuell sogar jedes Buch ein eigenes TeX-Format zu erstellen ist. Trotzdem gab es mit plainTeX bereits eine Art Grundebene, auf der diese Spezialformate aufbauen könnten. Diese Grundebene lieferte einfache Verwaltungsfunktionen, beispielsweise die `\new…`-Makros zur Reservierung von Registern. Diese sind vergleichbar mit Funktionen zur Speicherverwaltung in grundlegenden Sprachbibliotheken. Unter diese Ebene zu gehen ist möglich, aber dann sollte es konsequent erfolgen, indem man die Anweisungen dieser Ebene komplett durch ein Alternativmodell ersetzt.
Lösungsideen
============
Tatsächlich gab es immer wieder Überlegungen, TeX um *Scopes* zu erweitern. Ein *Scope* ist dabei ein Bereich eines Programms, indem Variablen, Funktionen und andere Elemente der Sprache quasi eingeschlossen werden können. Außerhalb des entsprechenden *Scope* sind diese Elemente nicht sichtbar. Meines Wissens wurden *Scopes* für TeX erstmals in [εχTEX][2] implementiert.
Resultierende neue Probleme
===========================
Allerdings gibt es bei LaTeX ein großes Problem mit solch gundlegenden Neuerungen: LaTeX ist kein monolithisches System. Stattdessen besteht es aus einem Kern und vielen Teilen, die von vielen unterschiedlichen Menschen hinzugefügt wurden. Die Einführung von grundlegenden Neuerungen bedeutet daher, dass nur ein Teil der LaTeX-Infrastuktur auf diese Neuerungen umgestellt werden. Für die Verwendung von *Scopes* bedeutet das, dass die Verwendung selbiger in LaTeX selbst entweder die Möglichkeit bieten müsste, dass es erlaubt wird, daraus auszubrechen, oder aber dass auf einen Schlag nicht nur sehr viele Dokumente, sondern auch die meisten Pakete und Klassen nicht mehr funktionierten. Darüber hinaus müsste man erst einmal jemand finden, der zum einen Scopes in die gängigen TeX-Maschinen (als da min. sind `tex`, `etex`, `pdftex`, `luatex`, `xetex`) einzubauen und dann auch noch LaTeX selbst komplett zu überarbeiten – letztlich neu zu implementieren. Bei LaTeX bis einschließlich LaTeX2ε war immer die Kompatibilität zu früheren Versionen ein hohes Gut. Änderungen, die diesem Gut entgegen stehen, werden wurden bis vor Kurzem nicht ohne Zwang eingeführt.
eingeführt. Neuerdings gibt es für LaTeX selbst eine Art Kompatibilitätsebene, die mit dem Paket [`latexrelease`](http://www.ctan.org/pkg/latexrelease) gesteuert wird.
Diese Probleme bei LaTeX sind eine Ursache dafür, dass Neuerungen bei TeX selbst in letzter Zeit hauptsächlich aus dem ConTeXt-Bereich kommen. ConTeXt selbst ist im Kern eher ein Projekt von wenigen. Zwischen den wenigen, die LuaTeX entwickeln, und den wenigen, die ConTeXt entwickeln, besteht eine gewisse Schnittmenge. Wenn für ConTeXt neue Dinge erforderlich sind, wurden sie daher oft zügig in LuaTeX umgesetzt. Darüber hinaus besteht bei ConTeXt ein gewisses Diktat von oben. Wenn die Entwickler eine Änderung für sinnvoll hielten, wurde sie ggf. auch ohne Rücksicht auf die Anwender umgesetzt.
Aus diesem unterschiedlichen Vorgehen resultiert die Vermutung: Wenn überhaupt besteht allenfalls bei LaTeX3 oder bei ConTeXt eine Chance die Einhaltung eines Schichtenmodells zu überwachen. Gleichzeitig resultiert aus einer derartigen Überwachung eine erheblich Inkompatibilität zu existierenden Formaten. Bei LaTeX2ε und erst recht bei plainTeX sollte man eine Überwachung der Konventionen nicht erwarten und stattdessen die Konventionen freiwillig einhalten.
[1]: http://www.ctan.org/pkg/texbytopic
[2]: http://www.extex.org/