# The default value of \newcommand is not as documented

The documentation of \newcommand in latex2e.pdf claims that if the optional parameter is specified as [] and is not given in the call, the value will be the string def. Instead, the command is getting the null string. Is this a documentation error or a bug?

\documentclass{article}

\usepackage{ifthen}

%Font for sequence
\newcommand \seqname [1] {\bm{\mathit{#1}}}

% Set former {x|P(x)} and {x,y,z}
% Trusting documentation
\newcommand {\setof} [2] []
{ \ifthenelse {\equal{#1}{def}}
{\{ #2 \}}
{\{ #2 | #1 \} p1=#1}
}

%Explicit default
\newcommand {\setxx} [2] [noP]
{ \ifthenelse {\equal{#1}{noP}}
{\{ #2 \}}
{\{ #2 | #1 \} p1=#1}
}

\begin{document}
Test setof x,y,z = $\setof{x,y,z}$

Test setof x P(x) = $\setof[P(x)] {x}$

Test setxx x,y,z = $\setxx{x,y,z}$

Test setxx x P(x) = $\setxx[P(x)] {x}$

\end{document}

• You must have misread it. An unspecified optional argument that is defined as [] indeed produces the null argument. One typical way to test for it is \ifx\relax#1\relax...\else...\fi. This will only fail if by chance an optional argument was specified that began with the token \relax. – Steven B. Segletes Sep 8 '16 at 17:17
• Exactly where does latex2e.pdf say this? – daleif Sep 8 '16 at 17:25
• To second @daleif's question: Are you referring to p. 59 of LaTeX2e: An unofficial reference manual? (emphasis mine) – Werner Sep 8 '16 at 17:27
• some random pdf that you found (on the internet (you don't say what the document is?) isn't the same as the documentation of the system. – David Carlisle Sep 8 '16 at 18:04
• @daleif lots of things are in TL:-), and texdoc will pick up the first thing with latex2e in its name, but still the phrasing of the question implies that it's the documentation of the system rather than a 3rd party tutorial, and that is far from the case. (Actually it's from Karl/et al so probably fairly reliable but still...) – David Carlisle Sep 8 '16 at 19:10

I've never seen mention of def being the default value when an argument is not specified. It's rather the second optional argument to \newcommand that gets substituted when the optional argument to the defined macro is absent.

So if you do

\newcommand{\foo}[2][def]{#1-#2}


the call \foo{x} will result in

def-x

whereas the call \foo[y]{x} will result in

y-x

You can easily check that

\newcommand {\setof} [2] []
{ \ifthenelse {\equal{#1}{def}}
{\{ #2 \}}
{\{ #2 | #1 \} p1=#1}
}


will print

{x|}p1 =

if called $\setof{x}$. Only \setof[def]{x} would print

{x}

which of course is not what you want.

A correct definition would be

\newcommand{\setof}[2][]{%
\if\relax\detokenize{#1}\relax
\{#2\}% no optional argument (or empty)
\else
\{#2\mid#1\}p1=#1%
\fi
}


It's even easier with xparse:

\usepackage{xparse}

\NewDocumentCommand{\setof}{om}{%
\IfNoValueTF{#1}
{\{#2\}}% no optional argument
{\{#2\mid#1\}p1=#1}%
}


where o denotes an optional argument (with no default value) and m a mandatory argument. The presence or absence of the optional argument is checked with \IfNoValueTF.

• I've been playing with xparse, and it gives me "! TeX capacity exceeded, sorry [input stack size=5000]." when I call \tl_gset_eq:NN. It also treats _ as a regular character even when I use expandafter. Also, I don't understand how to emit \\. Not that any of those relate to my original question, but I'd like to start using it if I can get comfortable with it. – shmuel Sep 14 '16 at 23:25
• @shmuel I'm not sure what the problem are, but surely they aren't connected with the code here. – egreg Sep 15 '16 at 6:12