%%% Bernd Raichle: check if defined, no side effects

\LaTeX{} and other macro packages include a test if a control sequence is
already defined using \verbatim|\csname...\endcsname|. In principle the following
definition is used:

\beginverbatim
\def\@ifundefined#1#2#3{%
  \expandafter\ifx\csname #1\endcsname\relax#2\else#3\fi}
\endverbatim

The use of \verbatim|\csname...\endcsname| has the side effect that an undefined control
sequence will be defined as \type{\relax} and a simple test using
\verbatim|\ifx<control sequence>\undefined| will fail.

To avoid this side effect, you can change the definition
above introducing a group ``around'' \type{\csname}:

\beginverbatim
\def\@ifundefined#1#2#3{%
  \begingroup \expandafter\expandafter\expandafter \endgroup
  \expandafter\ifx\csname #1\endcsname\relax#2\else#3\fi}
\endverbatim

{\bf Note:} This definition is not fully expandable, thus it will fail in
expansion-only contexts where the original definition will work.

If you are using \eTeX, the new \verbatim|\ifcsname...\endcsname|
primitive can be used instead.

\bigskip\hrule\bigskip

During the presentation of this pearl at the BachoTeX 2006 pearls session,
two alternatives to this trick has been proposed. Worthy to note, that the
macro above use more \type{\expandafter}'s then actually needed. Once we say

\beginverbatim
\def\@ifundefined#1#2#3{%
  \begingroup \expandafter
  \ifx\csname#1\endcsname\relax\endgroup#2\else\endgroup#3\fi}
\endverbatim

we get exactly the same effect in a bit more efficient way. But there is one
more sticky problem in all the constructions above; every control sequence
defined as \type{\relax} (and \type{\relax} itself) is treated as undefined. The solution
seems to be

\beginverbatim
\def\@ifundefined#1#2#3{%
  \begingroup \expandafter \endgroup \expandafter
  \ifx\csname#1\endcsname\undefined#2\else#3\fi}
\endverbatim

Here we expand \verbatim|\csname...\endcsname| before \type{\endgroup}, but the condition is
fixed outside the group. Thus, \type{\undefined} instead of \type{\relax} can be used for
comparison.

