
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_variant
seria confundido pelo número diferente de argumentos ( NNN
vs. V
ou 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 expl3
programação 'errada'. Uma V
variante do tipo deve estar relacionada a uma n
funçã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:V
dado? Além disso, você está x
expandindo -type em vez de V
expandir -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:Nn
para 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 x
variantes do tipo -, pois elas não mostraram os resultados corretos nesse aspecto.
A pergunta não diz, mas parece que tl
aqui 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:N
deve ser usada com tl
exatamente 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).