5

In my LaTeX laboratory I am doing weird experiments with expl3 (just started to use it some days ago, so regarding l3 I am complete newbie)

I am trying to generate command sequence within of another macro, the name being based on macro argument(s) of the outer macro.

In LaTeX(2e) this is easy

\newcommand{\foo}[1]{%
\expandafter\newcommand\csname foo#1\endcsname{Hello World}
}

and \foo{bar} would define \foobar (being not really useful here, of course)

I tried to apply this way (replacing \expandafter with \exp_after:wN) to a expl3 command sequence with \cs_new:Nn and it works, but I want to know:

Is there a better, cleaner way to get this in expl3, without using \csname etc., just from the signature or using variants?

P.S. I am aware, that expl3 commands are not really meant for typesetting, the output of Hello World is just an example.

\documentclass{article}

% Module named foo ;-)

\usepackage{xparse}


\ExplSyntaxOn
\NewDocumentCommand{\foo}{m}{%
  \exp_after:wN\cs_new:Nn  \csname foo_#1:\endcsname {Hello\space World}
}

\NewDocumentCommand{\foocall}{}{%
  \foo{start} % define \foo_start:
  \foo_start: 
}
\ExplSyntaxOff


\begin{document}
\foocall
\end{document}

A not really similar question about the expansion is Generalizing macros with LaTeX3, so I don't think my question is a duplicate.

  • 2
    \cs_new:cn { foo_#1: } { Hello ~ world }. Or may be in this case \tl_set:cn { l_foo_#1_tl } { Hello ~ world }. – Manuel Jul 26 '15 at 9:06
  • @Manuel: Ah, \cs_new:cn {foo_#1:}... I was failing using the :cn signature, because I omit the {...} pair around foo_#1: ... – user31729 Jul 26 '15 at 9:08
  • @Manuel: What's the advantage of using it as a token list with \tl_set:cn? – user31729 Jul 26 '15 at 9:13
  • Remember that we are in TeX, so \whatever foo_#1: will take f as the first argument of \whatever. Well, the advantage of setting it as a token list is that it can contain # for instance, but, in any case, what matters is that if it is a token list you should set it as a token list, and Hello ~  world looks like a token list to me :) – Manuel Jul 26 '15 at 9:21
  • @Manuel: Yes, I see, but the \foo_#1: is only a very simplified example. There is more internal setup actually and there is basically more work to do internally, as well as \foo_#1 would have some more arguments. – user31729 Jul 26 '15 at 9:24
7

The definition mangling should probably be really constrained to the programming (expl3) layer with just the top level "latex2e" interface defined via xparse \NewDocumentCommand, also it is clearer in l3 if you define the commands first taking a normal \zzzz argument then the \expandafter\...\csname idiom is pre-packaged as "define a c variant" so...

\documentclass{article}

% Module named foo ;-)

\usepackage{xparse}


\ExplSyntaxOn

\cs_new:Npn\foo:N#1{\show#1\cs_new:Npn#1{Hello ~ World}}
\cs_generate_variant:Nn\foo:N{c}


\NewDocumentCommand{\foocall}{}{%
  \foo:c{foo_start:} % define \foo_start:
  \foo_start: 
}
\ExplSyntaxOff


\begin{document}
\foocall
\end{document}
  • I suspected that the variants would be a cleaner way. Of course I would use the expl3 way only in package, not in the document directly. – user31729 Jul 26 '15 at 9:27
  • @ChristianHupfer yes but I meant that you should use xparse less and expl3 more, in your example. – David Carlisle Jul 26 '15 at 9:28
  • You mean because of \NewDocumentCommand? Well, that's true. Consider it as a remnant of another trial I had. And as xparse already loads expl3, I was too lazy to switch back ;-) – user31729 Jul 26 '15 at 9:31
3

The interface is already there, just use a c type argument instead of N:

\documentclass{article}

% Module named foo ;-)

\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\foo}{m}{%
  \cs_new:cn {foo_#1:}{Hello ~ World}
}

\NewDocumentCommand{\foocall}{}{%
  \foo{start} % define \foo_start:
  \foo_start: 
}
\ExplSyntaxOff


\begin{document}
\foocall
\end{document}

enter image description here

3

I know that you mentioned expl3 in the title of your post. But we have the TeX primitive language for such things 30 years.

\def\sdef#1{\expandafter\def\csname#1\endcsname}
\def\foo#1{\sdef{foo#1}{Hello World}}
\def\foocall{\foo{start}\foostart}

\foocall

Why to reinvent the wheel? Why to learn and use a new more complicated language?

  • 1
    I already mentioned the \csname ...\endcsname way in my question, I am using it for years already (ok, not 30 years ;-)) But thanks anyway. I am trying to learn the new and the 'old' TeX languages, because I like learning! – user31729 Jul 31 '15 at 7:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy