# What is the difference between \let and \def?

What is the difference between the \let and \def commands in TeX/LaTeX?

Ideally please provide a simple example that will illustrate the difference between them.

-

## 3 Answers

The difference is in the time at which the ‘right hand side’ is evaluated. \let applies immediate evaluation, while \def relies on delayed evaluation.

Thus \let\foo\bar defines \foo to have the value that \bar had at the point in time of definition. On the other hand, \def\foo{\bar} defines \foo to have the value that \bar has at the point in time of use.

Consider:

\def\bar{hello}
\let\fooi\bar
\def\fooii{\bar}
\fooi +\fooii

\def\bar{goodbye}
\fooi +\fooii


This produces

hello+hello
hello+goodbye


Annotated:

\def\bar{hello}
\let\fooi\bar % Let control sequence with the namefooi
% have the exact same value as control sequence with the name bar
% which in this case is hello. At the point it is created ("cloned") by \let,
% hello is the value it has, and the value it will keep
% (unless fooi itself is re-defined, e.g., as bar will be later in this example).

\def\fooii{\bar} % Control sequence named fooii value is \bar.
% Since the value of \bar is now hello the value of \foii
% at this moment in time is also hello

\fooi +\fooii % The value of control sequence fooi is hello the value of control
% sequence fooii is also hello.  The difference being that fooi is a "clone" of
% bar(a control sequence having the exact same value as another named control sequence)
% while the value of fooii is \bar.

\def\bar{goodbye} % Re-define control sequence with the name bar to contain the value
%goodbye. This also effects control sequence named foii which has \bar
% as its value. It does *not* change the value of control sequence fooi as \let
% created its "clone command" \fooi at the moment in time when control sequence
% bar contained the value hello.

\fooi +\fooii % Control sequence fooi having the value of bar earlier in time
% when it was "cloned" by \let has the value hello.  Control sequence fooii
% having the value \bar has the re-defined value of control sequence bar
% which is now goodbye.

-
Does this mean that \let\foo\bar is the same as \def\foo{\expandafter\bar}? Probably not, but why then? – Didii Jul 20 '12 at 9:59
With that definition, writing \foo\alpha at the bottom of the example would expand into \expandafter\bar\alpha; what that does is first expand \alpha, and then expand \bar (in this case to 'goodbye'). Using \expandafter counts as pretty advanced TeX, and is for the arcane cases where you need to control the order of evaluation in a non-default way. Try TeXing \def\baz{wibble} \def\x#1{-#1-} \x\baz \expandafter\x\baz – Norman Gray Jul 20 '12 at 11:15
The closest analogue to \let\foo\bar along the lines @Didii is suggesting would be \expandafter\def\expandafter\foo\expandafter{\bar}. There remain differences even between these, as detailed in Martin Scharrer's answer. But for most purposes, I think they would have much the same effect. – dubiousjim Sep 1 '14 at 23:15
Here is some more discussion. – dubiousjim Sep 2 '14 at 3:42
Awesome answer. I guess its a bit like assignment vs reference in other languages.... – Nicholas Hamilton Apr 30 '15 at 20:06

While the existing answers are all true I like to highlight one point which wasn't explicitly mentioned yet. I myself got this information recently from Joseph Wright (see his answer and our comments in Simple un-obfuscation of some LaTeX internals).

As Michael said \let\macroa\macrob "copies" the definition of \macrob to \macroa. However an IMHO important thing here is that the definition isn't actually copied, i.e. exists twice, but the command sequence \macroa now points to the same hash table entry as \macrob. This means that \let\macroa\macrob uses less memory space (very important in the early days but not anymore) and is faster then \def\macroa{\macrob} because in the second form two command sequence names have to be resolved in the hash table.

Also \let actually "copies" the definition of tokens, which do not need to be macros/command sequences. This allows the definition of command sequences representing implicit characters like \let\bgroup={.

-

They're pretty completely different. \let copies a command to a new name, while \def creates a new command.

For example:

\def \foo {bar}


creates a new command \foo, that evaluates to bar when run.

\let \foo \bar


copies the commands from the \bar commands to the \foo command, so you can call either. Because it's a copy (and not a pointer from one to the other), redefining \foo won't change the behavior of \baz. Hence:

\def \foo {bar}
\let \baz \foo
\baz % Outputs 'bar'
\def \foo {new-definition}
\baz % Still outputs 'bar'

-
Your \def statements are missing braces, and remember that unless 'bar' is a primitive then TeX expands the material rather then executing it. Good answer, though: more or less what I've have put. – Joseph Wright Jul 27 '10 at 6:10
@Joseph Ah yes, fixed; I never actually use \def, so I'm not surprised I botched the syntax :) – Michael Mrozek Jul 27 '10 at 14:34