Использует ли \let указатели?

Использует ли \let указатели?

Действительно ли \letсоздается новая управляющая последовательность или просто назначается указатель на уже определенную управляющую последовательность?

Кнут говорит, что:

let\cs=<token> дает \csтекущее значение токена. Если <token>это другая последовательность управления, \csприобретет то же значение, что и последовательность управления. (TeXbook 206)

Предположим, я определяю новую среду списка, barsв которой \barесть просто другое имя для \item:

\newenvironment{bars}
{\begin{enumerate}\let\bar\item}
{\end{enumerate}}

а затем использовать эту среду 1000 раз в моем документе следующим образом:

\begin{bars}
\bar bla bla
\bar bla bla bla
\end{bars}

Сколько мест в памяти в итоге будут иметь то же содержимое, что и \itemпри компиляции документа? 1, 2 или 1001?

решение1

Ответ на ваш вопрос — «еще один», т.е. \itemи \bar(итого два).

Способ \let\a<token>работает путем буквального копирования смысла <token>в управляющую последовательность \a, так что всякий раз, когда \aона "выполняется", она действует точно так же, как если бы <token>она была там. Это копирование выполняется во время инструкции \let, так что независимо от того, сколько раз \aона используется, никаких новых изменений не происходит; более того, если <token>измененияегозначение (скажем, через другое \let), значение \aне изменяется.

Использование вами термина «указатель» в некотором смысле неуместно, поскольку TeX как язык не имеет модели памяти, а язык, на котором он реализован, (и это не обязательно) имеет произвольный доступ кегомодель памяти, как и внутренние детали ее реализации, не имеют отношения к пониманию ее работы. Однако, даже если предположить, что TeX был реализован на (скажем) C, аналог указателя на токен будет

\def\a{<token>}

что было бы похоже на *\a = <token>, предполагая, что это допустимый синтаксис C. Воображаемый синтаксис *\a = *<token>соответствует \let\a<token>, в то время как синтаксис *\a = <token>, хотя и похож на первый, на самом деле определял бы \aтаким образом, что выполнение\def\a{<other token>} было быпереопределить <token>, что невозможно в TeX. Так что точного аналога указателям в TeX нет.

решение2

Хотя TeX может хранить несколько версий данного макроса, локально в группе { }, обычно довольно сложно заполнить память, поскольку память освобождается и повторно используется после выхода из группы (это было основой моего первоначального комментария). Большинство сред, таких как itemize, включают такую ​​группировку. Когда существующая команда \def'd или \let'd становится чем-то другим внутри группы, старая версия сохраняется (складывается) и восстанавливается в конце группы.

Ни одна из стандартных конструкций не будет генерировать больших потерь «стекового» трафика, если только вы не используете бесконечную рекурсию вложенных групп или что-то подобное.

Можно сгенерировать большое конечное число вложенных групп с различными определениями заданного макроса, но для этого придется проявить некоторую хитрость:

\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}

введите описание изображения здесь

Связанный контент