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.

This is of the same kind as the [halting problem](https://en.wikipedia.org/wiki/Halting_problem) (and, yes: there is no way an LLM can *understand* code, otherwise, this well-known problem wouldn't be undecidable).

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.