[Tex/LaTex] What do \@firstoftwo and \@secondoftwo do

latex-basemacros

The LaTeX kernel uses these two all over the place. For example, apparently the correct way of defining something like \ifeq{\macro 1}{\macro 2}{true}{false} is (note Martin's response: each case should begin with \expandafter)

\def\ifeq#1#2{%
 \ifx#1#2\relax
  \@firstoftwo
 \else
  \@secondoftwo
 \fi
}

rather than

\def\ifeq#1#2#3#4{%
 \ifx#1#2\relax
  #3%
 \else
  #4%
 \fi
}

However, they are equivalent as far as I can see:

\long\def\@firstoftwo#1#2{#1}
\long\def\@secondoftwo#1#2{#2}

There is even a \@firstofone! It does this:

\long\def\@firstofone#1{#1}

Clearly there is no functional difference in using these macros than simply declaring one or two more arguments. I can see two possible minor differences off the top of my head:

  1. \@firstoftwo is a control sequence and, as such, gobbles subsequent spaces. This means we don't have to put a % after it if it ends a line. Of course, we have to put % in lots of other places, and TeX doesn't actually store the % in the macro's expansion text, so this is truly minor.

  2. Macros defined with \@firstoftwo take two arguments fewer than those defined normally. Thus, TeX doesn't have to store the information that my \ifeq macro takes those two arguments; it just refers to the storage already used by \@firstoftwo and \@secondoftwo. I guess this cuts down a little on memory usage.

    Neither of these explains the purpose of \@firstofone, since it could only possibly be useful when placed as the very last token of a macro, and even there it doesn't actually change the subsequent input, so it seems like it could just be eliminated. Is there some reason one would want to "set off" the next token like that? There is one more possibility:

  3. These are \long\def'd rather than just \def'd. Thus, they can take multiple-paragraph arguments even if the macro using them is not \long. I guess this allows you to make the last one or two arguments of a macro \long when the others are not, but really, why not just use \long when you really mean it?

Are there other advantages that I've missed? Do they have minor effects on speed or tricky interactions with expansion or execution that I'm missing? What is the real reason for this bit of obfuscation?

Best Answer

You are missing two very important \expandafters. The normally used, "correct" code is:

\def\ifeq#1#2{%
 \ifx#1#2\relax
   \expandafter\@firstoftwo
 \else
   \expandafter\@secondoftwo
 \fi
}

The difference to a macro which uses #3 and #4 is that the if-statement is fully processed before the first or second of the next two arguments is processed. This allows that code to e.g. look ahead using \@ifnextchar. Otherwise the \else or \fi would still be after the #3 or #4, respectively, which would break such macros. Such techniques to close the if-statement first are also important for recursive macro to not accumulate a lot of cascaded if-statements.

The macros are defined \long simply to allow for the most flexible use.


The \@firstofone macro seems to be a no-op, but actually removes the braces around the argument. It is often used in an if-statement where \@gobble is used in the other clause (both again using \expandafter).

\def\foo#1#2{%
 \ifx#1#2%
   \expandafter\@firstofone
 \else
   \expandafter\@gobble
 \fi
}

\foo{\bar}{\baz}{Argument code}
Related Question