As I understand it, the point of \relax
is to stop a macro from swallowing up subsequent material (such as whitespace). But {}
(\bgroup\egroup
) serves the same function. Why do we need both?
3 Answers
Try the following couple examples:
\documentclass{article}
\begin{document}
\[
\begin{array}{rl}
+9mm & +9m^2 \\
[+9mm] & [+3m]^2 \\{}
+9mm & +9m^2 \\{}
[+9mm] & [+3m]^2 \\\relax
+9mm & +9m^2 \\\relax
[+9mm] & [+3m]^2
\end{array}
\]
\end{document}
- If you leave there
\\
alone, the[+9mm]
is interpreted as an optional argument to\\
and transformed into a vertical space. - If you use
{}
, then it inserts an "empty thing" into the formula and the+
is improperly spaced. - Only the variant with
\relax
works correctly here, because it really does nothing.
Very similar examples can be used to show that \relax
is the correct terminator of \dimexpr
and \numexpr
expansion etc.
-
There is an error in your code, the first
\` is just
` so it doesn't compile... and could you explain why is there a small space between the + and 9? I don't get that part (I understands it inserts a 'nothing', but why does it appear there?) Jun 4, 2017 at 6:55 -
4Thats not my error, that's the StackExchange whatevet that eats backslashes. Sorry for that, but complain to them, not to me.– yo'Jun 4, 2017 at 7:25
-
I would make also this example:
\[\relax-5\]
and\[{}-5\]
. The 1st one prints just-5
like a negative number. The 2nd one prints minus with a space like there is subtraction "empty string minus 5". So\relax
really does nothing and{}
makes an empty string and then does nothing like\relax
. I understand it in a way like this...– VladimirOct 14 at 10:07
It's hard to answer the question as the two constructs are different in almost all respects so it's a matter of where to start.
\relax
is a single token, an unexpandable TeX primitive that does nothing when executed.
{}
is two tokens which (assuming the standard catcodes) mark a TeX group or non delimited macro argument.
\baselineskip =13pt\relax
the\relax
stops the length parser looking ahead forplus
andminus
components, but does nothing else.\baselineskip =13pt{}
would define baselineskip the same way but then open and close a group which could have several effects, most notably in math mode where it will generate an empty math atom and affect the spacing of surrounding atoms.{\let\section\relax...\immediate\write\@auxout{.. \section}}
makes a command such as\section
locally inert and safe to write (as itself) to an auxiliary file.{\let\section{}...\immediate\write\@auxout{.. \section}}
does something but is unlikely to do what anyone wants:-)\relax
is the definition given to a new control name generated by\csname
hence the common idiom\expandafter\ifx\csname foo\endcsname\relax
to test if a macro is defined. This clearly has no analogue using{}
$a+{}$
produces infix spacing as the{}
generates a mathord atom.$a+\relax$
is like$a+$
and not produce infix spacing for+
.
-
10Instead of saying that
\relax
"does nothing", might it be more informative to state that\relax
tells TeX to "stop doing whatever you're doing right now (whatever 'whatever' may be)"? E.g., in the statement\baselineskip =13pt\relax
,\relax
tells TeX to stop scanning ahead forplus
andminus
items. That's not the same as "doing nothing", right?– MicoApr 21, 2014 at 10:00 -
7@Mico I think the form that I gave is more correct. (although it was of course not the whole truth)
\relax
only stops scanning for a length as it's an unexpandable primitive that isn't part of a length,X
or\def
would do the same, it's just that unlike\def
when it is re-evaluated after the length assignment has completed, it does nothing. Apr 21, 2014 at 16:59 -
1Thanks for posting this follow-up; as a result, I think I understand better what exactly
\relax
does.– MicoApr 21, 2014 at 17:12 -
3@Mico the bit that I didn't include in the above description is the use of
\relax
as <filler> in\toks0 = \relax{aa}\showthe\toks0
\relax
isn't playing the part of a general unexpandable token (as it is when it terminates a length) it is part of the syntax of a toks assignment and absorbed along with the=
sign and white space so the token register gets the tokensaa
. (I have never seen a case where this is useful, but still:-) Apr 21, 2014 at 17:49
There is more than one reason.
I'll give an example where \relax
is good and {}
isn't:
\def\mysize{144pt\relax} % when expanding \mysize we won't trigger
% expansion of the next token
\hbox to \mysize{\hfil abc\hfil}
When TeX is processing the \hbox
command, it expands the tokens after to
in order to find the required <dimen>
; it will find 144pt\relax
and the syntax rules make this \relax
disappear (in TeX's jargon it's a <filler>
); with
\def\mysize{144pt{}}
TeX would find
\hbox to 144pt{}{\hfil abc\hfil}
which would be a disaster.
Of course one might as well define
\def\mysize{144pt }
but then \mysize
could not be used in text without \unskip
. A bit contrived example, perhaps.
In any case, \relax
does really nothing, while {}
opens and closes a group.
You mention \bgroup\egroup
as equivalent to {}
: it isn't; for instance, a macro with an argument that finds {}
will absorb an empty argument, while \bgroup\egroup
would absorb \bgroup
as the argument, leaving \egroup
in the stream. Again, if we use \relax
it would be one token.
{}
at the**
prompt you get. ;-) Kill the process and retry typing\relax
, this time. :)