\edef
expands the argument, whereas \let
doesn't. Here is an example to illustrate the difference:
\def\txt{a}
\def\foo{\txt}
\let\bar\foo
\bar -> a
\def\txt{b}
\bar -> b
However,
\def\txt{a}
\def\foo{\txt}
\edef\bar{\foo}
\bar -> a
\def\txt{b}
\bar -> a
There are also other differences, say, the arguments and so on. But how to expansion may be the most important(?).
This is an interesting question. May I expand the question further more?
What is the difference between \let
and \expandafter\def\expandafter\foo\expandafter
? Do they always behave the same?
\def\txt{bar}
\def\foo{\txt}
\expandafter\def\expandafter\bar\expandafter{\foo}
\let\BAR\foo
{\tt \string\bar = \meaning\bar}\par
{\tt \string\BAR = \meaning\bar}
Sneaky inline answer to this rhetorical question, since I wrote the original question :)
If you are doing this on macros that take no arguments, then the difference between them is negligible. OTOH, you cannot use the \expandafter\def...
construct if you're trying to copy the definition of a macro that takes arguments.
In fact, this brings to light one of the aspects that I was hoping people would discuss here. \let
creates a literal copy of a macro at the instant that it is executed, whereas \edef
will take the contents of the macro and expand it recursively to create a new macro entirely. When you are only using the macros as places to store data (such as \def\name{Will}
) then the differences are largely inconsequential, but when the macros are being used as ‘functions’ that take arguments or have contents that have various expansion restrictions applied to it (with \protected
, \noexpand
, and so on) then the differences can be very important indeed.
When you
\def\foo{}
you are giving \foo
an empty definition, but \foo
still 'exists' using any of the tests used for this (such as \ifdefined
or LaTeX's \@ifundefined
). The same effect can be achieved by doing
\let\foo\empty
which is very slightly more efficient as it points to an already-used memory location (not a worry nowadays). When \foo
has such a definition, it is expandable, and so
\edef\baz{\foo}
will result in \baz
being empty, as \foo
expands to nothing at all.
On the other hand
\let\foo\relax
makes \foo
equal to the \relax
primitive. That is a 'do nothing' operation, but importantly is not expandable. So in this case
\edef\baz{\foo}
leaves \baz
with definition '\foo
'. That can be useful: it's a way of temporarily preventing a macro from doing anything while retaining it's appearance in other code. On the other hand, sometimes you don't want that: it depends on the context. When \foo
is equal to \relax
, whether it is regarded as 'existing' by the various tests is more variable. TeX automatically creates control sequences equal to \relax
in various cases, and so some tests will regard anything equal to \relax
as 'not defined'.
So which is better depends on your use case.
Best Answer
They're not the same at all:
%
will comment out the rest of the line, including the line break, while\relax
is just mostly a no-op and you're using that spaces (including line breaks) after control sequences are discarded.Frankly, I can't see any situation where you'd not want to use
%
.