[comp.text.tex] removing \outerness

em@dce.ie (Eamonn McManus) (01/07/91)

In a TeXhax digest some time ago (1988 I think) I wrote a tirade
complaining about the painfulness of \outer, or at least the unreasonable
number of macros so marked in Plain TeX.  LaTeX removes the \outerness of
several of the macros it has in common with Plain TeX, so I'm not the only
person to feel this way.  In any case, here's my unouter.tex that excises
\outerness from Plain TeX:

% unouter.tex - remove the concept of \outer from plain TeX
% By Eamonn McManus Nov 88.  This file is not copyrighted.

% This macro removes the outerness of the control sequence \csname#1\endcsname
% by copying it to \csname un*#1\endcsname and then defining
% \csname#1\endcsname to be a macro that expands to that.  For example,
% after \unouter{proclaim}, we have: \proclaim=macro:->\un*proclaim .
% and \un*proclaim=\outer macro:->[original definition of \proclaim] .
% It would be nice if we could avoid this extra level, but I know of no way
% of doing that short of writing the \meaning to a file and reading that in
% again (yeuch).
\def\unouter#1{\toks0=\expandafter{\csname un*#1\endcsname}%
	\edef\next{\let\the\toks0=}\expandafter\next\csname#1\endcsname
	\expandafter\edef\csname#1\endcsname{\the\toks0}}

% In the case where the macro has no parameter text, we can unouter it
% directly by putting its expansion into a token list and redefining it
% in terms of that expansion.
\def\simpunouter#1{%
	\toks0=\expandafter\expandafter\expandafter{\csname#1\endcsname}%
	\expandafter\edef\csname#1\endcsname{\the\toks0}}

% ^^L is defined as \outer\par
\let^^L=\par

% Change everything else defined as \outer.
\simpunouter{newcount} \simpunouter{newdimen} \simpunouter{newskip}
\simpunouter{newmuskip} \simpunouter{newbox} \simpunouter{newtoks}
\simpunouter{newread} \simpunouter{newwrite} \simpunouter{newfam}
\simpunouter{+} \simpunouter{bye}
\unouter{newhelp} \unouter{newif} \unouter{beginsection} \unouter{proclaim}

% \unouter no longer needed, and remove the offending primitive!
\let\unouter=\undefined \let\simpunouter=\undefined \let\outer=\relax

\endinput

xiaofei@acsu.buffalo.edu (Xiaofei Wang) (01/08/91)

In article <outrocity@dce.ie> em@dce.ie (Eamonn McManus) writes:
* In any case, here's my unouter.tex that excises
* \outerness from Plain TeX:

The \outer does all harm but no good? 
Why should Knuth have defined it? and carried along with TeX3.0 distribution?

eijkhout@s41.csrd.uiuc.edu (Victor Eijkhout) (01/08/91)

xiaofei@acsu.buffalo.edu (Xiaofei Wang) writes:

>The \outer does all harm but no good? 
>Why should Knuth have defined it? and carried along with TeX3.0 distribution?

The idea behing \outer is sensible. It's just that Knuth chose to
make some macros (\newetcetera) \outer that he shouldn't have.
In LaTeX these macros are redefined to be non-\outer.
Note that LaTeX has first the \outer definitions, and then
the redefinition withouth \outer. Talking of efficiency.

Victor.

em@dce.ie (Eamonn McManus) (01/10/91)

eijkhout@s41.csrd.uiuc.edu (Victor Eijkhout) writes:
>The idea behind \outer is sensible. It's just that Knuth chose to
>make some macros (\newetcetera) \outer that he shouldn't have.

My principal concern about \outer is indeed that too many Plain macros are
marked that way (\proclaim is another inexplicable example).  \outerness
provides a useful way of stopping runaway definitions and the like, but
the other problem is that there is no easy way to include an \outer macro
when you really do want it.  Admittedly the religious fervour with which
unouter.tex excises \outerness is a bit extreme.

I went to the effort to retrieve my original TeXhax article and an
interesting reply to it, which I include here.  The reply shows a simpler
way of getting around \outer than my unouter.tex macros.

Note that METAFONT allows the outerness of a macro to be switched on and
off independently of its definition.  This is a better design.

,
Eamonn

---------------------------------------------------------------------

To: TeXhax Digest <TeXhax@cs.washington.edu>
Subject: \outer considered painful
Lines: 58
Date: Tue, 10 Jan 89 17:13:29 +0000
From: Eamonn McManus <emcmanus@cs.tcd.ie>

Am I alone in thinking that \outer macros are a mistake in the design of
TeX?  There are no macros marked so in plain.tex that I couldn't imagine
wanting to use in the definition of another macro.  About the only thing
I can think of that should be \outer is the end of file, or maybe ^^L as
well.  I can't see why I should not be able to define a macro that makes
use of \newcount, or use \beginsection or \proclaim in conditional text.
The additional diagnostic information provided by \outerness cannot make
up for its painfulness to macro writers (OK, so I'm a macro writer).

I'm inclined to think Leslie Lamport would agree with me, given that the
LaTeX package doesn't define any new \outer macros, and it must redefine
some existing ones so it can use them in other macros.  A \nonouter that
could be placed before \outer macros to cancel their \outerness just for
that occurrence would be enough to make me happy.  Failing that, here is
a TeX source that redefines all of Plain's \outer macros not to be.  Any
better technique that accomplishes this for macros with parameters would 
interest me greatly.

--
Eamonn McManus				emcmanus@cs.tcd.ie
Distributed Systems Group, TCD		...!uunet!mcvax!cs.tcd.ie!emcmanus

[unouter.tex appeared here]

---------------------------------------------------------------------

Date: Wed, 1 Feb 89 13:26 EST
From: "Jerry Leichter (LEICHTER-JERRY@CS.YALE.EDU)" <LEICHTER@venus.ycc.yale.edu>
Subject: re: \outer definitions
To: emcmanus@cs.tcd.ie, TEXHAX@june.cs.washington.edu

In a recent TeXhax, Eamonn McManus complains that \outer macros are more
trouble than they are worth, and provides a means of "un-\outer'ing" a macro
definition.
     
I won't get into the debate on how valuable \outer is - to each his own - but
I do offer a much simpler way to get the "\outer'ing" effect he desires, which
is most useful when you want to keep the \outer form around but have a new
non-\outer form as well.
     
Here is a particular example, from which a general solution can be built.
Suppose you want a \declareif, which is the same as \newif but is NOT \outer.
(I wanted this as an extension to J E Pittman's set of \declarexxx macros.)
You can define it easily by doing:
     
    {\let\newif\relax \gdef\declareif{\newif}}
     
(Technically, \declareif is not "the same" as \newif - it requires an extra
level of expansion.  For most purposes, this should be fine.)
     
                            -- Jerry