Como saber com certeza em contextos de expansão o momento em que existe o resultado de uma função expl3 totalmente expansível?

Como saber com certeza em contextos de expansão o momento em que existe o resultado de uma função expl3 totalmente expansível?

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:napenas 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, ea -expansão é cara.

No caso de \str_tail:nalgué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:wo que antecede \fi:a correspondência \if_charcode:we mantém o Xargumento delimitado pela categoria 11 e remove o \s__str_stopargumento 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:ntambé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:wpara 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:nnexiste?
Essa informação não é fornecida oficialmente em interface3.pdf.
Posso confiar com segurança, por exemplo, em \use_i:nnsempre 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 econtexto 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 ea expansão -type, mas em geral siga-a, \protected@edefpois funciona com comandos robustos do LaTeX2e - expl3geralmente não faz isso. Para texto completo, \text_expand:nfaz algo semelhante, \protected@edefmas não funciona bem com expansão não textual. De qualquer forma, essas abordagens permitem a expansão de expl3funções enquanto preservam o material frágil do LaTeX2e (por exemplo, \textbfou 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).

informação relacionada