13

Possible Duplicate:
What does \begingroup\expandafter…\endgroup do?

In many of Heiko Oberdiek's packages one sees this type of construction:

\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname pdf@filesize\endcsname\relax
  \ifxetex
    ...

What is the purpose of enclosing the \expandafter commands within a begingroup...\endgroup? What are the advantages of such an approach?

  • Oh sorry @egreg's answer (and the following discussion in comments) is more complete as well. – David Carlisle Mar 13 '12 at 9:36
17

oh sneaky Heiko:-)

It tests whether the csname was undefined (or relax) but in the case that it was previously undefined, it leaves it undefined as the implicit definition to \relax happens inside the group.

plain TeX:

\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname aaaa\endcsname\relax
\show\aaaa
\fi

\expandafter\ifx\csname bbbb\endcsname\relax
\show\bbbb
\fi


\bye

produces:

(./heiko.tex
> \aaaa=undefined.
l.3 \show\aaaa

? 

> \bbbb=\relax.
l.7 \show\bbbb

? 
 )
2

Actually, it has to do with avoiding undue filling of the hash table.

The snag with

\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname pdf@filesize\endcsname\relax
  ...
\else
  ...
\fi

is that it isn't expandable. With eTeX, you can use \ifcsname instead. If it is a control sequence, and not name, you are testing, you can use \ifdefined instead. But Heiko creates platform-independent packages.

You can think also of etoolbox packages's definition of \csletcs:

\newrobustcmd*{\csletcs}[2]{% [2011/01/03]
  \ifcsdef{#2}{\expandafter\let
    \csname#1\expandafter\endcsname
    \csname#2\endcsname}{\csundef{#1}}%
}

The catoptions package defines this as (using a pseudoname here):

\def\letnames#1#2{%
  \begingroup\expandafter\endgroup
  \expandafter\let\csname#1\expandafter
  \endcsname\csname#2\endcsname
}

since \let is not expandable anyway. This leaves #1 and #2 undefined if #2 was originally undefined.

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