Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Any command sequence can be used to delimit a macro parameter. Even one that has not been defined. For example:

\def\YY#1,#2\@@{#1,#2}

\YY123,2345\@@

will happily work, even if the macro \@@ has not been defined.

In the LaTeX source there is an unusual macro, where the name of the macro itself was used as a delimiter. In simple terms the example below works, with no errors.

\def\XX#1,#2\XX{#1,#2}

\XX12,13\XX

Does this offer any memory or speed advantage or any other advantage for that matter?

Short MWE for experimentation is listed below:

\documentclass{article}
\begin{document}
\makeatletter
\def\YY#1,#2\@@{#1,#2}
\YY123,2345\@@

\def\XX#1,#2\XX{#1,#2}
\XX12,13\XX

\makeatother
\end{document}
share|improve this question
1  
I don't think that there are any advantages. Maybe the author didn't wanted to use an undefined macro nor define one just for this. –  Martin Scharrer Mar 31 '11 at 20:08
    
Well, it certainly doesn't waste a hash entry or any string pool on the delimiter, though I suspect that most of the time there is an existing control sequence that could be reused instead if that was an issue... –  SamB Mar 31 '11 at 20:09
    
@SamB: I don't think that macro tokens in the parameter text require a hash entry. There are never looked-up. The \@nil (undefined) and \@nnil (contains \@nil) are often used by LaTeX as end-markers. –  Martin Scharrer Mar 31 '11 at 20:18
1  
@Martin: I'd agree, as the hash table only contains things which are defined. Perhaps Yiannis might give us a clue as to the real case in hand, which might be enlightening! –  Joseph Wright Mar 31 '11 at 20:20
2  
@TH. You are right, no expansion. @Yiannis if the item you are searching for contains braces (e.g. Hef{}feron), then you must use strings. The only constraint on the delimiter is that it does not appear in #1#2. Also, that version of \in@ fails in some cases e.g. \in@false \in@{baba}{cba} \show\ifin@. –  Bruno Le Floch Mar 31 '11 at 23:51

2 Answers 2

up vote 15 down vote accepted

With inconclusive comments, I decided to look again for an explanation in the TeXBook, but with no success. However this led to another example. In the answer to exercise 24.6 Knuth shows how to make the control sequence \cs into an implicit space using \futurelet.

\def\\#1\\{}\futurelet\cs\\ \\

You can try this out with the minimal

\tt
\def\\#1\\{}\futurelet\cs\\ \\
% example
a.\cs b.c
\def\empty{}
% Trying with an empty macro
a.\empty b.c
\bye

The obvious next port of call was the original TeX source code itself. As Pascal is a typed language, my suspicion was that using delimiters in this manner, would conserve one string name.

Strings are defined in Part4, String Handling. All strings--as a matter of fact almost everything in TeX--are translated to integers and indexed. As far as TeX is concerned the name of a primitive macro or the string of an error message are no different they are all placed in str_pool.

When the original WEB system program called TANGLE processed the TEX.WEB file, it ouputted a Pascal program TEX.PAS (now it is CWEB and a C program) and also a string file called TEX.POOL which held all the strings used. The INITEX program read the latter file, where each string appeared as a two-digit decimal length followed by the string itself, and the information was recorded in TEX's string memory. INITEX would later on produce a binary format file which can subsequently be read at high speed by the TeX engine. (You can view the TEX.POOL file by searching for it in your distribution).

Given LaTeX's history, it made sense to use delimiters in this manner as it conserved one string.

I haven't looked carefully at the scanning routines for user-defined strings during normal typesetting operations i.e., without the source being passed through INITEX. In all probability the same mechanism is used and it is apparent that this will save some memory space, however little this is.

If one should use delimiters in such a manner is debatable as it tends to obscure the code and perhaps this is the reason for them being generally absent in packages. Rather two or three string names should be reserved for this purpose. If there is one exception I would make it would be for macros similar to the one Knuth defined:

 \def\\#1\\

It has a symmetry which one could argue has a certain beauty!

Special thanks to all the people that posted comments and especially to Lev Bishop for the additional example.

share|improve this answer
2  
The only response I can think of to this is: "Oh what a tangled web we weave when first we practise to ... program." –  Loop Space Apr 8 '11 at 7:49

In my opinion it does provide some advantage, specifically in order to capture the contents of argument-less macros where the macro is used repetitively. One practical example is taken from Order items in enumerate environment automatically where the repetitive use of \item in a list environment provides a means to delineate (or parameterize) the "argument" used. In general, an item in a list has the form

%...
\item <some stuff>
\item <some more stuff>
%...

or, more aptly written as

%...
\item <some stuff> \item
<some more stuff>
%...

which allows to be captured using

\def\item#1\item{<do something with #1>}

Sure you have to find a way to manage the end of the list, since the final item has no apparent ending \item to match the parameter text for the newly defined \item. That could be achieved by appending \item at the end of the environment after capturing its entire contents via the help of environ. More details on this in the linked post.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.