# Please tutor us on relative merits of various ways of defining macros

I understand that among the ways we can define macros, there are at least three main streams.

The original TeX method: We use the \def command (and similar ones) to define macros. One very attractive feature is being able to customize the argument parsing. When we write \def\mymacro#1.#2-(#3){<macro definition>} we understand that the first argument must be followed by a dot, the second one by a dash, while the third argument must be enclosed between parentheses.

In this method, is it possible to declare an argument to be optional in a straightforward manner?


What if there more than one optional arguments? What about several optional arguments scattered among the mandatory arguments? Is it possible to control parsing of the arguments?

Necessitating the use of \renewcommand preventing accidental redefinition of existing ones is a good feature.

\NewDocumentCommand using xparse: Looks like the latest one. The straightforward manner in which I can mix the mandatory and optional arguments is particularly attractive to me. Comes with other loads of features.

I am making this post asking those with really vast experience to tutor us on the relative merits and demerits of the three main streams. If want to stick to only one, which one should we choose? Or do we keep on using them all in the same document and use the one which fits my need of the moment?

(Though there are several sentences ending with question marks in this post, it is not a post with several questions. Rather, these are the talking points which the answerer will find to be helpful when creating the tutorial.)

• Avoid explicitly delimited arguments, unless they fit within established syntax (such as (x,y) for coordinates). The more arguments a macro has, the harder is to remember their order and their delimiter. – egreg Aug 10 '17 at 10:06

The way one uses the \newcommand structure to get multiple optional arguments is to have the called macro use auxiliary macros to absorb an additional optional argument.

\documentclass{article}
\usepackage[T1]{fontenc}
\newcommand\mymacro[2][\Humpty]{\def\tmpA{#1}\def\tmpB{#2}\mymacroaux}
\newcommand\mymacroaux[2][\Dumpty]{%
\detokenize\expandafter{\tmpA}
\detokenize\expandafter{\tmpB}
\detokenize{#1}
\detokenize{#2}.%
}
\begin{document}
\mymacro{\Charles}{did \relax}

\mymacro[Fat]{\old}{ate \cake}

\mymacro{\Dumpty}[\fell\&]{broke his \crown}

\mymacro[My]{\mom}[is the]{\greatest!}
\end{document}


As to the way to do optional arguments via \def, the standard approach using \futurelet, as documented on p.277 of https://www.tug.org/TUGboat/tb09-3/tb22bechtolsheim.pdf, is

\documentclass{article}
\begin{document}
\def\xxWithOpt[#1]#2{Optional argument #1, Mandatory argument #2}
\def\xxNoOpt#1{No optional argument, mandatory argument #1}

\def\xx {%
\futurelet\xxLookedAtToken\xxDecide
}

\def\xxDecide {%
\ifx\xxLookedAtToken [%
\let\next = \xxWithOpt
\else
\let\next = \xxNoOpt
\fi
\next
}

\xx{A}

\xx[a]{A}
\end{document}


The xparse approach is discussed at https://tug.org/TUGboat/tb31-1/tb97wright-xparse.pdf, by Joseph. There are many ways to specify arguments with this approach and here I show only one, similar to the first example:

\documentclass{article}
\usepackage{xparse}
\DeclareDocumentCommand \foo
{ o +m o +m } {%
% Four args, #1, #2, #3 and #4
% Only #2 and #4 can include \par tokens
\IfNoValueTF{#1}{%
a%
}{%
#1%
}%
.#2.%
\IfNoValueTF{#3}{%
c%
}{%
#3%
}%
.#4%
}
\begin{document}

\foo{B}{D}

\foo[A]{B}{D}

\foo{B}[C]{D}

\foo[A]{B}[C]{D}
\end{document}



• Thanks. Do you want to make a concluding remark? – Masroor Aug 10 '17 at 4:26
• @Masroor I have supplemented my answer. – Steven B. Segletes Aug 10 '17 at 10:03