26

I always thought TeX's macros are very Lispy like and stumbling across the definition of the LaTeXe logo confirmed it. The macro is defined as follows:

%\LaTeXe The LATEX2" logo as proposed by A-W designers.
 \def\LaTeXe{%
   \mbox{\m@th%
    \if b\expandafter\@car\f@series\@nil\boldmath\fi
     \LaTeX\kern.15em2$_{\textstyle\varepsilon}$}}

So what does the \@car do?

Introduced in the Lisp programming language, car and cdr are primitive operations upon linked lists composed of cons cells.

When cons cells are used to implement singly-linked lists (rather than trees and other more complicated structures), the car operation returns the first element of the list, while cdr returns the rest of the list.

How does the @car work and what is @nil? As far as I can see, it is undefined, but does not give an error. It does not even give an error even if I define it as \def\@nil{illdefined!}, as shown in the code below.

\documentclass[11pt]{article} 

\usepackage{graphicx} 

\usepackage{verbatim}
\begin{document}

\bigskip
\makeatletter
\def\@nil{illdefined!}
\scalebox{5}{\LaTeXe}
\makeatother

\end{document}

More on CAR and CDR at the wikipedia

yannisl
  • 117,160

2 Answers2

29

The link to Lisp is quite true (it's mentioned somewhere in the sources, but I can't put my finger on it just now). The way this works is very simple. The definitions are

\def\@car#1#2\@nil{#1}
\def\@cdr#1#2\@nil{#2}

In this context, \@nil is being used as a delimiter, so what it expands to does not matter at all. This is a classic 'delimited argument' situation in TeX. (The only thing that is important is that TeX finds the appropriate token in the input stream, in this case before any \par tokens.) TeX will allow us one blank the last item of this type of delimited macro to be empty. As a result, both \@cdr and \@car need to have at least one token supplied: something like

\expandafter\@cdr\@empty\@nil

will give an error.

Notice that these are TeX functions, not Lisp ones, and so we get the first <balanced text> separated off from the rest.

Joseph Wright
  • 259,911
  • 34
  • 706
  • 1,036
  • In plain LaTeX, \@nil is undefined, isn't it? How do you get \@@nil? – Hendrik Vogt Nov 07 '10 at 16:01
  • Must be mistaken: I'm sure I've seen that somewhere, but I'll update the answer. – Joseph Wright Nov 07 '10 at 16:03
  • @Hendrik, I was thinking of \@nnil, which is used by the looping system in LaTeX2e and is defined \def\@nnil{\@nil}. – Joseph Wright Nov 07 '10 at 16:06
  • \meaning\@nil gives undefined, but does not seem to affect the scanning, since I defined it as \def\@nil{Illdefined!} and still prints the logo with no complaints. Will read Chapter 20 once more, and yes of course is not Lisp, but Lispy! – yannisl Nov 07 '10 at 17:04
  • on your last line: shouldn't it be the last <balanced text> rather than token? – Bruno Le Floch Jan 04 '11 at 19:20
18

To expand a bit on Joseph's answer: The \@nil is just a macro delimiter that is only seen when the arguments of \@car are scanned, and it is never expanded. For example \@car can be invoked by \@car123\@nil, and the result is 1, whereas \@cdr123\@nil yields 23. You cannot use \@car123; then TeX will continue to scan tokens since it want's to find the matching \@nil that is a required part in the invocation of \@car. As Joseph already pointed out, using \@car\@nil also gives an error.

For more info about this I recommend reading Chapter 20 in the TeXbook, in particular page 202.

Hendrik Vogt
  • 37,935
  • I was just adding a shorter bit of text about the same thing! – Joseph Wright Nov 07 '10 at 16:12
  • @Joseph: And your answer appeared when I was typing mine, so I could make it a bit shorter before posting ... – Hendrik Vogt Nov 07 '10 at 16:17
  • @Hendrik From what you describe, I guess any delimiter could have been used for example \def\@car#1#2]{#1} and then the list should have been `@car\f@series]'. – yannisl Nov 07 '10 at 17:19
  • 2
    @Yiannis Indeed, all that is important when TeX does scanning for delimited arguments is finding the appropriate token(s). So you can use whatever you like as the end marker, provided you (1) know it won't be in the real input, and (2) remember to include it as the end marker! – Joseph Wright Nov 07 '10 at 17:42
  • @Yiannis: And it's not just about end markers, but also about separators, so guess how you would invoke a macro defined by \def\stupid#1: #2(\whatever)#3{#3,#2,#1}. (Yes, also spaces can be used here.) – Hendrik Vogt Nov 08 '10 at 08:49
  • Also remember that the category code of the delimiters is important: you see this in things like LaTeX2e's \strip@pt system, where there is some work to do so that the delimiting 'pt' are not letters but 'other' characters. – Joseph Wright Nov 08 '10 at 19:29
  • In \@car c\@nil, what is the #2 of \@car, \empty, @nil, \relax? If #2 is \@nil, then what is the argument delimiter? – lyl Sep 18 '22 at 12:43