# How to use a local variable inside a macro in expl3

I extended egregs answer by defining a macro, that creates and initializes an fp value in 1 line. Then put the variables into a sequence and printed the sequence:

\documentclass{article}
\usepackage{xparse}
\usepackage{expl3}
\setlength{\parindent}{0cm}
\begin{document}
\ExplSyntaxOn
\NewDocumentCommand{\newfpvar}{m}{\fp_new:N #1}
\NewDocumentCommand{\setfpvar}{mm}{\fp_set:Nn #1 { #2 }}
\NewDocumentCommand{\getfpvar}{m}{\fp_use:N #1}

%my new macro
\NewDocumentCommand{\define_fp_var}{mm}{
\newfpvar{#1}
\setfpvar{#1}{#2}
}

%define 3 variables
\define_fp_var{\One}{1}
\define_fp_var{\Two}{2}
\define_fp_var{\Three}{3}

%put them into sequence
\seq_new:N \fp_seq
\seq_put_right:Nn \fp_seq {\One}
\seq_put_right:Nn \fp_seq {\Two}
\seq_put_right:Nn \fp_seq {\Three}

%print sequence
\seq_map_inline:Nn \fp_seq
{
\getfpvar{#1}\\
}

\ExplSyntaxOff
\end{document}


Prints:

I tried to create a macro, when I can define a value and push it into a sequence in 1 line, but it doesn't work:

\documentclass{article}
\usepackage{xparse}
\usepackage{expl3}
\setlength{\parindent}{0cm}
\begin{document}
\ExplSyntaxOn
\NewDocumentCommand{\newfpvar}{m}{\fp_new:N #1}
\NewDocumentCommand{\setfpvar}{mm}{\fp_set:Nn #1 { #2 }}
\NewDocumentCommand{\getfpvar}{m}{\fp_use:N #1}

%my new macro
\NewDocumentCommand{\define_fp_var}{mm}{
\newfpvar{#1}
\setfpvar{#1}{#2}
}

%this doesn't work
%#1 - sequence name
%#2 - value
\NewDocumentCommand{\seq_put_fp_var_right}{mm}{
\group_begin:
%variable redefined
\define_fp_var{\temp}{#2}
\seq_put_right:Nx #1 \temp
\group_end:
}

\seq_new:N \fp_seq
\seq_put_fp_var_right \fp_seq {1}
\seq_put_fp_var_right \fp_seq {2}
\seq_put_fp_var_right \fp_seq {3}

\seq_map_inline:Nn \fp_seq
{
\getfpvar{#1}\\
}

\ExplSyntaxOff
\end{document}


Prints an error:

Control sequence \temp already defined.

l.28 \seq_put_fp_var_right \fp_seq {2}


How can I define a variable locally and store it in a sequence?

I read this: LaTeX3: how to define a variable locally, but still don't understand, how to do the task.

• Can you explain what do you want to achieve? It's really not clear. – Marco Daniel Jun 16 '13 at 10:15

It's not clear what you want to store in the sequence. However you shouldn't mix higher level functions defined with \NewDocumentCommand in lower level expl3 code.

A \NewDocumentCommand defined in the \ExplSyntaxOn context should only call a main inner function and perhaps some helper functions such as \group_begin: (this depends on many factors, the main one is avoiding code duplication).

\documentclass{article}
\usepackage{xparse}
\usepackage{expl3}
\setlength{\parindent}{0cm}
\begin{document}
\ExplSyntaxOn
% The following three macros are well defined
\NewDocumentCommand{\newfpvar}{m}
{
\fp_new:N #1
}
\NewDocumentCommand{\setfpvar}{mm}
{
\fp_set:Nn #1 { #2 }
}
\NewDocumentCommand{\getfpvar}{m}
{
\fp_use:N #1
}

% This one isn't well defined
%\NewDocumentCommand{\define_fp_var}{mm}{
%  \newfpvar{#1}
%  \setfpvar{#1}{#2}
%}

\cs_new_protected:Npn \mmmmxxxv_define_fp_var:Nn #1 #2
{
\cs_if_exist:NF #1
{
\fp_new:N #1
\fp_set:Nn { #1 } { #2 }
}
}

%#1 - sequence name
%#2 - value
\cs_new_protected:Npn \mmmmxxxv_seq_put_fp_var_right:Nn #1 #2
{
\seq_put_right:Nx #1 { \fp_eval:n { #2 } }
}

\seq_new:N \l_mmmmxxxv_fp_seq
\mmmmxxxv_seq_put_fp_var_right:Nn \l_mmmmxxxv_fp_seq { 1 }
\mmmmxxxv_seq_put_fp_var_right:Nn \l_mmmmxxxv_fp_seq { 2 }
\mmmmxxxv_seq_put_fp_var_right:Nn \l_mmmmxxxv_fp_seq { 3 }

\seq_map_inline:Nn \l_mmmmxxxv_fp_seq
{
#1\\
}

\ExplSyntaxOff
\end{document}


This prints

1
2
3

as expected.

Your code fails in two respects.

1. Commands defined with \NewDocumentCommand don't get expanded when arguments to a x function such as \seq_put_right:Nx

2. If you do the \seq_put_right:Nx in a group, at the end of the group the assignments will disappear.

User commands should be defined with the possibilities of xparse. Internal definitions should be done by \cs_new:Npn and friends. There is also a naming convention that says the last tokens of a function stands for the number of arguments and the first part of a function name represents the modul. Sorry but starting with seq is wrong. More about rules can be found in the documentation of expl3.

Related to your function \define_fp_var the correct syntax is:

\cs_new:Npn \user_define_fp_var:Nn #1 #2
{
\fp_new:N #1
\fp_set:Nn #1 {#2}
}


The symbol N stands for the new fp function and n for the value.