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.
    ...
}
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.