# \tl_set:Nf deletes beginning spaces in its #2

In syntax

\tl_set:Nf <tl var> {<tokens>}


if <tokens> begins with a space (input as ~), then this space does not appear in the definition of <tl var>. If a space appears in the middle or at the end of <tokens>, then it is kept in <tl var>.

Version info:

latex2e 2019-10-01
expl3   2020-01-12


Example

\documentclass{article}
\usepackage{expl3}

\begin{document}
\ExplSyntaxOn
\tl_new:N \l_test_tl

% \l_test_tl is set to "text", the beginning space is removed
\tl_set:Nf \l_test_tl { ~ text }
\verb|\tl_set:Nf|:~ |\l_test_tl| \par

% \l_test_tl is set to " text"
\edef \l_test_tl { ~ text }
\verb|\edef|:~ |\l_test_tl|

\ExplSyntaxOff
\end{document}

• This behavior is duly documented. If you want to understand why it is this way, I suggest reading up on the “\romannumeral trick”. – frougon Jan 18 at 10:10
• – Phelype Oleinik Jan 18 at 11:58

## 2 Answers

f-type expansion is documented as removing leading spaces: this is inevitable as it is implemented using \romannumeral. For new code, the e-type variant, which internally uses \expanded (or emulates it), avoids this issue and is usable in almost all cases that f-type expansion would have been used for in the past.

From documentation texdoc interface3, sec. I.1, where f-type expansion is introduced at the first time (Thank @frougon for pointing this in comment):

If this token is a <space token>, it is gobbled, and thus won’t be part of the resulting argument.

So an f-type expansion always gobbles the first space token.

• Better yet, use \tl_set:Ne – egreg Jan 18 at 9:31
• @JohannesZ 1) Regarding the \exp_not:N, note that \my_foo:f { \exp_not:N \c_space_tl } does call \my_foo:n with a space token as its argument. 2) No more than one space token can be gobbled by f-type expansion. I don't see any place containing “removes beginning space(s)” in my version of interface3.pdf. 3) The fact is documented in I.1, precisely where f-type expansion is introduced: “If this token is a 〈space token〉, it is gobbled, and thus won’t be part of the resulting argument.” – frougon Jan 18 at 10:28
• @frougon I have added another example to my answer. 1) \c_space_tl and \c_space_token are different, see the first group of tests in new example. 2) The second group of tests in new example shows that two beginning spaces are removed. 3) You are right, I will edit my answer. – muzimuzhi Z Jan 18 at 11:07
• @frougon I forget that in latex, multiple consecutive spaces are treated as one. – muzimuzhi Z Jan 18 at 11:29
• @JohannesZ I know that \c_space_tl and \c_space_token are not the same thing. A space token is unexpandable, therefore doing \exp_not:N \c_space_token is nonsensical. OTOH, \exp_not:N \c_space_tl has the expected effect, that's what I said in my 1). :-) – frougon Jan 18 at 11:52