9

According to the manual, LaTeX3 variables can be of local, global, or constant scope. When should one use the various types? In my naïve attempts at coding, I've just taken to declaring most variables with \l_@@_ as they're only intended to be used within the package macros and not meant to be touched otherwise. The packages I've been writing though have been contained within a single *.dtx, as at present the benefits of splitting it into multiple files doesn't seem worth the effort and additional complexity.

Is there a general guide or heuristic for when each type of variable should be used that goes into more depth than the one-line explanations in expl3.pdf?

Robbie
  • 2,893

2 Answers2

11

TeX scope is based on grouping not on files/definitions/... as might be seen in other languages. That stems from the fact TeX works by macro expansion, and so there is no scope created by where things are defined.

The most obvious form of grouping is that created explicitly, in expl3 terms by

\group_begin:
  % Local settings here
\group_end:

In this set up, any locally-set material will be lost at the end of the group. That is useful for 'containing' values

\int_new:N \l__my_int
\int_set:Nn \l__my_int { 10 }
\group_begin:
  \int_set:Nn \l__my_int { 20 }
\group_end:
\int_show:N \l__my_int % "10"

Importantly, TeX groups don't 'reset' values at their start, thus we would get

\int_set:Nn \l__my_int { 10 }
\group_begin:
   \int_show:N \l__my_int % "10"

Most variables are either set at the top level or are deliberately limited in scope, so most of the time you want expl3 \l_ variables and \int_set:Nn, etc.

Global variables are useful where there may be scopes that the value needs to 'escape' from. In LaTeX2e there are a couple of 'obvious' places you might consider. The first is environments: they form groups. So for example if we wanted to have a single list of how many times \foo was used, if it might crop up in

\begin{some-env}
  \foo ...
  \foo ...
\end{some-env}
\showfoousage % "2"

we'd need to use a global variable. The same applies to various lower-level TeX 'hidden' groupings. Probably the most important are boxes and table cells.

Thus what you need to think is 'is this value a single global value or not'. Most of the time, things like settings, scratch space, etc. are not. It's mainly ideas such as labels/tracking data that are global. (Depending on your use case, you might have some ideas that needs to 'ignore' TeX groups: again that has to be global.)

Joseph Wright
  • 259,911
  • 34
  • 706
  • 1,036
3

The following points are examples to illustrate use cases:

  • constants: You need constants for values you'll never change, but you need e.g. for consistency. Let's say you write a package that calculates values, but your output will (at the current state) only display two decimal figures. Therefore you introduce a constant containing your precision which makes it easy to change it in the future:

    \int_const:Nn \c_robbie_precision_int { 2 }
    
  • global variables: These variables are needed all over the document, but their value may (or should) change. One example: You want to simulate a LaTeX counter with l3 and you use it to number environments all over the document. That's global. Therefore you define it like

    \int_new:N \g_robbie_mycount_int
    \int_gset:Nn \g_robbie_mycount_int { 1 }
    

    and remember to use the global functions (those with the g) to alter values. To increment your "counter" you would do the following

    \int_gincr:N \g_robbie_mycount_int
    
  • local variables: These variables are only of use in the local group. Either they alter some existent setting or they introduce variable values that aren't needed (and accessible) outside of the group. The typical example are simple calculations where you need to store a result in a temporary variable. The following example switches the values of two integers (you do not want the temporary value anywhere else):

    \int_set:Nn \l_tmpa_int { \g_robbie_mycountx_int }
    \int_gset_eq:NN \g_robbie_mycountx_int \g_robbie_mycount_int
    \int_gset_eq:NN \g_robbie_mycount_int \l_tmpa_int
    
Joseph Wright
  • 259,911
  • 34
  • 706
  • 1,036
TeXnician
  • 33,589