Efficiently Passing Multiple Arguments into a \newcommand

Suppose I define a \newcommand with multiple arguments, such as in this example:

\documentclass{article}
\newcommand{\testing}[9]{#1,\ #2,\ #3,\ #4,\ #5,\ #6,\ #7,\ #8,\ #9}

\begin{document}
\title{Test}
\maketitle
$$\testing{S_1}{S_2}{S_3}{S_4}{S_5}{S_6}{S_7}{S_8}{S_9}$$
\end{document}


If I call the command \testings, I have to put each separate argument inside its own curly braces (to the best of my knowledge). Is there a more efficient way to pass these arguments into the command \testings? For example, something more along the lines of \testings{S_1,S_2,S_3,S_4,S_5,S_6,S_7,S_8,S_9}?

Note: The example above is very simple. A more realistic example might be something like \newcommand{\limset}[3]{\lim_{#1 \rightarrow #2^{#3}}.

• the two examples you give are very different, The first could easily be made to take a comma list as input so allow arbitrary number of terms, the second is really three structurally unrelated arguments so a three argument \newcommand is the most natural interface – David Carlisle Apr 3 '18 at 22:35
• In addition to what @DavidCarlisle said, you might want to have a look at the xparse package if you haven't already done so. – user121799 Apr 3 '18 at 22:37
• I could change the first example to something more complex--I was just trying to think of something that would use a lot of arguments. So if the 2nd example is more typical, the multiple brackets is the only way to go? And @marmot I will check out the xparse package. Thanks for the direction! – Inquisitive Apr 3 '18 at 22:39
• brace delimited arguments are the fundamental tex syntax, you can't really use tex and hide that. You need some separator, and \foo(a,b,c) is only two characters less than \foo{a}{b}{c} and if a,b,c are really single characters \foo abc is even shorter, so it is hard to see how significant gains could be made by changing the syntax. – David Carlisle Apr 3 '18 at 22:51

The more realistic example can be easily dealt with by using xparse facilities:

\NewDocumentCommand{\limset}{>{\SplitArgument{2}{,}}m}{%
\finallimset#1%
}
\NewDocumentCommand{\finallimset}{mmm}{%
\lim_{#1\rightarrow #2\IfValueT{#3}{^{#3}}}%
}


Complete example:

\documentclass{article}
\usepackage{xparse}

\NewDocumentCommand{\limset}{>{\SplitArgument{2}{,}}m}{%
\finallimset#1%
}
\NewDocumentCommand{\finallimset}{mmm}{%
\lim_{#1\rightarrow #2\IfValueT{#3}{^{#3}}}%
}

\begin{document}

$\limset{x,0}f(x) \qquad \limset{x,0,+}g(x)$

\end{document}


With the preprocessor \SplitArgument{2}{,} you tell LaTeX to split the argument at commas, which should be at most two. Then #1 will effectively become {A}{B}{C}, where A, B and C stand for the three pieces. If the last is missing, it will receive the special value -NoValue- that can be tested with \IfValueT: if there is not -NoValue-, perform the stated action, otherwise ignore it.

The split argument is then passed to the auxiliary macro \finallimset which must have three arguments as stated.

• Ok! I'm guessing this can extend to commands with more than 3 arguments simply by changing the comma value passed to \SplitArgument? I.e. if there are 9 arguments, then you would specify \SplitArgument{9}{,}? – Inquisitive Apr 3 '18 at 23:05
• @Inquisitive That would be 8, not 9 (you count the maximum number of commas). One could manage even more than nine arguments, but in this case it would become impossible to remember which is which and what's its role. More than three or four arguments, whatever syntax you use for inputting them is to be avoided. – egreg Apr 3 '18 at 23:08
\usepackage{xparse}
\NewDocumentCommand \testings { m }
{
\clist_set:Nn \l_tmpa_clist { #1 }
\clist_use:Nn \l_tmpa_clist { ,\ }
}
\NewDocumentCommand \limset { m }
{
\clist_set:Nn \l_tmpa_clist { #1 }
\lim
\sb % note \sb rather than _
{
\clist_item:Nn \l_tmpa_clist { 1 }
\to
\clist_item:Nn \l_tmpa_clist { 2 }
^ { \clist_item:Nn \l_tmpa_clist { 3 } }
}
}


And then: $\testings{S_1,S_2,S_3,S_4,S_5,S_6,S_7,S_8,S_9,S_{10},S_{11},S_{12}}$ and $\limset{t,0,+}$ should work.