1

When working with a LaTeX3 variable of type token list, it is possible to declare a new variable, and later to set its value:

\tl_new:N \g_my_tl
...
\tl_set:Nn \g_my_tl {tokens}

The same template can be used with LaTeX3 variables of type string, sequence, and integer.

Is there a way to use the same or similar template with LaTeX variables of type control-sequence? I'd like to separate the declaration of a control-sequence variable from the act of setting its value. It's OK if the declaration of the control-sequence also sets its value to 'undefined'.

To give an example of usage, suppose I wish to write a LaTeX3 function \f:NNN, which takes three parameters: an integer variable, a control-sequence variable, and a token-list variable. I wish to give these parameters descriptive names. For this purpose I'd like to start my function by declaring variables of type integer, control-sequence, and token-list, and then to initialize them, as follows.

\cs_new:Npn \f:NNN #1#2#3
{
    \int_zero_new:N \l_int
    \cs_clear_new:N \cs_myfunc_l:
    \tl_clear_new:N \l_tl

    \int_set:NN \l_int #1
    \cs_set:NN \cs_myfunc_l: #2
    \tl_set:NN \l_tl #3

    ...
    % Now I can use the variables' names rather than #1, #2, and #3.
    ...
}
Evan Aad
  • 11,066

1 Answers1

3

One can always use \cs_new:Npn or \cs_new_protected:Npn with one definition and later change them

\cs_new_protected:Npn \foo_demo:Nn #1#2 { }
...
\cs_set_protected:Npn \foo_demo:Nn #1#2 { <actual code> }

Typically, this is done for

  • 'Scratch' functions, for example \cs_tmp:w (used for various 'throw away' purposes)
  • Cases where the 'top level' function is not used but it is in some restricted context (for example, an auxiliary used inside a main function which needs to 'know' some detail set at point-of-use)

We might see the latter in setting up a delimited function

\cs_new_protected:Npn \my_main:nn #1#2
  {
    \cs_set_protected:Npn \__my_aux:nw ##1 #1 ##2 #1
      {
        % Stuff using #1
      }
    \__my_aux:nw #2 #1 #1
  }
\cs_new_protected:Npn \__my_aux:nw { }

Note that this reflects the fact that functions and variable are 'different': most of the time, one would use \cs_set_eq:NN or perhaps storage inside a tl for 'variable functions'. On might therefore do

\cs_new_protected:Npn \__my_saved_function:w { }
% Or perhaps
% \cs_new_eq:NN \__my_saved_function:w \prg_do_nothing:
\int_new:N \l__my_saved_int
\cs_new_protected:Npn \my_public_function:Nn #1#2
  {
    \group_begin:
      \cs_set_eq:NN \__my_saved_function:w #1
      \int_set:Nn \l__my_saved_int {#2}
      % Code using \__my_saved_function:w and \l__my_saved_int
    \group_end:
  }

though this will get tricky with any reasonably amount of separation of functions: one will need to be very careful about scope and not 'reusing' the name.

Joseph Wright
  • 259,911
  • 34
  • 706
  • 1,036