The \tl_new:(Nc) functions create a new token list variable globally. Is there a way to create a new token list variable locally?

  • 2
    I think the idea is that you define a variable (defined globally), and then set it locally. You can reuse that one locally everytime you want. What's the problem with that? Why would you need to define locally? By the way, you always have \l_tmpa_tl and \l_tmpb_tl available. Otherwise, you can actually \tl_set:Nn \local { .. } wherever you want (unless there's some check activated).
    – Manuel
    Sep 28, 2017 at 8:05
  • @Manuel: When you use local variables, you do not have to worry that they will be changed by another function. You also reduce the risk of name clashes.
    – Evan Aad
    Sep 28, 2017 at 8:13
  • @EvanAad Doesn't work in TeX due to the way scoping occurs, which is basically why we didn't go with local variable creation.
    – Joseph Wright
    Sep 28, 2017 at 8:14
  • 2
    @HenriMenke :Don't hehe
    – Manuel
    Sep 28, 2017 at 8:16
  • 1
    @EvanAad If you have a macro that itself defines \local, then calling it in a scope where you “locally declare” \local will change the value notwithstanding. There is no “local variable” like in other programming languages.
    – egreg
    Sep 28, 2017 at 9:13

1 Answer 1


'Yes and no'. If you are sticking to the official programming approach then 'no', as the method that the team have decided on is that all variables should be declared globally. On the other hand, if you decide to 'roll your own' then you can do

\cs_set_nopar:Npn \l_my_tl { }

as ultimately a token list is a macro with no arguments (at least in the current implementation). Unlike variables, there is no checking on pre-existence with \cs_set_nopar:Npn or similar. Note that I am not encouraging this, but you can do it. (There are a few places internally where we need to do this, most obviously in defining the tl operations themselves!)

(Note that \tl_set:Nn \foo with an undeclared \foo will create it locally unless checking is active. One of the checks that is available is to pick up exactly this non-supported behaviour.)

The reason for this approach is that experience suggests that this is the best way to deal with variables in TeX. Variables in TeX are scoped by groups (primitives \begingroup/\endgroup, {/}, _etc.), not by placement in (macro) definition. The team experimented with local creation of variables, not just tl but also other types. That is technically achievable but does not fit particularly well with TeX's underlying scoping: it could be read as suggesting that

\cs_new_protected:Npn \foo:
    \<var>_local_new:N \l_my_<var>
    % Code

is local to the definition rather than to a group. When it became clear that this approach was not particularly helpful, the local initialisation was dropped leading to the current position, that all variables should be globally declared even if assigned locally.

(Register-based variables are more 'scarce' than those using macros, so there is very little need to worry about tl or similar: the 'savings' offered by local creation of variables apply most to for example int or dim types. Note that also register-based variable names do have to be declared, whilst one doesn't have to for macro-based ones. However, one aim the team have is that people using expl3 shouldn't rely on implementation details: we reserve the right to alter how variables are created internally provided the API stays the same.)

  • May be explain that one could implement tl with toks? May be that way it's more understantable (given that one actually could think of implementing tl with toks, that I might be wrong).
    – Manuel
    Sep 28, 2017 at 8:18
  • 1
    @Manuel If we'd gone with a toks-based approach from day one then yes, but the API for tl does say they can be used without an accessor. As such, we can't change to a register-based 'back end'. (I have done experiments with expl3-like code that uses toks exclusively, particularly as LuaTeX offers various manipulation primitives.)
    – Joseph Wright
    Sep 28, 2017 at 9:32

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.