# Variable scoping in newcommand

Consider this example:

\documentclass{article}
\begin{document}
\def\something{something}
\something

{
\def\something{another thing}

\something
}

\something
\end{document}


From the output it can be seen that there are two variables something each living in their own scope:

Now, I put a variable to live inside a newcommand:

\documentclass{article}
\def\something{something}
\newcommand{\dosomething}{
invoking dosomething''
\def\something{another thing}

\something
}
\begin{document}
\something

\dosomething

\something
\end{document}


From output it can be seen that invoking the newcommand altered the previous definition of the variable:

This can lead to obscure errors particularly with libraries involving hundreds of variables. Is there a way to protect my variables from being altered by newcommands? What is the best approach?

• a macro is just expanded inline essentially as a textual replacement, it implies no grouping itself. You can of course define the replacement text of the command to include a group, But mixing \def and \newcommand in the same code is likely to lead to obscure errors clearer to stick to primitive constructs or latex ones, not a mixture of the two. – David Carlisle Dec 2 '19 at 11:14
• @campa better to use the more explicit \begingroup and \endgroup, imho. – Skillmon Dec 2 '19 at 11:14
• Your macros can have names from which you can see what they (are intended to) do. E.g., instead of \dosomething you could name the thing \WithinTheCurrentScopeTurnSomethingIntoAnotherThing. At first glimpse long macro names which have a semantical aspect as they explain what the thing does seem cumbersome. But they can be very nice when the need of debugging arises. – Ulrich Diez Dec 2 '19 at 20:27

TeX offers a macro expansion mechanism; the macro is replaced by the replacement text. Therefore, with your current definition

\newcommand{\dosomething}{
invoking dosomething''
\def\something{another thing}

\something
}


the document

\begin{document}
\something

\dosomething

\something
\end{document}


is effectively equivalent to

\begin{document}
\something

invoking dosomething''
\def\something{another thing}

\something

\something
\end{document}


(plus a couple of trailing spaces you have been somewhat careless about :-))

If you want changes to \something to be restricted to the execution of \dosomething you must include a level of grouping, either with explicit braces {...} or (more readable) with the primitives \begingroup/\endgroup

\newcommand{\dosomething}{% <-- don't forget this
\begingroup
invoking dosomething''%
\def\something{another thing}%

\something
\endgroup
}