\def
is a TeX primitive, \newcommand
is a LaTeX overlay on top of \def
. The most obvious benefits of \newcommand
over \def
are:
\newcommand
checks whether or not the command already exists
\newcommand
allows you to define an optional argument
In general, anything that \newcommand
does can be done by \def
, but it usually involves a little trickery and unless you want something that \newcommand
can't do, there's no point in reinventing the wheel.
In answer to your particular points:
- Yes and No. A command defined using
\def
has to know exactly what its options are, and how they will be presented to it. However, a TeX command can be a bit clever and examine things other than its arguments. The way that optional commands are handled is to look at the next character in the stream and if it is [
then one version of the command is called, whereas if it isn't then another is called. So if you're prepared to do some hackery, then optional arguments are possible via \def
, but it isn't half so easy as \newcommand
.
- No. Since
\def
doesn't check for a command already being defined, you can redefine stuff simply using \def
again. To get the checking, you need to use the \@ifundefined
command (note the ampersat (@
) sign!).
- No!
There's probably lots more to be said on the differences, but that's enough from me.
\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.
Best Answer
The difference is in the time at which the ‘right hand side’ is evaluated.
Thus
\let\foo\bar
defines\foo
to have the value that\bar
had at the point of definition. On the other hand,\def\foo{\bar}
in effect defines\foo
to have the value that\bar
has at the point of use.Consider:
This produces
This is a simple process.
However it's also a subtle one, so it might be worth highlighting a few key points:
When TeX encounters control sequences such as
\fooi
, it evaluates them; if these are macros (that is, they have been defined by\def
, or\let
equal to something which was defined by\def
), then the result is that they will expand to other tokens, which TeX will then examine in turn, and so on, recursively, until what's left is either ‘primitive’ control sequences or letters (I'm simplifying a little bit).\fooi
expands directly to the charactershello
(because\bar
initially did, and\fooi
was defined to have the same value).\fooii
, in contrast, expands to\bar
, which is then immediately reexamined and reexpanded. In the first case,\bar
expands tohello
and in the second case togoodbye
. The definition of\fooii
hasn't changed, but\bar
has been redefined in between.Getting a clear idea of the process of this recursive expansion is very helpful when learning how to develop and debug TeX macros.