1

According to this answer \protect\foo expands to something like \noexpand\protect\noexpand\foo when it gets saved to a macro (e.g. in a context like a beamer frame). I think \protected\def basically just places \protect in front of every instance of the macro. If not, what does it do? If so why does \expandafter in a protected macro applied to an argument work correctly?

The rest is just provided for clarification. I'm trying to understand what \protected does and felt the example might help explain what I'm asking.

For instance, the command defined below works fine even in beamer frames but if I think about what happens if I replaced \Tdeg{\zeron{5}} with \noexpand\protect\noexpand\Tdeg{\zeron{5}} wouldn't the result be to expand the argument \zeron{5} before it caught by the \expandafter in \Tdeg? If so why does this still work (i.e. output A not B) when I run it inside a beamer frame?

\def\zeron#1{0^{#1}}
\def\first@pmg@rdmxs(#1#2){#1}
\protected\def\Tdeg#1{\ifthenelse{
           \equal{\string \zeron }{\expandafter\string \first@pmg@rdmxs(#1)}
            {A}
            {B}}
egreg
  • 1,121,712
  • Sorry, but it's still the same problem: how can we test this without a full example? – egreg Oct 28 '21 at 17:49
  • But I don't want to know what the code does or to fix it. I want to understand how \protected works with macro arguments. The only point of the code is that I can use \expandafter on an argument in a protected macro and it sometimes seems to delay the expansion even in contexts where protected isn't \relax.

    If that isn't clear enough from the post just delete the post as I've failed to communicate utterly as the only point of the code was to illustrate how one might incorrectly reason about \protected.

    – Peter Gerdes Oct 28 '21 at 17:57
  • neither \protect not \protected deal with arguments at all. as you say if you use \protect\Tdeg{\zeron{5}} in an expansion context, the expansion of \Tdeg will be suppressed but \zeron{5} will expand. But you haven't shown any \Tdeg being used in such a context (or any context) – David Carlisle Oct 28 '21 at 18:19

2 Answers2

2

\protected is unrelated to the LaTeX macro \protect it sets a flag on a macro similar to \long but otherwise has no effect at the point of definition.

so

\def\foo{zzz \textbf{x}}
\show\foo

\long\def\foo{zzz \textbf{x}} \show\foo

\protected\def\foo{zzz \textbf{x}} \show\foo

produces

> \foo=macro:
->zzz \textbf {x}.
l.3 \show\foo

? > \foo=\long macro: ->zzz \textbf {x}. l.6 \show\foo

? > \foo=\protected macro: ->zzz \textbf {x}. l.9 \show\foo

However when used in an expansion-only context such as \edef or \write a protected macro acts like \relax and does not expand.

So...


\documentclass{article}

\begin{document}

\def\foo{zzz \textbf{x}} \immediate\write20{1: \foo}

\long\def\foo{zzz \textbf{x}} \immediate\write20{2: \foo}

\protected\def\foo{zzz \textbf{x}} \immediate\write20{3: \foo}

\end{document}

Produces

1: zzz \protect \unhbox \voidb@x \bgroup \def l3backend-pdftex.def{x}\let \futu
relet \@let@token \let \protect \relax \edef cmr{cmr}\edef cmss{cmss}\edef cmtt
{cmtt}\def ##1,b,{}\series@check@toks {,ulm,elm,lm,slm,mm,sbm,bm,ebm,ubm,muc,me
c,mc,msc,msx,mx,mex,mux,{}{},b,}\edef {}\edef b{b}\def ##1,m,{}\series@check@to
ks {,ulm,elm,lm,slm,mm,sbm,bm,ebm,ubm,muc,mec,mc,msc,msx,mx,mex,mux,{}{},m,}\ed
ef {}\edef m{m}\protect \let 
2: zzz \protect \unhbox \voidb@x \bgroup \def l3backend-pdftex.def{x}\let \futu
relet \@let@token \let \protect \relax \edef cmr{cmr}\edef cmss{cmss}\edef cmtt
{cmtt}\def ##1,b,{}\series@check@toks {,ulm,elm,lm,slm,mm,sbm,bm,ebm,ubm,muc,me
c,mc,msc,msx,mx,mex,mux,{}{},b,}\edef {}\edef b{b}\def ##1,m,{}\series@check@to
ks {,ulm,elm,lm,slm,mm,sbm,bm,ebm,ubm,muc,mec,mc,msc,msx,mx,mex,mux,{}{},m,}\ed
ef {}\edef m{m}\protect \let 
3: \foo 

Where you see that \foo doesn't fare well in a \write (and \protect would not help as normally it is \relax and only has the special definition within \typeout, \protected@write and similar latex constructs) but the \protected version of \foo stays as \foo in the \write.

David Carlisle
  • 757,742
0

The LaTeX \protect mechanism and the e-TeX \protected one work differently. A macro defined using \protected\def will not expand inside an \edef or similar context, but otherwise is exactly the same as one defined using \def. In contrast, \protect uses a token of variable definition to avoid expansion in some places: this requires 'opt-in' processing (\protected@edef or similar) to 'active' this mechanism.

Joseph Wright
  • 259,911
  • 34
  • 706
  • 1,036