Detect no argument in \newcommand

I wonder if there is a way to create a command which can discriminate when there is an argument or not. I don't mean empty argument, I mean no argument at all.

Here an example

\newcommand{\mycommand}[1]{
\if \totallyempty
0
\elseif \empty
1
\else
%whatever
2
\fi
}


Testing

\mycommand


0

\mycommand[]


1

\mycommand[2]


2

UPDATE

Apologies, the command argument does not need to be in braces {}, as many pointed, the optional arguments should be []. My main concern was about the possibility of not especify the argument, e.g. \mycommand,\mycommand[],\mycommand[2].

Apologies for not explaining correctly. I changed in the main text. Regards.

SOLUTION

Thanks very much to all the solution submitted, they are all very creative and useful.

I had to select @egreg solution (https://tex.stackexchange.com/a/409770/105956) for the very easy to implement and clear code. Mention to @Phelype Oleinik and @David Carlisle for not use any package.

Thanks very much. Kind regards.

• if the argument is optional it should be in [] not {} and you can define commands via \newcommand that can detect an optional argument. – David Carlisle Jan 10 '18 at 21:03

You can, but you shouldn't. Optional arguments should be delimited by [].

I hope that the command names are clear enough to tell what's my opinion on the matter.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\cs_new_eq:NN \IfBlankTF \tl_if_blank:nTF
\cs_new_eq:NN \IfEmptyTF \tl_if_empty:nTF
\ExplSyntaxOff

\IfNoValueTF{#1}
{0}
{%
\IfEmptyTF{#1}% if you allow { } to represent case 1, use \IfBlankTF instead
{1}
{2}%
}%
}

\NewDocumentCommand{\mygoodcommand}{o}{%
\IfNoValueTF{#1}
{0}
{%
\IfEmptyTF{#1}% if you allow [ ] to represent case 1, use \IfBlankTF instead
{1}
{2}%
}%
}

\begin{document}

\mygoodcommand

\mygoodcommand[]

\mygoodcommand[x]

\end{document}


xparse provides a g parameter specification:

An optional argument given inside a pair of TeX group tokens (in standard LaTeX, {...}), which returns -NoValue- if not present.

It goes against the convention of using [...] for optional arguments. However, the use-case exists.

\documentclass{article}

\usepackage{xparse}

\NewDocumentCommand{\mycommand}{ g }{%
\IfValueTF{#1}
{% https://tex.stackexchange.com/q/53068/5764
\if\relax\detokenize{#1}\relax
1%
\else
#1%
\fi}
{0}%
}

\begin{document}

\mycommand% 0

\mycommand{}% 1

\mycommand{1}% 1

\mycommand{2}% 2

\end{document}

• g is evil: use [] delimiters for optional arguments. (I know you are not to blame:-) – David Carlisle Jan 10 '18 at 21:04

You can define two commands, one with no arguments, and one with a conditional for an empty argument, like this:

\documentclass{article}

\makeatletter
\newcommand{\mycommand}{%
\@ifnextchar[{\mycommand@something}{\mycommand@nothing}%
}
\newcommand{\mycommand@nothing}{%
0%
}
\newcommand{\mycommand@something}[1][]{%
\if\relax\detokenize{#1}\relax
1%
\else
#1%
\fi
}
\makeatother

\begin{document}

0\mycommand

1\mycommand[]

2\mycommand[2]

\end{document}


The main command is \mycommand. If the next character is an [ then it executes the \mycommand@something, otherwise, the \mycommand@nothing.

The \mycommand@something checks for an empty argument. If it is empty then the conditional is true, otherwise it is false.

I could not make it work with "curry brackets" because they have special meaning in TeX. I suppose that changing their catcode momentarily could work...

Edit:

As @egreg pointed out using very few words (two tokens :)), one can use \bgroup as a replacement for { and trick TeX to check for a { after the \mycommand. In this case, \mycommand can be used exactly as desired:

\documentclass{article}

\makeatletter
\newcommand{\mycommand}{%
\@ifnextchar\bgroup{\mycommand@something}{\mycommand@nothing}%
}
\newcommand{\mycommand@nothing}{%
0%
}
\newcommand{\mycommand@something}[1]{%
\if\relax\detokenize{#1}\relax
1%
\else
#1%
\fi
}
\makeatother

\begin{document}

0\mycommand

1\mycommand{}

2\mycommand{2}

\end{document}

• You forgot to add a % after the \@ifnextchar-line. And changing the catcode of brackets seems like a bad idea (has to be done prior to the paragraph the command is used in, changing the syntax of each command in that paragraph). – Skillmon Jan 10 '18 at 20:33
• @Skillmon Thanks! Fixed it. Indeed, I tried doing some bizarre \catcodeing inside \mycommand, but then noticed that it would not work because of what you said U_U. But honestly I think that (as far as the example goes), there is no harm in using []... – Phelype Oleinik Jan 10 '18 at 20:41
• \@ifnextchar\bgroup – egreg Jan 10 '18 at 20:53

While it is technically possible to make {} delimited arguments optional you should not do it, it breaks all the LaTeX syntax guidelines. {} arguments denote mandatory arguments, [] delimted arguments are optional.

\documentclass{article}

\makeatletter
\def\mycommand{\@ifnextchar[\my@command{yippee no argument here}}
\def\my@command[#1]{Here I deal with an argument (#1) \if\relax\detokenize{#1}\relax(which is empty)\fi}

\makeatother
\begin{document}

\mycommand

\mycommand[]

\mycommand[zz]

\end{document}