# Modifying a list and passing it to another command

I am trying to write some macros to easy my life while writing mathematics in LaTeX. For this, I would like to have some macros to write wedge products in a more concise manner. I have a command which typesets general wedge products based on a comma separated list:

\DeclareListParser*{\forcommalist}{,}
\NewDocumentCommand{\wedgeproduct}{s m}{%
\IfValueTF{#1}{\forcommalist{\listadd\wedgelist}{#2}}{\forlistloop{\listadd\wedgelist}{#2}}
\newcounter{wedgelength}
\forlistloop{\ifnumequal{\value{wedgelength}}{0}{}{\wedge}\stepcounter{wedgelength}}{\wedgelist}
}


(using xparse and etoolbox). I am trying to define a macro \diffform as follows

\NewDocumentCommand{\diffform}{m}{%
\forcommalist{\listadd\formlist{}d}{#1}
\wedgeproduct*{{\formlist}}
}


But when using it as (in mathmode)

\diffform{x,y}


It gives the following error

! Undefined control sequence.
<argument> ...}{\wedge }\stepcounter {wedgelength}{\formlist
}
l.21    \diffform{x,y}


I do not really understand what is going wrong (because it should not be looking for \formlist but for \wedgelist). How can I solve this problem? Any references to general explanations about programming macros like this in (Lua)TeX are also appreciated.

Full source code:

\documentclass{article}

\usepackage{amsmath}
\usepackage{xparse}
\usepackage{etoolbox}

\DeclareListParser*{\forcommalist}{,}
\NewDocumentCommand{\wedgeproduct}{s m}{%
\IfValueTF{#1}{\forcommalist{\listadd\wedgelist}{#2}}{\forlistloop{\listadd\wedgelist}{#2}}
\newcounter{wedgelength}
\forlistloop{\ifnumequal{\value{wedgelength}}{0}{}{\wedge}\stepcounter{wedgelength}}{\wedgelist}
}

\NewDocumentCommand{\diffform}{m}{%
\forcommalist{\listadd\formlist{}d}{#1}
\wedgeproduct*{{\formlist}}
}

\begin{document}
\begin{equation*}
\diffform{x,y}
\end{equation*}
\end{document}


## 1 Answer

Rather than etoolbox, I'd go with the more powerful and less clumsy expl3.

\documentclass{article}

\usepackage{amsmath}
\usepackage{xparse}

\newcommand{\diff}{\mathop{}\!d}

\ExplSyntaxOn
\NewDocumentCommand{\diffform}{m}
{
\hoekstra_diffform:n { #1 }
}

\seq_new:N \l__hoekstra_diffform_in_seq
\seq_new:N \l__hoekstra_diffform_out_seq

\cs_new_protected:Nn \hoekstra_diffform:n
{
\seq_set_from_clist:Nn \l__hoekstra_diffform_in_seq { #1 }
\seq_set_map:NNn \l__hoekstra_diffform_out_seq \l__hoekstra_diffform_in_seq { \diff ##1 }
\seq_use:Nn \l__hoekstra_diffform_out_seq { \wedge }
}
\ExplSyntaxOff

\begin{document}

\begin{equation*}
\diffform{x} \qquad \diffform{x,y,z,t}
\end{equation*}

\end{document}


The working is as follows:

1. The input is split at commas and populates a sequence.
2. A new sequence is built from it by adding the “differential d” in front of each item.
3. The new sequence is delivered, with \wedge in between items.

• Thank you! It works like a charm. Jun 5 at 10:15
• +1: But I fear that this will soon cause your reputation to exceed the Porsche number :) (911k). Jun 6 at 1:39