137

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?

1
  • 15
    Try starting TeX from the terminal without any file name and type {} at the ** prompt you get. ;-) Kill the process and retry typing \relax, this time. :)
    – egreg
    Dec 10, 2012 at 15:55

3 Answers 3

110

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}

enter image description here

  • 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.

3
  • 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?)
    – Emil Vatai
    Jun 4, 2017 at 6:55
  • 4
    Thats 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...
    – Vladimir
    Oct 14 at 10:07
114
+300

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 for plus and minus 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 +.

4
  • 10
    Instead 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 for plus and minus items. That's not the same as "doing nothing", right?
    – Mico
    Apr 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
  • 1
    Thanks for posting this follow-up; as a result, I think I understand better what exactly \relax does.
    – Mico
    Apr 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 tokens aa. (I have never seen a case where this is useful, but still:-) Apr 21, 2014 at 17:49
63

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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .