8

TeX scope is an overwhelmingly convoluted and opaque subject. It is impossible to tell by sight when a scope starts and ends, and what exactly is being affected by it. Since scope is one of the fundamental building blocks of every programming language, this is one aspect of TeX that, in my opinion, desperately needs an overhaul from the ground up. Does LaTeX3 address this subject?


I was asked:

What do you mean by ”impossible to tell by sight“?

I'm not even talking about pathological examples like

\def\mymac{a}%
\input enigma %redefines \begingroup and \endgroup as \relax
\begingroup%
    \def\mymac{b}%
\endgroup%
\mymac%
\bye%

which typesets

b

(Could you tell it by sight?)

I'm talking about normal examples, like the fact that the {...} in \def<control sequence>{...} do not imply a grouping, but the {...} in \output{...} do imply a grouping, yet the {...} in \mymacro{...} don't imply grouping, whereas the {...} in \loop{...}\repeat do imply grouping.

I'm talking about the fact that \setbox<number> = ... is local, but \ht<number> = ... is global (could you tell it by sight?), and when you create a plain TeX box, the current font will be captured in the box, but the current color won't.

And this is just to give you a taste.

9
  • 1
    To be honest, your questions are very weird. For example this very question. LaTeX3 is implemented in TeX (what else?) and therefore shares the same grouping concept as the underlying engine. So no, LaTeX does not change the scoping rules. Commented Sep 4, 2017 at 9:29
  • 1
    a LaTeX document is build with environments, and an environment is also local scope delimiting. So "impossible to tell by sight" is a bit strange here. Of course there are subtleties like automatically global assignments or the way dimensions of boxes are handled.
    – user4686
    Commented Sep 4, 2017 at 10:21
  • 2
    Of course, devious programmers may hide grouping in macros without documenting it. Other than that, grouping is usually well understandable from the typescript. What do you mean by ”impossible to tell by sight“?
    – egreg
    Commented Sep 4, 2017 at 12:40
  • 1
    The size of a box isn't global:\setbox0=\hbox{A} \begingroup \setbox0=\hbox{g} \showthe\dp0 \dp0=2pt \endgroup \showthe\dp0 (it's set at the group level of the setting of the box).
    – Joseph Wright
    Commented Sep 4, 2017 at 15:21
  • 1
    Most of your examples are very low-level: I don't really see the link to expl3/LaTeX3 (where the entire point is to provide a higher-level set of interfaces). One can't avoid the fact that the argument to macros, etc. is a balanced text which can also be used for grouping, though in LaTeX3 code we've gone for \group_begin:/\group_end: exclusively for the latter.
    – Joseph Wright
    Commented Sep 4, 2017 at 15:24

1 Answer 1

16

LaTeX3 (and in particular expl3, the programming layer) is written in TeX so ultimately cannot change the way TeX works. However, it can provide documented interfaces which detail how particular concepts are to be used.

For grouping, expl3 thus has to work with the various constructs TeX uses. The major ones are {/} (catcode 1/2 pair group) and \begingroup/\endgroup (semi-simple group): the latter in expl3 are renamed as \group_begin:/\group_end:. The way that these work is simple: they create a group in which local assignments will be 'trapped'. Reflecting this, expl3 provides a range of \<thing>_set:Nn and \<thing>_gset:Nn (or similar) macros which either locally or globally set the <thing>. The latter will usually be a variable such as \l_tmpa_tl (a token list to be set locally), \g_tmpb_clist (a comma list to be set globally), etc.

There are some TeX constructs which can only be set globally. However, these are largely low-level and are not generally exposed by expl3. Where they are, the documentation is clear that they must be handled using global interfaces: they will be given \g_... names. (For example, \prevgraf is not exposed by l3galley but there is a \g_galley_previous_par_lines_int variable which covers the same concept.)

As LaTeX3/expl3 is still in development, there are places where TeX primitives are not yet covered or where some changes may still be needed (box dimensions may well fall into the latter). However, the general approach is clear: document the scope, name appropriately and provide higher-level interfaces for a range of low-level concepts.


One of the examples in the question is that { ... } may be used for (at least) two reasons:

  • To create a balanced text argument
  • For grouping

The two are linked as TeX determines something is a balanced text as it is enclosed as a group using begin-group and end-group tokens. However, for expl3 code we have favoured (as a convention) using \group_begin:/\group_end: only for grouping: any { ... } pairs appearing in code are therefore arguments.


On the example of setting box height/depth/width, this is an area in expl3 which may still need attention. One may imagine dealing with the slightly odd behaviour by using appropriate wrappers to allow setting the box 'correctly'. That is not (yet) done, and has performance implications. On the other hand, the box code is relatively lightly reviewed at present: this may change. (I've raised with the team: I have a plan of sorts.)

9
  • "name appropriately" - ouch. IMO \prevdepth is an appropriate name - it clearly suggests it's the depth of a box used previously, which is correct. On the other hand \g_galley_previous_par_lines_int is longer to type, doesn't talk about boxes at all, and it's not clear (to me) whether its referring to "the total number of lines in the previous paragraph" or "the number of lines processed previously in the current paragraph". I'll pass over the question of exactly what a "line" is means here - and how could the value not be an integer, unless you have some concept like "half a line!" ...
    – alephzero
    Commented Sep 4, 2017 at 11:50
  • 1
    ... reminds me of the Devil's Dictionary definition of Structured Programming: "A simple way to increase the length of a computer program, without significantly improving its performance" ;)
    – alephzero
    Commented Sep 4, 2017 at 11:52
  • @alephzero An answer about expl3 is never going to please people who dislike the entire approach :)
    – Joseph Wright
    Commented Sep 4, 2017 at 11:59
  • @alephzero I've corrected which primitive I meant: \prevgraf not \prevdepth (and yes, the integer business is an open issue: l3galley is certainly not finished and the entire business of lines versus space, for example for paragraph shape, is tricky).
    – Joseph Wright
    Commented Sep 4, 2017 at 12:00
  • So let me understand. expl3 renames all of TeX's primitives, and those primitives that are not susceptible to grouping, like \fontdimen, have names starting with g_, while all the others, like \def or registers, have names starting with l_?
    – Evan Aad
    Commented Sep 4, 2017 at 14:14

You must log in to answer this question.

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