Labelling confusion in expl3: (public, private) Vs (global, local)
A variable can be local or global; let me use a token list variable for the examples: the two instructions
\tl_new:N \l_aloui_whatever_tl
\tl_new:N \g_aloui_whatever_tl
define a local variable and a global one. The former should be set with functions such as
\tl_set:Nn \l_aloui_whatever_tl {abc}
whereas the second one should be set with
\tl_gset:Nn \g_aloui_whatever_tl {abc}
You can mix global and local variables; for instance, both the following calls are good
\tl_set_eq:NN \l_aloui_whatever_tl \g_aloui_whatever_tl
\tl_gset_eq:NN \g_aloui_whatever_tl \l_aloui_whatever_tl
but the reverse order is bad. A variable should always be manipulated with global functions if it has been declared global, with local functions if it has been declared local.
There is another distinction, between “public” and “private” variables, but it's mainly of a concern for package writers.
If you declare
\tl_new:N \l__aloui_whatever_tl
then you're stating that no package developer (or end user) should exploit this variable for their own usage, because it can disappear or be used in different ways in future versions of the package.
Similarly, a function declared like
\cs_new_protected:Nn \aloui_function:nn { ... }
is stated to be “publicly available”, so part of the “outer” interface, and that developers (or end users) can exploit it. Conversely, functions with __
at the beginning of their name are “private”: they are used in your package, but you make no guarantee whatsoever that they'll remain in future versions.
To make an example, the kernel function \cs_if_exist:NTF
is currently built upon the “private” function \__chk_if_exist_cs:N
. The “public” function \cs_if_exist:NTF
can be used by anyone and will not change in syntax and behavior in future releases*; the internal, “private”, function is used in the implementation, but nobody should rely on it, because the implementation could change.
* Well, the kernel is not stable at a point that all listed public functions are sure to be the same in future releases, but for a large part of the current functions this should be the case.
Here's an attempt to explain the difference between constant, global and local variables and functions.
Constant: should not be modified i.e. should be set to a particular value and then remain that way throughout.
Global: should always be set, cleared, modified etc. globally so that the change is effective even outside the current group.
Local: should always be set, cleared, modified etc. locally so that the change is effective only within the current group.
The following example attempts to illustrate this.
To keep things simple, I've done 2 things.
I've used non-expl3 syntax for unrelated aspects of the formatting such as
minipage
and\hfill
etc. so that the focus is clearly on the manipulation of different types of variables. The exception to this is\group_begin:
and\group_end:
which seemed innocuous enough not to distract (hopefully).I've picked a single type of thing to play with: token lists. So we have constant token lists, local token lists, global token lists etc.
Code:
\documentclass{article}
\usepackage{expl3}
\begin{document}
\ExplSyntaxOn
\tl_new:N \g_aloui_global_tl
\tl_new:N \l_aloui_local_tl
\tl_new:N \c_aloui_constant_tl
\tl_gset:cn \c_aloui_constant_tl { Do~not~change~me! }
Constant:~\tl_use:c \c_aloui_constant_tl
\tl_set:Nn \l_aloui_local_tl { Initial~value~for~local~token~list~variable. }
\tl_gset:Nn \g_aloui_global_tl { Initial~value~for~global~token~list~variable. }
\par
Local:~\l_aloui_local_tl
\par
Global:~\g_aloui_global_tl
\par
\group_begin:
Start~group.
\tl_set:Nn \l_aloui_local_tl { Within~group~value~for~local~token~list~variable. }
\tl_gset:Nn \g_aloui_global_tl { Global~change~of~value~for~global~token~list~variable. }
\par
\hfill
\begin{minipage}{.8\textwidth}
Local:~\l_aloui_local_tl
\par
Global:~\g_aloui_global_tl
\par
\end{minipage}
\par
End~group.
\par
\group_end:
\par
Local:~\l_aloui_local_tl
\par
Global:~\g_aloui_global_tl
\ExplSyntaxOff
\end{document}