# reverse expansion order with optional parameters

Trying to implement a command with more than nine parameters (that also reverses things about) when there are, e.g., 8 of them, the first invocation is temporarily saved with \def\mytemp{\mycommandtwo{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}}, and its expansion must be postponed after the second \mycommandone takes control: the latter has a first optional parameter.

A snippet that I supposed to gradually build arguments is:

\newcommand\mypriorcommand[8]{%
\def\mytemp{\mycommandtwo{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}}%
\expandafter\mytemp\mycommandone%
}

\newcommandx\mycommandone[4][1,2,3]{%
% #4 is mandatory
}

\newcommand\mycommandtwo[9]{%
% #9 is one more parameter besides the eight
}

assuming that \mycommandone becomes saturated with 4 arguments, before the expansion of \mytemp encounters the 9th argument to \mycommandtwo.

Without \expandafter, a correct use of \mycommandone - still without any arguments - would do well: take as much arguments as needed. How the "\expandafter" expansion differs in this case?

This is an MWE.

\documentclass{article}

\usepackage{xargs}

\title{MWE}
\author{tex.stackexchange.com}

\newcommand\test[1]{\typeout{--- test/1 ---}%
\def\temp{\typeout{--- temp/3 ---}\testa{#1}}%
\expandafter\temp\testb%
}

\newcommand\testa[2]{\typeout{--- testa/4 ---}4=#1 5=#2}

\newcommandx\testb[3][1,2]{\typeout{--- testb/2 ---}1=#1 2=#2 3=#3}

\begin{document}

\maketitle

\test{% EDIT: renamed arguments
4th
}[1st][2nd]{%
3rd
}{%
5th
}

\end{document}

EDIT: It typesets 4=4th 5=1=1st 2=2nd 3=3rd 5th and prints:

--- test/1 ---
--- temp/3 ---
--- testa/4 ---
--- testb/2 ---

whereas it should typeset 1=1st 2=2nd 3=3rd 4=4th 5=5th and the order should be test/1, testb/2, temp/3, testa/4.

EDIT: Here is how building gradually arguments without reversing arguments works for me:

\newcommandx\testc[4][1,2]{2=#1 3=#2 4=#3 5=#4}
\renewcommand\test[1]{1=#1 \testc}

EDIT: Also using a variation with \expandafter:

\newcommandx\testc[4][1,2]{2=#1 3=#2 4=#3 5=#4}
\renewcommand\test[1]{1=#1 \def\temp{\relax}\expandafter\temp\testc}

Please a plain TeX solution? Thank s.

• You're asking for a plain TeX or a Plain TeX solution? Sounds difficult with \documentclass;-) – user31729 Mar 14 '16 at 11:48
• in terms of \def, newcommand[x], square brackets, TeX expansion macros. – sjb Mar 14 '16 at 11:52
• why define a command with that many arguments (rather than a single comma separated list for example?) – David Carlisle Mar 14 '16 at 11:56
• let's just say my answer is no to "using single comma separated list to avoid square brackets and the parameter number limit"... – sjb Mar 14 '16 at 12:00
• your question is not very clear, you say you have more than 9 arguments, but your MWE only has 5 (but has optional arguments 2 and 3) so these seem to be quite different cases?? – David Carlisle Mar 14 '16 at 12:00

Replace the \expandafter\temp\testb by \testb in \test macro and add the \temp at the end of \testb macro (after 3=#3).

Especially if you have some optional arguments it is in general much easier to generate commands like this with newcommand. This is a python script which generates the necessary support macros. For example with 10 arguments (3 optional), it generates

% Prototype: MACRO test OPT[#1={}] OPT[#2={}] OPT[#3={}] #4 #5 #6 #7 #8 #9 #10
\makeatletter
\newcommand{\test}[1][]{%
\def\test@arg@i{#1}%
\@ifnextchar[{\test@i}{\test@i[{}]}%
}

\def\test@i[#1]{%
\def\test@arg@ii{#1}%
\@ifnextchar[{\test@ii}{\test@ii[{}]}%
}

\def\test@ii[#1]#2#3#4#5#6#7#8{%
\def\test@arg@iii{#1}%
\def\test@arg@iv{#2}%
\def\test@arg@v{#3}%
\def\test@arg@vi{#4}%
\def\test@arg@vii{#5}%
\def\test@arg@viii{#6}%
\def\test@arg@ix{#7}%
\def\test@arg@x{#8}%