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.

In plain.tex, D.E.Knuth decided to define as \outer all the macros which allocate registers: \newcount, \newdimen, \newskip, \newread, \newwrite. This forbids them from entering the argument of macros, or definitions: they can only appear at the outer-most level.

On the other hand, Leslie Lamport has mostly dropped the \outer primitive when writing the LaTeX format. In particular, the allocation macros are not \outer anymore in his approach.

What are the advantages and drawbacks of both choices? What about other formats (ConTeXt, LaTeX3)?

As a side question: is there some historical piece of folklore associated to the \outer primitive?

share|improve this question
add comment

1 Answer

up vote 16 down vote accepted

The primary purpose for \outer is to catch errors, such as carelessly allocating registers or streams in a macro definition or forgetting the closing brace of a \long macro argument. One often sees

\newcommand{\xyz}[1]{...\newlength{\xyzlen}\setlength{\xyzlen}{#1}...}

which is bad programming; this can't happen in Plain TeX (with \newskip or \newdimen, of course) because those macros are \outer. Why is it bad programming? Because at each call of \xyz a new register called \xyzlen will be allocated and the old ones forgotten and unusable. One can think to \xyzlen as a variable that's allowed to receive a value: thus

\newlength{\xyzlen}
\newcommand{\xyz}[1]{...\setlength{\xyzlen}{#1}...}

would do the same work and be much more efficient.

One has to remember also that the original TeX had 256 registers of each type and only 16 input and output streams. So sparing them was essential and declaring the \new... macros as \outer helped in avoiding register misuse. It would be bad programming anyway, even now that e-TeX provides 32768 registers of each type.

However, \outer usage has some drawbacks: \outer macros can't appear in the middle of skipped conditional text, so

\ifdefined\xyzlen\else\newdimen\xyzlen\fi

is invalid in Plain (pdf)TeX, once \xyzlen has been defined.

Another example: it's hard to define Plain TeX macros on top of \beginsection or \proclaim, say to add automatic numbering.

In my opinion, allocation macros should be outer. There are a few cases where this can be a nuisance. For example, a package that defines new kinds of floats will use \newcounter in the definition. It would be easy to provide an "inner" version \@newcounter to be used in packages

\outer\def\newcounter{\@newcounter}
\def\@newcounter#1{<what LaTeX does now>}

Plain TeX, for instance, says \outer\def\+{\tabalign} so we can use \tabalign in definitions involving simple alignments. At least this will catch errors in defining commands by inexperienced users.

However there's always the old trick of saying (as I learned to do in the olden days)

\newcount\thmcnt
\def\theorem{\advance\thmcnt 1
  \csname proclaim\endcsname \number\thmcnt\ }}

that avoids TeX seeing the forbidden control sequence and \theorem would behave in a similar way to \proclaim. But anyone that knows about \csname qualifies as `experienced user', if not TeX wizard.

An alternative route is suggested by Bruno in his comment:

\edef\innerproclaim{\noexpand\proclaim}
\newcount\thmcnt
\def\theorem{\advance\thmcnt 1 \innerproclaim\number\thmcnt\ }}

that works because the expansion of \noexpand\proclaim is performed before assigning the result as the meaning of \innerproclaim and the \noexpand in front makes TeX see, at assignment time, a control sequence equivalent to \relax, that's allowed to be in a replacement text. Again, \edef and \noexpand cognoscenti qualify as experienced users.

share|improve this answer
2  
Great answer! :) –  Bruno Le Floch Nov 23 '11 at 16:58
1  
Agreed, I wish I could upvote it twice (still, my upvote is a marginal increase in egreg's rep anyway;)). –  mbork Nov 24 '11 at 0:11
add comment

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.