# \expandafter, \expandbefor : what else?

I have a macro that prints exactly what I want, but I can't use it nested in another one. As far as I understand it is because the fist one is not completely executed and commands from first macro mixt together with those from the second one.

How to proceed ?

\documentclass{article}
\usepackage{tikz,pgfplots}
\usetikzlibrary{calc}
\pgfplotsset{compat=1.9}

\makeatletter
\def\L@ste#1#2{
\count255 = 1
\loop
\def\n{\the\count255}%
#1%
\ifnum\count255>#2
\else
,%
\repeat
}
\def\Liste#1#2{\L@ste{#1}{#2}}
\makeatother

\begin{document}

\verb+\Liste{\n-\n/(6-\n)*x}{5}+

Prints exactly what I need :

\Liste{\n-\n/(6-\n)*x}{5}

\bigskip

But I can't use it directly :

\verb+max(\Liste{\n-\n/(6-\n)*x}{5})+

produces errors ...

\bigskip

\begin{tikzpicture}

\begin{axis}[xmin=0,xmax=5,ymax=7]
{
% can't use it here, Why ?
%max(\Liste{\n-\n/(6-\n)*x}{5})
max(1-1/(6-1)*x,2-2/(6-2)*x,3-3/(6-3)*x,4-4/(6-4)*x,5-5/(6-5)*x)
};
\end{axis}
\end{tikzpicture}
\end{document}

-
This code makes no sense, sorry. For many reasons. One of them is that \else is not legal in \loop, but it's perhaps the least. – egreg Jun 15 '14 at 10:25
@egreg Loop seems to ignore that as it works well, the result is correct. I don't understand then what you mean. By the way, how to test count255<=#2 as <= is forbiden and doesn't work ? – Tarass Jun 15 '14 at 10:31
– David Carlisle Jun 15 '14 at 10:40
@DavidCarlisle I know that paper; but this has the original \loop macro. – egreg Jun 15 '14 at 10:48
@Tarass Your \Liste macro produces the instruction for printing what you'd like to feed to max; but you can't use it in the argument of max, because this wants the functions, not the instructions for printing them. – egreg Jun 15 '14 at 10:51

The loop via \loop is not expandable, because it contains assignments. For the same reason \def\n{\the\count255 } (BTW, note the space) is not expandable as advancing the counter via \advance.

\Liste could be implemented in an expandable way:

• Package intcalc helps in incrementing in an expandable way,
• \n needs to be exchanged by the number in an expandable way.

But it is much easier to construct a macro (also token register) that contains the expanded list. In the following example \Liste generates the list and stores the result in macro \ListeResult. The latter can be used in max:

\documentclass{article}
\usepackage{tikz,pgfplots}
\usetikzlibrary{calc}
\pgfplotsset{compat=1.9}

\makeatletter
\newcommand*{\Liste}[2]{%
\count@ = 1 %
\let\ListeResult\@empty
\loop
\def\n{\the\count@}%
\edef\ListeResult{\ListeResult#1}%
\ifnum#2<\count@
\else
\edef\ListeResult{\ListeResult,}%
\repeat
}
\makeatother

\begin{document}

Prints exactly what I need :

\Liste{\n-\n/(6-\n)*x}{5}
\ListeResult

\bigskip

\begin{tikzpicture}

\begin{axis}[xmin=0,xmax=5,ymax=7]
\Liste{\n-\n/(6-\n)*x}{5}
\end{axis}
\end{tikzpicture}
\end{document}


-
Great ! thank you for explantions and for the solution. – Tarass Jun 15 '14 at 11:09

You can't feed \Liste to max, because it wants a syntactically correct list of functions, not the instructions for printing them.

Here's a working implementation; you must first compute the substitutions and define a macro to contain the list. Then you can use this macro in the argument of \max.

\documentclass{article}
\usepackage{tikz,pgfplots}
\usetikzlibrary{calc}

\makeatletter
\newcommand\Liste[3][]{%
\def\Liste@temp{\@gobble}%
\count@=\z@
\loop\ifnum\count@<#3\relax
\begingroup\edef\n{\the\count@}%
\edef\x{\endgroup\def\noexpand\Liste@temp{\Liste@temp,#2}}\x%
\repeat
\if\relax\detokenize{#1}\relax
\Liste@temp
\else
\let#1=\Liste@temp
\fi
}
\makeatother

\begin{document}

\Liste{\n-\n/(6-\n)*x}{5}

\bigskip

\begin{tikzpicture}

\begin{axis}[xmin=0,xmax=5,ymax=7]
\Liste[\foo]{\n-\n/(6-\n)*x}{5}