
Wird \let
wirklich eine neue Steuersequenz erstellt oder wird lediglich ein Zeiger auf eine bereits definierte Steuersequenz zugewiesen?
Knuth sagt:
let\cs=<token>
gibt\cs
die aktuelle Bedeutung des Tokens an. Wenn es<token>
sich um eine andere Steuersequenz handelt,\cs
erhält es die gleiche Bedeutung wie diese Steuersequenz. (TeXbook 206)
Angenommen, ich definiere eine neue Listenumgebung bars
, in der \bar
lediglich ein anderer Name für Folgendes ist \item
:
\newenvironment{bars}
{\begin{enumerate}\let\bar\item}
{\end{enumerate}}
und verwende diese Umgebung dann 1000 Mal in meinem Dokument, und zwar wie folgt:
\begin{bars}
\bar bla bla
\bar bla bla bla
\end{bars}
Wie viele Speicherorte haben am Ende den gleichen Inhalt wie \item
zum Zeitpunkt der Kompilierung meines Dokuments? 1, 2 oder 1001?
Antwort1
Die Antwort auf Ihre Frage ist „noch eine“, also \item
und \bar
(also insgesamt zwei).
Die Methode \let\a<token>
funktioniert, indem die Bedeutung von wörtlich <token>
in die Steuersequenz kopiert wird \a
, so dass \a
es bei jeder „Ausführung“ genauso wirkt, als ob es <token>
dort wäre. Dieses Kopieren wird zum Zeitpunkt der \let
Anweisung durchgeführt, so dass unabhängig davon, wie oft \a
es verwendet wird, keine neuen Änderungen vorgenommen werden. Außerdem werden bei <token>
Änderungenes istBedeutung (sagen wir, durch ein anderes \let
), die Bedeutung von \a
bleibt davon unberührt.
Ihre Verwendung des Begriffs „Zeiger“ ist in gewisser Hinsicht unangebracht, da TeX als Sprache weder ein Speichermodell besitzt, noch (notwendigerweise) die Sprache, in der es implementiert ist, wahlfreien Zugriff aufes istSpeichermodell, noch sind die internen Details seiner Implementierung relevant für das Verständnis seiner Funktionsweise. Selbst wenn man jedoch annimmt, dass TeX in (sagen wir) C implementiert wäre, wäre das Analogon eines Zeigers auf ein Token
\def\a{<token>}
was wie wäre *\a = <token>
, vorausgesetzt, dass es sich um eine gültige C-Syntax handelt. Die imaginäre Syntax *\a = *<token>
entspricht \let\a<token>
, während die Syntax *\a = <token>
, obwohl ähnlich der ersten, tatsächlich \a
so definieren würde, dass dies der Fall \def\a{<other token>}
wäreneu definieren <token>
, was in TeX nicht möglich ist. Es gibt also kein genaues Äquivalent zu Zeigern in TeX.
Antwort2
Obwohl TeX mehrere Versionen eines bestimmten Makros lokal in einer { }-Gruppe speichern kann, ist es im Allgemeinen ziemlich schwierig, den Speicher zu füllen, da der Speicher nach Verlassen der Gruppe zurückgefordert und wiederverwendet wird (das war die Grundlage meines ursprünglichen Kommentars). Die meisten Umgebungen wie itemize beinhalten eine solche Gruppierung. Wenn ein vorhandener Befehl per \def'd oder \let'd zu etwas anderem innerhalb einer Gruppe gemacht wird, wird die alte Version gespeichert (gestapelt) und am Ende der Gruppe wiederhergestellt.
Keine der Standardkonstruktionen erzeugt viel „Stapel“-Verschwendung, es sei denn, Sie verwalten eine unendliche Rekursion verschachtelter Gruppen oder ähnliches.
Das Generieren einer großen endlichen Anzahl verschachtelter Gruppen mit unterschiedlichen Definitionen eines bestimmten Makros ist möglich, aber Sie müssen dabei ein wenig trickreich vorgehen:
\documentclass[a5paper,12pt]{article}
\usepackage[margin=20mm]{geometry}
%% version of plain TeX \loop that uses global macros
\def\gloop#1\repeat{\gdef\body{#1}\giterate}
\def\giterate{\body \global\let\next\giterate \else\global\let\next\relax\fi \next}
\let\repeat=\fi % this makes \loop...\if...\repeat skippable
\begin{document}
\raggedright
\section*{Ascending}
\newcount\n
\global\n=0
\gloop
\ifnum \n<100
\bgroup
\edef\foo{\the\n}
\let\baz=\foo
\global\let\foobar=\baz
$\foo^{\baz}_{\foobar} \uparrow$
\global\advance\n 1
\repeat
\section*{Descending}
\global\n=0
\gloop
\ifnum \n<100
$\foo^{\baz}_{\foobar} \downarrow$
\egroup
\global\advance\n 1
\repeat
\end{document}