Let's look at three examples from latex.ltx
(the LaTeX kernel).
\@namedef
\def\@namedef#1{\expandafter\def\csname #1\endcsname}
This is entirely analogous to the \expandafter\newcommand
that's the main object of the question. With \@namedef{foo}
we get
\expandafter\def\csname foo\endcsname
and the control sequence \foo
is built before \def
comes into action: the expansion of \csname
is the symbolic token whose name is what comes after it up to the matching \endcsname
(with complete expansion, but analyzing this would take too far).
\loop
\def\loop#1\repeat{\def\iterate{#1\relax\expandafter\iterate\fi}%
\iterate \let\iterate\relax}
We use this in the form
\loop
<code A>
\ifz<condition>
<code B>
\repeat
where \ifz
is one of the TeX conditionals and <condition>
is the test that, if true, will make the loop continue. This becomes
\def\iterate{<code A>\ifz<condition><code B>\relax\expandafter\iterate\fi}
\iterate \let\iterate\relax
The first line is an assignment: it's executed and removed from the input token list, leaving
\iterate \let\iterate\relax
Now \iterate
is expanded, so we get
<code A>\ifz<condition><code B>\relax\expandafter\iterate\fi
\let\iterate\relax
TeX expands/executes <code A>
and then evaluates the conditional. If it's false, everything up to \fi
is skipped, so what remains is
\fi\let\iterate\relax
The expansion of \fi
is empty; the next assignment is executed, ending the loop. If it's true, then we obtain
<code B>\relax\expandafter\iterate\fi
\let\iterate\relax
Now <code B>
is expanded/executed; \relax
does nothing and we have the magic
\expandafter\iterate\fi
\let\iterate\relax
Here \expandafter
expands \fi
, which has empty expansion: so TeX finds
\iterate \let\iterate\relax
and restarts. If the \expandafter
were omitted, the \fi
tokens would accumulate, possibly filling the memory on long loops.
\@onlypreamble
Several commands in the kernel are defined following the scheme
\def\@foo{...}
\@onlypreamble\@foo
which means that \@foo
cannot be used past \begin{document}
, where it would trigger the "Can be used only in the preamble" error. Let's see what \@onlypreamble
does:
\def\@preamblecmds{}
\def\@onlypreamble#1{%
\expandafter\gdef\expandafter\@preamblecmds\expandafter{%
\@preamblecmds\do#1}}
First \@preamblecmds
is initialized to empty. If we say
\@onlypreamble\@foo
we get
\expandafter\gdef\expandafter\@preamblecmds\expandafter{\@preamblecmds\do\@foo}}
The first \expandafter
expands the second, which expands the third; the last one, in turn, expands \@preamblecmds
. If this was the first call of the macro \@onlypreamble
, we'd get
\gdef\@preamblecmds{\do\@foo}
To make the problem more interesting, let's call now
\@onlypreamble\@bar
Again we get
\expandafter\gdef\expandafter\@preamblecmds\expandafter{\@preamblecmds\do\@bar}}
but now the expansion of \@preamblecmds
is \do\@foo
: so finally we get
\gdef\@preamblecmds{\do\@foo\do\@bar}
and so on for every call of \@preamblecmds
. When LaTeX works on \begin{document}
it says
\gdef\do#1{\global\let #1\@notprerr}\@preamblecmds
The \do
command is defined to make its argument equivalent to \@notprerr
(that triggers the above mentioned error); then \@preamblecmds
is expanded, so that
\do\@foo\do\@bar
(and many other tokens of the same type) will be executed.
In \@onlypreamble
the \expandafter
is needed to get the expansion of \@preamblecmds
in the replacement text before redefining \@preamblecmds
: doing
\gdef\@preamblecmds{\@preamblecmds\do\@foo}
would lead to a disaster, because the final replacement text of \@preamblecmds
would be
\@preamblecmds\do\@foo\do\@bar
(with many other \do...
combinations). And when the expansion of \@preamblecmds
is performed, TeX would find \@preamblecmds
and expand it, finding \@preamblecmds
which it would expand, finding… Infinite loop. Oops!
\@ifundefined
The LaTeX kernel provides \@ifundefined
that checks whether the control sequence having as name its argument is defined or not (actually, undefined means either really undefined or equivalent to \relax
).
\def\@ifundefined#1{%
\expandafter\ifx\csname#1\endcsname\relax
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi}
The \expandafter\@firstoftwo
and \expandafter\@secondoftwo
are explained elsewhere on the site; here the \expandafter
application is similar to the first one: the usage is \@ifundefined{foo}{true}{false}
and the control sequence token \foo
is built before \ifx
comes into action.
What I want to underline here is that generally using \expandafter\ifx
is wrong: for instance, after
\def\foo{foo}
the test
\expandafter\ifx\foo\foo
would return false. So don't use \expandafter
unless you know it's necessary.
\def
,\let
,\newcommand
, but some other primitives also require this, for instance\ifx
or\show
.\csname
is one token and would mercilessly be accepted by all the examples I gave as the token to be dealt with, which is almost never what is intended. So if the token to be given is a control sequence to be constructed with\csname
, that construct has to be expanded with\expandafter
before the primitive is seen. – Stephan Lehmke Jul 20 '12 at 6:11\expandafter
in my DocScape sources is 1227, at 36621 lines of code. I guess about 10% of those are not really needed, so you could say 1100\expandafter
s were needed to make DocScape (whatever that means ;-) – Stephan Lehmke Jul 20 '12 at 6:20\expandafter
to prepare arguments to other macros was the first thing I learned about basic TeX and also the reason I got the TeXbook to learn more. – Ryan Reich Jul 20 '12 at 10:22\expandafter
s?:-)
– Martin Schröder Jul 24 '12 at 18:38