Default value of command [duplicate]

I have the following command:

\newcommand{\plusbinomial}[3][2]{(#2 + #3)^{#1}}


This command takes 3 parameters and the default value of the first parameter is 2.

If I don't want to use the default value, then I would call it like this:

$\plusbinomial[4]{y}{y}$


My question is, how do I define default value for all the parameters and how should I call it then?

• I'm not sure in what \plusbinomial[4]{a}{b} is easier than (a+b)^{4}. – egreg Jul 24 '18 at 7:27
• it is usually a bad interface design to have more than one optional parameter as if you make all three optional it is very hard to have a natural usage, you can not use the third argument unless you provide the first two so they are no longer really optional. – David Carlisle Jul 24 '18 at 7:45
• This is an example given in the ShareLaTeX @egreg – Robur_131 Jul 24 '18 at 7:50
• @Robur_131 you should put braces around #1 in that code. – Skillmon Jul 24 '18 at 8:06
• Edited. @Skillmon – Robur_131 Jul 24 '18 at 8:56

Edit:
I agree with David Carlisle that it is generally bad practice to have multiple optional arguments with default values. If you want to give the last argument a value, you also have to provide the prior arguments. For these kind of macros, it might be more clear to use a key=<value> structure for the arguments. The following example uses pgf for that:

\documentclass{article}

\usepackage{pgf}

\pgfkeys{
/plus binomial/.cd,
a/.initial={5},
b/.initial={8},
c/.initial={2},
}

\newcommand{\plusbinomial}[1][]{%
\pgfkeys{/plus binomial/.cd,#1}%
(\pgfkeysvalueof{/plus binomial/a} + \pgfkeysvalueof{/plus binomial/b})^{\pgfkeysvalueof{/plus binomial/c}}%
}

\begin{document}
$$\plusbinomial$$

$$\plusbinomial[c=9]$$

$$\plusbinomial[c=9,b=1]$$

$$\plusbinomial[c=9,b=1,a=3]$$

$$\plusbinomial[c=9,a=3]$$
\end{document}


Which results in the following, which is more intuitive:

Without a package this can be done as follows:

\documentclass{article}

\makeatletter
\def\plusbinomial{%
\@ifnextchar[{%
\plusbinomial@i%
}{%
\plusbinomial@i[2]% Default is 2
}%
}
\def\plusbinomial@i[#1]{%
\@ifnextchar[{%
\plusbinomial@ii{#1}%
}{%
\plusbinomial@ii{#1}[5]% Default is 5
}%
}
\def\plusbinomial@ii#1[#2]{%
\@ifnextchar[{%
\plusbinomial@iii{#1}{#2}%
}{%
\plusbinomial@iii{#1}{#2}[8]% Default is 8
}%
}
\def\plusbinomial@iii#1#2[#3]{(#2 + #3)^#1}
\makeatother

\begin{document}
$$\plusbinomial$$

$$\plusbinomial[9]$$

$$\plusbinomial[9][1]$$

$$\plusbinomial[9][1][3]$$

$$\plusbinomial[9][][3]$$
\end{document}


But if you're willing to include the xparse package, this becomes a lot simpler:

\documentclass{article}

\usepackage{xparse}

\NewDocumentCommand{\plusbinomial}{O{2} O{5} O{8}}{(#2 + #3)^{#1}}

\begin{document}
$$\plusbinomial$$

$$\plusbinomial[9]$$

$$\plusbinomial[9][1]$$

$$\plusbinomial[9][1][3]$$

$$\plusbinomial[9][][3]$$
\end{document}


With exactly the same result:

You could test whether any of the arguments is a star/asterisk (*) and substitute a default value whenever this the case. This is how that would work: (with default values 2, 1 and \delta for #1, #2 and #3)

\documentclass{article}

\newcommand\defaultifstar[2]{\ifx*#1 #2\else #1\fi}
%% \defaultifstar{#1}{#2} --> #2 if #1 is a *, and --> #1 otherwise
\newcommand*\plusbinomial[3][2]{(\defaultifstar{#2}{1}+\defaultifstar{#3}{\delta})^{#1}}

\begin{document}

$\plusbinomial{x}{y}$,
$\plusbinomial*{y}$,
$\plusbinomial{x}*$,
$\plusbinomial[3]{x}{y}$,
$\plusbinomial[3]*{y}$,
$\plusbinomial[3]{x}*$

\end{document}


Note: The above method actually only tests if the first token of #1 is a *, so it fails spectacularly when you pass an actual argument that happens to start with a *. So don't use it if this is likely to happen. (To test whether the argument is equal to * you could replace \ifx*#1 by \ifnum\pdfstrcmp{*}{#1}=0 for pdfLaTeX, \ifnum\strcmp{*}{#1}=0 for XeLaTeX and \ifnum\pdf@strcmp{*}{#1} for LuaLaTeX (last one requires the pdftexcmds package).)

You could also test if an argument is empty and use a default value then.

\documentclass{article}

\newcommand\defaultifempty[2]{\if\relax\detokenize{#1}\relax #2\else #1\fi}
%% \defaultifempty{#1}{#2} --> #2 if #1 is empty, and --> #1 otherwise
\newcommand*\plusbinomial[3][2]{(\defaultifempty{#2}{1}+\defaultifempty{#3}{\delta})^{#1}}

\begin{document}

$\plusbinomial{x}{y}$,
$\plusbinomial{}{y}$,
$\plusbinomial{x}{}$,
$\plusbinomial[3]{x}{y}$,
$\plusbinomial[3]{}{y}$,
$\plusbinomial[3]{x}{}$

\end{document}


⟨ The output is the same ⟩