1

Recently I discovered a piece of code (from ucharclasses) using three expansion-related macros \noexpand, \unexpanded and \expandafter:

\def\do#1{\noexpand\setTransitionsFor{#1}{####1}{####2}}
\def\doclass#1{
  \begingroup\edef\x{\endgroup
    \noexpand\newcommand
    \unexpanded\expandafter{\csname setTransitionsFor#1\endcsname}[2]%
    {\csname #1Classes\endcsname}}\x}
\ClassGroups

I can find some references about these macros, but I still don't understand what they are doing exactly. I'd like to know why they are necessary in the above piece of code, and why would we ever need four sharps as in ####1 and ####2.

  • Here's an excellent tutorial on \expandafter: TUGBoat 9(1):57-61, 1988. – John Jun 26 at 20:38
  • @John OK. So \expandafter knows about \csname and \endcsname. That's a case explicitly listed. But in this piece of code there's unexpanded before \expandafter that still looks confusing. – Cyker Jun 26 at 20:44
  • 1
    David Carlisle has given a great answer, below. To reply to your comment, the role of \unexpanded is discussed in this thread. – John Jun 26 at 21:37
2

\do shows \noexpand and ##

\def\do#1{\noexpand\setTransitionsFor{#1}{####1}{####2}}

\edef\z{\do{abc}}
\show\z

this shows

> \z=macro:
->\setTransitionsFor {abc}{##1}{##2}.
l.4 \show\z

So you see that in defining \z with \edef the csname \setTransitionsFor was prevented from being expanded by the \noexpand , #1 got replaced by the argument to \do which is abc here and ## got replaced by #

For the second macro, adding \show\x then running this fragment with pdflatex

\def\doclass#1{
  \begingroup\edef\x{\endgroup
    \noexpand\newcommand
    \unexpanded\expandafter{\csname setTransitionsFor#1\endcsname}[2]%
    {\csname #1Classes\endcsname}}%
    \show\x
    \x}

\doclass{abc}

produces

> \x=macro:
->\endgroup \newcommand \setTransitionsForabc [2]{\abcClasses }.
\doclass ...csname #1Classes\endcsname }}\show \x 
                                                  \x 
l.9 \doclass{abc}
                 
? x

so after the \show the temporary macro \x will be executed and be equivalent to

\newcommand \setTransitionsForabc [2]{\abcClasses }

so the string abc that was passed to \doclass has been used to construct both the commandnames \setTransitionsForabc and \abcClasses

| improve this answer | |
  • Can we say \noexpand protects the next one token, while \unexpanded protects the entire token list between { and }? – Cyker Jun 27 at 7:22
  • 1
    @Cyker yes, exactly.noexpand is classic Tex , unexpanded is an etex addition. – David Carlisle Jun 27 at 7:25
  • And there seems to be another trick in this code: The use of \begingroup and \endgroup is meant to hide the definition of \x so that it doesn't pollute the current scope? – Cyker Jun 27 at 7:26
  • @Cyker you are getting the hang of this:) yes – David Carlisle Jun 27 at 7:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.