# "Clever tricks" for using \outer macros

From TeX by Topic, p. 111:

For certain applications, however, it is inconvenient that some of the plain macros are outer, in particular macros such as \newskip. One remedy is to redefine them, without the outer' option, which is done for instance in LaTeX, but cleverer tricks are possible.

What are examples of such tricks for using \outer macros where they are not usually allowed?

• 'Don't use them' ;) Mar 19, 2020 at 11:11

As egreg said, the standard way is with \csname: as long as there is no \outer token at the time of the definition, you are safe.

So another possibility is, in a group, make the macro non-outer, define your macro, and then reset everything:

\begingroup
\let\newdimen\relax
\gdef\makedimenandgivevalue#1#2{%
\newdimen#1%
#1=#2\relax}
\endgroup


The problem with this version is that if you need to pass the \outer macro as argument to an auxiliary, you can't. A handier version is to define a non-outer wrapper to the \outer macro, then you can use it freely:

\edef\mynewdimen{\noexpand\newdimen}
%
\def\makedimenandgivevalue#1#2{%
\mynewdimen#1%
#1=#2\relax
}


The standard trick is \csname:

\def\makedimenandgivevalue#1#2{%
\csname newdimen\endcsname#1%
#1=#2\relax
}


Or \noexpand:

\edef\myproclaim#1#2\endmyproclaim{\noexpand\proclaim #1. \ignorespaces #2\par}

\myproclaim{Theorem}
This is better syntax.
\endmyproclaim

\proclaim Theorem.
This is worse syntax.

\bye


The famous \cleartabs, \settabs and \+ macros from plain.tex show one such trick (TeXbook p. 354):

\let\+=\relax % in case this file (plain.tex) is being read in twice
\def\sett@b{\ifx\next\+ \let\next=\relax % turn off \outerness
\def\next{\afterassignment\s@tt@b\let\next}%
\else\let\next=\s@tcols\fi\next}

...

\outer\def\+{\tabalign}

1. \let\+=\relax is done before defining \sett@b in case \+ would already be an \outer token (otherwise, the \+ token in the replacement text of \sett@b would cause an error when \sett@b is defined).

2. When the \ifx\next\+ test is true during normal usage of \settabs in the document, \next is an \outer token since in normal usage, \+ is \outer. Thus, Knuth does \let\next=\relax before redefining \next with \def\next{\afterassignment\s@tt@b\let\next}, otherwise the \next token at the end of the replacement text in this definition would cause an error.

• +1 I love the irony ...
– wave
Mar 20, 2020 at 6:22
• Regarding “famous”? Well, these macros are famous for being the most difficult to understand in plain.tex. :) Mar 20, 2020 at 8:19
• no, just the fact that Knuth himself had to get rid of his own \outer definition due to the inconveniences coming along with it :D
– wave
Mar 20, 2020 at 8:30
• Ah, that way. :-) (Security is almost always antagonist to convenience, you know... for some special TeXish definition of security here) Mar 20, 2020 at 8:35

For luatex, there is

\suppressoutererror = 1


which makes the entire issue go away.

You can use it globally or just locally in a group while you make the required definitions.

If \outer-tokens are "hit" by \noexpand, they will be turned into \relax (only) for the next expansion:

\documentclass{article}

\outer\def\myoutermacro{My outer macro's definition.}

\def\FirstOfOne#1{#1}%

\newtoks\myscratchtoks

\begin{document}

% This does not work:
%
% \FirstOfOne{\myoutermacro}.
%
% These do work:

\expandafter\FirstOfOne\expandafter{\noexpand\myoutermacro}

\myscratchtoks\expandafter{\noexpand\myoutermacro}
\FirstOfOne{\the\myscratchtoks}

\edef\myscratchmacro{\noexpand\myoutermacro}
\FirstOfOne{\myscratchmacro}

\end{document}
`