
¿ \let
Realmente crea una nueva secuencia de control o simplemente asigna un puntero a una secuencia de control ya definida?
Knuth dice que:
let\cs=<token>
da\cs
el significado actual del token. Si<token>
se trata de otra secuencia de control,\cs
adquirirá el mismo significado que esa secuencia de control. (TeXbook 206)
Supongamos que defino un nuevo entorno de lista bars
en el que \bar
hay solo otro nombre para \item
:
\newenvironment{bars}
{\begin{enumerate}\let\bar\item}
{\end{enumerate}}
y luego usar ese entorno 1000 veces en mi documento de la siguiente manera:
\begin{bars}
\bar bla bla
\bar bla bla bla
\end{bars}
¿Cuántas ubicaciones en la memoria terminan teniendo el mismo contenido que \item
cuando compilo mi documento? 1, 2 o 1001?
Respuesta1
La respuesta a su pregunta es "uno más", es decir \item
y \bar
(entonces, dos en total).
La forma en que \let\a<token>
funciona es copiando literalmente el significado de <token>
en la secuencia de control \a
, de modo que cada vez que \a
se "ejecute" actúe exactamente como si <token>
estuviera allí. Esta copia se realiza en el momento de la \let
instrucción, de manera que por más veces que \a
se use no se realizan nuevos cambios; además, si <token>
hay cambiosessignificado (digamos, a través de otro \let
), el significado de \a
no se ve afectado.
Su uso del término "puntero" es inapropiado en cierto sentido, ya que TeX como lenguaje no tiene un modelo de memoria, ni (necesariamente) el lenguaje en el que se implementa tiene acceso aleatorio aesmodelo de memoria, ni los detalles internos de su implementación son relevantes para comprender su funcionamiento. Sin embargo, incluso suponiendo que TeX se implementara en (digamos) C, el análogo de un puntero a un token sería
\def\a{<token>}
que sería como *\a = <token>
, suponiendo que fuera una sintaxis C válida. La sintaxis imaginaria *\a = *<token>
corresponde a \let\a<token>
, mientras que la sintaxis *\a = <token>
, aunque similar a la primera, en realidad definiría \a
de tal manera que haciendo \def\a{<other token>}
seríaredefinir <token>
, lo cual no es posible en TeX. Así que en realidad no existe un análogo exacto de los punteros en TeX.
Respuesta2
Aunque TeX puede almacenar múltiples versiones de una macro determinada, local para un grupo {}, generalmente es bastante difícil llenar la memoria, ya que la memoria se recupera y reutiliza una vez que se abandona el grupo (esta fue la base de mi comentario original ). La mayoría de los entornos, como itemize, incluyen este tipo de agrupaciones. Cuando un comando existente se \def'd o \let'd para ser otra cosa dentro de un grupo, la versión anterior se guarda (apila) y se restaura al final del grupo.
Ninguna de las construcciones estándar generará mucho desperdicio de "pila", a menos que administre una recursión infinita de grupos anidados o similares.
Se puede generar un gran número finito de grupos anidados con diferentes definiciones de una macro determinada, pero hay que ser un poco tortuoso:
\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}