How to use \outer
? Keep at arm's length from it: it bites.
Suppose you want to exploit \proclaim
but you also want to automatically number your statements. You do
\newcount\statementcounter
\def\statement#1{%
\global\advance\statementcounter by 1
\proclaim#1 \number\statementcounter. \ignorespaces
}
\statement{Definition} This is the definition of foo.
\statement{Theorem} This is the statement of a theorem about foo.
Now text follows.
\bye
It ought to work, you say. Well, no: you get a very bizarre error message
Runaway definition?
#1->\global \advance \statementcounter by 1
! Forbidden control sequence found while scanning definition of \statement.
<inserted text>
}
<to be read again>
\proclaim
l.5 \proclaim
#1 \number\statementcounter. \ignorespaces
?
OK, how to do it? Simple:
\newcount\statementcounter
\def\statement#1{%
\global\advance\statementcounter by 1
\csname proclaim\endcsname#1 \number\statementcounter. \ignorespaces
}
\statement{Definition} This is the definition of foo.
\statement{Theorem} This is the statement of a theorem about foo.
Now text follows.
\bye
Apparently, Knuth doesn't use automatic numbering and is pleased to do it by hand (or he's able to type in papers directly without ever changing his mind about the order of statements).
Well, this was not what I was actually trying to do: I wanted to do automatic numbering using the AMS-TeX version of \proclaim
that suffers from the same problem (I was typesetting the book written by my “Maestro”, whom I owe so much).
In plain.tex
you also find
\def\tabalign{\us@true\m@ketabbox} % non-\outer version of \+
\outer\def\+{\tabalign}
which seems to mean that Knuth himself got bitten by \outer
.
What does “high speed” mean? Basically, it means “macro expansion is suppressed”, see When does tex do macro expansion?
Indeed, you can try
\newcount\statementcounter
\edef\statement#1{%
\global\advance\statementcounter by 1
\noexpand\proclaim#1 \noexpand\number\statementcounter. \ignorespaces
}
\statement{Definition} This is the definition of foo.
\statement{Theorem} This is the statement of a theorem about foo.
Now text follows.
\bye
and you'll see no error about \outer
, because \proclaim
is seen when TeX is doing macro expansion.
If you want to “de\outer
ize” \proclaim
, you can do
\newcount\statementcounter
\let\OUTERPROCLAIM\proclaim
\edef\proclaim{\noexpand\OUTERPROCLAIM}
\def\statement#1{%
\global\advance\statementcounter by 1
\proclaim#1 \number\statementcounter. \ignorespaces
}
\statement{Definition} This is the definition of foo.
\statement{Theorem} This is the statement of a theorem about foo.
Now text follows.
\bye
There are other methods; this doesn't rely on knowing the actual definition of the \outer
macro.