Is it possible to separate the declaration of a LaTeX3 variable of type control-sequence from the act of setting its value?

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


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.