It's not misleading because it follows the precisely laid out rules.
When \csname
is expanded, TeX looks for the matching \endcsname
with expansion; then TeX forms a control sequence token from the character tokens (irrespective of category code) it has found or issues an error if some non character token is discovered.
After the formation of the token, TeX looks up in its memory to find if that token has a meaning. If it hasn't, that token is made equivalent to \relax
with a local assignment.
\edef
expands the tokens it finds between the braces that delimit the replacement text before storing the resulting <balanced text>
as the replacement text.
Thus your \edef\x{\csname totallyundefined\endcsname}
is equivalent to
\let\totallyundefined\relax
\def\x{\totallyundefined}
On the contrary, the \ifdefined
and \ifcsname
tests (by precise choice of e-TeX's developers) never perform the assignment to \relax
of an undefined token.
The \relax
assignment is performed in many other cases as a precaution against premature expansions. Two cases mentioned in the TeXbook are
\chardef\cs=10\cs
\font\cs=name\cs
where \cs
is temporarily made equivalent to \relax
in order to stop expansion when the assignment is performed. In such cases it's really temporary, as \cs
will immediately be assigned a new meaning; in the case of \csname
it isn't. Where's the problem? If \cs
had a previous definition, without the temporary assignment to \relax
, TeX would expand \cs
searching for a number in the first case or the end of the file name in the second. Even worse, if \cs
was undefined, an error would be raised, because TeX hasn't yet assigned to \cs
the new meaning. Of course, using such a syntax is discouraged.
It may be unfortunate that e-TeX uses \ifcsname...\endcsname
with the same rules of \csname...\endcsname
for the formation of the token to be examined, but with the fundamental difference that the equivalence to \relax
is not performed, but that's what it is.
In the case you're presenting, that is
\edef\x{\unexpanded\expandafter{\csname test@\romannumeral\currentgrouplevel\endcsname}}
you might do it indirectly:
\edef\x{\noexpand\csname @test\romannumeral\currentgrouplevel\endcsname}
so that the \csname
won't be executed. Of course \x
would need two expansions steps:
\expandafter\expandafter\expandafter\cs\x
\edef\x{\ifnum0=0\else\fi}
separately, and perhaps give this one a clearer name?\relax
because it finds\else
in number reading mode which needs to be terminated then.\edef\x{\ifnum0=0\else\fi}
being\relax
and\def\y{\relax}
, we see that\ifx\x\y
is false? Are there two types of\relax
?