# What is the difference between put and gput in \tl_new:N token lists?

Why is there one function to define (globally) e.g. a token list \tl_new:N, but there are two functions to put an element into it: \tl_put_left:Nn and \tl_gput_left:nN

What does this g at the beginning of gput mean? “Global”?

How can I put a local item in a global list (or vice versa)?

Now at the point of writing this question: can I make list modifications which don’t survive the current grouping with “local” modifications or what?

• I don’t like the interface3 documentation. It make me feel stupid. – Robert Siemer Sep 7 '19 at 0:44
• Don't feel that way. interface3 is more of a reference manual than a documentation. It contains a very brief description of each function in the LaTeX3 kernel, just to tell you what it does. It tries to be as self-contained as possible but there are some TeX concepts which you need to have a grasp on before you can understand all of it. I suggest you take a look at expl3.pdf (texdoc expl3), which is a more conceptual guide to expl3, and then have your go at interface3. With the latter, the best way to master it is by using. Any problem you find along the way you have but to ask :-) – Phelype Oleinik Sep 7 '19 at 2:08
• I'm not clear on what you mean by 'How can I put a local item in a global list (or vice versa)?': the variable you are changing is either local or global not only in TeX but in any language with some form of scoping. (At least modulo things like 'non-local' variables in Lua.) – Joseph Wright Sep 7 '19 at 7:47

I see that Phelype has covered the key points: here I'll try to give some context for the approach.

To understand the ideas here, it's probably best to start with how TeX grouping works. As a macro expansion language, TeX has no concept of being 'inside' a macro, and so definitions do not form scopes. Instead, scopes are created explicitly by for example the primitives \begingroup/\endgroup, in expl3 referred to as \group_begin: and \group_end:.

This also means that local variables do not work quite the same as in some other languages. For example, with something like

\begingroup
\def\foo{abc}
\begingroup
\show\foo


or in expl3 terms

\group_begin:
\tl_set:Nn \foo { abc }
\group_begin:
\tl_show:N \foo


we see that \foo is defined and expands to abc: nested groups 'inherit' all local variables from their parent.

This is important as it influences what abstractions do and do not make sense on top of TeX itself. The LaTeX team at one point explored variable declaration at local scope: token lists are easy, but things like int or dim variables are slightly more complicated. (This stems from the fact that TeX registers are used for the latter cases.) However, in use it became clear that this didn't really work: the fundamentals of TeX grouping mean that you always need a \group_begin:/\group_end: pair and something like \tl_new_local:N was potentially misleading.

The result is that all variables are declared globally in expl3, but they are then used as either always-local or always-global storage as appropriate. (Mixing local and global assignment may lead to save stack issues.) By convention, variable names at the code level start with either l or g to indicate which usage they are intended for. Similarly, most functions for setting variables have versions where the 'action' part has a g prepended: these are the global versions. For example, we have set and gset, put and gput, remove and gremove. Where a variable is being used but not set, there is no split: for example, \tl_use:N can be applied to both local and global token lists.

The net result is that one should declare a variable once, noting it's intended scope in the name, then use the matching 'setting' functions.

\tl_new:N \l_my_tl
\tl_new:N \g_my_tl
\group_begin:
\tl_set:Nn \l_my_tl { a }
\tl_gset::Nn \g_my_tl { b }
% ...
\group_end:
% \l_my_tl back to empty, \g_my_tl still 'b'


Why is there one function to define (globally) e.g. a token list \tl_new:N, but there are two functions to put an element into it: \tl_put_left:Nn and \tl_gput_left:nN

Because all variables are supposed to be declared globally once, then used as needed. There is few to no use of a variable that is declared within a scope and ceases to exist afterwards. Such a variable would be a temporary variable, so it can be created globally (\tl_new:N \l_my_temp_tl, for instance) and then used locally for temporary storage. In fact, LaTeX2e's variables (counters, lengths, skips, IO streams, etc.) are all defined globally as well.

There are two functions for assignments, because differently from the declaration of a variable, its usage might need to be global or local, and that's why there are two commands. And global variables (whose name start with \g_...) should always use the global variants of the functions and so for the local ones. That is so because mixing them is bad practice and may cause TeX to deplete its save stack memory.

What does this g at the beginning of gput mean? “Global”?

Yes :-)

See section 3.2.3 Variables: scope and type of The expl3 package and LaTeX programming (texdoc expl3).

How can I put a local item in a global list (or vice versa)?

You can't. You actually can, but you definitely should not!

Now at the point of writing this question: can I make list modifications which don’t survive the current grouping with “local” modifications or what?

Yes. TeX's scoping model is the same in expl3. For instance this:

\documentclass{article}
\usepackage{expl3}
\begin{document}
\ExplSyntaxOn
\tl_new:N \l_my_global_tl
\tl_set:Nn \l_my_global_tl { 0~ }
\tl_use:N \l_my_global_tl
\group_begin:
\tl_set:Nn \l_my_global_tl { 1~ }
\tl_use:N \l_my_global_tl
\group_end:
\tl_use:N \l_my_global_tl
\ExplSyntaxOff
\end{document}


prints 0 1 0, whereas the same document, replacing \tl_set:Nn by \tl_gset:Nn and \l_my_global_tl by \g_my_global_tl prints 0 1 1.