5

On page 148 of The LaTeX3 Interfaces (interface3.pdf) dated 2021-10-12, the documentation for \seq_set_map:Nn states that the inline function that I'm using should receive each item in the sequence as #1. When I do this as illustrated in the MWE below, I obviously get unintended output. I finally figured out from this post that I should use ##1 instead.

Now I understand why using #1 gives the results it gives; because #1 is the argument of the outer function. So my question then is, should I know in advance to use ##1 in the mapping function and if so, how would I know that? I understand how to use ##1 when defining a function within a function and passing the argument to the new function, so is this issue related to that one? It occurred to me that the #1 mentioned in the docs might refer to the argument specification of the mapping function, but if that were the case then using (#1)^2 inline for the function should work, and it doesn't.

% !TEX program = lualatexmk
% !TEX encoding = UTF-8 Unicode

\documentclass{article}

\ExplSyntaxOn \cs_new:Npn \joe_zzzz:n #1 { \seq_set_from_clist:Nn \l_tmpa_seq { #1 } %\seq_set_map:NNn \l_tmpb_seq \l_tmpa_seq { \joe_square:n { #1 } } % doesn't work \seq_set_map:NNn \l_tmpb_seq \l_tmpa_seq { \joe_square:n { ##1 } } % works \seq_use:Nn \l_tmpb_seq { + } } \cs_new:Npn \joe_square:n #1 { (#1)^2 } \NewDocumentCommand{ \zzzz }{ m } { \joe_zzzz:n { #1 } } \ExplSyntaxOff

\begin{document} ( \zzzz{1,2,3} ) \end{document}

1 Answers1

8

You need #1 in the map, but you have it in the definition cs_new:Npn \joe_zzzz:n within a definition #1 refers to the argument of \joe_zzzz:n so you want #. To get a # in a definition you use ##.

## is replaced by # just as #1 is replaced by the first argument of the command being defined.

So your line

\seq_set_map:NNn \l_tmpb_seq \l_tmpa_seq { \joe_square:n { ##1 } }

adds

 \seq_set_map:NNn \l_tmpb_seq \l_tmpa_seq { \joe_square:n { #1 } }

to the replacement text of the command being defined.

David Carlisle
  • 757,742