# Tricky expansion in macro

I wrote the following code

\documentclass{article}
\makeatletter
\newtoks\a@toks
\newtoks\b@toks
\newcounter{a@counter}%
\newcounter{b@counter}%
\setcounter{a@counter}{0}%
\setcounter{b@counter}{0}%
\ifnum\thea@counter>0\a@toks=\expandafter{\the\a@toks {#1}}%
\else\a@toks=\expandafter{\the\a@toks {#1}}%
\fi
\stepcounter{a@counter}%
}
\newcommand{\reset}{%
\setcounter{a@counter}{0}%
\a@toks={}%
}
\newcommand{\bexp}{%
\ifnum\theb@counter>0\b@toks=\expandafter{\the\b@toks, (\the\a@toks)}%
\else\b@toks=\expandafter{\the\b@toks (\the\a@toks) }%
\fi
\stepcounter{b@counter}%
\setcounter{a@counter}{0}%
\a@toks=\noexpand{}%
}
\newcommand{\print}{%
\the\b@toks%
}
\makeatother
\begin{document}
Hello World!\\[3cm]
\bexp
\print
\end{document}


What I'm trying to do is the following: with \aAdd I add some element to a list, specifically in this example after

\aAdd{a}


I expect \a@toks to be equal to ab. Then I flush this into another token, so I expect \b@toks to be equal to ab. The problem is when the command

\a@toks={}


is executed, this resets even \b@toks that continues to follow \a@toks, so that, when I execute

\aAdd{c}


\b@toks has the value c.

I would like, once set \b@toks = \a@toks to set only the value of \b@toks, so that, when I redefine \a@toks, \b@toks continues to have the preceding value (in this case ab).

Can anyone help me?

• the question is very hard to understand, after the first two \aAdd the register \a@toks is {a}{b} not ab do you not want the braces? and after \bexp the register \b@toks is (\the \a@toks )  but (I think?) you want the content of a@toks not a reference? – David Carlisle May 4 '16 at 19:30
• The problem is not what is stored in \a@toks, but what is stored in\b@toks. I want that after I reset \a@toks={} in \b@toks continues to be {a}{b}. Have I explained it better? – MaPo May 4 '16 at 19:33
• beware doing \ifnum\theb@counter>0\b@toks which will try to expand \b@toks to terminate the number before doing the test, it works here as b@toks is not expandable but safer to leave a space after 0 or better use \z@ – David Carlisle May 4 '16 at 19:34
• \b@toks=\expandafter{\the\a@toks} for the first assignment? – user31729 May 4 '16 at 19:35
• but your description said a@toks contains ab which it does not, so the whole question is very confusing. b@toks is never set to {a}{b} in the above code. – David Carlisle May 4 '16 at 19:35

\expandafter doesn't expand everything after it, just the following token. Also, since it seems like b@counter measures the content added to \b@toks, I don't see the need for

\ifnum...
\else\b@toks=\expandafter{\the\b@toks (\the\a@toks) }
\fi


where you want to add (an empty) \b@toks to itself.

The following produces what you're after, I think (I've cleaned it up a bit):

\documentclass{article}

\makeatletter
\newtoks\a@toks
\newtoks\b@toks
\newcounter{b@counter}%
\newcounter{a@counter}[b@counter]%

\ifnum\value{a@counter}>0 \a@toks=\expandafter{\the\a@toks {#1}}%
\else\a@toks=\expandafter{\the\a@toks {#1}}%
\fi
\stepcounter{a@counter}%
}
\newcommand{\reset}{%
\setcounter{a@counter}{0}%
\a@toks={}%
}
\newcommand{\bexp}{%
\ifnum\value{b@counter}>0
\edef\x{\noexpand\b@toks={\the\b@toks, (\the\a@toks)}}%
\else
\edef\x{\noexpand\b@toks={(\the\a@toks)}}%
\fi
\x
\stepcounter{b@counter}%
\a@toks={}%
}
\newcommand{\print}{%
\the\b@toks%
}
\makeatother

\begin{document}

Hello World!

\bigskip

\bexp% \a@toks = {}, \b@toks = {a}{b}
\print% \b@toks

\end{document}


One could use

\b@toks=\expandafter{\expandafter(\the\a@toks)}


to make sure \a@toks is expanded before inserting it into \b@toks. However, I've instead opted to make sure everything expands before adding it to \b@toks by using an \edef\x{...}\x approach.

If leaving behind an unwanted \x is a problem, you can use the following definition for \bexp:

\newcommand{\bexp}{%
\begingroup
\ifnum\value{b@counter}>0
\edef\x{\endgroup\noexpand\b@toks={\the\b@toks, (\the\a@toks)}}%
\else
\edef\x{\endgroup\noexpand\b@toks={(\the\a@toks)}}%
\fi
\x
\stepcounter{b@counter}%
\a@toks={}%
}

• \noexpand{ is harmless, but... – David Carlisle May 4 '16 at 19:40
• @DavidCarlisle... sorry, missed that one. – Werner May 4 '16 at 19:42
• Just use e-TeX! – Joseph Wright May 4 '16 at 19:47
• It is almost I like to do, the last thing is that I was lookin for. I still do not understand why, if between the \aAdd{c} and the \print i write another \bexp I get (ab), () instead of (ab), (c),which I would like to obtain for my purposes... – MaPo May 4 '16 at 19:50
• Thanks for helping me understand a bit more about token registers and such. I've always been clueless on them. – Steven B. Segletes May 4 '16 at 19:51

Werner's analysis is very good. Here's an alternative implementation with xparse and expl3. Note that you can define as optional argument to \print the separator between items (default is “comma-space”).

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

{
}
\NewDocumentCommand{\bexp}{}
{
\mapo_bexp:
}
\NewDocumentCommand{\reset}{}
{
\mapo_reset:
}
\NewDocumentCommand{\print}{O{,~}}
{
\mapo_print:n { #1 }
}

\tl_new:N \l_mapo_a_tl
\seq_new:N \l_mapo_b_seq

{
\tl_put_right:Nn \l_mapo_a_tl { #1 }
}
\cs_new_protected:Nn \mapo_bexp:
{
\seq_put_right:Nx \l_mapo_b_seq { ( \exp_not:V \l_mapo_a_tl ) }
\mapo_reset:
}
\cs_new_protected:Nn \mapo_reset:
{
\tl_clear:N \l_mapo_a_tl
}
\cs_new:Nn \mapo_print:n
{
\seq_use:Nn \l_mapo_b_seq { #1 }
}
\ExplSyntaxOff

\begin{document}

\noindent
Hello World!\\