# Saving a value between successive macro calls

I want to save a variable value between calls of a macro, the intention being not to have to repeat a whole lot of parameters in successive calls. It all works as intended if in textmode. If I invoke mathmode individually for each call, i.e. $\myMacro$, which is what I want to do, the variable is reset for each call. Is there a workaround?

\documentclass{article}
\usepackage{xparse}
\usepackage{amsmath}
\ExplSyntaxOn
%   VARIABLE DECLARATIONS:
\tl_new:N \savevar_rn_tl
\tl_set:Nn \savevar_rn_tl {INIT}
\NewDocumentCommand\myMacro{O{1}O{Z}}
{
!*\tl_use:N \savevar_rn_tl*!        \\
\str_case:nn {#1}
{
{1}
{
#2\\
\tl_set:Nn \savevar_rn_tl {#2@#2}
}
{2}
{
\tl_use:N \savevar_rn_tl \\
\tl_set:Nn \savevar_rn_tl {RESET}
}
}
}
\ExplSyntaxOff
\begin{document}
\section{The way I want to use it, but savevar is not preserved between calls:}
$\myMacro$\\
$\myMacro[2]$\\
$\myMacro[1][\alpha]$\\
$\myMacro[2]$\\
\section{savevar is preserved between calls, but only if calls are made in textmode:}
\myMacro\\
\myMacro[2]\\
\myMacro[1][W]\\
\myMacro[2]\\
\end{document}

• I think, this is an grouping issue. Use \tl_gset:Nn – user31729 Sep 13 '15 at 7:54
• I'm not sure what's the purpose of saving the value Z as Z@Z. – egreg Sep 13 '15 at 9:30
• @egreg Just for the purpose of the MWE - an easily recognisable value to see if it is preserved correctly. – Reinhard Neuwirth Sep 13 '15 at 10:06
• Instead of two optional arguments, you could use \myMacro where you now use \myMacro[1] and \myMacro* for the “use and reset case”. This way you don't have to use [1] when you need the optional argument. So the calls would be $\myMacro$ $\myMacro*$ $\myMacro[\alpha]$ $\myMacro*$. – egreg Sep 13 '15 at 10:12

Switching to math mode enters a group, so \tl_set:Nn sets the value only within the group, but not outside. If the value should be preserved, \tl_gset:Nn (global set) has to be used.

The apparent 'reset' is just due to the fact that \savevar_rn_tl outside still has the value of the initial setting and the filling with #2@#2 is only locally, within the group.

\documentclass{article}
\usepackage{xparse}
\usepackage{amsmath}
\usepackage{mathtools}
\ExplSyntaxOn
%   VARIABLE DECLARATIONS:
\tl_new:N \g_savevar_rn_tl
\tl_set:Nn \g_savevar_rn_tl {INIT}
\NewDocumentCommand\myMacro{O{1}O{Z}}
{
!*\tl_use:N \g_savevar_rn_tl*!        \\
\str_case:nn {#1}
{
{1}
{
#2\\
Value\space before:\tl_use:N \g_savevar_rn_tl \\
\tl_gset:Nn \g_savevar_rn_tl {#2@#2}
Value\space after:\tl_use:N \g_savevar_rn_tl \\
}
{2}
{
Before: \tl_use:N \g_savevar_rn_tl \\
\tl_gset:Nn \g_savevar_rn_tl {RESET}
Value: \tl_use:N \g_savevar_rn_tl \\
}
}
}
\ExplSyntaxOff
\begin{document}
\section{The way I want to use it, but savevar is not preserved between calls:}
$\myMacro$\\
$\myMacro[2]$\\
$\myMacro[1][\alpha]$\\
$\myMacro[1][\beta]$
\section{savevar is preserved between calls, but only if calls are made in textmode:}
\ExplSyntaxOn
\tl_clear:N \g_savevar_rn_tl
\ExplSyntaxOff
\myMacro[1][A]\\
\myMacro[2]\\
\myMacro[1][W]\\
\myMacro[2]\\
\end{document}


• The name of the variable should be \g_savevar_rn_tl (every variable should have either the g or the l prefix). – egreg Sep 13 '15 at 9:18
• @egreg: Yes, agreed, but \tl_gset:Nn is needed anyway, I suppose? The \g_ is only a name convention – user31729 Sep 13 '15 at 9:20
• Yes, of course, but the g_ prefix will also help in remembering what function to use. – egreg Sep 13 '15 at 9:22
• @egreg: Yes, that's true. I changed it -- please bear me, I am still new in expl3 ;-) – user31729 Sep 13 '15 at 9:25
• @ChristianHupfer Thanks, it is another step forward. – Reinhard Neuwirth Sep 13 '15 at 10:01