Some additional notes/demonstration about the "hash table" and the "equivalence table" etc.. as mentioned in some comments above.
Hash table
The hash table (or hash_extra, it's complicated) maps each control sequence name to a number (for fast manipulation of tokens, etc.).
In LuaTeX it's possible to check whether a token is in the hash table using token.get_next() or token.create().
In the example below, initially \undefineda is not in the hash table, but after it's "seen" (even if it's never defined) it's in the hash table. (also you can see that \ifdefined alone does not create new hash table entry even if the token is "read" by TeX)
%! TEX program = lualatex
\documentclass{article}
\usepackage{luacode}
\begin{document}
\begin{luacode*}
print("\n\n\n\n")
function f()
print("f: csname =", token.get_next().csname)
end
\end{luacode*}
\ExplSyntaxOn
\directlua{f()} \undefineda % here the output is empty, so \undefineda is not in the hash table
\ifdefined\undefineda \directlua{print "defined"} \else \directlua{print "undefined"} \fi
\directlua{f()} \undefineda % special case: \ifdefined (alone) does not put the token into the hash table
\iffalse \undefineda \fi
\directlua{f()} \undefineda % special case 2: \iffalse ... \fi does not put the token into the hash table
\use_none:n {\undefineda} % the token appears, but \use_none:n "throws it away" immediately
\directlua{f()} \undefineda % now undefineda is in the hash table
\ExplSyntaxOff
\begin{luacode}
print("\n\n\n\n")
\end{luacode}
\end{document}
Relevant output:
f: csname =
undefined
f: csname =
f: csname =
f: csname = undefineda
Equivalence table
The "equivalence table" is an implementation details of TeX, in texdoc tex it's called "The table of equivalents", part 17, section 220; and in the source code it's the variable eqtb.
As the documentation states, it holds the current "equivalents" of things.
Note that (implementation details) this table is not called "macro definition table", as it holds more than just macro definitions, as
control sequences/active characters can be defined to be something other than macro (for example:
\chardef \% = `% which makes \% equivalent (not "expands to"! It remains unexpandable) to \char `% when executed;
\let \c_math_toggle_token = $;
- etc.)
the value of e.g. the baselineskip, are also put in this table.
In short, "not to have \directlua in the equivalence table" is just a complicated way of saying "undefine \directlua", if I understood correctly.
Note on \let \directlua \undefined and the save stack
In this particular case, if you execute \begingroup, do \csname directlua \endcsname then execute \endgroup it's similar to if you do \let \directlua \undefined after a csname-endcsname -- the only difference (as far as I know) is in the "save stack" i.e. if you do \let \directlua \undefined alone it will leave an item in the save stack:
%! TEX program = lualatex
\documentclass{article}
\begin{document}
\ExplSyntaxOn
\begingroup
\tracingrestores=1~
\wlog{========~first~example}
\begingroup
\begingroup \expandafter \endgroup \expandafter \use_none:n \csname testtest \endcsname
\wlog{//there's~a~restore~above~because~of~the~endgroup,~but~no~restoration~below}
\endgroup
\wlog{========~second~example}
\begingroup
\expandafter \use_none:n \csname testtest \endcsname
\let \testtest \undefined
\wlog{//note~that~there's~still~a~restoration~below}
\endgroup
\endgroup
\ExplSyntaxOff
\end{document}
The relevant output of this program is:
======== first example
{restoring \testtest=undefined}
//there's a restore above because of the endgroup, but no restoration below
======== second example
//note that there's still a restoration below
{restoring \testtest=undefined}
{restoring \tracingrestores=0}
side note, \use_none:n is abused to gobble a single token here, but not a big problem
Addition
As shown in the comments under egreg's answer
I was a bit puzzled
why they don't just do \ifx\directlua\undefined.
My conjecture is that, the LaTeX3 team knows that \csname...\endcsname (and various other constructs using that) automatically defines the control sequence
to be \relax when it was originally undefined, think that's error-prone, and decide to hide the behavior from the user
and treat \relax and undefined the same way.
In particular, in this case, the code will consider \directlua "nonexistent" even if the user accidentally does (something that internally does) \csname directlua \endcsname somewhere before. Which I think is rather unlikely.
Compare this with how \cs_if_exist:NTF or \cs_if_exist:cTF works. While the \ifdefined and \ifcsname primitives
are true on \relax and false on undefined, both of the commands above are hard coded to be false on \relax.
(worth noting that, unlike many other commands that take c-type argument which are implemented in terms of \exp_args:Nc or \::c,
this command does not implicitly define the control sequence to \relax when it was undefined
because it's special-case implemented using \ifcsname;
nevertheless this behavior (as well as the fact that most-but-not-all c-type argument implicitly converts undefined to \relax, or in its LaTeX3 name, \scan_stop:)
is as far as I can see never documented anywhere in interface3.pdf)
That having said, my opinion (not really related to this question however) is that this can never be completely abstracted away from the user,
as an undefined control sequence will create an error when expanded/executed while a \relax control sequence will not.
\directluaat all outside of the test. This approach keeps the hash table clean. – Joseph Wright Jul 29 '11 at 08:47\csname...\endcsnamethe hash table is always touched. The point is just not to have\directluain the equivalence table, which is the most that can be done in pure TeX. – egreg Jul 30 '11 at 08:12{\expandafter}\expandafter\ifx \csname directlua\endcsname\relax ..., which if I understand properly what's going on, should have the same effect as the longer code in the question...? – dubiousjim Aug 19 '14 at 12:21{...}instead of\begingroup...\endgroupis equivalent (but I prefer the latter). The triple\expandafterensures the\ifxis expanded before the group is closed. – egreg Aug 19 '14 at 12:28{\expandafter}\expandafter\ifx\csname xxx\endcsname\undefined a\else b\fiand relies on a certain token to be undefined. – egreg Jan 12 '16 at 00:11\begingroup \ifx \directlua \@undefinedwhich would also "not have \directlua on the equivalence table"? (because\@undefinedcannot be assumed to be undefined?) – user202729 Jul 13 '22 at 02:38\relaxbeing the primitive is safer. Redefining\relaxwould badly break everything. Of course, the test would fail if the user has previously defined\directluato be\relaxand that’s why e-TeX has\ifdefinedand\ifcsname. – egreg Jul 13 '22 at 07:41\tex_undefined:Dwhich are used everywhere-else anyway? – user202729 Jul 13 '22 at 07:46\@undefined. – egreg Jul 13 '22 at 08:11