文件 expl3.pdf - “expl3 包和 LaTeX3 编程”解释了应如何命名 expl3 函数,根据方案 还是根据方案。
\⟨module⟩_⟨description⟩:⟨arg-spec⟩
\__⟨module⟩_⟨description⟩:⟨arg-spec⟩
这引出了两个问题:
如何准确区分“函数”和“宏”?
假设它是关于程序员的接口,其中接口的程序员/用户要调用一个顶级宏,它本身不处理任何参数,但它反过来会启动扩展级联,在此过程中调用内部宏来处理参数。
在这种情况下,应该如何处理参数规范的问题?
我看到两种可能性:
顶层宏的参数规范为空,即顶层宏的名称以冒号结尾
:
。每个内部宏的名称都带有一个参数规范,该规范准确指定了相应内部宏处理的参数。顶级宏的参数规范不为空,但指定了在扩展级联过程中,基于宏的机制整体处理哪些类型的参数。每个内部宏的名称都带有一个参数规范,该规范精确指定了相应内部宏处理的参数。
这种可能性引发了以下额外问题:- 是否适用
\cs_generate_variant:Nn
于顶层宏,以及 - 例如,如何处理处理可变数量参数的尾递归宏机制的顶级宏的参数规范。
- 是否适用
答案1
- 如何准确区分“函数”和“宏”?
呃...:)
实际上没有明显的区别。在记录用户级宏时,我倾向于写“函数”,而在编写代码文档时,我更经常使用“宏”。术语“函数”expl3
用于区分宏,即做来自宏的东西(函数)抓住-stuff(tl
例如变量),并且“宏”使用较少,因此原则上应该遵循这一点。
- 假设它是关于程序员的接口,其中接口的程序员/用户要调用一个顶级宏,它本身不处理任何参数,但它反过来会启动扩展级联,在此过程中调用内部宏来处理参数。
从你提到的两个选项来看,后者。即使一个函数没有直接地(如:在第一次扩展之后)采用一个参数,其名称必须包含它将在后续步骤中抓取的参数。这正是\cs_generate_variant:Nn
在这些情况下起作用的原因。从内核中举一个简单的例子:
\cs_new_protected:Npn \clist_concat:NNN
{ \__clist_concat:NNNN \__kernel_tl_set:Nx }
\clist_concat:NNN
不接受任何参数,但这是:NNN
因为某些辅助函数将接受这三个参数。这很重要,因为:
- (最重要的是)你不必深入挖掘它的内部结构
\clist_concat:NNN
来弄清楚它需要多少个参数,因为从它的名字就可以看出来; \cs_generate_variant:Nn \clist_concat:NNN { ccc }
将会起作用,因为\cs_generate_variant:Nn
知道函数需要多少个参数(并且如果您尝试从中创建变体则会引发错误:ccccc
(那么生成的变体将很简单\exp_args:Nccc \clist_concat:NNN
)。
- 例如,如何处理处理可变数量参数的尾递归宏机制的顶级宏的参数规范。
:w
。如果你编写一个类似这样的递归宏函数:
\cs_new:Npn \my_tmp:w #1
{
\if_meaning:w \scan_stop: #1
\else:
\my_do_stuff_with:n {#1}
\exp_after:wN \my_tmp:w
\fi:
}
然后使用
\my_tmp:w { some } { arguments } { then } { end } { with } { \relax }
您不知道函数将接受多少个参数,因为这取决于输入。这意味着您无法执行\cs_generate_variant:Nn
,因为您无法知道要处理多少个参数。也许,如果此类文档\my_tmp:w
说它至少需要一个实际参数,那么您可以调用它\my_tmp:nw
,并仅为第一个参数生成一个变体。
答案2
让我用一些简单的语言重新表述一下 Phelype 对第 2 点的回答:
expl3 函数的签名(即名称中冒号后面的内容)应该表示全部参数和这些参数的预处理,换句话说,就是该函数在其之后需要的所有东西。这些参数是直接还是间接获取的(出于效率原因或……)完全无关紧要。
例如,如果您写下\foo:nnn
,那么阅读您的代码的每个人都会立即知道“foo”后面需要 3 个括号参数。
这里的重点是:“查看签名,然后您就知道该函数将拾取什么作为参数(以及如果签名对参数进行一些预处理,例如使用“c”或“V”或...)
这也解释了我们使用“函数”而不是“宏”的原因(尽管 TeX 是一种宏扩展语言,但你无法完全掩盖这一事实(除了惯例))。函数是你通过签名知道它们接受什么参数的东西(除了在少数情况下它们是“奇怪的”并且具有签名:w
),而宏就是宏:对你施展各种花招或你施展各种花招的肮脏东西,我们试图避免在 expl3 编程中这样做(或至少限制在非常内部的东西上)。