I noob in LaTeX3 and I try to understand this language. As I read here one can define a new macro by using \cs_new:

\cs_new:Npn \SayHello #1
 { \prg_replicate:nn {#1} { Hello~World!~ } }

where N respect to \SayHello, p --- to #1 and n --- to {...}

Ok, I try to create my function to show square of some number:

\cs_new:Npn \Show #1 
\int_eval:n {#1*#1}

Macro \Show{number} work fine. But if I try to define macro \Show, which should show me some integer:

\cs_new:Nn \Show 
\int_eval:n {2+2}

I get a LaTeX error: "kernel/missing-colon".

Ok, then I add a colon:

\cs_new:Nn \Show:n 
\int_eval:n {2+2}

and I agein get an error, but now it just ! Undefined control sequence.

This behavior is not clear to me. Where am I breaking the rules?

MWE below.

\cs_new:Nn \Show:n 
\int_eval:n {2+2}

  • The functions with p allow for non - colon macro names, the other ones must have a colon at the end! You can't call \Show just this way outside of expl3 space. You must define it with Npn or call it with \Show:n{} in expl3 space
    – user31729
    Jan 28, 2017 at 17:46
  • Actually, expl3 space should be \Show: to work with \cs_new:Nn, or if you use \cs_new:Npn you can use whatever name you want. In any case, you should actually define \Show with xparse to make the public interface, and then the internal through expl3 language. Of course, for this example is too much, but in general that should be the way.
    – Manuel
    Jan 28, 2017 at 17:52
  • You should do \cs_new:Npn \sergio_show: {...} (without argument) or \cs_new:Npn \sergio_show:n #1 {...} (with argument) and define the document command in addition (with xparse): \NewDocumentCommand \Show {} { \sergio_show: } or \NewDocumentCommand \Show {m} { \sergio_show:n {#1} }
    – cgnieder
    Jan 28, 2017 at 18:08
  • Why I should to use xparse, why not LaTeX3 directly? In the first example it was possible. Jan 28, 2017 at 18:15
  • @sergiokapone it is possible but doesn't follow the expl3/LaTeX3 conventions that if you define commands for use in the document they should have a code-level equivalent function. The code level function should also follow the naming conventions (\<module>_<name>:<arg spec>).
    – cgnieder
    Jan 28, 2017 at 18:21

1 Answer 1


With \cs_new:Nn you're only allowed to define a function (macro) which has a signature, that is a list of the argument types after a colon.

With \cs_new:Npn you don't have this restriction, because you have to type in explicitly the parameter text (which is what p in the signature means).

For example, \cs_new:Nn expects a single token argument (N) and a braced argument (n). Conversely, \cs_new:Npn expects a single token argument, a “parameter argument” (see the discussion of parameter text in the TeXbook or TeX by topic) followed by a braced argument.

The codes

\cs_new:Nn \sergio_show:n { \int_eval:n { #1+#1 } }


\cs_new:Npn \sergio_show:n #1 { \int_eval:n { #1+#1 } }

are completely equivalent, because \cs_new:Nn can build a suitable parameter text from the signature.

If the command you want to define has no signature, you must define it with \cs_new:Npn or \cs_new_protected:Npn.

Alternatively, you can do

\cs_new:Nn \sergio_show:n { \int_eval:n { #1+#1 } }
\cs_set_eq:NN \Show \sergio_show:n

However, for user space commands, using the xparse interface is recommended.

You can't do

\cs_new:Nn \Show:n { \int_eval:n { #1+#1 } }

and then use \Show in the document, because you've never defined \Show.

Beware that you should use \cs_new_protected:Npn or \cs_new_protected:Nn (same rules apply) whenever the code contains non expandable functions (those without a red full or hollow star in the manual). Not the case here, because \int_eval:n is fully expandable.

  • 1
    Also note perhaps that _show would be wrong here as it's not a non-expandable function placing material in the .log/terminal.
    – Joseph Wright
    Jan 28, 2017 at 18:51

You must log in to answer this question.

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