Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

The following usage of \ifx can be found in several packages and also in answers on this site. What does this syntax exactly mean? Are there any alternatives and drawbacks?

\newcommand{\mycommand}[2][]{%
  \ifx\\#1\\
    <true>
  \else
    <false>
  \fi
  % ...
}

(I actually know the answer, but thought this question should exists here. It pops up from time to time. In the unlikely case that it isn't fully answered I will post an own answer in a few days.)

share|improve this question
    
Martin: In this contents the answer of Will Robertson is very importan: Test whether token list is empty –  Marco Daniel Nov 6 '11 at 11:19

2 Answers 2

up vote 36 down vote accepted

It's one of the uncountable ways to check whether an argument is empty. Almost all of them suffer of some drawback: in the case at hand, the argument mustn't be \\.

What does \ifx do? It compares the two tokens following it, without expanding them. The test return success if both tokens are equal in the sense of \meaning or \show:

  • if they are characters (or control sequences \let to a character), they must represent the same (character code, category code) pair

  • if they are control sequences (but not \let to a character), they must have the same meaning; the cases are too many to list them all.

Before analyzing the macro, we should know something about TeX conditional: the abstract form is

\ifZ<test><true text>\else<false text>\fi

where \ifZ denotes one of the primitive conditionals. The <test> can take many forms, depending on \ifZ (it's empty, in some cases); what is important is that the <true text> is everything that goes from the end of <test> to \else (or \fi if \else is missing).

So let's see what happens when we call \mycommand{abc}, that is, the default argument, which is empty, is substituted to #1: the tokens that TeX sees are

\ifx\\\\<true>\else<false>\fi

Of course the test is true, because the tokens that follow \ifx are both \\.

When we call \mycommand[xyz]{abc}, instead, TeX sees

\ifx\\xyz\\<true>\else<false>\fi

and TeX compares \\ to x and they are different. But now the <true text> is

yz\\<true>

(remember: the <true text> is what goes from the test to the \else) and it will be ignored altogether.

This test is quite safe, because it doesn't do expansion; however it might fail miserably if the user calls \mycommand[\\]{abc}, so often different delimiter tokens are used, which are supposed not to creep into user's input (for instance \uchyph or \vfuzz). Another similar test might be

\if\relax\noexpand#1\relax

with the caveat that \if does expand what's next until two unexpandable tokens remain. The first token is \relax, which is unexpandable. The second one will be what becomes of the expansion of \noexpand, that is, the first token of #1 (if non empty) but made unexpandable; if #1 is empty, then \noexpand applies to \relax, resulting again in \relax because it's unexpandable.

In both cases some token is reserved (\\ in the first case, \relax in the second one). The safest test is

\if\relax\detokenize{#1}\relax

because the expansion of a non empty #1 can never give a first token equivalent to \relax: even if #1 is \relax, \detokenize{\relax} will give the string \relax (the first token of which is the character \).

Again, if #1 is empty, the test compares \relax to \relax; if #1 is not empty, everything will be ignored up to the \else. Of course it requires that an engine with the e-TeX extensions is run: it won't work with "Knuth TeX".

share|improve this answer
    
Incidentally, \show is slightly more powerful than \meaning for control sequences (or active characters) let to a character (\show also shows the \string part). –  Bruno Le Floch Nov 6 '11 at 14:56
    
Indeed \show<token> always begins with <token>=; but the part after = is the same as for \meaning –  egreg Nov 6 '11 at 15:01
1  
Actually, you're right, what I point out is not specific to control sequences let to a character. The more interesting thing is that \lccode126=97\lowercase{\let~a\show~}\show a distinguishes between the active a let to a letter a and that letter itself, whereas it is not possible to distinguish those using the usual \string, \meaning, \ifx, \if, etc. –  Bruno Le Floch Nov 7 '11 at 10:43
\ifx <command> #1 <command> 
  <code for #1 is empty>
\else
  <code for #1 is _not_ empty>
\fi

<command> can also be

\ifx\relax#1\relax

if #1 is empty (or doesn't exist), then we have \relax=\relax which is true. If #1 is not empty, then we have \relax=#1 which is false (except #1=\relax) and the following \relax doesn't hurt.

With \ifx\\#1\\ the LaTeX kernel does a test for an extension of a filename:

\def\test#1.#2\\{%
  \ifx\\#2\\ 
    <no extension #2 is empty, because \\=\\>
  \else
    <extension is #2>
  \fi
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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