# Newcommand with optional argument and ifthenelse

I would like to define a new command comp with two arguments where the second (and last) argument is optional, using 'ifthenelse'. I tried :

\newcommand{\comp}[2]{%
\ifthenelse{\isempty{#2}}%
{{#1}^{c}}% if #2 is empty
{#2 \backslash #1}% if #2 is not empty
}


but \comp{Y}{X} gives Y\X instead of X\Y as wanted and \comp{Y} gives Y\ instead of the result of Y^c as wanted.

Optional arguments are usually set first and specified in brackets [] rather than braces {}.

With your code, if you type $\comp{Y}=Z$, the second argument is taken to be =, because of how TeX decides what the argument to a command is. Indeed, with

\newcommand{\comp}[2]{...}


the required arguments are two.

In my opinion, the optional argument should be the first, so you read

\comp[X]{Y}        \comp{Y}


as “the complement in X of Y” or “the complement of Y” respectively.

How to define that?

\usepackage{xifthen}

\newcommand{\comp}[2][]{\ifthenelse{\isempty{#1}}{#2^c}{#1\setminus#2}}


or

\usepackage{xparse}

\NewDocumentCommand{\comp}{om}{\IfNoValue{#1}{#2^c}{#1\setminus#2}}


Here is an alternative version that checks if the code following the first parameter starts with an opening brace {. If so it treats it as a second argument, otherwise it assumes only one argument is given. However, as this makes the code less readable and maintainable, I do not really recommend its usage.

The implementation uses \@ifnextchar to test for the following character after grabbing the first parameter, and then switches to either of the two implementations \comp@single or \comp@double.

\documentclass{article}

\makeatletter

\newcommand\comp[1]{%
\@ifnextchar\bgroup{\comp@double{#1}}{\comp@single{#1}}%
}
\newcommand\comp@single[1]{%
{{#1}^{c}}%
}
\newcommand\comp@double[2]{%
{#2 \backslash #1}%
}

\makeatother

\begin{document}

$\comp{Y}{X}$\par
$\comp{Y}$

\end{document}


outputs

An answer without ifthen package:

\documentclass[10pt,a4paper]{article}
\newcommand{\comp}[2][]{%
\def\FirstArg{#1}
\ifx\FirstArg\empty
\ensuremath{{#2}^{c}}% if #1 is empty
\else
\ensuremath{#2 \backslash #1}% if #2 is not empty
\fi
}
\begin{document}

$X\backslash Y$=\comp[Y]{X}

${Y}^{C}$=\comp{Y}
\end{document}


An answer with ifthen:

\documentclass[10pt,a4paper]{article}
\usepackage{ifthen}
\newcommand{\comp}[2][]{%
\ifthenelse{\equal{#1}{}}
{\ensuremath{{#2}^{c}}}% if #1 is empty
{\ensuremath{#2 \backslash #1}}% if #2 is not empty
}
\begin{document}

$X\backslash Y$=\comp[Y]{X}

${Y}^{C}$=\comp{Y}
\end{document}


Explaining:

A command has a defined number of arguments. If the arguments are mandatory (let's say 4) you have to define it like:

\newcommand{\mycommand}[4]{<Do things>}


If it has an optional argument {like in your case} it has to be the first one and (in case of 3 mandatory and an optional) you have to define it like:

\newcommand{\mycommand}[4][<First Argument Default Value>]{<Do things>}


The rest is the usage in your case (feel free to ask for anything not clear to you.).

• I'm not sure why you're suggesting $X\backslash Y$=\comp[Y]{X} which is wrong under semantic and typographic points of view. Oct 11 '19 at 7:35
• @egreg ... it is not my code ... It is op's code ... But still I am not sure about what exactly you mean here. Oct 11 '19 at 7:49
• OP's code? I see nothing similar to \ensuremath in the OP's code. The syntax you're suggesting, namely $Z$=\comp[Y]{X} is really wrong, not because of the order of the arguments (which is wrong as well), but semantically: that should be a single formula. Oct 11 '19 at 7:54
• @egreg ... I just added \ensuremath because OP ... talked about "\comp{Y}{X}" and not "$\comp{Y}{X}$" ... So, I thought it will be useful to him/her. This is why I just tested the command out of the math environment too. But thanks anyway for your comments ... Sure will help future visitors. PS: The part inside the document environment is just a test to show that this produces the desired order etc ... Not a typographic suggestion. Oct 11 '19 at 8:01