31

I want to define two versions of the command \Set, depending if I provide one or two parameters. I.e. like this:

\newcommand{\Set}[1]{\bigl\{ #1 \bigr\}}
\newcommand{\Set}[2]{\bigl\{ #1 \bigm| #2 \bigr\}}

But that doesn't work. It complains about the redefinition of the command.

0
25

You can't "overload" macros in TeX like functions in other programming languages.

You can either define the macro to use a normal optional argument for one of the two parameters or define a special macro which looks ahead if a opening brace follows. The xparse package can help you defining one:

\documentclass{article}

\usepackage{amsmath}
\usepackage{xparse}

\NewDocumentCommand\Set{mg}{%
    \ensuremath{\bigl\{ #1 \IfNoValueTF{#2}{}{\bigm| #2} \bigr\}}%
}

\begin{document}

\[
\Set{A}{B}
\Set{A}
\]

\end{document}

Here the m in the definition stand for mandatory argument and the g for optional argument delimited by a TeX group, i.e. {}.

7
  • I'd probably use G{} in the argument specification, then do the \IfNoValueTF test inside the \ensuremath, including #2 in all cases (as this will be fine with an empty default).
    – Joseph Wright
    Mar 16 '11 at 15:23
  • Thanks @Joseph, I'm a beginner with xparse. But the "#2 in all cases` doesn't work because there is still \bigm| which must not be included in the first case.
    – Martin Scharrer
    Mar 16 '11 at 15:28
  • Thanks, perfect! And that doesn't actually seem to be so complicated, why would you suggest not to use it?
    – Albert
    Mar 16 '11 at 15:32
  • @Martin: Fair point, but you could stick to g and so use \IfNoValueF{#2}{\bigm| #2}.
    – Joseph Wright
    Mar 16 '11 at 15:33
  • @Albert: I didn't say don't use it, I said defining such macros isn't that easy. But I had more the manual definition in mind. The xparse package simplifies things very much.
    – Martin Scharrer
    Mar 16 '11 at 15:38
1

Sorry to be late to the party. Anyway, the g and G argument specifiers are deprecated.

The most natural syntax is \Set{A} or \Set{A | B} which is even easier to type than $\Set{A}{B}$.

\documentclass{article}

\NewDocumentCommand{\Set}{ >{\SplitArgument{1}{|}}m }{\SetAux#1}
\NewDocumentCommand{\SetAux}{mm}{%
  \bigl\{%
  #1%
  \IfValueT{#2}{\bigm|#2}%
  \bigr\}%
}

\begin{document}

This is a simple set $A=\Set{1,2,3}$, but this is more
complex
\[
B=\Set{x\in C | x=x^2}.
\]

\end{document}

enter image description here

2
  • Not the most flexible solution in terms of scalability of the braces.
    – Gaussler
    Jul 25 at 9:47
  • @Gaussler Sure, but that's what the OP wanted. This is covered elsewhere; my aim was to provide an answer that's free of g argument types.
    – egreg
    Jul 25 at 9:55
0

You can create two macros with the different parameter counts (and name) and invoke them within a composite macro with the desired name. Inside the new macro, call one of the two macros based on the number of parameters passed using \IfNoValueTF.

\documentclass{article}
%Import xparse for \IfNoValueTF 
\usepackage{xparse}

%Define behavior of the command with one parameter
\newcommand{\Seta}[1]{\bigl\{ #1 \bigr\}}

%Define behavior of the command with two parameter
\newcommand{\Setb}[2]{\bigl\{ #1 \bigm| #2 \bigr\}}

%Define a new command with the desired name. It checks if parameter #2 exists; 
%if no, it invokes the first command definition for single parameter (\Seta), else it invokes the \Setb
\NewDocumentCommand\Set{ m g }{
  \IfNoValueTF{#2}{\Seta{#1}}{\Setb{#1}{#2}}
}

\begin{document}
\[
\Set{A}{B}
\Set{A}
\]
\end{document}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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