# \csname not working as expected

The following code prints ==atname==

\def\atname{atname}
\def\xxx{name}
\def\at{at}
==\csname\at\xxx\endcsname==
\bye


but this does not:

\def\@name{atname}
\def\xxx{name}
\def\at{@}
==\csname\at\xxx\endcsname==
\bye


Why, and how can I make this work?

-

\def\@name{atname} has not defined \@name, but \@ with parameter text name. Also in plain TeX, the default catcode for @ is 12.

\catcode\@=11
\def\@name{atname}
\def\xxx{name}
\def\at{@}
==\csname\at\xxx\endcsname==
\bye

-
Ah, that was stupid - I use plain Tex only in Latex class and style files, where I had a problem and tried to simplify my question; hadn't realized that latex changes @'s catcode. Thanks! –  Wybo Dekker Feb 17 at 8:13

A control sequence definition is composed of three parts:

1. the control sequence name;
2. the parameter text;
3. the replacement text.

The parameter text is whatever is placed between the control sequence name and the open brace {1 that delimits the replacement text. It can contain parameter tokens #1#9, but also other tokens.

A control sequence can be formed by a sequence of one or more letters (a letter, in this context, is a character with category code 11) or by a single non letter (any category code).

However, control sequence names can be formed with the expansion of \csname: all character tokens resulting from the full expansion of the tokens up to the matching \endcsname will be used, independently of their category code.

Under the normal setting, @ has category code 12, so doing

\def\@name{atname}


defines \@, because a single non letter ends the scanning for the control sequence name. The parameter text is the token list name, which is required to follow \@ at usage time.

So you go through by doing

\catcode@=11 % make @ a letter
\def\@name{atname}
\catcode@=12 % go back to the default
\def\xxx{name}
\def\at{@}
==\csname\at\xxx\endcsname==
\bye


or

\expandafter\def\csname @name\endcsname{atname}
\def\xxx{name}
\def\at{@}
==\csname\at\xxx\endcsname==
\bye


because \expandafter forms the control sequence name from the expansion of \csname before \def` does its job.

-