1

Could I have some explanation. For instance, What are these Nn and nn about. Very cryptic syntax.

\cs_new_protected:Nn \piston_newteorema_define:nn
  {
    \NewDocumentEnvironment { #1 } {D(){#2}}
      {
        \tl_set:Nn \piston_teorema_setcolor_tl { ##1 }
        \use:c { #1_inner }
      }
    {
      \use:c { end#1_inner }
    }
  }

Is the above the way to present the function, or is the following more clear ?

\cs_new_protected:Nn 
\piston_newteorema_define:nn
  {
    \NewDocumentEnvironment { #1 } {D(){#2}}
      {
        \tl_set:Nn \piston_teorema_setcolor_tl { ##1 }
        \use:c { #1_inner }
      }
    {
      \use:c { end#1_inner }
    }
  }
Veak
  • 1

1 Answers1

5

I find the documentation very good. The problem is figuring out where to find it.

For an explanation of the syntax, see the documentation l3kernel. expl3.pdf and interface3.pdf both discuss the basic syntax. The latter is an enormous document but the explanation you want starts on page 2.

Basically, the bit after the : in the function name is the function's signature. It consists of zero or more argument specifiers. N and n both stand for 'no manipulation'. That is, the arguments are passed to the function as-is. N means a single token; n means zero or more tokens in braces (curly brackets). So \c_empty_tl could be passed where a function has N because it's a single token. { \c_empty_tl } or { a 8 \c_empty_tl something-else } could be given where there's an n.

N and n are basic. If you want to pass an expanded token or tokens to a function, you use a variant. Variants can be generated as needed.

For example,

\cs_new_protected_nopar:Nn \__mymodule_hello:n
{
  \group_begin:
    Say ~ `Hello!' ~ to ~ #1!
  \group_end:
}
\cs_generate_variant:Nn \__mymodule_hello:n { V }
\tl_new:N \l__mymodule_greeted_tl
\tl_set:Nn \l__mymodule_greeted_tl { The ~ Pied ~ Piper }
\__mymodule_hello:n { The ~ Pied ~ Piper } ~
\__mymodule_hello:V \l__mymodule_greeted_tl

will produce greet the Pied Piper, twice

V tells LaTeX to pass the value of the variable to the function, so the function receives the same stream of tokens in both cases.

On the face of it, neither of your proposed definitions is consistent with the l3 approach. Commands such as \NewDocumentEnvironment are for handling user input. Control sequences such as \piston_newteorema_define:nn are for programmatic use. One of the aims of expl3 is a clearer separation of these layers, so typically the \NewDocument... are used to create wrappers around programming-layer functions.

But it is hard to suggest a different approach without knowing what your package function is trying to do. (I assume you aren't just making twenty differently-named environments with a different default colour.)

cfr
  • 198,882
  • Comments have been moved to chat; please do not continue the discussion here. Before posting a comment below this one, please review the purposes of comments. Comments that do not request clarification or suggest improvements usually belong as an answer, on [meta], or in [chat]. Comments continuing discussion may be removed. – Joseph Wright Sep 28 '23 at 06:22