# Exposing a new command for each element of a list

I have a macro lVars, defined using foreach from the pgffor package (part of PGF) as:

\newcommand{\lVars}[1]{\foreach \x [count=\ii] in {#1}{
\ifnum\ii=1{} \else {,} \fi \lVar[\x]}
}


The intended use is in terms like \exists \lVars{a, b, c, d}, which produces the result \exists \lVar[a], \lVar[b], \lVar[c], \lVar[d]. The command \lVar[a] is another custom command of the form \newcommand{\lVar}[1][x]{\textsc{#1}}, but may become more complex shortly. I then use the newly quantified \lVar elements inside larger forumlae.

However, I'm extremely lazy. I'd quite like this macro to expose each list element as a new command of the form \lA, \lB etc, which themselves expand to the actual underlying \lVar[A], \lVar[B].... These new commands would make my formula notation significantly less verbose. These new commands should last until the next time a, b,... are used in the list parameter to the lVars macro. So, the overall usage will be situations like:

\begin{displaymath}
\begin{array}{l}
\exists \lVars{a, b, c}.~ \lA = \lB \implies \lA = \lC \\
\lC = 0 \implies \lA = 0
\exists \lVars{a, b}.~ \lA \neq \lB
\end{array}
\end{displaymath}

And, as we see in the term $\lA = \lB$, the implication...


I've experimented with various permutations on \newcommand and \def within the body of the foreach, without any luck. Any advice or tips?

-
Can you please expand about the intended usage? –  egreg Apr 13 '13 at 16:32
@egreg Easily! I've added a rough example of how I'd expect to use it. If it's stupid idea, fair enough, but at the moment, I'm getting verbosity overload in my forumlae (which are rather more complex than my examples). –  Adam Wright Apr 13 '13 at 16:36
The tag foreach seems to be more appropriate –  Alain Matthes Apr 13 '13 at 19:25

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\lVars}{m}
{
% cycle through the argument
\clist_map_inline:nn { #1 }
{
% print the variable
\lVar[##1]
% if the variable is a, define \lA
\tl_to_uppercase:n
{
\cs_gset_protected:cpn { \c_wright_prefix_tl ##1 }
}
{ \lVar[##1] }
}
}
% We need to store the l' prefix in a control sequence to hide it from \uppercase
\tl_const:Nn \c_wright_prefix_tl { l }
\ExplSyntaxOff

\newcommand{\lVar}[1][x]{\textsc{#1}}

\begin{document}
\begin{displaymath}
\begin{array}{l}
\exists \lVars{a, b, c}.~ \lA = \lB \implies \lA = \lC \\
\lC = 0 \implies \lA = 0
\exists \lVars{a, b}.~ \lA \neq \lB
\end{array}
\end{displaymath}

And, as we see in the term $\lA = \lB$, the implication...
\end{document}


However, the definition of \lC will survive forever; if you plan to use it in different cells of an array a global definition is necessary.

A version that accepts multiletter variables and defines \lFoo from \lVars{foo}:

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\lVars}{m}
{
% cycle through the argument
\clist_map_inline:nn { #1 }
{
% print the variable
\lVar[##1]
% build the name with the first letter uppercase
\wright_make_var_name:n { ##1 }
\cs_gset_protected:cpn { \l__wright_var_name_tl } { \lVar[##1] }
}
}
\tl_const:Nn \c_wright_prefix_tl { l }
\cs_new:Npn \wright_make_var_name:n #1
{
% get the first letter and uppercase it
\tl_to_uppercase:n
{
\tl_set:Nx \l__wright_var_name_tl { \tl_head:n {#1} }
}
\tl_put_right:Nx \l__wright_var_name_tl { \tl_tail:n {#1} }
\tl_put_left:Nx \l__wright_var_name_tl { \c_wright_prefix_tl }
}
\ExplSyntaxOff
\newcommand{\lVar}[1][x]{\textsc{#1}}

\begin{document}
\begin{displaymath}
\begin{array}{l}
\exists \lVars{a, b, c}.~ \lA = \lB \implies \lA = \lC \\
\lC = 0 \implies \lA = 0
\exists \lVars{a, b}.~ \lA \neq \lB
\end{array}
\end{displaymath}

And, as we see in the term $\lA = \lB$, the implication...

Now $\forall\lVars{foo}\;\lFoo=0$
\end{document}


-
That's lovely, thanks! Just to be a pain, is there any way to combine it with the work in tex.stackexchange.com/questions/7992/… to make the upper-casing only apply to the first letter of each variable? So that \lVars{a, b, foo} defines \lA, \lB and \lFoo? I think I need to learn this xparse package! –  Adam Wright Apr 13 '13 at 17:14
@AdamWright Your wish is my command. ;-)` –  egreg Apr 13 '13 at 17:39
Thanks so much. My fingers will be eternally grateful :) –  Adam Wright Apr 13 '13 at 18:12