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.

By a too quick search/replace of "mathcal" by "mc" I ended up with a loopy or recursive statement like


It seems to cause the compilation of my document to hang. Is this a known bug? (Why has it not been fixed?)

share|improve this question
I guess it could be considered a bug, but you are trying to define something in terms of itself. If you want to change the defintion of \mc use \let\OldMc\mc and then \newcommand{mc}{\OldMc}, and make any changes as required. –  Peter Grill Apr 8 at 19:51
It's not a bug. TeX just dutifully follows its rules; you're asking that \mc is substituted with \mc which then is substituted by \mc… No error, no memory filling, no hanging process: just an everlasting run. –  egreg Apr 8 at 19:55
Sure, but ideally there should be some check against this sort of thing –  Bjørn Kjos-Hanssen Apr 8 at 19:58
It's the halting problem. There is no check possible in general. But any programming language allows you to write a non terminating loop: C java javascript python.... –  David Carlisle Apr 8 at 19:59
@HenriMenke It would just \relax. ;-) –  egreg Apr 8 at 20:09

2 Answers 2

up vote 5 down vote accepted

It is possible to define a macro in terms of itself. As mentioned in the comments, you need to be careful. The problem with \newcommand\mc{\mc} does not occur when it's defined but when you first try to use it, at which point, if left as is, it will recursively call itself. Sometimes this is the behavior you want.

But sometimes you want something else, in which case you can use one of the powerful \edef and \xdef to create what you want.

Here's a completely trivial example which illustrates building a tabular environment from a list of elements. The content of the tabular environment is built up from what was previously defined: in other words \ae@tabular@content is defined in terms of itself, but precautions are taken not to expand too much (hence the use of tools from etoolbox.


  \foreach \myx/\myy in {#1}  
    \xdef\ae@tabular@content{\expandonce\myx & \myy }%%
    \xdef\ae@tabular@content{\expandonce\ae@tabular@content \noexpand\\ \expandonce\myx & \myy }%%




to produce

enter image description here

Sometimes you may want to make a recursive call to trim (or do something else). This next example takes in a string and throws away tokens until it comes to the first occurence of E in the string. If there is no E, then it just restores the original string.

  #1 $\rightarrow$ \ae@striptoE#1\@nil

      (unchanged) \ae@old





enter image description here

share|improve this answer
& is not expandable, so \noexpand& does nothing more than & alone. What's \ae@newcol for? –  egreg Apr 8 at 21:07
@egreg. Hmm. I've had problems in the past with &.... now I don't remember what those are. I'll clean the code. –  A.Ellett Apr 8 at 21:11

The declaration \newcommand{\mc}{\mc} ultimately becomes, in terms of TeX primitives,


where \long is irrelevant for the case in discussion.

You have to consider that TeX doesn't interpret in any way the replacement text of a macro when it stores the definition for it. It's a necessary feature, because when we expand a macro, we want that the macros in the replacement text use their current meaning, not what was valid at definition time, when they even need not be defined!

To make a silly example, consider the macro definition


In LaTeX, the macro \\ changes its meaning in several occasions; it means something at the outer level, something else when a declaration such as \centering or \raggedright is in force and has a very different meaning when inside array, tabular or tabbing.

This is wanted! The user has to know just that \\ causes a line break. Then \mybreak can be used in any situation where \\ can be given, because the \\ token in the replacement text will be interpreted (expanded and executed) at call time.

Here's an example from the TeXbook:

\def\hex{{\count0=\n \divide\n by16
  \ifnum\n>0 \hex\fi \count2=\n \multiply\count2 by-16
  \advance\count0 by\count2 \hexdigit}}
\def\hexdigit{\ifnum\count0<10 \number\count0
  \else\advance\count0 by-10 \advance\count0 by`A \char\count0 \fi}

The token \n is supposed to be a count register. As you see, the macro \hex has a replacement text calling \hex itself; however at every call the value of \n will decrease, so eventually the call of \hex, which happens in the true branch of a conditional, will not take place and the macro's work will come to a happy ending.

Thus, a simplistic check that the replacement text of a macro doesn't contain the macro itself can't be implemented, because it would make recursion much more difficult, if not impossible.

This of course has a price: your definition causes TeX, when it finds \mc to replace \mc with \mc, which then it replaces with \mc… Bingo! Infinite loop. The program doesn't hang: it's just dutifully replacing a token with itself without using up resources in the computer; no error will be raised, because there's nothing wrong, from the point of view of the machine, which just follows the rules.

A different case would be


Now at the first call of \mc some part of TeX's memory would fill up, in this case the “input stack”, which is assigned a size of 5000 by TeX Live 2013 (simultaneous input sources): the expansion of \mc pushes the first ( on the stack while expanding \mc, which pushes ( on the stack while expanding \mc… Another infinite loop, but this one fills the memory.

Assuming \mc is originally defined as a parameterless macro, adding parentheses to either end of its replacement text can be accomplished by


because the chain of \expandafter's will put a finger inside the replacement text before the definition is performed. In this case, however, the new replacement text will not contain \mc (assuming it didn't in the original definition).

An equivalent construction would be


but this would take us too far (it need e-TeX, so it's not available with Knuth's TeX).

share|improve this answer

Your Answer


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.