在interface3的l3expan
模块遇到如下三个问题:
1.在使用\exp_arg:
系列函数控制函数各参数展开部分讲到了一个叫优化函数(optimized functions)的东西,目的在于提高函数处理其参数的速度,原文截取图如下
我对这段话的理解(翻译)是:
由于用于处理参数展开的内部函数有两种形式,有些处理起来更快,因此若想让函数处理其参数的速度更快,需注意以下事项:
话虽如此,但是在后面出现的\exp_arg:
系列函数中,却有这么几个处理速度较慢的函数满足前面所谓“优化函数”的定义:
\exp_args:NVo
\exp_args:NNVV
\exp_args:NcVV
原文截取图如下:
所以不知道这该怎么解释,是不是我对“优化函数”的解读有误?
2.\exp_last_unbraced:
系列函数的作用是什么?能否举个例子说明?
3.该模块最后一部分的诸如\::n
、\::o_unbraced
这种东西是干啥的?
这三个问题大佬您能解答多少就解答多少,最后两个我是真没读懂原文(太菜了),在此先行谢过!
1.
你的理解是对的,定义函数时遵循这个规则可以在需要展开其参数时不至于有太大的开销。
如果需要展开 nofe
参数之后的参数,如 \foo:Nno
、\foo:Nne
、\foo:Nff
、\foo:NnV
、\foo:no
,只有使用 \expanded
primitive(\tex_expanded:D
)才是最快的。而所谓的“optimized function”则总可以找到一个不用 \expanded
实现且比 \expanded
快的方法。(“最快”与“更快”都是从一般的情况来说的)
就是说,使用 \expanded
实现的函数都认为是需要更慢的处理。
在终端中执行 latexdef -b \ExplSyntaxOn -a \ExplSyntaxOff \exp_args:NVo
可以查看 \exp_args:NVo
的定义,(目前)它是用 \expanded
实现的,但可以找到一个不用 \expanded
(且比它快)的实现:
\cs_gset:Npn \exp_args:NVo #1#2#3
{
\exp_after:wN #1
\exp_after:wN { \exp:w \exp_after:wN
\__exp_eval_register:N \exp_after:wN #2 \exp_after:wN }
\exp_after:wN { #3 }
}
\exp_args:NNVV
和 \exp_args:NcVV
也是如此。但由于它们目前都是使用 \expanded
实现的,因此才把它们归类到需要更慢的处理的函数上。
2.last_unbraced
就是最后一个参数展开的结果的最外层不自动添加 {}
。比如
\tl_set:Nn \foo { ab }
\exp_args:No \faa { \foo } % 结果是 \faa { ab }
\exp_last_unbraced:No \faa { \foo } % 结果是 \faa ab
如果展开的结果中有括号,也不会移除括号。另外,N
和 c
参数的结果总是不自动添加 {}
。
3.
这些是用来定义 \exp_args:...
和 \exp_last_unbraced:...
的。已经明确表示应当仅用于 l3expan
这个模块中,当然想在其它地方用也不是不可以。\:::
作为分割符,前面的是展开方式,后面的是参数。
比如 \::n \::f \::o \::e \::e_unbraced \:::
就是 \:::
后面的那一项移除可能的括号,接着对随后的那些项依次进行指定的展开。(\.._unbraced
只能是最后一个)
好处是不受 TeX 的函数最多 9 个参数的限制,坏处是甚至可能比 \expanded
更慢。
非常感谢,茅塞顿开!
这个命令行查函数定义的方法真不错,又学到了新知识。