Use N type for own macros

Background
In LaTeX3 I’m programming some macros to store and read contents from a variable like \tl_set:Nn does. An thus I’m generating variants using the N type, which causes a warning. The warning suggests to use V instead wich would be comprehensible for the reading macro \tobiw_use_thing but feels wrong for the writing macro \tobiw_save_thing. Since the manual says (highlighting by me):

The V and v specifiers are used to get the content of a variable […]

MWE

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn

\cs_new:Nn \tobiw_save_thing:nn {
\tl_set:Nn #1 { #2 }
}
\cs_generate_variant:Nn \tobiw_save_thing:nn { Nn }

\cs_new:Nn \tobiw_use_thing:n {
\tl_use:N #1
}
\cs_generate_variant:Nn \tobiw_use_thing:n { N }

\NewDocumentCommand{\saveanduse}{ m }{
\tobiw_save_thing:Nn \l_tmpa_tl { #1 }
\fbox { \tobiw_use_thing:N \l_tmpa_tl }
}

\ExplSyntaxOff

\begin{document}
Test
\saveanduse{Tokens}
\end{document}


Question
So what is the best approach to create macros like this? What argument types should be used here?

• It should be \cs_new_protected:Nn \tobiw_save_things:Nn to begin with. No variant needed. – egreg Mar 31 '18 at 7:59
• Why aren't you directly generating functions like \tobiw_save_thing:Nn? You would not get any warning. – TeXnician Mar 31 '18 at 7:59
• Btw: Conversion n to N is not well-formed, it should be n to V, but on the other hand there are the equivalents c and N if you want to be able to consume a group as csname. – TeXnician Mar 31 '18 at 8:00

You must not use variants here.

Variants are needed when a basic function, with signature consisting only of N or n specifiers (or in inclusive sense, to be clear), needs some kind of expansion of arguments before it takes action:

• V is a variant for n, where the variant function will receive a single token (which should be the name of a suitable variable) and the basic function will receive as its n argument the value.

• f and x are variants for n, where the contents of the braces will be f- or x-expanded.

• o is a variant for n, where the contents of the braces will be “one time expanded”, in the sense that the first token in the list will be expanded once.

• c is a variant for N, where the contents of the braces will be transformed in a single token to be fed as the N argument.

You are defining two basic functions and both expect a single token as their first (or unique) argument: this asks for an argument of type N.

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn

\cs_new_protected:Nn \tobiw_save_thing:Nn
{
\tl_set:Nn #1 { #2 }
}

\cs_new:Nn \tobiw_use_thing:N
{
\tl_use:N #1
}

\NewDocumentCommand{\saveanduse}{ m }
{
\tobiw_save_thing:Nn \l_tmpa_tl { #1 }
\fbox { \tobiw_use_thing:N \l_tmpa_tl }
}

\ExplSyntaxOff

\begin{document}
Test
\saveanduse{Tokens}
\end{document}


Note that the first function should be defined with _protected, because it sets some variable.

The function defining facilities \cs_new_... or \cs_set_... have basic signatures :Nn or :Npn. The signature of the defined function should only consist of strings of N or n (inclusive sense); w is only allowed in the :Npn case.

As an example, you have \tobiw_use_thing:N, but you possibly want

\cs_new:Nn \tobiw_use_thing:n
{
Do something with #1
}
\cs_generate_variant:Nn \tobiw_use_thing:n { V }


allowing calls such as

\tobiw_use_thing:n {whatever}


or

\tobiw_use_thing:V \l_tmpa_tl


But, at the end, it depends on what your functions are supposed to do.

• Thanks! … sometimes its quite easy … didn’t saw this solution. In this case would you recommend to use \tobiw_use_thing:N or \tobiw_use_thing:V? – Tobi Mar 31 '18 at 12:08
• @Tobi It depends on what you want the function to do. I'll add something. – egreg Mar 31 '18 at 12:31
• I see. So N when I’m sure that there is always a single token and n+V when there are multiple tokes directly given as argument or as a variable content, right? – Tobi Mar 31 '18 at 12:36
• @Tobi Yes, that's the idea. – egreg Mar 31 '18 at 12:37

You do not need any variant here, you could simply define functions with N type arguments. If your main concern is to allow also grouped input (as csname) generate a c variant afterwards.

Your functions uses the specifier n which stands for a group of tokens. You can convert those (as variant) to V type arguments, because that way the idea of getting a group of tokens stays intact. On the other hand you have the pair of c and N, where the former accepts a group of tokens (but forms one control word out of it) and the latter accepts one token, a control word.

When designing functions you should design with the purpose of the argument in mind. If you want a control sequence as argument use one of N or c. If you want some value use n, o, x, f, V or v.

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn

\cs_new:Nn \tobiw_save_thing:Nn {
\tl_set:Nn #1 { #2 }
}
\cs_generate_variant:Nn \tobiw_save_thing:Nn { cn }

\cs_new:Nn \tobiw_use_thing:N {
\tl_use:N #1
}
\cs_generate_variant:Nn \tobiw_use_thing:N { c }

\NewDocumentCommand{\saveanduse}{ m }{
\tobiw_save_thing:Nn \l_tmpa_tl { #1 }
\fbox { \tobiw_use_thing:N \l_tmpa_tl }
}

\ExplSyntaxOff

\begin{document}
Test
\saveanduse{Tokens}
\end{document}