Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

In Appendix D - Dirty Tricks Knuth gives an example of expanding four tokens in the right order by using eleven \expandafter commands. Here, is the code slightly adapted for to-morrow!

\tracingmacros=2  \tracingcommands=2
\def\z{M}
\def\Z{C}
\def\a{\z er}
\def\b{ry }
\def\c{\Z hr}
\def\d{ist}
\def\e{mas}

\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\a
\expandafter\expandafter\expandafter\b\expandafter\c\d \e

\bye

This is in plain TeX, so you need to run it with pdfTeX. Why do we need 11 expandafters? Is there a rule of thumb for this type of definitions? How many do you need to expand five i.e, to expand \e also which I conveniently spaced out!

share|improve this question
9  
\expandafters tend to come in powers of two, minus one: one expandafter is "reach over token once", to reach over the token twice, you need thre:, the first jumps to the third, the third jumps over your token, leaving the second to jump over the second time, and so on. –  Ulrich Schwarz Dec 24 '10 at 14:51
    
could one define a \superexpandafter{n} that would expand to 2^n-1 \expandafter's? –  Yossi Farjoun Dec 24 '10 at 14:54
    
@Yossi. Only to some extent. You can do this if it is the first thing which needs to get expanded, but imagine \expandafter\SomeToken\superexpandafter{n}. You can't get the \superexpandafter to work 'as expected' here, as it would require at least two expansions to continue the chain past \SomeToken. –  Joseph Wright Dec 24 '10 at 15:49
    
@Yiannis: By the way, there's no need for the two %. –  Hendrik Vogt Dec 24 '10 at 16:53
    
@Hendrik You right I edited them out! –  Yiannis Lazarides Dec 24 '10 at 19:40
show 2 more comments

2 Answers 2

up vote 27 down vote accepted

The short answer

Don't think of 11, but of 7+3+1 \expandafters. To also reach the \e, you'll need 15+7+3+1 \expandafters. As Ulrich says in his comment, these number are 2^4-1, 2^3-1 and so on.

What does \expandafter do?

The TeX primitive \expandafter steps over the token following it and once expands the next one. Since your macros \b, \c and \d don't take arguments, the code

\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\a
\expandafter\expandafter\expandafter\b\expandafter\c\d\e

expands to

\expandafter\expandafter
\expandafter\a
\expandafter\b\c "\d, once expanded" \e

and this in turn to

\expandafter\a\b "\c, once expanded" "\d, once expanded" \e

to finally yield

\a "\b, once expanded" "\c, once expanded" "\d, once expanded" \e

With your definition of \a, \b and \c, you don't need all these \expandafters since those macros don't take any arguments. In fact, the above is an oversimplification: In the general case, if the macros do take arguments, the last line above would look somewhat like

\a \once{\b \once{\c \once{\d \e}}}

where \once is not a TeX command but should mean that the argument is expanded once, and the innermost expansion happens first, the outermost last. Here's a really stupid example:

\def\a#1.{#1}
\def\b#1:{#1.}
\def\c#1,{#1:}
\def\d{Hello world!,}
\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\a
\expandafter\expandafter\expandafter\b
\expandafter\c\d
\bye
\def

Firstly, \c replaces the , in Hello world!, with :. Secondly, \b replaces the : with ., and finally \a strips the .. In this example, all the \expandafters are needed.

What do 2^n-1 \expandafters do?

2^1-1=1 \expandafter expands the stuff after the next token once, and by induction you easily see that 2^n-1 \expandafters expand the stuff after the next token n times. Moreover, making this happen takes n expansion steps. Let's look again at your code, now from this point of view:

The first 7 \expandafters expand the stuff after \a 3 times. Two of these 3 expansion steps are needed to expand the 3 \expandafters after \a; let's keep in mind that a last expansion step is missing. Before that last step, the 3 \expandafters after \a expand the stuff after \b 2 times. The first expansion yields \c \once{\d \e} after the \b, the second one yields \once{\c \once{\d \e}}. This completes the description of two of these 3 expansion steps. In the third of these 3, the stuff after \a is expanded one last time.

In TH's comment, the 3 \expandafters expand the \csname bar\endcsname twice, thus yielding the expansion of \bar. Another important case is

\expandafter\def\expandafter\mycommand\expandafter{\somecontrolsequence}

This defines \mycommand as \somecontrolsequence, once expanded.

Another stupid example:

\expandafter\expandafter\expandafter\a
\expandafter\expandafter\expandafter\b\c

expands \c twice, thus expanding to something like

\a\b\twice{\c}
share|improve this answer
    
And sometimes \expandafter\expandafter\expandafter\foo\csname bar\endcsname is useful. That is, expand \bar once before \foo even though \bar is constructed using \csname ... \endcsname. –  TH. Dec 24 '10 at 17:18
add comment

To expand on the same theme as TH.'s comment to Hendrik's answer, when you must use lengthly \expandafter chains, you can exploit constructions like \csname...\endcsname (or, in some contexts, \number) which completely expand things by placing the right number of \expandafters just after/before the token you want to expand, e.g.

\csname macroone\expandafter\expandafter\expandafter\endcsname\macrotwo

will be the same as \macroone followed by \macrotwo expanded two times.

To give a concrete example, suppose you have \a\b\c\d\e and want to expand \e three times, \c two times, and \a, \b, \d one time. With the \csname...\endcsname method, it would be (here, we store the result of expansion inside a \temp macro and then \show it to see clearly what was expanded; you need the three \expandafter in the \def\temp because the first token needs two expansions):

\def\a{a}
\def\b{b}
\def\c{\C}\def\C{c}
\def\d{d}
\def\e{\E}\def\E{\ee}\def\ee{e}

\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\temp
\expandafter\expandafter\expandafter{%
\csname a\expandafter\expandafter\expandafter\endcsname
\csname b\expandafter\expandafter\expandafter\expandafter
         \expandafter\expandafter\expandafter\endcsname
\csname c\expandafter\expandafter\expandafter\endcsname
\csname d\expandafter\expandafter\expandafter\expandafter
         \expandafter\expandafter\expandafter\endcsname
\e
}
\show\temp

\csname @@end\endcsname\bye % to work with both plain and LaTeX

To compare, here's the same version with chains of \expandafters:

\def\a{a}
\def\b{b}
\def\c{\C}\def\C{c}
\def\d{d}
\def\e{\E}\def\E{\ee}\def\ee{e}

\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\temp
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter{%
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\a
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\b
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\c
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\d
\e
}
\show\temp

\csname @@end\endcsname\bye % to work with both plain and LaTeX
share|improve this answer
4  
I am going to read this carefully once the new year's wine has disappeared. In the meantime I take my hat off to you! –  Yiannis Lazarides Dec 31 '10 at 16:41
    
Ingenious idea! I've used it in this answer to define a "superexpandafter". –  Hendrik Vogt Jan 2 '11 at 12:47
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.