8

Question: Why is \l_keys_choice_tl in l3keys a tl instead of a str variable?

My understanding is that key names are stored as strings using \tl_to_str:n. For choice keys, each choice is implemented as just another key. e.g. \keys_define:nn { module } { key .choices:nn = { one , two } { <code> } } defines the keys module/key/one and module/key/two.

For example, the following code:

\documentclass{article}


\ExplSyntaxOn
\debug_on:n { all }
\str_new:N \l_module_name_str
\keys_define:nn { module }
  {
    key .choices:nn = { one , two }
      { \str_set:Nn \l_module_name_str {#1} }
  }
\ExplSyntaxOff


\begin{document}
text
\end{document}

generates the following in the .log file:

Defining key module/key on line 11
Defining key module/key/unknown on line 11
Defining key module/key/one on line 11
Defining key module/key/two on line 11

Since the selected choice of a choice key is treated as a string, then shouldn't the variable that stores the selected choice also be a string?

1 Answer 1

6

The code in l3keys was originally written before we formalised a str data type distinct from 'it's a tl which only contains catcode-12 tokens by convention'. We changed a few others to be str a while ago, but this one was overlooked. I'll likely tighten up in the next release!

2
  • Follow-up question: Is #1 used in .choices:nn also supposed to be equivalent to \l_keys_choice_str? Commented Oct 11 at 21:18
  • 1
    @User23456234 The answer is no. #1 used in .choices:nn's 2nd argument represents the value passed to the choice key, which is not normalized to str, for consistency. Note that \l_keys_choice_str has been added in l3kernel 2025-10-09. Also l3kernel 2025-10-24 corrected catcode of \l_keys_choice_tl content (deprecated but kept for compatibility). Commented Oct 24 at 20:17

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.