如何在扩展上下文中确定地知道完全可扩展的 expl3 函数的结果出现的时刻?

如何在扩展上下文中确定地知道完全可扩展的 expl3 函数的结果出现的时刻?

expl3 编程环境提供的许多功能在 interface3.pdf 中用黑色星号(完全可扩展)或白色星号(受限可扩展)标记。

为什么这么多函数被标记为完全可扩展,却没有提供获得结果所需扩展量的官方信息?

嗯,对于一些完全可扩展的尾递归事物,在实现中不应用\exp:w/之类的扩展控制手段\exp_end:,获得结果所需的递归量和扩展量都取决于用户提供的参数。因此,无法在此处提供有关获得结果所需扩展量的确切信息。

但有很多函数并非如此,并且可以提供有关获得结果所需的扩展量的准确信息。

使用这种完全可扩展的 expl3 函数,如何在扩展上下文中确切地知道结果出现的时刻?

例如,我想知道需要触发多少次扩展才能获得结果\str_tail:n

在扩展上下文中,您不能使用x-expansion,因为它本身不可扩展。
您不能安全地使用f-expansion,因为这可能会从字符串中删除另一个前导空格。
如果所讨论的完全可扩展函数不是,\str_tail:n而是参数本身不是不可扩展的显式字符标记字符串的东西,那么-expansion 可能会触发比想要的更多的扩展。除此之外,对于-primitive 不可用e的引擎, -expansion 是昂贵的。\expandede

在这种情况下,\str_tail:n人们可以研究 source3.pdf 并发现当前的实现需要四个扩展:

\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 }

扩展 1 可获得 的替换文本\str_tail:n
扩展 2 执行\exp_after:wN-thingie 操作,在评估 -test 的结果时结束\if_charcode:w,因此字符串的第一个标记被用作将其类别代码与 的类别代码进行比较的参数\scan_stop:
扩展 3 进行扩展\__str_tail_auxi:w,将其添加\fi:到匹配的前面\if_charcode:w,并保留类别 11-X分隔的参数并删除\s__str_stop-分隔的参数。
扩展 4 删除\fi:

但是查看 source3.pdf 并不能获取有关实施的官方细节信息。

如果内部实现发生变化,则获得结果所需的扩展量\str_tail:n也可能会发生变化。

我没有看到一种通用方法,它具有完全可扩展的函数,可以确保在正确的时刻用其他标记包围形成该函数结果的标记,除了知道函数结果出现的扩展次数之外。
当使用\exp:wexpl3 编程环境提供的完全可扩展函数的扩展来触发该函数的扩展,直到该函数的结果出现时,我没有看到一种通用方法可以确保\exp_end:在正确的时间执行该操作以停止\exp:w扩展,而无需知道该函数结果出现的扩展次数。

因此我认为,如果功能完全可以扩展,则应该将这些信息作为官方信息提供。

需要多少次扩展才能得到函数结果\exp_args:...\use_i:nn
信息未在 interface3.pdf 中正式提供。
我是否可以安全地依赖,例如,\use_i:nn始终只需要一次扩展而不会有人抱怨,因为我从内部实现细节中推断出信息,而不是仅依赖官方记录的事实?
是什么让我在没有官方记录的方面依赖于 expl3 版本之间的一致性?
(我的 Linux 发行版附带的 LaTeX 发行版与 TeX Live 2024 有很大不同......)

答案1

文档情况是设计使然的。只有极少数(低级)函数的扩展数量很重要,并且团队或其他人需要了解/依赖它:这些函数都有文档记录。在其他情况下,使用e- 或f-type 扩展通常就足够了。例如,\str_tail:n 一定生成一个字符串 - 因此这在e-type 上下文中是安全的,因此不需要记录需要多少次扩展。

更一般地,如果一个函数文档标记,那么您不能使用e-type 扩展,但一般坚持使用它,因为\protected@edef它适用于 LaTeX2e 健壮命令 -expl3通常不会这样做。对于彻头彻尾的文本,它的\text_expand:n作用类似于\protected@edef非文本扩展,但效果不佳。无论哪种方式,这些方法都允许扩展expl3功能,同时保留 LaTeX2e 脆弱材料(例如\textbf或类似)。

记录所需扩展的数量会限制任何代码更改:我们尽可能不这样做 - 限制仅限于构成 API 一部分的限制。如果您有一个明确的用例似乎需要这样的 API 稳定性,请记录问题并请求(文档)更改。

相关内容