add tag
निरंजन
This is not a question with a problem to solve, but rather to understand how something _just works_.

```
\documentclass{article}

\begin{document}
\ExplSyntaxOn
\cs_new_protected:Npn \__int_incr_and_use:N #1 {
  \int_incr:N #1
  \int_use:N #1
}

\cs_generate_variant:Nn \__int_incr_and_use:N { c }

\__int_incr_and_use:N \l_tmpa_int\

\__int_incr_and_use:c { l_tmpa_int }

\par

\cs_new_protected:Npn \__str_save_and_use:n #1 {
  \str_set:Nn \l_tmpa_str { #1 }
  \str_use:N  \l_tmpa_str
}

\cs_generate_variant:Nn \__str_save_and_use:n { V }

\__str_save_and_use:n { foo } ~

\str_set:Nn \l_tmpb_str { bar }
\__str_save_and_use:V \l_tmpb_str
\ExplSyntaxOff
\end{document}
```

What I don't understand here is that the definition of `\__int_incr_and_use:{N|c}` only has `\int_incr:N` and `\int_use:N`, similarly the definition of `\__str_save_and_use:{n|V}` only has `\str_set:Nn`. How is everything converted to the required variant just when one issues the `\cs_generate_variant` command? Agreed that it is expected, but the fact that all the parent variants inside the definition too are converted to the new variants is something so amazing! What I mean is, the following is what is generally seen in the examples of `\cs_generate_variant:Nn` which is not very surprising, because no other function is there in the definition.

```
\cs_new_protected:Npn \__text_bf:n #1 { \textbf { #1 } }
\__text_bf:n { meow }
\cs_generate_variant:Nn \__text_bf:n { V }
\tl_set:Nn \l_tmpa_tl { quack }
\__text_bf:V \l_tmpa_tl
```

but the first example has other macros too which select the appropriate variant and that is... magical! I wonder how this specific facility is not documented.

How does this happen?
Top Answer
frougon
The variants generated by `\cs_generate_variant:Nn` only process arguments so that the base function can be called as expected in the end. In your question, `\__int_incr_and_use:N` will be called after an automatic `\csname ... \endcsname` whenever you use `\__int_incr_and_use:c`.

There is no digging nor any “search and replace” performed inside the replacement text of the base function: that would be very, very fragile because hypothetical code that analyzes replacement texts couldn't know how a given token in the replacement text of the base function is supposed to be used(\*). Also, tokens can be dynamically created using `\csname ... \endcsname`—another reason why hypothetical code that analyzes replacement texts couldn't work reliably. `\cs_generate_variant:Nn` is nevertheless very clever machinery!

(\*) For instance, a token from the replacement text of the base function could be stored in a macro or a token list to be later processed by a completely different function, and such a feature of the base function can't be reliably detected by an algorithm that analyzes its replacement text.
Answer #2
Skillmon
There used to be hand-optimised functions in `expl3` (for instance the definition of `\tl_set:Ne` used to be akin to `\edef#1{\unexpanded\expanded{{#2}}}` and `\tl_set:Nx` used to be akin to `\edef#1{#2}`. But in order to simplify the language most if not all of those optimisations of variants were dropped.

So if you stumble upon a definition that really changes something internally this is optimised by hand.

Otherwise the algorithm is basically the following:

- Pick the base variant (let's call it `<base>`) and the new argument variant (let's call it `<spec>`)
- if `\<base>:<spec><more-args>` does already exist, we're done (with `<more-args>` being any extra arguments that `<base>` has compared to the arguments given in `<spec>`)
- if it doesn't exist generate a `\exp_args:N<spec>` variant for the given `<spec>`
- create a macro akin to `\def\<base>:<spec><more-args>{\exp_args:N<spec>\<base>:<normal-args>}`

And that's it. (well there's still checking whether the variants are valid for the base arguments, but those are details)

Enter question or answer id or url (and optionally further answer ids/urls from the same question) from

Separate each id/url with a space. No need to list your own answers; they will be imported automatically.