4

Previously I thought it is always safe to \edef a macro to its existing definition. But \edef\relax{\relax} makes \relax hang forever and CPU is very busy. So what is TeX doing there?

5
  • 1
    this is an explicit infinite recursion, but what was the intention? Or is the answer simply "don't do that" Jun 13, 2020 at 13:25
  • @DavidCarlisle No there is no intention. As I said I thought \edef{<same_macro>}{<same_macro>} is always safe but this one is a counterexample.
    – Cyker
    Jun 13, 2020 at 13:28
  • It isn't really a counter example, as \relax is not a macro (it's an unexpandable primitive) But most macros are not safe in an \edef either but would fail in other ways, either in the edef itself or when used after the definition. Jun 13, 2020 at 13:30
  • 2
    The \edef itself is safe. Try inside a group: {\edef\relax{\relax}} the problem is the later use of the redefined command (which will happen sooner or later, as every document has lots of \relax in the code). Jun 13, 2020 at 13:32
  • as @UlrikeFischer says the edef here does not error just redefines \relax to loop, but if you try it with a macro typically you will get errors in the edef, try \edef\section{\section} for example. Jun 13, 2020 at 13:36

3 Answers 3

14

\relax is not expandable so this is the same as \def\relax{\relax} as you can check with \show\relax. So then any use of \relax will cause it to expand in one step to \relax and so be an infinite loop.

10

It's definitely unsafe to do \edef\foo{\foo} if by “safe” you mean “to get the same as before”.

Suppose you have

\newif\ifblurb
\def\foo{\ifblurb A\else B\fi}

then doing

\edef\foo{\foo}

will not yield the same definition of \foo as before; since a conditional starts out false, your \edef would be the same as

\def\foo{B}

whereas if given after \blurbtrue it would be equivalent to

\def\foo{A}

In other words, you get the “expanded” version of the replacement text, which may or may not be what you'd think.

There is something else to take into account: when TeX processes \edef, it first puts apart the macro name and the parameter text, then fully expands the given replacement text until only unexpandable tokens remain; each macro is expanded with its current value; once the new replacement text has been obtained, TeX does \def using it along with the original tokens in the parameter text.

Since \relax is not expandable, your definition turns out to be the same as \def\relax{\relax}. Note that after this \relax has become a macro rather than the primitive.

When later you say \relax, TeX knows it is a macro and expands it according to its definition, so it replaces it with \relax and restarts expansion…

3
  • OK I understand why \edef doesn't keep things intact: it redefines with an "expanded" body instead of the body itself. But I was a bit surprised when the compiler didn't warn me when I redefined a primitive. Aren't there any reserved keywords there in tex such that cannot be redefined?
    – Cyker
    Jun 13, 2020 at 21:39
  • 1
    @Cyker No, nothing is reserved except a few internal tokens that are quite difficult to access. As you discovered, it's easy to shoot on one's foot…
    – egreg
    Jun 13, 2020 at 21:55
  • @Cyker You can look at tex.stackexchange.com/a/57417/4427 for one of those internal tokens; the “frozen \relax” token cannot be redefined.
    – egreg
    Jun 13, 2020 at 22:06
0

Your question asserts that \edef\relax{\relax} on its own causes an infinite loop. But it is not so:

C:\Users\hammerite>tex
This is TeX, Version 3.14159265 (MiKTeX 2.9.7400 64-bit)
**\relax

*\edef\relax{\relax}

*

TeX prints the * prompt immediately after executing the line containing \edef\relax{\relax}, so it didn't go into a loop at all. You are mistaken.

1
  • You are right. The definition itself doesn't hang. Actually I mean the redefined \relax hangs. This is updated now.
    – Cyker
    Jun 14, 2020 at 21:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.