\csname is expandable, which means that it will do its action in an \edef. The action is to build a control sequence token from the tokens it finds up to the matching \endcsname, performing full expansion as it goes.
Once the action of \csname ends, the token gets expanded or not according to the context; it will, in \edef, provided it is expandable. If it is not expandable, \edef will simply store it in the replacement text it is building and go on to the next token.
Thus the problem is: what token results from \csname y\endcsname? Obviously \y, but now its expandability depends on the meaning \y has.
There are two cases:
There are several methods to assign a meaning to a control sequence token: \y can be
- a macro (defined with
\def, \edef, \gdef or \xdef);
- a primitive;
- a
\countdef, \dimendef, \skipdef, \muskipdef, \toksdef, \chardef, or \mathchardef token;
- a font selector (defined with
\font);
- a token defined with
\let.
In case 1 \y is expandable; in case 2 it can be or not, depending on the primitive (for instance \if, \the, \csname are expandable, \relax is not). In cases 3 and 4 \y is not expandable. In case 5, \y inherits the expandability (and definedness) from the token it is \let to.
However, there is a big difference between
\edef\x{... \y ...}
and
\edef\x{... \csname y\endcsname ...}
when \y has no previous meaning. When a token is built with \csname, if it is unknown, TeX will always assign it the same meaning as \relax (such an assignment is local).
Consider your \edef\x{\expandafter\def\csname y\endcsname{1}\y}, which is the same as \edef\x{\def\csname y\endcsname{1}\y} (because \def is not expandable). Assuming \y has no previous definition, the built token is equivalent to \relax. Indeed, if you add \show\x you will be answered
> \x=macro:
->\def \y {1}\y .
Now if you execute \x, \y will be defined as a macro expanding to 1. A further \edef\x{\def\csname y\endcsname{1}\y} followed by \show\x will print
> \x=macro:
->\def 1{1}1.
Note that the built token has been expanded, because now \y is a macro.
Still no error will be raised, because TeX has simply stored the definition. But if we try to execute \x, we get
! Missing control sequence inserted.
<inserted text>
\inaccessible
<to be read again>
1
\x ->\def 1
{1}1
because \def 1 is illegal.
Your “working” example does not raise errors because \y, \z and \w are undefined tokens when \edef\x{...} is performed.
For completeness, what happens when you do \edef\x{... \y ...} and \y is undefined? You of course get an error of Undefined control sequence when the \edef is being carried out.
\csname whatever\endcsnameexpands to\whatever. If the command is not defined,\whateveris exactly the same as\relax, so in your case after getting\yit doesn't expand further. So you are defining\xthree times, first with meaning\def\y{1}\y, second with\edef\y{1}\y, and third with\let\y=1\y. The problem would be if you actually executed those definition by letting\xexpand, in which case\ywould be defined after the first use so the second definition of\xwould be like\edef1{1}1and when executing\xagain it would raise errors. – Manuel May 07 '18 at 22:08\edef\xtoo – percusse May 07 '18 at 22:46\edef\x{\edef\y{1}\y}and the version that uses\csname... – dow May 07 '18 at 23:17\edef1{1}. How does the use of\csnamecause that, when\def\y{1}does not cause a subsequent re-definition to expand to\edef1{1}. – dow May 07 '18 at 23:20