Variantes 'falsas' em expl3

Variantes 'falsas' em expl3

Suponha que você tenha uma função que opera em três tokens,

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

E você tem uma variável cujo valor são os três tokens:

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

E você gostaria de ter uma variante

\@@_on_three:V

para que você possa dizer

\@@_on_three:V \l@@_three_tl

Porém, se não me engano, um direto \cs_generate_variantseria confundido pelo número diferente de argumentos ( NNNvs. Vou x) e, em qualquer caso, passará o argumento expandidoentre colchetes, certo?

Então o que você precisa é de uma espécie de variante ‘falsa’, definida como:

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

Para ser claro:isso funciona. Minha pergunta é se havia outra maneira de fazer isso que fosse menos 'perversa' - menos truques de nível médio expl3.

Responder1

A definição

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

é pelas diretrizes da expl3programação 'errada'. Uma Vvariante do tipo deve estar relacionada a uma nfunção subjacente do tipo e não deve fazer suposições sobre o conteúdo da variável que está sendo processada. Por exemplo, o que acontece com

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

com a definição de \@@_on_three:Vdado? Além disso, você está xexpandindo -type em vez de Vexpandir -type, o que falhará, por exemplo, se a variável passada for um registro TeX ou se contiver algo como código 'protegido' do LaTeX2e.

Para ser claro: não é necessário usar \cs_generate_variant:Nnpara criar variantes, mas é 'obrigatório' que elas se comportem da mesma maneira como se fossem. Existem várias variantes ajustadas manualmente, por exemplo l3tl, mas isso serve apenas para melhorar o desempenho e não altera o comportamento. Veja também o fato de que recentemente restringimos muitas xvariantes do tipo -, pois elas não mostraram os resultados corretos nesse aspecto.

A pergunta não diz, mas parece que tlaqui está sendo usado para armazenar alguns dados estruturados que sempre consistirão em três tokens. Como tal, o que parece ser desejado é

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

onde está a semântica que \@@_on_three:Ndeve ser usada com tlexatamente três tokens. Isso é comum em trabalhos de baixo nível, e código semelhante é usado, por exemplo, em partes da rotina de saída experimental ( xor) (que eu deveria estar revisando).

informação relacionada