1

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?

  • 6
    I'm not sure in what \plusbinomial[4]{a}{b} is easier than (a+b)^{4}. – egreg Jul 24 '18 at 7:27
  • 3
    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
5

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:

enter image description here


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:

enter image description here

1

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}

enter image description here

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 ⟩

Not the answer you're looking for? Browse other questions tagged or ask your own question.