\edef\relax{\relax} makes \relax hang forever

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


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…