30 l3中宏展开控制模块(l3expan)中对几个函数的疑惑

发布于 2023-08-22 21:57:40

interface3l3expan模块遇到如下三个问题:

1.在使用\exp_arg:系列函数控制函数各参数展开部分讲到了一个叫优化函数(optimized functions)的东西,目的在于提高函数处理其参数的速度,原文截取图如下1.png
我对这段话的理解(翻译)是:

由于用于处理参数展开的内部函数有两种形式,有些处理起来更快,因此若想让函数处理其参数的速度更快,需注意以下事项:

  • 由N, c, V, v所对应的参数应该靠前放置。
  • 由于在n, f, e, o所对应参数之后的参数需要稍慢一点的特殊处理才能被展开,因此,如果想要提高函数处理其参数的速度,那么该函数的参数说明符中最好是只有N, c, V, v(可以是单个也可以是它们的组合),若有o, f, e以及可能出现的N(或n、T、F),则其应当出现在最后一位,将满足这种条件的函数称为优化函数

话虽如此,但是在后面出现的\exp_arg:系列函数中,却有这么几个处理速度较慢的函数满足前面所谓“优化函数”的定义:

\exp_args:NVo
\exp_args:NNVV
\exp_args:NcVV

原文截取图如下:
2.png
3.png
所以不知道这该怎么解释,是不是我对“优化函数”的解读有误?

2.\exp_last_unbraced:系列函数的作用是什么?能否举个例子说明?
4.png

3.该模块最后一部分的诸如\::n\::o_unbraced这种东西是干啥的?
5.png

这三个问题大佬您能解答多少就解答多少,最后两个我是真没读懂原文(太菜了),在此先行谢过!

查看更多

关注者
0
被浏览
802
雾月
雾月 2023-08-23
这家伙很懒,什么也没写!

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

如果展开的结果中有括号,也不会移除括号。另外,Nc 参数的结果总是不自动添加 {}

3.
这些是用来定义 \exp_args:...\exp_last_unbraced:... 的。已经明确表示应当仅用于 l3expan 这个模块中,当然想在其它地方用也不是不可以。
\::: 作为分割符,前面的是展开方式,后面的是参数。
比如 \::n \::f \::o \::e \::e_unbraced \::: 就是 \::: 后面的那一项移除可能的括号,接着对随后的那些项依次进行指定的展开。(\.._unbraced 只能是最后一个)
好处是不受 TeX 的函数最多 9 个参数的限制,坏处是甚至可能比 \expanded 更慢。

1 个回答

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览