在开发expl3
附加包时,我希望延续我所用语言的趋势,并且不是引入新的模式。有人能谈谈 中遵循的类型模型(如果有的话)吗expl3
?
我正在寻找的具体内容是:
来自评论:
它是底层语言概念,通过该概念,‘数据类型’具有‘类型’。什么使 a 成为 a
seq
?seq
什么说它不是 aclist
或 acoffin
?即使类型不匹配,会发生什么情况,如下所示?\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
) 实现的,但目前是作为“幕后”宏实现的。
综上所述,如果你做了“错误”的事情,具体会发生什么取决于所涉及的变量。dim
、int
、muskip
和skip
变量都作为 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 }
抱怨未定义的控制序列。
另一方面,tl
、clist
、fp
和prop
(seq
目前)作为宏实现。TeX 在此处不进行错误检查,因此它们的区别取决于代码如何expl3
尝试操作它们。对这些数据类型的赋值不依赖于它们的开始定义(尽管在检查处于活动状态时,expl3
如果您尝试设置未定义的,某些代码会发出警告)。因此
\prop_set:Nnn \l_tmpa_tl { foo } { bar }
可以正常工作,但你会遇到麻烦
\seq_pop:NN \l_tmpa_tl \l_tmpb_tl
因为代码实现\seq_pop:NN
是围绕输入流中留下的某些标记而设计的。
这里有几点值得注意:
原则上,我们至少可以实现
prop
和seq
作为 tok,因为它们无需在没有\..._use:N
函数的情况下扩展。tl
数据类型明确地在没有访问器的情况下扩展。Bruno 有一些关于制作通用“对象”的想法,这些想法可能会导致
prop
并seq
以一些检查值开始,这些检查值表示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
给出655360
,IE10 pt 以 sp 表示!
棺材的情况有点奇怪,因为它们实际上需要两个底层项,一个盒子寄存器和一个宏(prop
)来存储句柄。在某一时刻,只要盒子存在,实现就会“自动生成”句柄部分,虽然目前情况并非如此,但它确实有一些优势。由于棺材内相同信息的用途多种多样,代码会明确检查数据结构是否存在,因此与其他类型不同,滥用棺材更加棘手。(我们通过这种方式避免重复出现 TeX 错误。)
综上所述,团队的建议是,除了我们记录的数据类型之外,“一切都无所谓”!的实现expl3
只是宏:它无法改变 TeX 的工作方式,因此我们依赖惯例。