# \csname error in defining in loop

In following snippet I try to use TeX programming to define commands \Ab, \Bb, \Cb and so on. Strangely, I get Missing \endcsname inserted error. What is my mistake? I hadn't read TeXBook, so it is a bit of magic for me.

\input repeat.tex

\repeat\for{charcode}\from{A}\by{1}\to{Z}\do{%
\edef\letter{\char\charcode}
\expandafter\gdef\csname\letter b\endcsname{{\bf \letter}}
}

\bye
-
I think I'd have picked a variable name other than '\charcode' here: makes life a bit confusing. Your problem is that \char<number> does not expand to the letter specified by <number>. Could you give more context so we can target what you actually need: there are various 'loop over all the letters' questions on the site already. –  Joseph Wright Mar 4 '13 at 17:30

\char is a non expandable instruction to typeset a character, it doesn't construct a character token usable in \csname. You want

\input repeat.tex

\repeat\for{xcharcode}\from{A}\by{1}\to{Z}\do{%
\begingroup\lccode\a\xcharcode\relax
\lowercase{\endgroup
\expandafter\xdef\csname a}b\endcsname{{\noexpand\bf \char\the\xcharcode\space}%
}}

\show\Qb

\bye

which makes

> \Qb=macro:
->{\bf \char 81 }.

Note that it is really unfortunate that repeat.tex calls its macro \repeat that name is used already in the existing plain (and latex) macro \loop so loading that file breaks a lot of existing code. You could just use \loop here.

{\count0=A
\loop
\begingroup\lccode\a\count0\relax
\lowercase{\endgroup
\expandafter\xdef\csname a}b\endcsname{{\noexpand\bf \char\the\count0 \space}}
\ifnum\count0<Z
\repeat
}
\show\Qb

\bye
-
Thanks! It works! Will google what this all means. –  KAction Mar 4 '13 at 17:38

There are many issues in your code.

1. \edef\letter{\char\charcode} doesn't expand anything, because \charcode is \count28 and so, together with \char, it's unexpandable; then \csname\letter b\endcsname becomes \csname\char\charcode b\endcsname which is illegal.

2. Even if that could work, you'd need \xdef and not \gdef, or any \Ab command (assuming the \csname problem has been solved) would expand to {\bf\letter}.

Actually, it's much simpler:

\input repeat.tex
\let\eijkhoutrepeat\repeat
\let\repeat\fi % restore the original meaning

\eijkhoutrepeat\for{tmpcount}\from{A}\by{1}\to{Z}\do{%
\begingroup\lccode`A\tmpcount
\lowercase{\endgroup\expandafter\def\csname Ab\endcsname{{\bf A}}}
}
\show\Ab
\show\Zb
\bye

The output is

This is pdfTeX, Version 3.1415926-2.4-1.40.13 (TeX Live 2012)
restricted \write18 enabled.
entering extended mode
(./rep.tex (/usr/local/texlive/2012/texmf-dist/tex/generic/eijkhout/repeat.tex
> \Ab=macro:
->{\bf A}.
l.7 \show\Ab

?
> \Zb=macro:
->{\bf Z}.
l.8 \show\Zb

?
)
No pages of output.
-

As they are only 26 letters, a simpler minded method:

\def\definethem #1{\ifx #1\stop\else
\expandafter\def\csname #1b\endcsname{{\bf #1}}%
\expandafter\definethem\fi}

\definethem ABCDEFGHIJKLMNOPQRSTUVWXYZ\stop

\csname Ab\endcsname % or \Ab, by why should I make things simple?
\csname Bb\endcsname
\csname Cb\endcsname

\bye

-