30

Why don't we always use \long\def instead of \def? It seems that \long\def is more complete than \def.
By the way, I know the difference between these two commands.

1

2 Answers 2

30

We do. \newcommand is \long by default; if you want un-long macros, you have to use \newcommand*.


A more philosophical answer: \long is one of the several error-catching mechanisms that Knuth built into TeX. Or rather, not using \long allows TeX to catch missing-brace errors where the argument of a macro would appear to span multiple paragraphs; that's where the "runaway argument" errors come from. So using \long by default means that you may use up TeX's memory before finding an error.

This is similar to my answer to this question about \outer, which has a similar purpose in buck-stopping out-of-control code. My conclusion there was that \outer reflects an obsolete prioritization of computer resources versus human resources, and I believe that I will make the same judgment of \long here. It appears that in both cases, the authors of LaTeX take this position as well.

6
  • Can you please give me a simple example where \def MUST be used instead of \long\def? I mean if \long\def is used, one gets into trouble. Commented Dec 27, 2011 at 22:49
  • 1
    @Vahid: You never have to use it. Presumably code of the form \def\macro#1{} \macro{*\par<enormous amounts of text with no unbalanced closing brace> will do you in. It depends how big TeX's memory capacity is and how much patience you have in trying to write that much or program something to do it for you.
    – Ryan Reich
    Commented Dec 27, 2011 at 23:05
  • 8
    One place you do need \def is if you want to do an \ifx comparison against another macro which is not long. The \ifx will only be true if the two macros are identical in definition, which applies even if the macro takes no arguments (and so the long concept makes no practical difference).
    – Joseph Wright
    Commented Dec 27, 2011 at 23:08
  • 10
    there's almost no MUST with tex. but if you want to save debugging time and headaches, you'll learn soon enough that it's a good idea to avoid making everything \long. having once spent hours debugging program-generated files comprising a membership list of over 30,000 addresses to find an unmatched brace, i scrapped the brace-enclosed argument approach for arguments delimited by a character that would never appear in the data. (no paragraphs in that data, unfortunately.) it's the same principle -- limit your exposure. Commented Dec 27, 2011 at 23:08
  • 3
    @RyanReich I'm thinking in general terms: for example, some LaTeX internal storage macros are long and some are not. So if you want to compare reliably with them then you need to check, and if you change the values of someone else's code should retain the appropriate long status.
    – Joseph Wright
    Commented Dec 27, 2011 at 23:17
15

Let me put my LaTeX3 hat on before Joseph does. [But Joseph, feel free to edit.]

The current plan for LaTeX3 is to make almost all macros long. The first aspect of that is at the level of defining macros: by default, macros are \long, and you need to type the extra _nopar to make them non-long "no-\par". For instance,

\cs_set:Npn                  = \long \def
\cs_set_nopar:Npn            =       \def
\cs_gset_protected:Npx       = \long \protected \xdef
\cs_gset_protected_nopar:Npx =       \protected \xdef

The second aspect is the convention that we have recently (i.e., perhaps not yet on CTAN?) enforced in the kernel about which macros are long and which are not. Clearly, you never want to do \newcount\par (in LaTeX3 coding conventions, \int_new:N\par), so until recently we had defined \int_new:N to be short. However, the error that you get in that case is not very enlightening anyways, and other cases are not so clear cut. Thus, we decided that every macro that takes parameters would be \long, and parameterless macros should be _nopar.

The third aspect is the user interface, currently covered by xparse. Only there does it make sense to try and catch missing braces and other "runaway" arguments. At this level, we keep \long and non-\long arguments, adding + before \long arguments in the specification: for instance,

\NewDocumentCommand{\foo}{ m +m }
  { \section{#1} {\bfseries #2} }

creates a macro \foo with a short first argument and a long second argument.

You must log in to answer this question.

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