For the same reason as TeX gobbles a trailing spaces from numbers. In the case of TeX, this is needed to stop a number cleanly and make sure that in all cases it will be terminated without expanding anything further nor inserting a blank space. In fact, TeX probably skips spaces after control words (multiletter control sequences) for the same reason (although that happens at a different stage of processing). The idea is that it should always be possible to "stop without inserting anything".
Example: \ifdigit
below tests whether the argument is a digit. The space after #1
is required to stop TeX from expanding the first \expandafter
prematurely. On the other hand, we don't want the space to end up in the output. So in that case at least, TeX's space gobbling is a feature.
\long\def\ifdigit#1{%
\ifnum 9<1\string #1 %
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi}
eTeX's designers could decide that a space stops the \numexpr
or \dimexpr
, because they simply use TeX's procedures to read operands. And these procedures already remove a trailing space. eTeX does not see the space before +
in \numexpr 1 + 2
. It would have been technically possible to let \numexpr
be stopped by two space tokens in a row, and gobble them, but that would be very difficult to input, since two space characters in a row are equivalent to one. Some other delimiter had to be chosen. It had to be non-expandable, preferably already there in the language, and it had better do nothing when used outside a \...expr
situation... No need to add a new primitive: \relax
was a natural choice.
Now consider a \compareint
function defined as follows
\long\def\compareint#1#2#3{%
\ifnum\numexpr#1\relax#2\numexpr#3\relax
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi}
\compareint{1+2}<{3-1}{Yes}{No}
In this particular case, leaving \relax
behind would not be a problem. However, think of nesting this:
\def\X{345}\def\Y{534}
\compareint {132} < {\compareint{12}>{9}{\X}{\Y}+1} {Yes} {No}
If the \relax
was not removed from the internal \compareint
, it would stop expansion of the outside \compareint
too early (actually, before expanding to \X
or \Y
, so that would be a problem).
\dimexpr
, etc. are terminated by the first token which cannot form part of an appropriate number. So something like a letter will terminate\numexpr
without needing a\relax
. So it is optional. – Joseph Wright♦ Jun 10 '11 at 13:26\relax
is optional but whether the swallowing was optional. – Andrew Stacey Jun 10 '11 at 14:33\relax
', as the swallowing itself is not optional. – Joseph Wright♦ Jun 10 '11 at 15:51