
Existem muitas funções fornecidas pelo ambiente de programação expl3 que em interface3.pdf estão marcadas com um asterisco preto (totalmente expansível) ou com um asterisco branco (expansível restrito).
Por que tantas funções são marcadas como totalmente expansíveis sem fornecer informações oficiais sobre a quantidade de expansões necessárias para obter o resultado?
Bem, com algumas coisas recursivas de cauda totalmente expansíveis onde meios de controle de expansão como \exp:w
/ \exp_end:
não são aplicados na implementação, tanto a quantidade de recursões quanto a quantidade de expansões necessárias para obter o resultado dependem dos argumentos fornecidos pelos usuários. Portanto, informações exatas sobre a quantidade de expansões necessárias para obter o resultado não podem ser fornecidas ali.
Mas há muitas funções onde este não é o caso e onde podem ser fornecidas informações exatas sobre a quantidade de expansões necessárias para obter o resultado.
Como, com funções expl3 totalmente expansíveis, saber com certeza em contextos de expansão o momento em que o resultado está lá?
Ex: gostaria de saber a quantidade de expansões que precisam ser acionadas para obter o resultado de \str_tail:n
.
Em contextos de expansão você não pode usar x
-expansion pois isso não é expansível.
Você não pode simplesmente usar f
-expansion com segurança, pois isso pode remover outro espaço inicial da string.
Se a função totalmente expansível em questão não fosse \str_tail:n
apenas algo em que os próprios argumentos não fossem sequências de tokens de caracteres explícitos não expansíveis, então e
-expansion poderia desencadear mais expansão do que o desejado. Além disso, com motores onde o \expanded
-primitivo não está disponível, e
a -expansão é cara.
No caso de \str_tail:n
alguém poderia ter a ideia de olhar para source3.pdf e descobrir que com a implementação atual são necessárias quatro expansões:
\cs_new:Npn \str_tail:n #1
{
\exp_after:wN \__str_tail_auxi:w
\reverse_if:N \if_charcode:w
\scan_stop: \tl_to_str:n {#1} X X \s__str_stop
}
\cs_new:Npn \__str_tail_auxi:w #1 X #2 \s__str_stop { \fi: #1 }
A expansão 1 fornece o texto de substituição de \str_tail:n
.
A expansão 2 faz o \exp_after:wN
-thingie que termina quando o resultado do \if_charcode:w
-test é avaliado e, por meio disso, o primeiro token da string é usado como argumento para comparar seu código de categoria com o código de categoria de \scan_stop:
.
A expansão 3 expande \__str_tail_auxi:w
o que antecede \fi:
a correspondência \if_charcode:w
e mantém o X
argumento delimitado pela categoria 11 e remove o \s__str_stop
argumento delimitado.
A expansão 4 remove \fi:
.
Mas consultar source3.pdf não é uma forma de obter informações sobre detalhes oficiais da implementação.
Caso a implementação interna mude, a quantidade de expansões necessárias para obter o resultado \str_tail:n
também poderá mudar.
Não vejo um método geral com uma função totalmente expansível para garantir que você obtenha o momento certo para cercar com alguns outros tokens os tokens que formam o resultado dessa função, além de saber a quantidade de expansões após as quais o resultado da função existe.
Ao usar \exp:w
para acionar a expansão de uma função totalmente expansível fornecida pelo ambiente de programação expl3 até que o resultado dessa função esteja lá, não vejo um método genérico para garantir que isso \exp_end:
seja executado no momento certo para parar \exp:w
-expansion que pode fazer sem saber a quantidade de expansões após as quais o resultado dessa função existe.
Então eu acho que com funções totalmente expansíveis, esta informação deveria ser fornecida como uma informação oficial.
Quantas expansões são necessárias até o resultado das funções \exp_args:...
ou \use_i:nn
existe?
Essa informação não é fornecida oficialmente em interface3.pdf.
Posso confiar com segurança, por exemplo, em \use_i:nn
sempre exigir exatamente uma expansão sem que alguém reclame porque deduzo informações de detalhes internos de implementação em vez de confiar apenas em fatos documentados oficialmente?
O que deveria me levar a confiar na consistência entre as versões expl3 em aspectos que não estão documentados oficialmente?
(A distribuição LaTeX que acompanha minha distribuição Linux difere muito do TeX Live 2024...)
Responder1
A situação da documentação é intencional. Existem muito poucas funções (de baixo nível) onde o número de expansões é importante e onde a equipe ou outras pessoas precisam saber/confiar nisso: elas estão documentadas. Em outros casos, o uso da expansão do tipo e
- ou f
- é normalmente suficiente. Por exemplo,\str_tail:n
necessariamenteproduz uma string - portanto, isso é seguro em um e
contexto do tipo -, portanto, hánão há necessidadepara documentar quantas expansões são necessárias.
Mais geralmente, se uma função assumedocumentotokens, então você não pode usar e
a expansão -type, mas em geral siga-a, \protected@edef
pois funciona com comandos robustos do LaTeX2e - expl3
geralmente não faz isso. Para texto completo, \text_expand:n
faz algo semelhante, \protected@edef
mas não funciona bem com expansão não textual. De qualquer forma, essas abordagens permitem a expansão de expl3
funções enquanto preservam o material frágil do LaTeX2e (por exemplo, \textbf
ou similar).
Documentar o número de expansões necessárias impõe uma restrição a quaisquer alterações de código: na medida do possível, não fazemos isso - as restrições são apenas aquelas que fazem parte da API. Se você tiver um caso de uso claro que parece exigir essa estabilidade da API, registre um problema e solicite uma alteração (na documentação).