Expansion is simply half of how TeX works, so this is not going to be an easy answer.
First of all, TeX operates on tokens (see What is a token?). A token can be either expandable or unexpandable; if it's unexpandable, it obviously never expands, otherwise it can expand. What an expandable token expands to depends on how it has been made part of the language.
Some primitive (that is, whose meaning is predeclared when TeX starts from scratch) tokens are expandable, some aren't. Among the expandable primitives one finds \expandafter
, \if
and all other conditionals; this was predictable, as these primitive are used to control the expansion process itself; the expansion of an expandable primitive can be void, but it can trigger some other action. All macros defined with \def
(along with its variants \gdef
, \edef
or \xdef
) are expandable and their expansion is precisely the replacement text.
So, assume we have
\def\test{some text}
or, in LaTeX, \newcommand\test{some text}
which is pretty similar. Under normal operations, if TeX finds
Here is \test
it will absorb Here<space>is<space>
(eight unexpandable tokens) and stop at \test
, examine it and decide that it is expandable (TeX uses the current meaning of \test
), so it replaces it by some text
and goes on starting from “s”. Since this token is unexpandable, it's handed over to another phase of processing and TeX goes on with “o” and so on.
Now, suppose that we have
\def\test{\foo{o}me text}
\def\foo#1{s#1}
an input such as
Here is \test
would make TeX hand over tokens up to finding \test
, which it would replace with
\foo{o}me text
and \foo
would now be expanded to so
, after having absorbed its argument.
I said “normal operations”, because in some cases expansion is inhibited:
when TeX is looking for macro arguments;
when TeX is doing a definition with \def
or \gdef
, with regard to the macro to be defined, the parameter text and the replacement text;
when TeX is doing a definition with \edef
or \xdef
, but this only concerns the macro to be defined and the parameter text, not the replacement text;
when TeX is examining the token to be defined after \let
, \chardef
, \mathchardef
and all other \...def
commands;
when TeX is examining the “right hand side” of a \let
;
when TeX is absorbing the tokens for \write
, \uppercase
, \lowercase
, \detokenize
, \unexpanded
or an assignment to a token register.
Sometimes we talk about "full expansion". What's that? When we do
\edef\baz{<tokens>}
the <tokens>
are subject to expansion, the resulting token list is subject to expansion and so on, until only unexpandable tokens remain, always starting from the next token as explained before. After this, the definition is performed, using the token list thus obtained as replacement text. Thus, with the definition above,
\edef\baz{\test}
would expand \test
to \foo{o}me text
and this to some text
, resulting in the same as if we said \def\baz{some text}
. Why should we want to do in this way? Because TeX uses the current meaning of the tokens; if we said
\def\baz{\test}
and later change the definition of \foo
(or of \test
, of course), the macro \baz
would expand to something else; with \edef
we're sure it expands to some text
.
However, \edef
doesn't perform assignments. So if we do
\count255=1
\edef\baz{\advance\count255 by 1 \number\count255 }
using \baz
would print 1, not 2. This is because \advance
and \count
are not expandable; character tokens aren't expandable either; \number
is expandable and its expansion is the decimal representation of the <number>
following it. So this \edef
is just equivalent to
\def\baz{\advance\count255 by 1 1}
The same happens when, ultimately, TeX expands the token list in a \write
: the expansion is performed "all the way", just like in \edef
. Expansion of tokens can be inhibited by preceding the one we don't want to expand with \noexpand
or enclosing them as the argument to \unexpanded
. Note that this is just a “one shot” activity: if one does
\def\a{A}\def\b{B}\def\c{C}
\edef\foo{\a\b\noexpand\c}
the replacement text for \foo
will be AB\c
; upon usage of \foo
, \c
will be expanded according to its current meaning.
Also tokens appearing after \csname
and before the matching \endcsname
are subject to full expansion; in this case only character tokens must remain, so a \relax
is illegal here, while it wouldn't be in \edef
or \write
.
Complicated? Yes.