expl3 编程环境提供的许多功能在 interface3.pdf 中用黑色星号(完全可扩展)或白色星号(受限可扩展)标记。
为什么这么多函数被标记为完全可扩展,却没有提供获得结果所需扩展量的官方信息?
嗯,对于一些完全可扩展的尾递归事物,在实现中不应用\exp:w
/之类的扩展控制手段\exp_end:
,获得结果所需的递归量和扩展量都取决于用户提供的参数。因此,无法在此处提供有关获得结果所需扩展量的确切信息。
但有很多函数并非如此,并且可以提供有关获得结果所需的扩展量的准确信息。
使用这种完全可扩展的 expl3 函数,如何在扩展上下文中确切地知道结果出现的时刻?
例如,我想知道需要触发多少次扩展才能获得结果\str_tail:n
。
在扩展上下文中,您不能使用x
-expansion,因为它本身不可扩展。
您不能安全地使用f
-expansion,因为这可能会从字符串中删除另一个前导空格。
如果所讨论的完全可扩展函数不是,\str_tail:n
而是参数本身不是不可扩展的显式字符标记字符串的东西,那么-expansion 可能会触发比想要的更多的扩展。除此之外,对于-primitive 不可用e
的引擎, -expansion 是昂贵的。\expanded
e
在这种情况下,\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:w
expl3 编程环境提供的完全可扩展函数的扩展来触发该函数的扩展,直到该函数的结果出现时,我没有看到一种通用方法可以确保\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 稳定性,请记录问题并请求(文档)更改。