The argument specifier N and n

I am reading the documentation about Argument Specifiers in 1.1 Naming functions and variables of interfaces.pdf, where each argument is represented by a single letter.

I am confused of the argument specifier N and n. The document states that N and n mean no manipulation of a single token for N and no manipulation of a set of tokens given in braces for n.

I need some examples, because I see many functions having N then n. Does that mean the the function takes two arguments ?

• I cannot answer, but am interested in whatever answers are provided by others. As you noted, the documentation explanation is a bit mystifying.
– user287367
Commented Oct 1, 2023 at 19:02
• yes, each letter denotes an argument, so \foo:Nn would be used as \foo:Nn \something {some tokens} Commented Oct 1, 2023 at 19:13
• that is how you can tell the number of arguments from this signature, as explained in your earlier question Commented Oct 1, 2023 at 19:17
• "where each argument is represented by a single letter" <- Explanation and answer for your question, stated in your question. Commented Oct 1, 2023 at 19:24
• I thought that name of the new function was \feuds_newteorema_simple with the Argument Specifier being :nn to signify two arguments are to be passed to \feuds_newteorema_simple. Rather, you state that the names are \cs_new:Nn and \function_name:n meaning that : is an acceptable character like _ in function names. Latex in turn reads the function name from which Latex extracts the Argument Specifier. Correct ?
– Veak
Commented Oct 1, 2023 at 20:15

User level commands are comparatively much fewer than internal functions in the LaTeX kernel.

Just to make an example, \parbox is defined in terms of

\@iparbox \@iiparbox \@iiiparbox \@parboxto


the last one being redefined each time \parbox is called. Each of the first three internal functions has a different parameter text and it's quite difficult to read the code.

Perhaps the example is misleading, but expl3 was born to get rid of such difficulties by first providing a layer for “normalizing” arguments and then a clearer interface for internal functions.

In expl3 style we'd have

\NewDocumentCommand{\parbox}{O{c}oomm}
{
\innerlevel_parbox:nnnnn {...}
}


that passes the arguments to an internal function with five arguments, as clearly specified by the function's signature.

The signature is what comes after the colon that should always appear in the name of an expl3 function.

For instance, \innerlevel_parbox:nnnnn would be defined with

\cs_new_protected:Nn \innerlevel_parbox:nnnnn { ... }


where ... stands for code using the five arguments. An alternative way would be

\cs_new_protected:Npn \outerlevel_parbox:nnnnn #1#2#3#4#5 { ... }


but I find that the former way is simpler and doesn't require code bits that can be deduced from the function's signature. On the other hand, the latter version is slightly more efficient.

You see that already \cs_new_protected:Nn has a signature itself, namely Nn. This tells the programmer that it should be followed by a single token (a control sequence, in this case) and then an argument in braces, neither of which is manipulated in any way.

After the definition, the programmer knows that \innerlevel_parbox:nnnnn should be followed by five arguments in braces.

Naming guidelines for the kernel functions also help in remembering what arguments a function will expect. For instance,

\hbox_set:Nn


expects a box variable as its first argument (a single unbraced token) and some text as the second argument. A more complex example is

\int_compare:nNnTF


but with some practice in expl3 programming one should be able to remember that the first argument should be an “integer denotation”, the second argument a comparator among <, = or > (single unbraced token), the third denotation another “integer denotation”, then two braced arguments for the code when the test is succesful or not, respectively.

You mention “manipulation” and this requires some explanation. One of the strong point of expl3 is the possibility of defining variants of functions.

With \cs_new(_protected):Nn we can only define functions whose signature only consists of N or n. But as soon as the function is defined, we can define variants thereof.

An example: \hbox_set:Nn is mostly similar to the user level function \sbox. But suppose you want to define a command that uses text stored in some macro, but using the current contents, to feed \sbox with. The legacy programming style would require

\expandafter\sbox\expandafter\mybox\expandafter{\container}


The analog with expl3 would look like

\hbox_set:NV \l_fluffy_my_box \l_fluffy_container_tl


after having done (just once, you do this at the outer level)

\cs_generate_variant:Nn \hbox_set:Nn { NV }


Thus the signature doesn't only tells the programmer how many arguments are expected: it also allows to modify how the function manipulates the arguments before the main function is called.

I dare you to write cleanly the code corresponding to \innerlevel_parbox:nnnnV. You can't do it with a bunch of \expandafter', but you'd need auxiliary function doing argument swapping in order to bring the fifth argument at the head, so \expandafter can be effectively used. Instead, the expl3 kernel already has the infrastructure to cleanly perform the task, without the programmer needing to know how the magic happens.

• From your discussion one could use \cs_new_protected:Npn \myfunc #1#2#3#4#5 { ... } rather than \cs_new_protected:Npn \myfunc:nnnnn #1#2#3#4#5 { ... }. The new function \myfunc taking five arguments would not have Latex complain.
– Veak
Commented Oct 1, 2023 at 23:14
• @Fluffy you could but then you would not be able to generate variants as latex would not be able to construct names for them, \cs_generate_variant:Nn \myfunc:nnnnn {eeeee} would generate \myfunc:eeeee which is a variant that expands all arguments before the call) Commented Oct 1, 2023 at 23:24
• Thank you for explaining what \cs_generate_variant:Nn does.
– Veak
Commented Oct 2, 2023 at 0:13