I have a situation where I want to define a command that takes a variable number of arguments, where the number of arguments is known programmatically via a \count, and process the parameters in some way (say as if they are a list).
As an example, say I'd like to output the parameters as a comma-separated list.
\newcommand{\makecsv}[N]{#1, #2, ..., #N}
The code that I've come up with to do this kind of operation (in a generic-ish way) essentially takes a command, \csv and expands it recursively N times. \csv needs to know how to continue the recursion, and has some state that I'd like to thread through the recursion (rather than using \global).
\documentclass{report}
\usepackage{etoolbox}
\makeatletter
\newcommand{\ifzero}[3]{%
% #1: count
% #2: state for #3
% #3: macro to expand to
% - should take at least 2 parameters
% - ##1: count threaded through
% - ##2: macro state threaded through
\ifnum\c > 0
\def\tmp@f##1##2##3{##1{##2}{##3}}%
\advance#1 -1%
\else
\def\tmp@f##1##2##3{)}% note closeparen here (could be param)
\fi
\tmp@f{#3}{#1}{#2}%
}
\makeatother
\newcommand{\csv}[3]{
% #1: count
% #2: separator state
% #3: string to concat
%
#2#3\ifzero{#1}{, }{\csv}%
}
\newcommand{\makecsv}[1]{%
\ifzero{#1}{}{\csv}%
}
\makeatletter
\newcommand{\decl}[3]{%
% #1: decl id
% #2: decl symbol
% #3: # params
\csgdef{decl@#1}{#2}%
\global\expandafter\newcount\csname decl@#1@nparams\endcsname%
\csuse{decl@#1@nparams} #3\relax%
}
\newcommand{\usedecl}[1]{%
\newcount\c
\c \the\csuse{decl@#1@nparams}
\csuse{decl@#1}(\makecsv{\c}%
}
\makeatother
% declare some interface routines
\decl{foo}{FOO}{3}
\decl{bar}{BAR}{4}
\begin{document}
\usedecl{foo}{p1}{p2}{p3}\par
\usedecl{bar}{p1}{p2}{p3}{p4}\par
\end{document}
Is this a reasonable thing to do in 2e, or is there some sort of standard approach to this that is normally used?
Edit 1
It seems like my original MWE wasn't adequate to describe why someone might want this. I've updated the MWE with a use case. \decl allows authors to declaratively define a C-style function, and \usedecl allows the author to generate a use of the function, with its parameters bound to specific arguments.
This is similar enough to what I'm doing that it should help motivate the example.




etoolboxorl3clist. – Marco Daniel Jun 07 '13 at 16:42{foo}{bar}{foobar}to{foo|bar|foobar}. I do see how I could solve this problem somewhat generically with a list though, with a generic\makelistfromargs{\listname}{\counter}that reads a bunch of arguments into an internal list. Is this the more common solution that you see people doing? – Luke Jun 07 '13 at 16:54\makecsv{\c}{abc}{def}{ghi}? – egreg Jun 07 '13 at 18:06void makecsv(int N, ...)orint main(int argc, char** argv). It may be that you've answered my question by establishing that this isn't normally done and any custom solution that works is good enough (as opposed to there being an established technique). – Luke Jun 07 '13 at 18:37\declrecords a declaration for an interface function (presumably the .tex author is documenting an API), and\usedeclrefers back to the declaration by id. There are two example declarations in the text. Note that these are restricted forms of what our documentation effort actually provides. Real text use looks likegiven P and Q such that [...] \usedecl{foo}{P}{Q} results in [...]. Thanks for\@ifnextchar\bgroup, that may be a more reasonable approach. – Luke Jun 07 '13 at 19:29\@ifnextcharis much simpler. – Qrrbrbirlbel Jun 07 '13 at 20:14