Static analysis of expl3 programs (8½): First stages of semantic analysis and working with the community
Today, I’m excited to announce another update to expltools, the bundle that includes the static analysis tool explcheck for the expl3 programming language. This update introduces initial support for semantic analysis. In this post, I’ll explain what this means for expl3 programmers, what’s still missing, and where we’re headed next.
In a previous post, I introduced a public website listing issues in current TeX Live packages detected by explcheck. This time, I’ll also talk about how I’ve been using that resource to collaborate with package authors and help fix real-world issues.
What is semantic analysis?
Semantic analysis builds on the results of syntactic analysis (covered in my last post) by interpreting recognized function calls as high-level statements and performing additional processing based on their type.
For example, consider this expl3 snippet, which prints “Hello, world!” when executed:
\cs_new:Nn
\example_foo:n
{
\cs_new:Nn
\example_bar:n
{
#1,~##1!
}
}
\example_foo:n { Hello }
\example_bar:n { world }
Semantic analysis identifies three top-level statements here:
- The definition of the function
\example_foo:n
. - A call to
\example_foo:n
with the argument “Hello”. - A call to another user-defined function,
\example_bar:n
, with the argument “world”.
Let’s take a closer look at the first one.
The definition of \example_foo:n
contains parameter tokens like #1
. During semantic analysis, these are replaced with ⟨argument⟩ pseudo-tokens to represent the values inserted during a function call. Doubled parameter characters (##
) are simplified to single ones (#
). After this transformation, the inner function definition becomes:
\cs_new:Nn
\example_bar:n
{
⟨argument⟩,~#1!
}
This replacement text is then re-analyzed syntactically and semantically, producing one nested statement:
- The definition of the function
\example_bar:n
.
This nested definition is processed again, yielding the fully transformed replacement text:
⟨argument⟩,~⟨argument⟩!
However, no further nested statements are found.
What does this mean for expl3 programmers?
Until now, explcheck only analyzed top-level function calls. With this update, it also parses replacement texts inside function definitions. This allows issues from Section 3 of Warnings and errors for the expl3 analysis tool to be detected not just at the top level, but also within functions.
That said, semantic analysis currently recognizes only function definitions. Other constructs—such as variable declarations, function variant generation, or key-value assignments—are not yet interpreted. As a result, issues described in Section 4 of the same document are still out of scope. Expect support for (some of) these in the next release.
Working with the community
In March, I reached out to the maintainers of five packages with issues listed on our website:
- BITNP/BIThesis#604
- jspitz/jslectureplanner#7
- dbitouze/nwejm#5
- dbitouze/gzt#56
- michal-h21/responsive-latex#1
Thanks to the maintainers’ quick responses, three of these issues have already been resolved!
Following today’s update, six more issues were found in TeX Live packages with public repositories. I’ve submitted reports to their maintainers as well:
- fpantigny/nicematrix#12
- josephwright/siunitx#796
- BITNP/BIThesis#640
- se2p/se2thesis#23
- John02139/asmeconf#11
- dickimaw-books.com#?? (pending review)
One of these has already been fixed—before I even finished writing this post. Let’s see how many more we can fix before the next update! 😉
Last updated on April 25, 2025