expl3 的类型是怎样的?

expl3 的类型是怎样的?

在开发expl3附加包时,我希望延续我所用语言的趋势,并且不是引入新的模式。有人能谈谈 中遵循的类型模型(如果有的话)吗expl3

我正在寻找的具体内容是:


来自评论:

它是底层语言概念,通过该概念,‘数据类型’具有‘类型’。什么使 a 成为 a seqseq什么说它不是 aclist或 a coffin?即使类型不匹配,会发生什么情况,如下所示?

\seq_new:N       \some_seq
\seq_push:Nn     \some_seq {some item} 
\clist_set_eq:NN \l_tmpa_clist \some_seq
\clist_item:Nn   \some_seq 5

那种事。

答案1

我没有计算机科学背景,因此我不会用我不太理解的术语来回答,而是尝试描述事情是如何实现的以及如果你行为不端会发生什么!

TeX 是一种宏扩展语言,因此很多存储都归结为“使用宏”。同时,TeX 为我们提供各种专用寄存器,可以通过数字或更常见的分配名称来寻址。这两种存储在“原始”级别上的行为不同。除了 toks 之外,所有寄存器在接受的内容方面都相当有限,因此需要宏或 toks 来构建任何其他数据形式。

值得注意的是,expl3文档并未特别说明该级别的变量是如何实现的。这是故意的,例如,prop数据类型过去是使用寄存器 ( toks) 实现的,但目前是作为“幕后”宏实现的。

综上所述,如果你做了“错误”的事情,具体会发生什么取决于所涉及的变量。dimintmuskipskip变量都作为 TeX 寄存器实现。因此,如果你尝试

\dim_set:Nn \l_my_dim { 10 }
\dim_set:Nn \l_my_dim { a }  

TeX 会报错。由于它们的实现方式,你也会得到一个错误

\int_set:Nn \l_tmpa_tl { foo }

尽管

\int_set:Nn \l_undefined_int { 10 }

抱怨未定义的控制序列。

另一方面,tlclistfppropseq目前)作为宏实现。TeX 在此处不进行错误检查,因此它们的区别取决于代码如何expl3尝试操作它们。对这些数据类型的赋值不依赖于它们的开始定义(尽管在检查处于活动状态时,expl3如果您尝试设置未定义的,某些代码会发出警告)。因此

\prop_set:Nnn \l_tmpa_tl { foo } { bar }

可以正常工作,但你会遇到麻烦

\seq_pop:NN \l_tmpa_tl \l_tmpb_tl

因为代码实现\seq_pop:NN是围绕输入流中留下的某些标记而设计的。

这里有几点值得注意:

  1. 原则上,我们至少可以实现propseq作为 tok,因为它们无需在没有\..._use:N函数的情况下扩展。tl数据类型明确地在没有访问器的情况下扩展。

  2. Bruno 有一些关于制作通用“对象”的想法,这些想法可能会导致propseq以一些检查值开始,这些检查值表示expl3“我是……”。然而,tl函数总是低级的,并且会忽略这一点,所以

    \tl_set:Nn \<control sequence>
    

    无论如何都会设置控制序列。(许多“更高级别”的基于宏的函数在后台要么等于要么基于等效tl函数。)

TeX 在某些地方对数值类型做了一些强制转换。因此

\dim_set:Nn \l_tmpa_dim { 10 pt }
\int_set:Nn \l_tmpa_int { \l_tmpa_dim }
\int_show:N \l_tmpa_int

给出655360IE10 pt 以 sp 表示!

棺材的情况有点奇怪,因为它们实际上需要两个底层项,一个盒子寄存器和一个宏(prop)来存储句柄。在某一时刻,只要盒子存在,实现就会“自动生成”句柄部分,虽然目前情况并非如此,但它确实有一些优势。由于棺材内相同信息的用途多种多样,代码会明确检查数据结构是否存在,因此与其他类型不同,滥用棺材更加棘手。(我们通过这种方式避免重复出现 TeX 错误。)

综上所述,团队的建议是,除了我们记录的数据类型之外,“一切都无所谓”!的实现expl3只是宏:它无法改变 TeX 的工作方式,因此我们依赖惯例。

相关内容