«Поддельные» варианты в expl3

«Поддельные» варианты в expl3

Предположим, у вас есть функция, которая работает с тремя токенами,

\cs_new:Nn \@@_on_three:NNN { #1, #2, #3 }

И у вас есть переменная, значением которой являются три токена:

\tl_set:Nn \l@@_three_tl { foo }

И вы хотели бы иметь вариант

\@@_on_three:V

так что вы можете сказать

\@@_on_three:V \l@@_three_tl

Однако, если я не ошибаюсь, прямой аргумент \cs_generate_variantбудет сбит с толку разным количеством аргументов ( NNNпо сравнению с Vили x), и в любом случае он передаст расширенный аргумент.в фигурных скобках, верно?

Итак, вам нужен своего рода «поддельный» вариант, определяемый как:

\cs_new:Nn \@@_on_three:V
  { \exp_last_unbraced:Nx \@@_on_three:NNN #1 }

Для ясности:это работает. Мой вопрос скорее в том, был ли другой способ сделать это, менее «непослушный» — менее мошеннический на среднем уровне expl3.

решение1

Определение

\cs_new:Nn \@@_on_three:V
  { \exp_last_unbraced:Nx \@@_on_three:NNN #1 }

является по правилам expl3программирования «неправильным». VВариант типа должен быть связан с nбазовой функцией типа и не должен делать предположений о содержании переменной, которая обрабатывается. Например, что происходит с

\tl_set:Nn \l_@@_three_tl { A }

с определением \@@_on_three:Vдано? Кроме того, вы xрасширяете -type, а не V-type expand, что приведет к ошибке, например, если переданная переменная является регистром TeX или если она содержит что-то вроде «защищенного» кода LaTeX2e.

Для ясности: не обязательно использовать \cs_generate_variant:Nnдля создания вариантов, но «требуется», чтобы они вели себя так же, как если бы они были. Существуют различные вручную настроенные варианты, например l3tl, , но это только для улучшения производительности и не меняет поведение. Также обратите внимание на тот факт, что мы недавно ужесточили множество xвариантов типа , поскольку они не показали правильных результатов в этом отношении.

В вопросе не говорится, но он читается так, как будто tlздесь используется для хранения некоторых структурированных данных, которые всегда будут состоять из трех токенов. Таким образом, то, что, кажется, требуется, это

\cs_new:Nn \@@_on_three:N
  { \exp_last_unbraced:No \@@_on_three:NNN #1 }

где семантика такова, что \@@_on_three:Nдолжна использоваться с , tlсодержащим ровно три токена. Это обычное дело для низкоуровневой работы, и похожий код используется, например, в частях экспериментальной процедуры вывода ( xor) (которую я должен пересматривать).

Связанный контент