# Creating new primitives

Consider the following TeX:

\tt

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

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

\let\define\def
\define\hi{hello,}

\let\let\define
\let\hello{world!}

\vskip 2ex

\centerline{
{\hi}
{\hello}
{\macro{argument-based}}
}

\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

\bye


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\def{bad}
\def                \par
[def]: \meaning\def \par
[let]: \meaning\let


would produce

bad
macro:->what?
\def


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. –  Qrrbrbirlbel Nov 7 '13 at 20:08
@Qrrbrbirlbel I actually expected to not be able to \let onto a primitive, actually. See my edit. –  Sean Allred Nov 7 '13 at 20:21
you can \let a command to anything, consider \let\bgroup{ which defines bgroup to be an (implicit) catcode 1 brace. –  David Carlisle Nov 7 '13 at 21:09
Don’t forget \iftrue and \iffalse which are let to \if<something> every time \<something>true and \<something>false are used. –  Qrrbrbirlbel Nov 7 '13 at 21:24
@Qrrbrbirlbel or rather the other way round: \ifsomething is let to \iftrue or \iffalse –  David Carlisle Nov 7 '13 at 21:39

## 2 Answers

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

\let\define\def


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

\let\define\def
\let\let\define


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

\def\macro{replacement}
\let\newmacro\macro


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

-
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. –  Bruno Le Floch Nov 8 '13 at 2:09

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

\let\let\futurelet
\let\def\let\xdef\futurelet\gdef\xdef\futurelet{}

\immediate\write20{\string\let=\meaning\let}
\immediate\write20{\string\futurelet=\meaning\futurelet}
\immediate\write20{\string\def=\meaning\def}
\immediate\write20{\string\gdef=\meaning\gdef}
\immediate\write20{\string\xdef=\meaning\xdef}

\bye


produces

\let=\futurelet
\futurelet=macro:->
\def=\xdef
\gdef=\futurelet
\xdef=\gdef

-
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! –  jfbu Nov 7 '13 at 21:52
Terse... say what? –  Werner Nov 7 '13 at 21:53