I try to understand the subtleties of TeX programming, but it is not always easy.
For example, in the following code :
\def\first{abc}
\def\second{abc}
\ifx\first\second OK!\else false \fi
I understand why the output is OK!.
But I do not understand why the output is false with this code :
\if\first\second OK!\else false \fi
Best Answer
\if
compares the following two tokens after macro expansion, because it wants to compare unexpandable tokens.Thus
\if\first\second...\fi
expands\first
and the input stream has nowand the comparison between
a
andb
returns false.You can make
\first
and\second
unexpandable by sayingbut this would return true independently of the meaning of
\first
and\second
, because\if
compares character codes and, if a token is not a character, it is considered as having character code 256 (not really, but it is convenient to think so). A control sequence will be considered as having character code 256 unless it has been defined with(or any other character) and in this case
\if a\cs
would return true.Of course, the value 256 represents any number that cannot be a character code, so it would be
0x11000
for XeLaTeX or LuaLaTeX, where character codes can be as high as0x10FFFF
.Usage of
\if
is not easy, and has many subtleties. For instance one cannot use directly an active character for comparison and it must be preceded (after macro expansion) by\noexpand
.A clever example of
\if
is for testing whether an argument is empty:It uses
\detokenize
which is an e-TeX feature. If the argument is empty, the comparison would be between\relax
and\relax
, which are equal as far as\if
is concerned; otherwise,\detokenize
would return a string of characters (of category code 12) and\relax
is never equal to a character for\if
. So withone would get
and the true text would be
which would be discarded.
Similarly, with
the expansion of
\first
givesand, since the first two unexpandable tokens after
\if
are equal, the true text iswhile
\else false\fi
will be discarded.