# Problems getting \expandafter\<controlsequence>\endgroup to work as expected

I have a scenario where I'm testing for a condition within a group which will then trigger inputting a corresponding outside file. The problem is that the outside file may contain control sequences that I later need. I tried to make sure the expansion was going to happen after closing the group as in the following example. (I've omitted the testing condition because this example nevertheless duplicates my error.)

\begin{filecontents}{anotherfile}
\def\aemoon{This is the moon}
This is my other file.
\end{filecontents}

\documentclass{article}

\begin{document}

Testing

\begingroup
\def\helloworld{\input{anotherfile}}
\expandafter\helloworld
\endgroup

\aemoon

\end{document}


But this results in an error

! Undefined control sequence.
l.17 \aemoon


The same thing happens below where there's no need to input an outside file

\documentclass{article}
\begin{document}

Testing

\begingroup
\def\helloworld{\newcommand\aemoon{this is the moon}}
\expandafter\helloworld
\endgroup

\aemoon

\end{document}


In either example, I was expecting that the command \aemoon was getting defined outside of the group on account of \expandafter. (\aftergroup will clearly not work since after the group \helloworld has not been defined.)

Thinking back to my original situation where I'm inputting another file, I know I could write something like

\begin{filecontents}{anotherfile}
\def\aemoon{This is the moon}
This is my other file.
\end{filecontents}

\documentclass{article}

\begin{document}

Testing

\begingroup
\gdef\helloworld{\input{anotherfile}}
\endgroup
\helloworld

\aemoon

\end{document}


So, I do have a work around. But I would like to know why the first two examples are not working because my understanding is that the expansion should be happening outside the group, but...

So, what is happening here?

-
I'm not sure what would be the reason for the group. Can you think of one? – egreg Jan 8 at 19:08
@egreg In this MWE there's no need except to create the situation I'm facing. In the real deal, I'm doing a number of tests etc. and defining a number of temporary control sequences for this and that for which I felt a group was the ideal way to proceed. But then I needed a way of getting some information out of the group in a context where definitions may not be global. – A.Ellett Jan 8 at 19:41
Be careful that with Hood Chatham's (good) technique, you only get the first level expansion of \helloworld and then the group ends, destroying all assignments made inside it. So, if you say \begingroup\ifbla\def\foo{bla}\else\def\foo{bar}\fi\def\gnu{A \foo}\expandafter\endgroup\gnu you'll be in trouble. – egreg Jan 8 at 22:08
@egreg Good point. Nothing of the sort will happen since mostly the machinations inside the group are to determine which file to input. – A.Ellett Jan 8 at 23:42

You should say:

\begingroup
\def\helloworld{\newcommand\aemoon{this is the moon}}
\expandafter
\endgroup\helloworld



You probably confused this situation with the case where there's a command in a conditional that takes an argument, and you don't want it to use \fi or \else and the false clause as its argument so you say: \ifsomething \expandafter\somecommand\fi. Since \else and \fi are fully expandable and when expanded delete themselves (and in the case of \else the false clause), this fixes that problem.

The problem with saying \expandafter\helloworld\endgroup is that \endgroup is not expandable, so the result is the \expandafter expands the \endgroup, which changes it not at all -- \endgroup acts like a } here. Then what TeX sees is \mycommand\endgroup, which doesn't do what you want.

Roughly speaking, TeX has two stages of evaluation -- expansion, where it takes macros and repeatedly expands them, and evaluation, where it takes unexpandable primitives (either characters or commands like \bgroup, \relax, \def, \show etc) and evaluates them. \expandafter only interacts with the expansion stage. Many nonintuitive behaviors of TeX result from this expansion evaluation distinction.

However, even if \expandafter\helloworld\egroup did behave as you expected, it would not be right, because that would then be the same as saying \egroup\helloworld, which would cause an error because the definition of \helloworld went out of scope.

-
Very nice. This is a solution. But, it still leaves my question unanswered. Why is \expandafter\helloworld\endgroup not doing what I think it should be? – A.Ellett Jan 8 at 18:47
That is definitely the case I was thinking of. – A.Ellett Jan 8 at 18:55
I'll try to add a bit more detail as to why they are different -- it's actually quite subtle and confusing. – Hood Chatham Jan 8 at 18:57
Thank you for your very informative explanation. – A.Ellett Jan 8 at 20:01

\endgroup is not expandable, which makes

\begingroup
\def\helloworld{\newcommand\aemoon{this is the moon}}
\expandafter\helloworld
\endgroup


equivalent to

\begingroup
\def\helloworld{\newcommand\aemoon{this is the moon}}
\helloworld
\endgroup


As such, \helloworld is defined, executed and then everything within the group that isn't \global does not survive. This includes \aemoon. You may consider an alternative

\begingroup
\def\helloworld{\endgroup\newcommand\aemoon{this is the moon}}
\helloworld


where \helloworld ends the group implicitly, leaving \aemoon still defined.

-
Hmmm. I like this approach. – A.Ellett Jan 8 at 19:02
@A.Ellett: The approach is similar to the commonly-used \begingroup \edef\x{\endgroup <xxx>}\x technique to expand <xxx> but not keep the definition of \x. – Werner Jan 8 at 19:05
which is exactly why I like it so much – A.Ellett Jan 8 at 23:43
   \expandafter\helloworld\endgroup


applies \expandafter to \endgroup that is not an error but it does nothing as \endgroup is not expandable so it is equivalent to

  \helloworld\endgroup


So \helloworld acting inside the group is the expected behaviour.

-