5

Is the choice whether a variable should be a \g_ or l_ type variable something a programmer can more or less freely decide on? Or are there some strict rules or at least some best-practices that a package creator should adhere to?

I feel that it is sometimes a bit tricky to decide whether a variable is "global" or "local", but this might as well be due to the fact that I don't fully understand why it is so important in TeX to distinguish here. This nice answer suggests that it has something to do with how TeX works internally and the LaTeX3 manuals state that a g_ type variable should always be set globally using one of the various g type operations (such as gset). There is also this Q&A, but it rather focuses on the difference of \c_ and g_ type variables.

I'd typically define variables at the "root" level (so "globally" in the sense that I can use them in any scope). But if I want to set and use such a variable inside a function and its value should be scoped within this function, I would argue that this variable should be an l_ type variable. This is probably easy to decide. But when should a variable be a g_ type variable?

I would think that boolean variables set by document option keys are probably candidates for g_ type variables. But then again, there might be some command defined by the package that allows these variables to be set to a different value mid-document or even inside a scope in which case I should probably still opt for an l_ type variable. So, I think it really depends on how the variable is used in the package.

Maybe I can adhere to the following rule (for the sake of completeness, I also added the c_ type here):

  1. Should the variable be changed at all? If no: use a \c_ type. If yes:
  2. Is it reasonable in the context of the package for the variable to be only set via g type operations? If yes: use a g_ type.
  3. In all other cases: use an l_ type.

Is this a sensible approach? Are there any best practices as to how to decide upon whether to use g_ or l_?

3
  • 3
    use local assignments unless you really want to be global. global variables are things that should act like classic latex counters which are document global and you can \stepcounter{section} inside any nested environments and it globally increases Commented Mar 4 at 17:02
  • 1
    Are you familiar with e.g. tex.stackexchange.com/questions/389698/…?
    – Joseph Wright
    Commented Mar 4 at 17:02
  • 2
    your 1 2 3 are about right but for 2 it's usually not reasonable to be global. Typical things that are managed using g are seen in eg the new pdf tagging code where the pdf file format has some structures that have to be built that can only appear once in the document. and they are essentially independent of any grouping in the source document. But these are very specialized uses. If you are doing such things you are in no doubt that they are global Commented Mar 4 at 17:25

1 Answer 1

5

A general rule of programming is to use local variables unless otherwise needed. TeX's scoping rules mean that this doesn't work quite the same as in other languages, but the general idea stands.

In TeX, scope is defined by groups (\begingroup/\endgroup or {/}) as well as some 'intrinsically grouped' constructed (\halign cells, math mode, ...). Values set locally before such groups are available inside the group, but if altered there are reset at the end of the group. Using expl3 cannot alter these fundamental rules, only help us to track them.

As such, most of the time you want to use \l_... variables. Whilst expl3 defines the name in global scope (as TeX doesn't have built-in namespacing), they are only ever set locally. Thus for example we might have

\tl_new:N \l_my_first_tl
\tl_set:Nn \l_my_first_tl { a }
\group_begin:
  \tl_show:N \l_my_first_tl % => a
  \tl_set:Nn \l_my_first_tl { b }
  \tl_show:N \l_my_first_tl % => b
\group_end:
\tl_show:N \l_my_first_tl % => a

Global variables should be used sparingly, when you know that settings need to escape groups to the global context: typically things that are document-wide, but also used for ideas that need to escape arbitrary group levels. This can sometimes lead to using a local and global variable pair, such that at given points in a document, local versions can be saved and restored.

Stuff that happens to be set at the top level doesn't have to be global: it's only if you need to set within a group and have the value escape.

The convention of using \l_... and \g_... is only enforced when debugging is active. The main reason for the convention is that TeX saves values when they are set within a group: intermixing local and global settings for the same control sequence leads to 'save stack build-up', which can cause issues.

2
  • Thank you! Actually, this confirms (and extends) my understanding. It is especially good to be confirmed in that g_ variables should really be used only in special circumstances. The point with "escaping groups" is a good hint to a rule of thumb. In the end, a take away also is: using l_ variables can never hurt. And for best practice of concrete issues, I can also look how (reliable) others do things in their packages =) Commented Mar 4 at 18:07
  • hm, that reminds me of an open problem ;-) Commented Mar 4 at 18:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .