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 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?

share|improve this question

4 Answers 4

up vote 27 down vote accepted

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}
share|improve this answer
    
I came here to learn about the use of \@fristoftwo in ifs and find the part about the \fi/\else removal(?) interesting but can't quite understand how it works. Would you mind elaborating that a little bit further so that I can understand it? (p.s. please notify me per comment if you edit this) –  ted Aug 3 '13 at 8:46

The correct syntax for \ifeq should be

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

Martin has explained well the reasons for preferring this approach than the "four argument" one.

What about \@firstofone? Well it may be used for stripping a pair of braces around an argument, for example. Another use is to make something a noop; in the LaTeX kernel there's

\let\AtBeginDocument\@firstofone

which is executed as part of the \document macro; so if something added with \AtBeginDocument calls by itself \AtBeginDocument, the argument to this command will be executed (and not in braces). The example might be stupid, but in the real world it can happen:

\AtBeginDocument{\AtBeginDocument{do something}}

If the kernel said \let\AtBeginDocument\relax, the result would be to feed the tokens

{do something}

and assignments in the code would be lost at group end. With the correct definition, LaTeX would be presented with \@firstofone{do something} that's expanded into do something, without braces.

Of course nobody writes code like that; but a package might say

\AtBeginDocument{\macro}

and another package might have redefined \macro with a call of \AtBeginDocument.

Another example: we want a macro that does nothing to its argument when called in normal form, but prints it in italics if called in the *-form.

\newcommand{\macro}{\@ifstar{\textit}{\@firstofone}}

Then \macro{x} will print x, while \macro*{x} will print x. One might leave out \@firstofone, but this would not strip the braces around the (apparent) argument to \macro. In this cases it's customary to use \@iden, which is the same as \@firstofone.

There's another case where \@firstofone is very useful, see Bruno Le Floch's answer to "Will two-letter font style commands (\bf, \it, …) ever be resurrected in LaTeX?

share|improve this answer
    
I think you meant Bruno Le Floch's answer,I didn't answer the question you linked to ;-) –  Gonzalo Medina Jun 21 '11 at 21:45
    
@Gonzalo: My apologies to Bruno! –  egreg Jun 21 '11 at 21:54

Since some previous answers went over the use of \@firstofone, I will as well. One use is that catcodes of its argument are fixed when \@firstofone is expanded. Hence,

\begingroup
\makeatletter
\catcode`\*=\active
\@firstofone{\endgroup
  \newcommand{*}}{*}

defines the active character * to expand to the "other" character *. Here, \makeatletter is needed because \@firstofone contains an @, and we put it within the group: this way, all the catcodes are reverted when reading \endgroup once \@firstofone has been expanded.

share|improve this answer
    
But after your code is executed, * is no longer active, right? If I type \show * it tells me "the character *". So what does this accomplish? –  Ryan Reich Jun 22 '11 at 13:58
    
Sorry, that wasn't clear. It is used to give a definition to the active *, typically useful in a package for the sake of making it active later in the document (see an answer on markup which I was reminded of recently). –  Bruno Le Floch Jun 22 '11 at 21:39

There's a use for \@firstofone in the TikZ code. The macro \tikz@scan@one@point converts the variety of ways of specifying a TikZ coordinate in to something more standardised. That is, it takes things like (1,2) or (a.north) and converts them in to something of the form \pgfpoint{10pt}{20pt}. This is a general use macro so it tries not to presuppose what should be done with this point, thus it takes an argument and that argument is a command, and what is executed is \command{\pgfpoint{10pt}{20pt}}. This makes it very flexible. Now \pgfpoint{10pt}{20pt} sets two lengths: \pgf@x and \pgf@y. If, after the \tikz@scan@one@point you just want those two lengths then you don't want to execute a command on \pgfpoint{10pt}{20pt}, you just want to execute \pgfpoint{10pt}{20pt}. So you can tell \tikz@scan@one@point to use the command \@firstofone. Thus \tikz@scan@one@point\@firstofone returns the x and y values of the point in the lengths \pgf@x and \pgf@y.

share|improve this answer
1  
That's a very specific example for a quite general question, isn't it? –  Martin Scharrer Jun 21 '11 at 15:48
    
@Martin: he just knows that I like TikZ :) –  Ryan Reich Jun 21 '11 at 16:22
5  
@Martin: Evidently not a mathematician! To answer a question, "Is X necessary?" it suffices to give one example where it is useful. Seriously, your answer covered the general case and I was merely trying to help out with a specific example (and one that I recently used). –  Loop Space Jun 21 '11 at 18:37

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.