
Supongamos que tiene una función que opera con tres tokens,
\cs_new:Nn \@@_on_three:NNN { #1, #2, #3 }
Y tienes una variable cuyo valor son los tres tokens:
\tl_set:Nn \l@@_three_tl { foo }
Y te gustaría tener una variante
\@@_on_three:V
para que puedas decir
\@@_on_three:V \l@@_three_tl
Sin embargo, si no me equivoco, un directo \cs_generate_variant
se confundiría por el diferente número de argumentos ( NNN
vs. V
or x
), y en cualquier caso pasará el argumento expandido.entre llaves, ¿bien?
Entonces, lo que necesitas es una especie de variante "falsa", definida como:
\cs_new:Nn \@@_on_three:V
{ \exp_last_unbraced:Nx \@@_on_three:NNN #1 }
Para ser claro:esto funciona. Mi pregunta es más bien si había otra forma de hacer esto que fuera menos "traviesa" (menos engaños de nivel medio) expl3
.
Respuesta1
La definición
\cs_new:Nn \@@_on_three:V
{ \exp_last_unbraced:Nx \@@_on_three:NNN #1 }
es por las pautas de expl3
programación 'incorrectas'. Una V
variante de tipo debe estar relacionada con una n
función subyacente de tipo y no debe hacer suposiciones sobre el contenido de la variable que se está procesando. Por ejemplo, ¿qué pasa con
\tl_set:Nn \l_@@_three_tl { A }
con la definición de \@@_on_three:V
dado? Además, está x
expandiendo -type en lugar de V
expandiendo -type, lo que fallará, por ejemplo, si la variable pasada es un registro TeX o si contiene algo como código 'protegido' LaTeX2e.
Para ser claros: no es necesario que uses \cs_generate_variant:Nn
para crear variantes, pero sí que se 'requiere' que se comporten de la misma manera que si lo fueran. Hay varias variantes ajustadas a mano, por ejemplo l3tl
, pero esto es sólo para mejorar el rendimiento y no altera el comportamiento. Véase también el hecho de que recientemente hemos restringido muchas x
variantes de tipo - ya que no mostraron los resultados correctos en este sentido.
La pregunta no lo dice, pero se lee como si tl
aquí se estuviera usando para almacenar algunos datos estructurados que siempre consistirán en tres tokens. Como tal, lo que parece querer es
\cs_new:Nn \@@_on_three:N
{ \exp_last_unbraced:No \@@_on_three:NNN #1 }
donde está la semántica que \@@_on_three:N
debe usarse con un tl
que contenga exactamente tres tokens. Esto es común en trabajos de bajo nivel y se usa código similar, por ejemplo, en partes de la rutina de salida experimental ( xor
) (que se supone que debo revisar).