Consider the following TeX:


~~~[def]: \meaning\def              \par
~~~[let]: \meaning\let              \par
[define]: \meaning\define           \par
~[macro]: \meaning\macro

\def\macro#1{some #1 transformation}



\vskip 2ex


\vskip 2ex

~~~[def]: \meaning\def              \par
~~~[let]: \meaning\let              \par
[define]: \meaning\define           \par
~~~~[hi]: \meaning\hi               \par
~[hello]: \meaning\hello            \par
~[macro]: \meaning\macro


which produces the output

   [def]:  \def
   [let]:  \let
[define]:  undefined
 [macro]:  undefined

           hello, world!  some argument-based transformation

   [def]:  \def
   [let]:  \def
[define]:  \def
    [hi]:  macro:->hello,
 [hello]:  macro:->world!
 [macro]:  macro:#1->some #1 transformation

I had thought that \let only copied that macro definition of a control sequence; is something more fundamental happening here? In fact, I would not expect \let to be able to redirect the control sequence for primitive functions to others at all. Even if \let is simply creating a new reference to a definition, as this related answer implies, primitives should not have 'definitions' as I understand them in the context of TeX. Do the primitives have such 'definitions' that are simply inexpressible in TeX, but still able to be referenced?

Consider also the extended scenario:

\def                \par
[def]: \meaning\def \par
[let]: \meaning\let

would produce


If \let is doing what it says it's doing, how is \meaning getting a value of \def at all?

  • I am confused. What did you expect to happen? You let \let to \def and now \let is (not expands to) the primitive \def. Commented Nov 7, 2013 at 20:08
  • @Qrrbrbirlbel I actually expected to not be able to \let onto a primitive, actually. See my edit. Commented Nov 7, 2013 at 20:21
  • 1
    you can \let a command to anything, consider \let\bgroup{ which defines bgroup to be an (implicit) catcode 1 brace. Commented Nov 7, 2013 at 21:09
  • 1
    Don’t forget \iftrue and \iffalse which are let to \if<something> every time \<something>true and \<something>false are used. Commented Nov 7, 2013 at 21:24
  • 1
    @Qrrbrbirlbel or rather the other way round: \ifsomething is let to \iftrue or \iffalse Commented Nov 7, 2013 at 21:39

2 Answers 2


When you do \let<token-a>=<token-b>, TeX creates a pointer to the memory location where <token-b> is stored. Primitives are stored with the name they had at the beginning of the TeX run, before the format file is loaded; there would be no other way to represent them; maybe primitive \def would have been better, but Knuth chose not to and to represent a primitive just with its (primitive) name. So if you do


a \show\define will output \define=\def even if \def is redefined afterwards. Whenever \show<token> says <token>=\xyz you know that \xyz is a primitive and <token> has the same meaning as that primitive. So, in LaTeX, \show\@@input outputs

> \@@input=\input.

If you do


you make \let point to the same memory location \define points to, that is, the original memory location of \def. Of course you've lost the \let primitive, unless you saved it beforehand with \let\primitivelet\let (or similar). TeX follows instructions: if you want to shoot yourself in the foot, it will gladly let you to. Only some (inaccessible) tokens are protected against redefinition because one can't really access their names.

Actually, one of the aims of the LaTeX3 project is to rename all primitives, so as to avoid problems when a user does \renewcommand{\box}{something}: after saving every primitive under a new name, LaTeX3 code only uses those new names and not the original ones.

This doesn't happen with macros: if you say


a \show\newmacro will not have any trace of \macro. Indeed, \macro could then be redefined without changing the meaning of \newmacro.

Note: The fact that \let\define\def\show\define prints \define=\def doesn't mean that TeX remembers what \def is in case one also does \define\def{Oops}. After the = sign \def is just a representation of the meaning, not the actual command. With pdftex one can however access primitives by prefixing their name with \primitive. So \primitive\input will execute the primitive meaning of \input independently of any redefinition of \input.

Note that \meaning and \show are identical in this respect; the difference is that \show interrupts the TeX run and shows the meaning on the terminal, while \meaning simply prints it (TeXnically, it produces a representation of the meaning by characters of category code 12, 10 for spaces).

  • 1
    your next to last paragraph is misleading because its last sentence is also true of primitives: the control sequence \def which originally pointed to the internal meaning \def can be redefined without affecting any other control sequence which points to the same internal meaning. Commented Nov 8, 2013 at 2:09

egreg's answer is of course correct but perhaps a bit terse. An illustrative example might help.





  • what a pity that LaTeX3 takes the spice out these kind of things that the average users love to do, now that the danger will be a thing of the past!
    – user4686
    Commented Nov 7, 2013 at 21:52
  • 4
    Terse... say what?
    – Werner
    Commented Nov 7, 2013 at 21:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .