Expl3 - \cs_generate_variant:Nn / \exp_args:N... - 在什么条件下哪种方法更可取?

Expl3 - \cs_generate_variant:Nn / \exp_args:N... - 在什么条件下哪种方法更可取?

如果需要在 TeX 将参数传递给宏之前对其进行预处理/扩展,则可以在 expl3 中执行两件事:

  1. 用于\cs_generate_variant:Nn生成宏的变体,其中参数经过预处理。
  2. 使用\exp_args:N...

在下面的第一个例子中,
\mymodule_foo:o { \mymodule_bar: }
生成与相同的消息
\exp_args:No \mymodule_foo:n { \mymodule_bar: }

问题是:

除了

  • 减少 .tex 输入文件大小的目标,
  • LaTeX 运行期间的内存消耗(假设它没有出现在许多宏的定义文本中)对于该\exp_args:N...变体来说应该更低,因为不需要存储额外的宏,
  • 代码的可读性
  • LaTeX 运行的持续时间/运行时间

那么,是否有其他标准/条件来选择其中一种方法?

如果是:哪些?

这两种方法哪一种更快?

\ExplSyntaxOn

\msg_new:nnnn {mymodule} {generic} {#1} {}
\cs_new:Nn \mymodule_foo:n 
 {
   \msg_term:nnn {mymodule} {generic} {
     This~is~the~argument~of~\mymodule_foo: #1
   }
 }
\cs_generate_variant:Nn \mymodule_foo:n { o }
\cs_new:Nn \mymodule_bar:
 {
   Toplevel~expansion~of~\mymodule_bar:
 }


\mymodule_foo:o {\mymodule_bar:}

\exp_args:No \mymodule_foo:n {\mymodule_bar:}

\stop

我提到可读性是因为\exp_args:N...当处理需要预处理的多个参数时,代码很快就会让没有经验的人感到困惑:

\ExplSyntaxOn

\msg_new:nnnn {mymodule} {generic} {#1} {}
\cs_new:Nn \mymodule_foo:nnn 
 {
   \msg_term:nnn {mymodule} {generic} { 1st~argument~of~\mymodule_foo: #1 }
   \msg_term:nnn {mymodule} {generic} { 2nd~argument~of~\mymodule_foo: #2 }
   \msg_term:nnn {mymodule} {generic} { 3rd~argument~of~\mymodule_foo: #3 }
 }
\cs_generate_variant:Nn \mymodule_foo:nnn { ooo }
\cs_new:Nn \mymodule_bar: { Toplevel~expansion~of~\mymodule_bar: }
\cs_new:Nn \mymodule_bas: { Toplevel~expansion~of~\mymodule_bas: }
\cs_new:Nn \mymodule_bat: { Toplevel~expansion~of~\mymodule_bat: }

% This is readable:

\mymodule_foo:ooo {\mymodule_bar:}{\mymodule_bas:}{\mymodule_bat:}

\msg_term:nnn 
    {mymodule} {generic} 
    { ------------------------------------------------------------------- }

% This is sort of readable:

\exp_args:Nooo \mymodule_foo:nnn {\mymodule_bar:}{\mymodule_bas:}{\mymodule_bat:}

\msg_term:nnn 
    {mymodule} {generic} 
    { ------------------------------------------------------------------- }

% This might occur confusing:

\exp_args:Nno \use:n {
  \exp_args:Nno \use:n {
    \exp_args:No \mymodule_foo:nnn {\mymodule_bar:}
  } {\mymodule_bas:}
} {\mymodule_bat:}

\stop

答案1

总体而言,团队的建议侧重于可读性:这里的性能差异很小。我们提倡的方法是强烈支持\cs_generate_variant:Nn,而“直接”使用\exp_args:N...保留给

  • 变体仅使用一次的地方
  • 无法使用变体的情况:通常是动态生成 csname

相关内容