0

any suggestion on how to debug or fix this problem would be appreciated.

\documentclass{minimal}
\usepackage{expl3}
\ExplSyntaxOn

\cs_new:Npn \__foo_aux:n #1{\c_novalue_tl}
\cs_set:Npn \__foo:n #1
{
    \cs_set:Npn \__foo_aux:n ##1{#1}
     __foo_aux:n
}

\begin{document}

% For comparison's sake:
\tl_new:N \__bar_tl
\tl_set:Nn \__bar_tl {__foo_aux:n}
\use:c{\__bar_tl}{X} % -No Value-

% The code that generates an error:
\\
\__foo_aux:n{X} % -No Value- %
\\ \__foo:n{(#1)} % __foo_aux:n % 
\\ \__foo_aux:n{X} % (X)
\\ \use:c{\__foo:n{(#1)}}{X} % Expected: (X)
% Console output
%! Missing \endcsname inserted.
%<to be read again> 
%                   \tex_long:D 
%l.22 \\ \use:c{\__foo:n{(#1)}}
%  {X} %! Missing \endcsname inserted.
\ExplSyntaxOff
\end{document}
  • 1
    You can't do assignments inside the argument of \use:c. – egreg May 10 '18 at 21:40
  • Apparently so. Dead end then? – Erwann May 10 '18 at 21:41
  • It's not really clear what your aim is. – egreg May 10 '18 at 21:42
  • Have a macro taking one argument, modify the code \__foo_aux, return its cs name, and invoke it using \use:c. I would have thought preceding \use:c by \exp_args:No, Nf or Nx would have eliminated the error, but not. Why not? – Erwann May 10 '18 at 21:45
  • The argument of \use:c must consist of fully expandable tokens and the final expansion must consist of characters only. If something is not expandable, like \cs_set:Npn it cannot appear there, notwithstanding any usage of \exp_args:N<whatever> (which would do nothing to unexpandable tokens). – egreg May 10 '18 at 21:49
2

The \use:c function is just a wrapper around the \csname primitive of TeX. The description in the TeXbook is quite clear (page 40):

Conversely, you can go from a list of character tokens to a control sequence by saying ‘\csname⟨tokens⟩\endcsname’. The tokens that appear in this construction between \csname and \endcsname may include other control sequences, as long as those control sequences ultimately expand into characters instead of TeX primitives; the final characters can be of any category, not necessarily letters. For example, ‘\csname TeX\endcsname’ is essentially the same as ‘\TeX’; but ‘\csname\TeX\endcsname’ is illegal, because \TeX expands into tokens containing the \kern primitive. Furthermore, ‘\csname\string\TeX\endcsname’ will produce the unusual control sequence ‘\\TeX’, i.e., the token |\TeX|, which you can't ordinarily write.

Not only the mentioned \kern is illegal, but any unexpandable primitive such as \hbox or \def. Since every assignment is made with unexpandable primitives, no assignment can take place in \csname...\endcsname as well as in the argument to \use:c.

There may be workarounds, but I can't figure out a situation where you would use that idea.

0
\cs_new:Npn \__erwann_action:n #1 { \c_novalue_tl }
\cs_new_protected:Npn \erwann_set:n #1 { \cs_set:Npn \__erwann_action:n ##1 { #1 } }
\cs_new:Npn \erwann_do:n #1 { \__erwann_action:n { #1 } }
\cs_new_protected:Npn \erwann_do:nn #1 #2 { \erwann_set:n { #1 } \erwann_do:n { #2 } }

and then use

\__erwann_action:n {X} % -No Value-
\erwann_do:n {X} % -No Value-
\erwann_set:n {(#1)} % just setup
\erwann_do:n {X} % (X)
\erwann_do:nn {(#1)} {X} % Expected: (X) OK

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.