2

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 ?

16
  • I cannot answer, but am interested in whatever answers are provided by others. As you noted, the documentation explanation is a bit mystifying.
    – rallg
    Oct 1 at 19:02
  • 1
    yes, each letter denotes an argument, so \foo:Nn would be used as \foo:Nn \something {some tokens} Oct 1 at 19:13
  • 2
    that is how you can tell the number of arguments from this signature, as explained in your earlier question Oct 1 at 19:17
  • "where each argument is represented by a single letter" <- Explanation and answer for your question, stated in your question.
    – Skillmon
    Oct 1 at 19:24
  • 1
    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
    Oct 1 at 20:15

1 Answer 1

3

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.

3
  • 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
    Oct 1 at 23:14
  • 1
    @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) Oct 1 at 23:24
  • Thank you for explaining what \cs_generate_variant:Nn does.
    – Veak
    Oct 2 at 0:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .